Internal Model Representation
Internal Model Representation
As the CLI tool for making, squashing, merging, applying and reverting migrations is only written once because it is able to utilize our declarative migration format, for making migrations, it is required to include a step in your building pipeline to generate intermediate json files that represent the current model state.
The resulting JSON should live in the root of your project
directory. The cli tools assumes the JSON file has the name
.models.json
.
Intermediate JSON representation
This is an example of the intermediate representation:
{
"Models": [
{
"Name": "foo",
"SourceDefinedAt": {
"File": "/path/to/source/file.rs",
"Line": 140,
"Column": 1
},
"Fields": [
{
"Name": "foo",
"Type": "varchar",
"SourceDefinedAt": {
"File": "/path/to/source/file.rs",
"Line": 142,
"Column": 4
},
"Annotations": [
{
"Type": "primary_key"
},
{
"Type": "not_null"
},
{
"Type": "index"
},
{
"Type": "max_length",
"Value": 255,
"Column": 4
}
]
}
]
}
]
}
Explanation
Models
The Name
of a model should be already in the correct table name format.
This is enforced by the linter.
SourceDefinedAt
is an optional object that specifies the file the
model originates from as well as the line number of the start of the
model definition. If the key SourceDefinedAt
is found, File
and Line
must be there as well.
Fields
is an array of the model fields. See Fields
{
"Name": "table_name",
"SourceDefinedAt": {
"File": "/path/to/source/file.rs",
"Line": 140,
"Column": 1
},
"Fields": []
}
Fields
Fields represent a column in the database.
Name
must be in the correct column name format. For further
information, see linter.
Type
must be one of the allowed database types.
SourceDefinedAt
is an optional object that specifies the file the
field originates from as well as the line number of the start of the
field definition. If the key SourceDefinedAt
is found, File
and Line
must be there as well.
Annotation
is an array of possible annotations.
{
"Name": "foo",
"Type": "varchar",
"SourceDefinedAt": {
"File": "/path/to/source/file.rs",
"Line": 142,
"Column": 4
},
"Annotations": []
}
Annotations
Annotations must always have a key named Type
with a possible
annotation type.
Depending on the type, it may be required to add a Value
key.
The type of Value
is depending on the annotation type.
E.g. max_length
is using a value of type integer.
choices
on the other hand uses a value of type array of strings.
Annotation types
Annotation name | Value required | Value type |
---|---|---|
auto_create_time |
||
auto_update_time |
||
autoincrement |
||
choices |
array of strings | |
default |
See default | |
index |
depends | See index |
max_length |
integer | |
not_null |
||
primary_key |
||
unique |
default
One of [string, number, bool]. Default types for varbinary should be encoded using hex strings.
Index
If index
is used without a value, a new index is created on the column.
If a composite index is desired, the Name
and Priority
fields are required:
The Name
attribute is only used to determine which indexes should be
considered as composite by checking if the Name
is used more than once
in the same model.
The Priority
attribute is used to determine the order in which the fields
are placed when creating the index. This can have an impact on performance.
The lower the number, the more important is the field. More significant fields
get placed first at index creation.
If two fields have the same priority, the order in the Fields
array is used
to determine the order in the index. The order of the Fields
array should
map in the best case to the order of placement in the source code.
Database types
Type name | Additional notes |
---|---|
varchar |
max_length annotation is required |
binary |
|
int16 |
|
int32 |
|
int64 |
|
float_number |
|
double_number |
|
boolean |
|
date |
|
datetime |
|
timestamp |
|
time |
|
choices |
choices annotation is required |