Example: Schema Builder === [back](../README.md) ## index - [Example: Schema Builder](#example-schema-builder) - [index](#index) - [Create table](#create-table) - [Alter Table](#alter-table) - [add column](#add-column) - [change column](#change-column) - [drop column](#drop-column) - [rename table](#rename-table) - [drop table](#drop-table) - [Migration history](#migration-history) - [seeder template](#seeder-template) - [integer](#integer) - [float](#float) - [char](#char) - [date](#date) - [others](#others) - [options](#options) - [Foreign Key Constraints](#foreign-key-constraints) --- ## Create table ```nim import allographer/schema_builder import connections # or define rdb here rdb.create( table("auth", [ Column.increments("id"), Column.uuid("uuid"), Column.string("name"), Column.timestamps() ]), table("users", [ Column.increments("id"), Column.string("name"), Column.foreign("auth_id").reference("id").onTable("auth").onDelete(SET_NULL), Column.strForeign("uuid").reference("uuid").onTable("auth").onDelete(SET_NULL) ]) ) ``` ## Alter Table ### add column ```nim rdb.alter( table("auth", [ Column.string("email").add(), ]), table("users", [ Column.string("email").unique().default("").add(), Column.foreign("auth_id").reference("id").onTable("auth").onDelete(SET_NULL).add() ]) ) ``` `>> ALTER TABLE "users" ADD COLUMN 'email' VARCHAR UNIQUE DEFAULT '' CHECK (length("email") <= 255)` ### change column ```nim rdb.alter( table("users", [ Column.renameColumn("name", "new_name"), Column.char("name", 20).unique().default("").change() ]) ) ``` - Create new table with new column definition - Rename table which you want to change column - Copy table data from old table to new table - Drop old table ### drop column ```nim rdb.alter( table("users", [ Column.dropColumn("name") ]) ) ``` ### rename table ```nim rdb.alter( table("users").renameTo("new_users") ) ``` `>> ALTER TABLE users RENAME TO new_users` ### drop table ```nim rdb.drop( table("users") ) ``` `>> DROP TABLE users` ## Migration history allographer generate `_allographer_migrations` table in your database. It has migration history data which have hash key generated a query. ```nim # migrate.nim import std/asyncdispatch import std/json import allographer/schema_builder import connections rdb.create( table("auth", [ Column.increments("id"), Column.string("name") ]), table("users", [ Column.increments("id"), Column.string("name"), Column.foreign("auth_id").reference("id").onTable("auth").onDelete(SET_NULL) ]) ) seeder rdb, "auth": rdb.table("auth").insert(@[ %*{"name": "admin"}, %*{"name": "member"} ]) .waitFor seeder rdb, "users": var data: seq[JsonNode] for i in 1..10: data.add(%*{ "name": &"user{i}", "auth_id": if i mod 2 == 0: 1 else: 2 }) rdb.table("users").insert(data).waitFor ``` ```sh # first time nim c -r migrate >> run query and generate `_allographer_migrations` table # secound time nim c -r migrate >> nothing to do # reset existsing table and run migration again nim c -r migrate --reset or nim c -d:reset -r migrate >> drop table and create table ``` ### seeder template The `seeder` block allows the code in the block to work only when the table or specified column is empty. ```nim template seeder*(rdb:Rdb, tableName:string, body:untyped):untyped template seeder*(rdb:Rdb, tableName, column:string, body:untyped):untyped ``` ## integer |Command|Description| |---|---| |`increments("id")`|Auto-incrementing UNSIGNED INTEGER (primary key) equivalent column.| |`integer("votes")`|INTEGER equivalent column.| |`smallInteger("votes")`|SMALLINT equivalent column| |`mediumInteger("votes")`|MEDIUMINT equivalent column| |`bigInteger("votes")`|UNSIGNED BIGINT equivalent column.| ## float |Command|Description| |---|---| |`decimal("amount", 8, 2)`|DECIMAL equivalent column with a precision (total digits) and scale (decimal digits).| |`double("amount", 8, 2)`|DOUBLE equivalent column with a precision (total digits) and scale (decimal digits).| |`float("float")`|FLOAT equivalent column with a implicit precision (total digits) and scale (decimal digits).| ## char |Command|Description| |---|---| |`uuid("name")`|VARCHAR indexed and unique column.| |`char("name", 100)`|CHAR equivalent column with an optional length.| |`string("name")`|VARCHAR equivalent column.| |`string("name", 100)`|VARCHAR equivalent column with a optional length.| |`text("description")`|TEXT equivalent column.| |`mediumText("description")`|MEDIUMTEXT equivalent column.| |`longText("description")`|LONGTEXT equivalent column.| ## date |Command|Description| |---|---| |`date("created_at")`|DATE equivalent column.| |`datetime("created_at")`|DATETIME equivalent column.| |`time("sunrise")`|TIME equivalent column.| |`timestamp("added_on")`|TIMESTAMP equivalent column.| |`timestamps()`|Adds nullable `created_at` and `updated_at` TIMESTAMP equivalent columns.| |`softDelete()`|Adds a nullable `deleted_at` TIMESTAMP equivalent column for soft deletes.| ## others |Command|Description| |---|---| |`binary("data")`|BLOB equivalent column.| |`boolean("confirmed")`|BOOLEAN equivalent column.| |`enumField("level", ["easy", "hard"])`|ENUM equivalent column.| |`json("options")`|JSON equivalent column.| ## options |Command|Description| |---|---| |`.nullable()`|Designate that the column allows NULL values| |`.default(value)`|Declare a default value for a column| |`.unsigned()`|Set INTEGER to UNSIGNED| |`.unique()`|Adding an unique index| |`.index()`|Adding an index| |`.comment("value")`|Adding a comment to a column. Only for Postgres, Mariadb and Mysql| ## Foreign Key Constraints For example, let's define a `user_id` column on the table that references the `id` column on a `users` table: ```nim Column.foreign("user_id") .reference("id") .onTable("users") .onDelete(SET_NULL) Column.strForeign("uuid") .reference("uuid") .onTable("users") .onDelete(SET_NULL) # use `onTable("users")` ``` arg of `onDelete` is enum - RESTRICT - CASCADE - SET_NULL - NO_ACTION