Skip to content

Data model

Types

Built-in type system with typed value accessors and the SQLite column mapping.

core

Every XDB Value carries type metadata. Use it to read typed values in Go and map values to SQLite columns.

Supported Types

The user-facing type names are lowercase. Internally, XDB stores type identifiers as uppercase constants (TID). TID.Lower() returns the lowercase form for JSON output and CLI display.

TypeGo TypeSQLiteDescription
stringstringTEXTUTF-8 string
integerint64INTEGER64-bit signed integer
unsigneduint64INTEGER64-bit unsigned integer
floatfloat64REAL64-bit floating point
booleanboolINTEGERTrue or false
timetime.TimeINTEGERDate and time in UTC
jsonjson.RawMessageTEXTArbitrary JSON data
bytes[]byteBLOBBinary data
array[]*ValueTEXTArray of typed values

core.ValueTypes is the ordered list of user-facing types. From the CLI, you declare types in schema field definitions, for example {"fields":{"age":{"type":"integer"}}}. Filter predicates use the declared types. Run xdb describe --value-types for the live list.

Type Identifiers

A TID (Type ID) is a string constant that identifies a type:

core.TIDString // "STRING"
core.TIDInteger // "INTEGER"
core.TIDUnsigned // "UNSIGNED"
core.TIDFloat // "FLOAT"
core.TIDBoolean // "BOOLEAN"
core.TIDTime // "TIME"
core.TIDJSON // "JSON"
core.TIDBytes // "BYTES"
core.TIDArray // "ARRAY"
core.TIDUnknown // "UNKNOWN"

Values

A Value is a typed container. It holds the data and its type metadata.

Creating Values

Typed constructors are preferred, because they do not use reflection:

core.StringVal("hello")
core.IntVal(42)
core.UintVal(100)
core.FloatVal(3.14)
core.BoolVal(true)
core.TimeVal(time.Now())
core.JSONVal(json.RawMessage(`{"key":"val"}`))
core.BytesVal([]byte{0x01, 0x02})
core.ArrayVal(core.TIDString, core.StringVal("a"), core.StringVal("b"))

The dynamic constructors use reflection:

v, err := core.NewValue("hello") // returns ErrUnsupportedValue
v := core.MustNewValue("hello") // panics instead; for compile-time values

Accessing Values

Use the As* methods to read a value with its type. Each method returns (T, error):

s, err := value.AsStr() // string
n, err := value.AsInt() // int64
u, err := value.AsUint() // uint64
f, err := value.AsFloat() // float64
b, err := value.AsBool() // bool
t, err := value.AsTime() // time.Time
j, err := value.AsJSON() // json.RawMessage
bs, err := value.AsBytes() // []byte
a, err := value.AsArray() // []*Value

If the value does not have the requested type, the method returns ErrTypeMismatch.

A nil *Value is an attribute that is explicitly set to null. The As* methods on a nil *Value return the zero value with no error. The same As* methods on a nil Tuple return ErrAttrNotFound. A nil tuple means that the attribute is absent, which is different from an explicit null. See Tuples.

Inspecting Values

value.Type() // Type — type metadata
value.IsNil() // bool — true if the value is nil

Use As* methods for type-safe access. Unwrap() returns a raw any value without a type guarantee.

Array Types

Arrays carry an element type:

arrType := core.NewArrayType(core.TIDString) // ARRAY<STRING>
arrType.ID() // TIDArray
arrType.ElemTypeID() // TIDString

In Schema definitions, every array field must declare its element type with the elem_type JSON property. In Go, the element type is part of the Type of the field, built with core.NewArrayType. The element type is required in all modes. It is immutable after the field exists. See Schemas -> Array fields.

SQLite Type Mapping

The SQLite driver is the only driver that maps XDB types to database column types. The mapping lives in store/xdbsqlite/internal/sql:

  • SQLiteTypeName returns the column type from the table above. A strict or dynamic schema gets a column table with one column per field. A flexible schema and schema-free records get a key-value table. The key-value table stores each value in its native SQLite storage class, with _type and _elem columns that record the XDB type.

  • The Value type implements driver.Valuer and sql.Scanner. It converts a *core.Value to a SQL parameter on write and back to a *core.Value on read. A boolean is stored as 0 or 1. A time is stored as Unix milliseconds. A json value is stored as text. An array is stored as a JSON array in text form.

The other drivers (memory, filesystem, redis) have no column types. See Drivers.

  • Tuples: Tuples carry typed values

  • Schemas: Field definitions reference type IDs

  • Encoding: Type conversion during JSON serialization

  • Stores: The store facade that the drivers sit behind