Absolutely not a Database (WorkTable)
WorkTable is in-memory (on-disk persistence is in progress currently) storage.
Usage
WorkTable can be used just in user's code with worktable! macro. It will generate table structs and other related
structs that will be used for table logic.
worktable!;
Declaration parts
name declaration
name field is used to define table's name, and is a prefix for generated objects. For example declaration
above will generate struct TestWorkTable, so table struct will always have name as <name>WorkTable.
let table = default ;
let name = table.name;
assert_eq!;
columns declaration
columns field is used to define table's row schema. Default usage is <column_name>: <type>. But also there are some
flags that can be applied to columns as <column_name>: <type> <flags>*.
Flags list:
primary_keyflag and related to it.optionalflag.
primary_key flag declaration
If user want to mark column as primary key primary_key flag is used. This flag can be used on multiple columns at a
time. Primary key generation is also supported. For some basic types autoincrement is supported. Also custom
generation is available. In this case user must provide his own implementation.
;
;
worktable!;
For primary key newtype is generated for declared type:
// Generated code
;
optional flag declaration
If column field is Option<T>, optional flag can be used like it was done in declaration.
another: u64 optional,
Row type generation
For described column row type struct is generated:
// Generated code
This struct is used in WorkTable interface and will be used by users.
indexes declaration
indexes field is used to define table's index schema. Default usage is <index_name>: <column_name> <unique>?.
Index allows faster access to data by some field. Adding indexes field adds methods to the generated WorkTable. This
method for now is select_by_<indexed_column_name>. It will be described below.
Default implemented queries
There are some default query implementations that are available for all WorkTable's:
select(&self, pk: <Name>PrimaryKey) -> Option<<Name>Row>;insert(&self, row: <Name>Row) -> Result<<Name>PrimaryKey, WorkTableError>;upsert(&self, row: <Name>Row) -> Result<(), WorkTableError>;update(&self, row: <Name>Row) -> Result<(), WorkTableError>;delete(&self, pk: <Name>PrimaryKey) -> Result<(), WorkTableError>;select_all<'a>(&'a self) -> SelectQueryBuilder<'a, <Name>Row, Self>;
queries declaration
indexes field is used to define table's queries schema. Queries are used to update/select/delete data.
queries: {
update: {
AnotherByExchange(another) by exchange,
AnotherByTest(another) by test,
AnotherById(another) by id,
},
delete: {
ByAnother() by another,
ByExchange() by exchange,
ByTest() by test,
}
}
Default query declaration is <QueryName>(<column_name>*) by <column_name>. It is same for update/select/delete.
For each query <QueryName>Query and <QueryName>By structs are generated. They will be used by user to call the
query.
update query declaration
update queries are used to update row's data partially. Default generated update allows only full update of the row.
But if user's logic needs some simultaneous update of row parts from different code parts. update logic supports
smart lock logic that allows simultaneous update of not overlapping row fields.
select_all query declaration
select_all queries are used to select row's data. select_all query returns Result accepts next params
.where_by, Returns exact range of a column, works only with Number types,
e.g. .where_by exclusive or for inclusive .where_by, default i32; Supports multiple chain
.order_by, Returns rows sorted by column, e.g .order_by; Supports multiple chain
.offset, Skips first N records, e.g .offset -
.limit, Takes first N records, e.g .limit
The all params could be chained, for example - my_table.select_all
.where_by
.where_by
.order_by
.order_by
.limit
.offset
.execute
select_by_index_filed the same as select_all, just iterates by non unique index, for unique index returns Option<TestRow>
WorkTable internals structure
worktable
-- creates default WorkTable
in_memory
pages: >>>, // an array of pages (Data) that hold the records
empty_links: , // a stack for storing links to deleted records
row_count: AtomicU64, // a counter for the current number of records
last_page_id: AtomicU32, // identifier for last page
current_page_id: AtomicU32, // identifier for current page
Implementations
in-data
id: PageId, // the identifier of the page
inner_data: , // a byte array where rows are stored
_phantom: , // a helper field for type management
Implementations
Examples
Check out - Examples