Data Types
SQLite database engine primarily stores data into the database file as Integer
, Float
, Text
, or Blob
. To incorporate this, Quill provides some custom data types for data binding and retrieval to ensure consistency, ease of use, compile-time type checks and code generations.
Scaler Types
- Int - Represents an
i64
integer number. - Bool - Represents a
bool
oftrue
orfalse
value. - Float - Represents a
f64
floating point number. - Slice - Represents a slice of
[]const u8
value.
User Defined Types
Any()
TypeCasts SQLite column data into T
when evaluated at runtime.
Example 01: Converts Text
data from a column into Zig's struct
.
Example 02: Converts Text
data from a column into Zig's enum
.
Remarks: In both of these cases Text
data of the column must be stored as stringified JSON.
CastInto()
TypeCasts T
into SQLite column data when evaluated at runtime.
Example 01: Converts enum
data into a SQLite's Integer
column.
Example 02: Converts enum
data into a SQLite's Text
column.
Example 03: Converts struct
data into a SQLite's Text
column.
Remarks: As of now, CastInto()
doesn't support .Blob
conversion for user defined types.
Record Schema
A record contains multiple fields with their corresponding data types. Quill's record is just a synonym for SQLite Row and the fields are synonym for SQLite Column.
To reduce development time, Quill automatically TypeCasts between Zig's type and SQLite data. Use following DataType
format for the appropriate use cases.
Model
Contains type definitions that are automatically casts into SQLite complaint data types. All available type combinations are:
const Gender = enum { Male, Female };
const Social = struct { website: []const u8, username: [] const u8 };
pub const ModelUser = struct {
uuid: Dt.CastInto(.Blob, Dt.Slice),
name1: Dt.CastInto(.Text, Dt.Slice),
name2: ?Dt.CastInto(.Text, Dt.Slice),
balance1: Dt.Float,
balance2: ?Dt.Float,
age1: Dt.Int,
age2: ?Dt.Int,
verified1: Dt.Bool,
verified2: ?Dt.Bool,
gender1: Dt.CastInto(.Int, Gender),
gender2: ?Dt.CastInto(.Int, Gender),
gender3: Dt.CastInto(.Text, Gender),
gender4: ?Dt.CastInto(.Text, Gender),
about1: Dt.CastInto(.Blob, Dt.Slice),
about2: ?Dt.CastInto(.Blob, Dt.Slice),
social1: Dt.CastInto(.Text, Social),
social2: ?Dt.CastInto(.Text, Social),
social3: Dt.CastInto(.Text, []const Social),
social4: ?Dt.CastInto(.Text, []const Social)
};
View
Contains type definitions that are automatically casts into Zig complaint data types. All available type combinations are:
const Gender = enum { Male, Female };
const Social = struct { website: []const u8, username: [] const u8 };
pub const ViewUser = struct {
uuid: Dt.Slice,
name1: Dt.Slice,
name2: ?Dt.Slice,
balance1: Dt.Float,
balance2: ?Dt.Float,
age1: Dt.Int,
age2: ?Dt.Int,
verified1: Dt.Bool,
verified2: ?Dt.Bool,
gender1: Dt.Any(Gender),
gender2: ?Dt.Any(Gender),
gender3: Dt.Any(Gender),
gender4: ?Dt.Any(Gender),
about1: Dt.Slice,
about2: ?Dt.Slice,
social1: Dt.Any(Social),
social2: ?Dt.Any(Social),
social3: Dt.Any([]const Social),
social4: ?Dt.Any([]const Social)
};
Filter
Contains limited number of type definitions that are automatically casts into SQL statement complaint values. All available type combinations are:
pub const FilterUser = struct {
uuid: Dt.Slice,
name1: []const Dt.Slice,
age1: Dt.Int,
balance1: []const Dt.Int,
};
Remarks: Only use Int
, Slice
, []const Int
, and []const Slice
.
Schema Directory and Naming Conversions
For a large codebase, use following convention for structural consistence.
Create a schema
directory in your project's src
directory. Within your schema directory create file such as user.zig
to represent a database container (Table). Now declare all of your Model, View, and Filter structure within this file.
- Every file (e.g.,
user.zig
) should contain aModel
andView
record structure for representing all the record fields in a container. - Any sub-structure should start with a
Model
orView
for code clarity. - Use
Filter
with informative name (e.g.,FilterProfile
) for code clarity.
pub const Model = struct {
uuid: Dt.CastInto(.Blob, Dt.Slice),
name: Dt.CastInto(.Text, Dt.Slice),
balance: Dt.Float,
age: Dt.Int
};
pub const View = struct {
uuid: Dt.Slice,
name: Dt.Slice,
balance: Dt.Float,
age: Dt.Int
};
pub const FilterId = struct { uuid: Dt.slice };
pub const FilterProfile = struct { balance: Dt.Int, age: []const Dt.Int };
pub const ModelProfile = struct {
uuid: Dt.CastInto(.Blob, Dt.Slice),
name: Dt.CastInto(.Text, Dt.Slice)
};
pub const ViewProfile = struct {
uuid: Dt.Slice,
name: Dt.Slice,
};