feat: add core storage value model and exception types

This commit is contained in:
dualfroz committed 2026-08-24 09:47:08 +02:00
1 parent 61bcc02ea2
commit 2ca0f2b866
5 files changed
+108

No files matched your search

@@ -0,0 +1,16 @@
package kestrel
open class KestrelException(message: String) : RuntimeException(message)
class LexException(
message: String,
val line: Int,
val column: Int,
val incomplete: Boolean = false
) : KestrelException("$message at line $line, column $column")
class ParseException(
message: String,
val line: Int,
val column: Int
) : KestrelException("$message at line $line, column $column")
+3
View File
@@ -0,0 +1,3 @@
package kestrel.storage
data class Row(val values: List<Value>)
+7
View File
@@ -0,0 +1,7 @@
package kestrel.storage
import kestrel.catalog.TableSchema
class Table(val schema: TableSchema) {
val rows: MutableList<Row> = mutableListOf()
}
+52
View File
@@ -0,0 +1,52 @@
package kestrel.storage
enum class ColumnType {
Integer, Text, Boolean, Real;
val displayName: String
get() = when (this) {
Integer -> "INTEGER"
Text -> "TEXT"
Boolean -> "BOOLEAN"
Real -> "REAL"
}
companion object {
fun fromKeyword(keyword: String): ColumnType? = when (keyword.uppercase()) {
"INTEGER" -> Integer
"TEXT" -> Text
"BOOLEAN" -> Boolean
"REAL" -> Real
else -> null
}
}
}
sealed class Value {
abstract val type: ColumnType?
data class IntegerValue(val value: Long) : Value() {
override val type get() = ColumnType.Integer
}
data class RealValue(val value: Double) : Value() {
override val type get() = ColumnType.Real
}
data class TextValue(val value: String) : Value() {
override val type get() = ColumnType.Text
}
data class BooleanValue(val value: Boolean) : Value() {
override val type get() = ColumnType.Boolean
}
object NullValue : Value() {
override val type: ColumnType? get() = null
}
val isNull: Boolean get() = this is NullValue
}
val Value.typeName: String
get() = type?.displayName ?: "NULL"
@@ -0,0 +1,30 @@
package kestrel.storage
object ValueOrdering : Comparator<Value> {
override fun compare(left: Value, right: Value): Int = when {
left is Value.NullValue && right is Value.NullValue -> 0
left is Value.NullValue -> -1
right is Value.NullValue -> 1
left is Value.IntegerValue && right is Value.IntegerValue -> left.value.compareTo(right.value)
isNumeric(left) && isNumeric(right) -> asDouble(left).compareTo(asDouble(right))
left is Value.TextValue && right is Value.TextValue -> left.value.compareTo(right.value)
left is Value.BooleanValue && right is Value.BooleanValue -> left.value.compareTo(right.value)
else -> rank(left).compareTo(rank(right))
}
private fun isNumeric(value: Value): Boolean = value is Value.IntegerValue || value is Value.RealValue
private fun asDouble(value: Value): Double = when (value) {
is Value.IntegerValue -> value.value.toDouble()
is Value.RealValue -> value.value
else -> 0.0
}
private fun rank(value: Value): Int = when (value) {
is Value.NullValue -> 0
is Value.BooleanValue -> 1
is Value.IntegerValue -> 2
is Value.RealValue -> 2
is Value.TextValue -> 3
}
}