Moved tables to a separate project

This commit is contained in:
Alexander Nozik 2021-07-18 14:35:31 +03:00
parent a9cec666a3
commit 14455c2b2b
28 changed files with 52 additions and 1002 deletions

View File

@ -16,6 +16,7 @@
### Removed ### Removed
- Public PluginManager mutability - Public PluginManager mutability
- Tables and tables-exposed moved to the separate project `tables.kt`
### Fixed ### Fixed
- Proper json array index treatment. - Proper json array index treatment.

View File

@ -4,7 +4,7 @@ plugins {
allprojects { allprojects {
group = "space.kscience" group = "space.kscience"
version = "0.5.0-dev-1" version = "0.5.0"
} }
subprojects { subprojects {

View File

@ -164,11 +164,6 @@ public final class space/kscience/dataforge/context/PluginFactory$Companion {
} }
public final class space/kscience/dataforge/context/PluginManager : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker, space/kscience/dataforge/context/ContextAware { public final class space/kscience/dataforge/context/PluginManager : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker, space/kscience/dataforge/context/ContextAware {
public fun <init> (Lspace/kscience/dataforge/context/Context;)V
public final fun fetch (Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;Z)Lspace/kscience/dataforge/context/Plugin;
public final fun fetch (Lspace/kscience/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun fetch$default (Lspace/kscience/dataforge/context/PluginManager;Lspace/kscience/dataforge/context/PluginFactory;Lspace/kscience/dataforge/meta/Meta;ZILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun fetch$default (Lspace/kscience/dataforge/context/PluginManager;Lspace/kscience/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public final fun find (ZLkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin; public final fun find (ZLkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/context/Plugin;
public static synthetic fun find$default (Lspace/kscience/dataforge/context/PluginManager;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin; public static synthetic fun find$default (Lspace/kscience/dataforge/context/PluginManager;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/context/Plugin;
public final fun get (Lkotlin/reflect/KClass;Lspace/kscience/dataforge/context/PluginTag;Z)Ljava/lang/Object; public final fun get (Lkotlin/reflect/KClass;Lspace/kscience/dataforge/context/PluginTag;Z)Ljava/lang/Object;
@ -178,7 +173,6 @@ public final class space/kscience/dataforge/context/PluginManager : java/lang/It
public fun getContext ()Lspace/kscience/dataforge/context/Context; public fun getContext ()Lspace/kscience/dataforge/context/Context;
public fun iterator ()Ljava/util/Iterator; public fun iterator ()Ljava/util/Iterator;
public final fun list (Z)Ljava/util/Collection; public final fun list (Z)Ljava/util/Collection;
public final fun remove (Lspace/kscience/dataforge/context/Plugin;)V
} }
public final class space/kscience/dataforge/context/PluginTag : space/kscience/dataforge/meta/MetaRepr { public final class space/kscience/dataforge/context/PluginTag : space/kscience/dataforge/meta/MetaRepr {

View File

@ -1,15 +0,0 @@
plugins {
id("ru.mipt.npm.gradle.jvm")
}
dependencies {
api("org.jetbrains.exposed:exposed-core:0.31.1")
testImplementation("org.jetbrains.exposed:exposed-jdbc:0.31.1")
testImplementation("com.h2database:h2:1.4.200")
testImplementation("org.slf4j:slf4j-simple:1.7.30")
api(project(":dataforge-tables"))
}
readme {
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
}

View File

@ -1,150 +0,0 @@
package space.kscience.dataforge.exposed
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.tables.Column
import space.kscience.dataforge.tables.Row
import space.kscience.dataforge.tables.Table
import kotlin.reflect.KType
import kotlin.reflect.typeOf
import org.jetbrains.exposed.sql.Column as SqlColumn
/**
* Exposed based [Column] implementation.
*
* @param T The type of table items.
* @property db The Exposed database.
* @param sqlTable The Exposed table, which must follow the properties defined for [ExposedTable.sqlTable].
* @param sqlColumn The Exposed column.
* @param type The type of [T].
*/
public class ExposedColumn<T : Any>(
public val db: Database,
public val sqlTable: IntIdTable,
public val sqlColumn: SqlColumn<T>,
public override val type: KType,
) : Column<T> {
/**
* The name of this column.
*/
public override val name: String
get() = sqlColumn.name
/**
* Returns [Meta.EMPTY] because it is impossible to store metadata correctly with SQL columns.
*/
public override val meta: Meta
get() = Meta.EMPTY
/**
* Returns the count of rows in the table.
*/
public override val size: Int
get() = transaction(db) { sqlColumn.table.selectAll().count().toInt() }
/**
* Acquires the value of this column in the row [index].
*/
public override fun get(index: Int): T? = transaction(db) {
sqlTable.select { sqlTable.id eq index + 1 }.firstOrNull()?.getOrNull(sqlColumn)
}
}
/**
* Exposed based [Row] implementation.
*
* @param T The type of table items.
* @param db The Exposed database.
* @param sqlTable The Exposed table, which must follow the properties defined for [ExposedTable.sqlTable].
* @param sqlRow The Exposed row.
*/
@Suppress("UNCHECKED_CAST")
public class ExposedRow<T : Any>(
public val db: Database,
public val sqlTable: IntIdTable,
public val sqlRow: ResultRow,
) :
Row<T> {
/**
* Acquires the value of [column] in this row.
*/
public override fun get(column: String): T? = transaction(db) {
val theColumn = sqlTable.columns.find { it.name == column } as SqlColumn<T>? ?: return@transaction null
sqlRow.getOrNull(theColumn)
}
}
/**
* Exposed based [Table] implementation.
*
* @property db The Exposed database.
*
* @property sqlTable The Exposed table. It must have the following properties:
* 1. Integer `id` column must be present with auto-increment by sequence 1, 2, 3&hellip;
* 1. All other columns must be of type [T].
*
* @property type The type of [T].
*/
@Suppress("UNCHECKED_CAST")
public class ExposedTable<T : Any>(public val db: Database, public val sqlTable: IntIdTable, public val type: KType) :
Table<T> {
/**
* The list of columns in this table.
*/
public override val columns: List<ExposedColumn<T>> =
sqlTable.columns.filterNot { it.name == "id" }.map { ExposedColumn(db, sqlTable, it as SqlColumn<T>, type) }
/**
* The list of rows in this table.
*/
public override val rows: List<ExposedRow<T>>
get() = transaction(db) {
sqlTable.selectAll().map { ExposedRow(db, sqlTable, it) }
}
public override operator fun get(row: Int, column: String): T? = transaction(db) {
val sqlColumn: SqlColumn<T> = sqlTable.columns.find { it.name == column } as SqlColumn<T>?
?: return@transaction null
sqlTable.select { sqlTable.id eq row + 1 }.firstOrNull()?.getOrNull(sqlColumn)
}
}
/**
* Constructs [ExposedTable].
*
* @param T The type of table items.
* @param db The Exposed database.
* @param sqlTable The Exposed table, which must follow the properties defined for [ExposedTable.sqlTable].
* @return A new [ExposedTable].
*/
public inline fun <reified T : Any> ExposedTable(db: Database, sqlTable: IntIdTable): ExposedTable<T> =
ExposedTable(db, sqlTable, typeOf<T>())
/**
* Constructs [ExposedTable].
*
* @param T The type of table items.
* @param db The Exposed database.
* @param tableName The name of table.
* @param columns The list of columns' names.
* @param sqlColumnType The [IColumnType] for [T].
* @return A new [ExposedTable].
*/
public inline fun <reified T : Any> ExposedTable(
db: Database,
tableName: String,
columns: List<String>,
sqlColumnType: IColumnType,
): ExposedTable<T> {
val table = object : IntIdTable(tableName) {
init {
columns.forEach { registerColumn<T>(it, sqlColumnType) }
}
}
transaction(db) { SchemaUtils.createMissingTablesAndColumns(table) }
return ExposedTable(db, table)
}

View File

@ -1,40 +0,0 @@
package space.kscience.dataforge.exposed
import org.jetbrains.exposed.sql.Column
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.IntegerColumnType
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.transactions.transaction
import kotlin.test.Test
import kotlin.test.assertEquals
@Suppress("UNCHECKED_CAST")
internal class ExposedTableTest {
@Test
fun exposedTable() {
val db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")
val table = ExposedTable<Int>(
db,
"test",
listOf("a", "b", "c"),
IntegerColumnType(),
)
transaction(db) {
table.sqlTable.insert {
it[table.sqlTable.columns.find { t -> t.name == "a" } as Column<Int>] = 42
it[table.sqlTable.columns.find { t -> t.name == "b" } as Column<Int>] = 3
it[table.sqlTable.columns.find { t -> t.name == "c" } as Column<Int>] = 7
}
}
assertEquals(42, table[0, "a"])
assertEquals(3, table[0, "b"])
assertEquals(7, table[0, "c"])
assertEquals(3, table.columns.size)
table.columns.forEach { assertEquals(1, it.size) }
assertEquals(1, table.rows.size)
}
}

View File

@ -1,6 +1,6 @@
public abstract class space/kscience/dataforge/meta/AbstractMutableMeta : space/kscience/dataforge/meta/AbstractTypedMeta, space/kscience/dataforge/meta/MutableMeta { public abstract class space/kscience/dataforge/meta/AbstractMutableMeta : space/kscience/dataforge/meta/AbstractTypedMeta, space/kscience/dataforge/meta/MutableMeta {
public fun <init> ()V public fun <init> ()V
protected final fun getChildren ()Ljava/util/Map; protected abstract fun getChildren ()Ljava/util/Map;
public fun getItems ()Ljava/util/Map; public fun getItems ()Ljava/util/Map;
protected fun replaceItem (Lspace/kscience/dataforge/names/NameToken;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/TypedMetaItem;)V protected fun replaceItem (Lspace/kscience/dataforge/names/NameToken;Lspace/kscience/dataforge/meta/TypedMetaItem;Lspace/kscience/dataforge/meta/TypedMetaItem;)V
public fun setItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)V public fun setItem (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/TypedMetaItem;)V
@ -11,35 +11,8 @@ public abstract class space/kscience/dataforge/meta/AbstractTypedMeta : space/ks
public fun <init> ()V public fun <init> ()V
} }
public final class space/kscience/dataforge/meta/Config : space/kscience/dataforge/meta/AbstractMutableMeta, space/kscience/dataforge/meta/ItemPropertyProvider {
public static final field ConfigSerializer Lspace/kscience/dataforge/meta/Config$ConfigSerializer;
public fun <init> ()V
public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta;
public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
public fun removeListener (Ljava/lang/Object;)V
public synthetic fun wrapNode (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/MutableMeta;
}
public final class space/kscience/dataforge/meta/Config$ConfigSerializer : kotlinx/serialization/KSerializer {
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/meta/Config;
public final fun empty ()Lspace/kscience/dataforge/meta/Config;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/meta/Config;)V
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class space/kscience/dataforge/meta/ConfigKt {
public static final fun asConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config;
public static final fun copy (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/Config;
public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Config;
public static final fun get (Lspace/kscience/dataforge/meta/Config;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static final fun toConfig (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Config;
}
public abstract interface class space/kscience/dataforge/meta/Configurable { public abstract interface class space/kscience/dataforge/meta/Configurable {
public abstract fun getConfig ()Lspace/kscience/dataforge/meta/Config; public abstract fun getConfig ()Lspace/kscience/dataforge/meta/ObservableMeta;
} }
public final class space/kscience/dataforge/meta/ConfigurableKt { public final class space/kscience/dataforge/meta/ConfigurableKt {
@ -95,9 +68,6 @@ public final class space/kscience/dataforge/meta/ItemDelegateKt {
public static synthetic fun value$default (Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; public static synthetic fun value$default (Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty;
} }
public abstract interface class space/kscience/dataforge/meta/ItemPropertyProvider : space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/ObservableItemProvider {
}
public abstract interface class space/kscience/dataforge/meta/ItemProvider { public abstract interface class space/kscience/dataforge/meta/ItemProvider {
public static final field Companion Lspace/kscience/dataforge/meta/ItemProvider$Companion; public static final field Companion Lspace/kscience/dataforge/meta/ItemProvider$Companion;
public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem; public abstract fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
@ -188,12 +158,16 @@ public final class space/kscience/dataforge/meta/Meta$Companion {
} }
public abstract class space/kscience/dataforge/meta/MetaBase : space/kscience/dataforge/meta/Meta { public abstract class space/kscience/dataforge/meta/MetaBase : space/kscience/dataforge/meta/Meta {
public static final field Companion Lspace/kscience/dataforge/meta/MetaBase$Companion;
public fun <init> ()V public fun <init> ()V
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I public fun hashCode ()I
public fun toString ()Ljava/lang/String; public fun toString ()Ljava/lang/String;
} }
public final class space/kscience/dataforge/meta/MetaBase$Companion {
}
public final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/dataforge/meta/AbstractMutableMeta { public final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/dataforge/meta/AbstractMutableMeta {
public fun <init> ()V public fun <init> ()V
public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta; public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta;
@ -399,23 +373,46 @@ public final class space/kscience/dataforge/meta/MutableMetaKt {
public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V public static final fun append (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V
} }
public abstract interface class space/kscience/dataforge/meta/ObservableItemProvider : space/kscience/dataforge/meta/ItemProvider { public abstract interface class space/kscience/dataforge/meta/ObservableItemProvider : space/kscience/dataforge/meta/ItemProvider, space/kscience/dataforge/meta/MutableItemProvider {
public abstract fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V public abstract fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V
public abstract fun removeListener (Ljava/lang/Object;)V public abstract fun removeListener (Ljava/lang/Object;)V
} }
public final class space/kscience/dataforge/meta/ObservableItemProviderKt { public final class space/kscience/dataforge/meta/ObservableItemProviderKt {
public static final fun ObservableMeta ()Lspace/kscience/dataforge/meta/ObservableMeta;
public static final fun asObservable (Lspace/kscience/dataforge/meta/MutableItemProvider;)Lspace/kscience/dataforge/meta/ObservableItemProvider;
public static final fun asObservable (Lspace/kscience/dataforge/meta/MutableMeta;)Lspace/kscience/dataforge/meta/ObservableMeta;
public static final fun copy (Lspace/kscience/dataforge/meta/ObservableMeta;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ObservableMeta;
public static synthetic fun copy$default (Lspace/kscience/dataforge/meta/ObservableMeta;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/ObservableMeta;
public static final fun get (Lspace/kscience/dataforge/meta/ObservableMeta;Lspace/kscience/dataforge/names/NameToken;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public static final fun useProperty (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)V
public static synthetic fun useProperty$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V public static synthetic fun useProperty$default (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lkotlin/reflect/KProperty1;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V
} }
public abstract interface class space/kscience/dataforge/meta/ObservableMeta : space/kscience/dataforge/meta/MutableMeta, space/kscience/dataforge/meta/ObservableItemProvider {
}
public final class space/kscience/dataforge/meta/ObservableMetaSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lspace/kscience/dataforge/meta/ObservableMetaSerializer;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/meta/ObservableMeta;
public final fun empty ()Lspace/kscience/dataforge/meta/ObservableMeta;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/meta/ObservableMeta;)V
}
public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification { public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecification {
public abstract fun empty ()Lspace/kscience/dataforge/meta/ItemProvider; public abstract fun empty ()Lspace/kscience/dataforge/meta/ItemProvider;
public fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider; public fun invoke (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/ItemProvider;
public abstract fun read (Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/ItemProvider; public abstract fun read (Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/ItemProvider;
} }
public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/ItemPropertyProvider, space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/descriptors/Described { public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/ObservableItemProvider, space/kscience/dataforge/meta/descriptors/Described {
public fun <init> ()V public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/ItemProvider;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/ItemProvider;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
protected fun getDefaultItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta; public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta;
public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
@ -522,16 +519,16 @@ public final class space/kscience/dataforge/meta/descriptors/ItemDescriptor$Comp
public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/descriptors/ItemDescriptor { public abstract class space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder : space/kscience/dataforge/meta/Configurable, space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion; public static final field Companion Lspace/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder$Companion;
public static final field DEFAULT_INDEX_KEY Ljava/lang/String; public static final field DEFAULT_INDEX_KEY Ljava/lang/String;
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Lspace/kscience/dataforge/meta/ObservableMeta;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public abstract fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public abstract fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun getAttributes ()Lspace/kscience/dataforge/meta/Config;
public synthetic fun getAttributes ()Lspace/kscience/dataforge/meta/Meta; public synthetic fun getAttributes ()Lspace/kscience/dataforge/meta/Meta;
public final fun getConfig ()Lspace/kscience/dataforge/meta/Config; public fun getAttributes ()Lspace/kscience/dataforge/meta/ObservableMeta;
public final fun getConfig ()Lspace/kscience/dataforge/meta/ObservableMeta;
public fun getIndexKey ()Ljava/lang/String; public fun getIndexKey ()Ljava/lang/String;
public fun getInfo ()Ljava/lang/String; public fun getInfo ()Ljava/lang/String;
public fun getMultiple ()Z public fun getMultiple ()Z
public abstract fun getRequired ()Z public abstract fun getRequired ()Z
public fun setAttributes (Lspace/kscience/dataforge/meta/Config;)V public fun setAttributes (Lspace/kscience/dataforge/meta/ObservableMeta;)V
public fun setIndexKey (Ljava/lang/String;)V public fun setIndexKey (Ljava/lang/String;)V
public fun setInfo (Ljava/lang/String;)V public fun setInfo (Ljava/lang/String;)V
public fun setMultiple (Z)V public fun setMultiple (Z)V
@ -551,7 +548,7 @@ public final class space/kscience/dataforge/meta/descriptors/ItemDescriptorKt {
public abstract interface class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor { public abstract interface class space/kscience/dataforge/meta/descriptors/NodeDescriptor : space/kscience/dataforge/meta/descriptors/ItemDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion; public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor$Companion;
public abstract fun getDefault ()Lspace/kscience/dataforge/meta/Config; public abstract fun getDefault ()Lspace/kscience/dataforge/meta/Meta;
public abstract fun getDefaultMeta ()Lspace/kscience/dataforge/meta/Laminate; public abstract fun getDefaultMeta ()Lspace/kscience/dataforge/meta/Laminate;
public abstract fun getItems ()Ljava/util/Map; public abstract fun getItems ()Ljava/util/Map;
public abstract fun getNodes ()Ljava/util/Map; public abstract fun getNodes ()Ljava/util/Map;
@ -565,11 +562,12 @@ public final class space/kscience/dataforge/meta/descriptors/NodeDescriptor$Comp
public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/NodeDescriptor { public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/NodeDescriptor {
public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion; public static final field Companion Lspace/kscience/dataforge/meta/descriptors/NodeDescriptorBuilder$Companion;
public fun <init> ()V public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Config;)V public fun <init> (Lspace/kscience/dataforge/meta/ObservableMeta;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Lspace/kscience/dataforge/meta/ObservableMeta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun build ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor; public fun build ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
public fun getDefault ()Lspace/kscience/dataforge/meta/Config; public synthetic fun getDefault ()Lspace/kscience/dataforge/meta/Meta;
public fun getDefault ()Lspace/kscience/dataforge/meta/ObservableMeta;
public fun getDefaultMeta ()Lspace/kscience/dataforge/meta/Laminate; public fun getDefaultMeta ()Lspace/kscience/dataforge/meta/Laminate;
public fun getDefaultValue ()Lspace/kscience/dataforge/meta/TypedMetaItem; public fun getDefaultValue ()Lspace/kscience/dataforge/meta/TypedMetaItem;
public fun getItems ()Ljava/util/Map; public fun getItems ()Ljava/util/Map;
@ -580,7 +578,7 @@ public final class space/kscience/dataforge/meta/descriptors/NodeDescriptorBuild
public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V public final fun item (Lspace/kscience/dataforge/names/Name;Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;)V
public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V public final fun node (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
public fun setDefault (Lspace/kscience/dataforge/meta/Config;)V public fun setDefault (Lspace/kscience/dataforge/meta/ObservableMeta;)V
public fun setRequired (Z)V public fun setRequired (Z)V
public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V public final fun value (Lspace/kscience/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
@ -604,8 +602,8 @@ public abstract interface class space/kscience/dataforge/meta/descriptors/ValueD
public final class space/kscience/dataforge/meta/descriptors/ValueDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/ValueDescriptor { public final class space/kscience/dataforge/meta/descriptors/ValueDescriptorBuilder : space/kscience/dataforge/meta/descriptors/ItemDescriptorBuilder, space/kscience/dataforge/meta/descriptors/ValueDescriptor {
public fun <init> ()V public fun <init> ()V
public fun <init> (Lspace/kscience/dataforge/meta/Config;)V public fun <init> (Lspace/kscience/dataforge/meta/ObservableMeta;)V
public synthetic fun <init> (Lspace/kscience/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> (Lspace/kscience/dataforge/meta/ObservableMeta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun allow ([Ljava/lang/Object;)V public final fun allow ([Ljava/lang/Object;)V
public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor; public synthetic fun build ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
public fun build ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor; public fun build ()Lspace/kscience/dataforge/meta/descriptors/ValueDescriptor;
@ -668,7 +666,7 @@ public final class space/kscience/dataforge/meta/transformations/MetaConverterKt
public final class space/kscience/dataforge/meta/transformations/MetaTransformation { public final class space/kscience/dataforge/meta/transformations/MetaTransformation {
public static final field Companion Lspace/kscience/dataforge/meta/transformations/MetaTransformation$Companion; public static final field Companion Lspace/kscience/dataforge/meta/transformations/MetaTransformation$Companion;
public static final fun apply-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta; public static final fun apply-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/Meta;
public static final fun bind-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/Config;Lspace/kscience/dataforge/meta/MutableMeta;)V public static final fun bind-impl (Ljava/util/Collection;Lspace/kscience/dataforge/meta/ObservableMeta;Lspace/kscience/dataforge/meta/MutableMeta;)V
public static final synthetic fun box-impl (Ljava/util/Collection;)Lspace/kscience/dataforge/meta/transformations/MetaTransformation; public static final synthetic fun box-impl (Ljava/util/Collection;)Lspace/kscience/dataforge/meta/transformations/MetaTransformation;
public static fun constructor-impl (Ljava/util/Collection;)Ljava/util/Collection; public static fun constructor-impl (Ljava/util/Collection;)Ljava/util/Collection;
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z

View File

@ -21,6 +21,7 @@ public interface MetaRepr {
* *
* * Same name siblings are supported via elements with the same [Name] but different queries * * Same name siblings are supported via elements with the same [Name] but different queries
*/ */
@Serializable(MetaSerializer::class)
public interface Meta : MetaRepr, ItemProvider { public interface Meta : MetaRepr, ItemProvider {
/** /**
* Top level items of meta tree * Top level items of meta tree

View File

@ -5,7 +5,6 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.* import space.kscience.dataforge.names.*
import kotlin.js.JsName import kotlin.js.JsName
import kotlin.jvm.Synchronized import kotlin.jvm.Synchronized
@ -123,7 +122,6 @@ public fun ObservableMeta(): ObservableMeta = MetaBuilder().asObservable()
* *
* Optional [owner] property is used for * Optional [owner] property is used for
*/ */
@DFExperimental
public fun <O : ObservableItemProvider, T> O.useProperty( public fun <O : ObservableItemProvider, T> O.useProperty(
property: KProperty1<O, T>, property: KProperty1<O, T>,
owner: Any? = null, owner: Any? = null,

View File

@ -17,7 +17,7 @@ public open class Scheme(
private var items: ObservableItemProvider = ObservableMeta(), private var items: ObservableItemProvider = ObservableMeta(),
final override var descriptor: NodeDescriptor? = null, final override var descriptor: NodeDescriptor? = null,
private var default: ItemProvider? = null private var default: ItemProvider? = null
) : Described, MetaRepr, ObservableItemProvider, MutableItemProvider { ) : Described, MetaRepr, ObservableItemProvider {
/** /**
* Add a listener to this scheme changes. If the inner provider is observable, then listening will be delegated to it. * Add a listener to this scheme changes. If the inner provider is observable, then listening will be delegated to it.

View File

@ -11,17 +11,17 @@ class MetaDelegateTest {
NO NO
} }
class InnerSpec : Scheme() { class InnerScheme : Scheme() {
var innerValue by string() var innerValue by string()
companion object : SchemeSpec<InnerSpec>(::InnerSpec) companion object : SchemeSpec<InnerScheme>(::InnerScheme)
} }
class TestScheme : Scheme() { class TestScheme : Scheme() {
var myValue by string() var myValue by string()
var safeValue by double(2.2) var safeValue by double(2.2)
var enumValue by enum(TestEnum.YES) var enumValue by enum(TestEnum.YES)
var inner by spec(InnerSpec) var inner by spec(InnerScheme)
companion object : SchemeSpec<TestScheme>(::TestScheme) companion object : SchemeSpec<TestScheme>(::TestScheme)
} }
@ -33,7 +33,7 @@ class MetaDelegateTest {
testObject.set("myValue","theString".asValue()) testObject.set("myValue","theString".asValue())
testObject.enumValue = TestEnum.NO testObject.enumValue = TestEnum.NO
testObject.inner = InnerSpec { innerValue = "ddd" } testObject.inner = InnerScheme { innerValue = "ddd" }
assertEquals("theString", testObject.myValue) assertEquals("theString", testObject.myValue)
assertEquals(TestEnum.NO, testObject.enumValue) assertEquals(TestEnum.NO, testObject.enumValue)

View File

@ -1,21 +0,0 @@
plugins {
id("ru.mipt.npm.gradle.mpp")
id("ru.mipt.npm.gradle.native")
}
kotlin {
sourceSets {
commonMain{
dependencies {
api(project(":dataforge-context"))
api(project(":dataforge-io"))
api(kotlin("reflect"))
}
}
}
}
readme{
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
}

View File

@ -1,10 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import kotlin.reflect.KType
public data class ColumnDef<out T : Any>(
override val name: String,
override val type: KType,
override val meta: Meta
): ColumnHeader<T>

View File

@ -1,37 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.int
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.values.Value
import space.kscience.dataforge.values.ValueType
import kotlin.reflect.KType
public typealias TableHeader<C> = List<ColumnHeader<C>>
public typealias ValueTableHeader = List<ColumnHeader<Value>>
public interface ColumnHeader<out T : Any> {
public val name: String
public val type: KType
public val meta: Meta
}
public data class SimpleColumnHeader<T : Any>(
override val name: String,
override val type: KType,
override val meta: Meta
) : ColumnHeader<T>
public val ColumnHeader<Value>.valueType: ValueType? get() = meta["valueType"].string?.let { ValueType.valueOf(it) }
public val ColumnHeader<Value>.textWidth: Int
get() = meta["columnWidth"].int ?: when (valueType) {
ValueType.NUMBER -> 8
ValueType.STRING -> 16
ValueType.BOOLEAN -> 5
ValueType.NULL -> 5
ValueType.LIST -> 32
null -> 16
}

View File

@ -1,17 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Scheme
import space.kscience.dataforge.meta.SchemeSpec
import space.kscience.dataforge.meta.enum
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.values.ValueType
public open class ColumnScheme : Scheme() {
public var title: String? by string()
public companion object : SchemeSpec<ColumnScheme>(::ColumnScheme)
}
public class ValueColumnScheme : ColumnScheme() {
public var valueType: ValueType by enum(ValueType.STRING)
}

View File

@ -1,26 +0,0 @@
package space.kscience.dataforge.tables
/**
* @param T bottom type for all columns in the table
*/
public class ColumnTable<T : Any>(override val columns: Collection<Column<T>>) : Table<T> {
private val rowsNum = columns.first().size
init {
require(columns.all { it.size == rowsNum }) { "All columns must be of the same size" }
}
override val rows: List<Row<T>>
get() = (0 until rowsNum).map { VirtualRow(this, it) }
override fun get(row: Int, column: String): T? = columns[column]?.get(row)
}
internal class VirtualRow<T : Any>(val table: Table<T>, val index: Int) : Row<T> {
override fun get(column: String): T? = table.get(index, column)
// override fun <T : C> get(columnHeader: ColumnHeader<T>): T? {
// return table.co[columnHeader][index]
// }
}

View File

@ -1,36 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class ListColumn<T : Any>(
override val name: String,
private val data: List<T?>,
override val type: KType,
override val meta: Meta
) : Column<T> {
override val size: Int get() = data.size
override fun get(index: Int): T? = data[index]
public companion object {
public inline operator fun <reified T : Any> invoke(
name: String,
def: ColumnScheme,
data: List<T?>
): ListColumn<T> = ListColumn(name, data, typeOf<T>(), def.toMeta())
public inline operator fun <reified T : Any> invoke(
name: String,
def: ColumnScheme,
size: Int,
dataBuilder: (Int) -> T?
): ListColumn<T> = invoke(name, def, List(size, dataBuilder))
}
}
public inline fun <T : Any, reified R : Any> Column<T>.map(meta: Meta = this.meta, noinline block: (T?) -> R): Column<R> {
val data = List(size) { block(get(it)) }
return ListColumn(name, data, typeOf<R>(), meta)
}

View File

@ -1,31 +0,0 @@
package space.kscience.dataforge.tables
/**
* Mutable table with a fixed size, but dynamic columns
*/
public class MutableColumnTable<C: Any>(public val size: Int) : Table<C> {
private val _columns = ArrayList<Column<C>>()
override val columns: List<Column<C>> get() = _columns
override val rows: List<Row<C>> get() = (0 until size).map {
VirtualRow(this, it)
}
override fun get(row: Int, column: String): C? = columns[column]?.get(row)
/**
* Add a fixed column to the end of the table
*/
public fun add(column: Column<C>) {
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
_columns.add(column)
}
/**
* Insert a column at [index]
*/
public fun insert(index: Int, column: Column<C>) {
require(column.size == this.size) { "Required column size $size, but found ${column.size}" }
_columns.add(index, column)
}
}

View File

@ -1,50 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.values.Value
import kotlin.properties.PropertyDelegateProvider
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class MutableTable<C : Any>(
override val rows: MutableList<Row<C>>,
override val headers: MutableList<ColumnHeader<C>>,
) : RowTable<C>(rows, headers) {
@PublishedApi
internal fun <T : C> addColumn(name: String, type: KType, meta: Meta): ColumnHeader<T> {
val column = SimpleColumnHeader<T>(name, type, meta)
headers.add(column)
return column
}
public inline fun <reified T : C> addColumn(
name: String,
noinline columnMetaBuilder: ColumnScheme.() -> Unit = {},
): ColumnHeader<T> = addColumn(name, typeOf<T>(), ColumnScheme(columnMetaBuilder).toMeta())
public inline fun <reified T : C> column(
noinline columnMetaBuilder: ColumnScheme.() -> Unit = {}
): PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, ColumnHeader<T>>> =
PropertyDelegateProvider { _, property ->
val res = addColumn<T>(property.name, columnMetaBuilder)
ReadOnlyProperty { _, _ -> res }
}
public fun row(map: Map<String, C?>): Row<C> {
val row = MapRow(map)
rows.add(row)
return row
}
public fun <T : C> row(vararg pairs: Pair<ColumnHeader<T>, T>): Row<C> =
row(pairs.associate { it.first.name to it.second })
}
public fun MutableTable<Value>.row(vararg pairs: Pair<ColumnHeader<Value>, Any?>): Row<Value> =
row(pairs.associate { it.first.name to Value.of(it.second) })
public fun <C : Any> Table<C>.edit(block: MutableTable<C>.() -> Unit): Table<C> {
return MutableTable(rows.toMutableList(), headers.toMutableList()).apply(block)
}

View File

@ -1,34 +0,0 @@
package space.kscience.dataforge.tables
import kotlinx.coroutines.flow.toList
import space.kscience.dataforge.meta.Meta
import kotlin.jvm.JvmInline
import kotlin.reflect.KType
@JvmInline
public value class MapRow<C : Any>(private val values: Map<String, C?>) : Row<C> {
override fun get(column: String): C? = values[column]
}
internal class RowTableColumn<T : Any, R : T>(val table: Table<T>, val header: ColumnHeader<R>) : Column<R> {
init {
require(header in table.headers){"Header $header does not belong to $table"}
}
override val name: String get() = header.name
override val type: KType get() = header.type
override val meta: Meta get() = header.meta
override val size: Int get() = table.rows.size
@Suppress("UNCHECKED_CAST")
override fun get(index: Int): R? = table[index, name]?.let { it as R}
}
public open class RowTable<C : Any>(override val rows: List<Row<C>>, override val headers: List<ColumnHeader<C>>) :
Table<C> {
override fun get(row: Int, column: String): C? = rows[row].get(column)
override val columns: List<Column<C>> get() = headers.map { RowTableColumn(this, it) }
}
public suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), headers)

View File

@ -1,57 +0,0 @@
package space.kscience.dataforge.tables
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
/**
* Finite or infinite row set. Rows are produced in a lazy suspendable [Flow].
* Each row must contain at least all the fields mentioned in [headers].
*/
public interface Rows<out T : Any> {
public val headers: TableHeader<T>
public fun rowFlow(): Flow<Row<T>>
}
public interface Table<out T : Any> : Rows<T> {
public operator fun get(row: Int, column: String): T?
public val columns: Collection<Column<T>>
override val headers: TableHeader<T> get() = columns.toList()
public val rows: List<Row<T>>
override fun rowFlow(): Flow<Row<T>> = rows.asFlow()
/**
* Apply typed query to this table and return lazy [Flow] of resulting rows. The flow could be empty.
*/
//fun select(query: Any): Flow<Row> = error("Query of type ${query::class} is not supported by this table")
public companion object {
public inline operator fun <T : Any> invoke(block: MutableTable<T>.() -> Unit): Table<T> =
MutableTable<T>(arrayListOf(), arrayListOf()).apply(block)
}
}
public operator fun <T : Any> Collection<Column<T>>.get(name: String): Column<T>? = find { it.name == name }
public inline operator fun <T : Any, reified R : T> Table<T>.get(row: Int, column: ColumnHeader<R>): R? {
require(headers.contains(column)) { "Column $column is not in table headers" }
return get(row, column.name) as? R
}
public interface Column<out T : Any> : ColumnHeader<T> {
public val size: Int
public operator fun get(index: Int): T?
}
public val Column<*>.indices: IntRange get() = (0 until size)
public operator fun <T : Any> Column<T>.iterator(): Iterator<T?> = iterator {
for (i in indices) {
yield(get(i))
}
}
public interface Row<out T : Any> {
public operator fun get(column: String): T?
}
public inline operator fun <T : Any, reified R : T> Row<T>.get(column: ColumnHeader<R>): R? = get(column.name) as? R

View File

@ -1,65 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
* A virtual column obtained by transforming Given row to a single value
*/
public class TransformationColumn<T : Any, R : Any>(
public val table: Table<T>,
override val type: KType,
override val name: String,
override val meta: Meta,
public val mapper: (Row<T>) -> R?,
) : Column<R> {
override val size: Int get() = table.rows.size
override fun get(index: Int): R? = mapper(table.rows[index])
}
/**
* A virtual column obtained via transformation of single column with caching results on call (evaluation is lazy).
*
* Calls are not thread safe
*/
public class CachedTransformationColumn<T : Any, R : Any>(
public val table: Table<T>,
override val type: KType,
override val name: String,
override val meta: Meta,
public val mapper: (Row<T>) -> R?,
) : Column<R> {
override val size: Int get() = table.rows.size
private val values: HashMap<Int, R?> = HashMap()
override fun get(index: Int): R? = values.getOrPut(index) { mapper(table.rows[index]) }
}
/**
* Create a virtual column from a given column
*/
public inline fun <T : Any, reified R : Any> Table<T>.mapRows(
name: String,
meta: Meta = Meta.EMPTY,
cache: Boolean = false,
noinline mapper: (Row<T>) -> R?,
): Column<R> = if (cache) {
CachedTransformationColumn(this, typeOf<R>(), name, meta, mapper)
} else {
TransformationColumn(this, typeOf<R>(), name, meta, mapper)
}
public fun <T : Any> Table<T>.mapRowsToDouble(
name: String,
meta: Meta = Meta.EMPTY,
block: (Row<T>) -> Double,
): RealColumn {
val data = DoubleArray(rows.size) { block(rows[it]) }
return RealColumn(name, data, meta)
}
public fun <T : Any> Table<T>.mapRowsToInt(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Int): IntColumn {
val data = IntArray(rows.size) { block(rows[it]) }
return IntColumn(name, data, meta)
}

View File

@ -1,151 +0,0 @@
package space.kscience.dataforge.tables.io
import io.ktor.utils.io.core.Output
import io.ktor.utils.io.core.readBytes
import kotlinx.coroutines.flow.*
import space.kscience.dataforge.io.Binary
import space.kscience.dataforge.io.readSafeUtf8Line
import space.kscience.dataforge.io.writeUtf8String
import space.kscience.dataforge.tables.*
import space.kscience.dataforge.values.*
/**
* Read a lin as a fixed width [Row]
*/
private fun readRow(header: ValueTableHeader, line: String): Row<Value> {
val values = line.trim().split("\\s+".toRegex()).map { it.lazyParseValue() }
if (values.size == header.size) {
val map = header.map { it.name }.zip(values).toMap()
return MapRow(map)
} else {
error("Can't read line \"$line\". Expected ${header.size} values in a line, but found ${values.size}")
}
}
/**
* Finite or infinite [Rows] created from a fixed width text binary
*/
public class TextRows(override val headers: ValueTableHeader, private val binary: Binary) : Rows<Value> {
/**
* A flow of indexes of string start offsets ignoring empty strings
*/
public fun indexFlow(): Flow<Int> = binary.read {
//TODO replace by line reader
val text = readBytes().decodeToString()
text.lineSequence()
.map { it.trim() }
.filter { it.isNotEmpty() }
.scan(0) { acc, str -> acc + str.length }.asFlow()
// var counter: Int = 0
// flow {
// do {
// val line = readUTF8Line()
// counter += line?.length ?: 0
// if (!line.isNullOrBlank()) {
// emit(counter)
// }
// } while (!endOfInput)
// }
}
override fun rowFlow(): Flow<Row<Value>> = binary.read {
val text = readBytes().decodeToString()
text.lineSequence()
.map { it.trim() }
.filter { it.isNotEmpty() }
.map { readRow(headers, it) }.asFlow()
// flow {
// do {
// val line = readUTF8Line()
// if (!line.isNullOrBlank()) {
// val row = readRow(headers, line)
// emit(row)
// }
// } while (!endOfInput)
// }
}
public companion object
}
/**
* Create a row offset index for [TextRows]
*/
public suspend fun TextRows.buildRowIndex(): List<Int> = indexFlow().toList()
/**
* Finite table created from [RandomAccessBinary] with fixed width text table
*/
public class TextTable(
override val headers: ValueTableHeader,
private val binary: Binary,
public val index: List<Int>,
) : Table<Value> {
override val columns: Collection<Column<Value>> get() = headers.map { RowTableColumn(this, it) }
override val rows: List<Row<Value>> get() = index.map { readAt(it) }
override fun rowFlow(): Flow<Row<Value>> = TextRows(headers, binary).rowFlow()
private fun readAt(offset: Int): Row<Value> {
return binary.read(offset) {
val line = readSafeUtf8Line()
return@read readRow(headers, line)
}
}
override fun get(row: Int, column: String): Value? {
val offset = index[row]
return readAt(offset)[column]
}
public companion object {
public suspend operator fun invoke(header: ValueTableHeader, binary: Binary): TextTable {
val index = TextRows(header, binary).buildRowIndex()
return TextTable(header, binary, index)
}
}
}
/**
* Write a fixed width value to the output
*/
private fun Output.writeValue(value: Value, width: Int, left: Boolean = true) {
require(width > 5) { "Width could not be less than 5" }
val str: String = when (value.type) {
ValueType.NUMBER -> value.numberOrNull.toString() //TODO apply decimal format
ValueType.STRING, ValueType.LIST -> value.string.take(width)
ValueType.BOOLEAN -> if (value.boolean) {
"true"
} else {
"false"
}
ValueType.NULL -> "@null"
}
val padded = if (left) {
str.padEnd(width)
} else {
str.padStart(width)
}
writeUtf8String(padded)
}
/**
* Write rows without header to the output
*/
public suspend fun Output.writeRows(rows: Rows<Value>) {
val widths: List<Int> = rows.headers.map {
it.textWidth
}
rows.rowFlow().collect { row ->
rows.headers.forEachIndexed { index, columnHeader ->
writeValue(row[columnHeader] ?: Null, widths[index])
}
// appendLine()
writeUtf8String("\r\n")
}
}

View File

@ -1,43 +0,0 @@
package space.kscience.dataforge.tables.io
import space.kscience.dataforge.io.Binary
import space.kscience.dataforge.io.Envelope
import space.kscience.dataforge.io.asBinary
import space.kscience.dataforge.io.buildByteArray
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.tables.SimpleColumnHeader
import space.kscience.dataforge.tables.Table
import space.kscience.dataforge.values.Value
import kotlin.reflect.typeOf
public suspend fun Table<Value>.toEnvelope(): Envelope = Envelope {
meta {
headers.forEachIndexed { index, columnHeader ->
set("column", index.toString(), Meta {
"name" put columnHeader.name
if (!columnHeader.meta.isEmpty()) {
"meta" put columnHeader.meta
}
})
}
}
type = "table.value"
dataID = "valueTable[${this@toEnvelope.hashCode()}]"
data = buildByteArray {
writeRows(this@toEnvelope)
}.asBinary()
}
@DFExperimental
public fun TextRows.Companion.readEnvelope(envelope: Envelope): TextRows {
val header = envelope.meta.getIndexed("column")
.entries.sortedBy { it.key?.toInt() }
.map { (_, item) ->
SimpleColumnHeader<Value>(item.node["name"].string!!, typeOf<Value>(), item.node["meta"].node ?: Meta.EMPTY)
}
return TextRows(header, envelope.data ?: Binary.EMPTY)
}

View File

@ -1,84 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import kotlin.reflect.KType
import kotlin.reflect.typeOf
public class RealColumn(
override val name: String,
public val data: DoubleArray,
override val meta: Meta = Meta.EMPTY
) : Column<Double> {
override val type: KType get() = typeOf<Double>()
override val size: Int get() = data.size
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
override inline fun get(index: Int): Double = data[index]
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is RealColumn) return false
if (name != other.name) return false
if (!data.contentEquals(other.data)) return false
if (meta != other.meta) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + data.contentHashCode()
result = 31 * result + meta.hashCode()
return result
}
public companion object {
public inline operator fun <reified T : Any> invoke(
name: String,
data: DoubleArray,
noinline metaBuilder: ColumnScheme.() -> Unit
): RealColumn = RealColumn(name, data, ColumnScheme(metaBuilder).toMeta())
}
}
public class IntColumn(
override val name: String,
public val data: IntArray,
override val meta: Meta = Meta.EMPTY
) : Column<Int> {
override val type: KType get() = typeOf<Int>()
override val size: Int get() = data.size
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
override inline fun get(index: Int): Int = data[index]
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is IntColumn) return false
if (name != other.name) return false
if (!data.contentEquals(other.data)) return false
if (meta != other.meta) return false
return true
}
override fun hashCode(): Int {
var result = name.hashCode()
result = 31 * result + data.contentHashCode()
result = 31 * result + meta.hashCode()
return result
}
public companion object {
public inline operator fun <reified T : Any> invoke(
name: String,
data: IntArray,
noinline metaBuilder: ColumnScheme.() -> Unit
): IntColumn = IntColumn(name, data, ColumnScheme(metaBuilder).toMeta())
}
}

View File

@ -1,37 +0,0 @@
package space.kscience.dataforge.tables
import space.kscience.dataforge.meta.Meta
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
@Suppress("UNCHECKED_CAST")
public fun <T : Any> Column<*>.cast(type: KType): Column<T> {
return if (type.isSubtypeOf(this.type)) {
this as Column<T>
} else {
CastColumn(this, type)
}
}
private class CastColumn<T : Any>(private val origin: Column<*>, override val type: KType) : Column<T> {
override val name: String get() = origin.name
override val meta: Meta get() = origin.meta
override val size: Int get() = origin.size
@Suppress("UNCHECKED_CAST")
override fun get(index: Int): T? = origin[index]?.let {
it as T
}
}
public class ColumnProperty<C: Any, T : C>(public val table: Table<C>, public val type: KType) : ReadOnlyProperty<Any?, Column<T>> {
override fun getValue(thisRef: Any?, property: KProperty<*>): Column<T> {
val name = property.name
return (table.columns[name] ?: error("Column with name $name not found in the table")).cast(type)
}
}
public operator fun <C: Any, T : C> Collection<Column<C>>.get(header: ColumnHeader<T>): Column<T>? =
find { it.name == header.name }?.cast(header.type)

View File

@ -1,35 +0,0 @@
package space.kscience.dataforge.tables.io
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.runBlocking
import space.kscience.dataforge.io.toByteArray
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.tables.Table
import space.kscience.dataforge.tables.row
import space.kscience.dataforge.values.Value
import space.kscience.dataforge.values.int
import space.kscience.dataforge.values.string
import kotlin.test.Test
import kotlin.test.assertEquals
@DFExperimental
class TextRowsTest {
val table = Table<Value> {
val a by column<Value>()
val b by column<Value>()
row(a to 1, b to "b1")
row(a to 2, b to "b2")
}
@Test
fun testTableWriteRead() = runBlocking {
val envelope = table.toEnvelope()
val string = envelope.data!!.toByteArray().decodeToString()
println(string)
val table = TextRows.readEnvelope(envelope)
val rows = table.rowFlow().toList()
assertEquals(1, rows[0]["a"]?.int)
assertEquals("b2", rows[1]["b"]?.string)
}
}

View File

@ -21,9 +21,6 @@ include(
":dataforge-io:dataforge-io-yaml", ":dataforge-io:dataforge-io-yaml",
":dataforge-context", ":dataforge-context",
":dataforge-data", ":dataforge-data",
// ":dataforge-output",
":dataforge-tables",
":dataforge-workspace", ":dataforge-workspace",
":dataforge-exposed",
":dataforge-scripting" ":dataforge-scripting"
) )