Schemas
Declare a table, its fields and types (integer, string, uuid, json, datetime...) with options like primary key, unique, nullable and default — all in one place.
Talk to your database, typed
Ecto-inspired database layer for Lx. Describe your data with schemas and associations, build queries by composition, run them through the Repo, wrap work in transactions and evolve the schema with migrations. Adapter-based — Postgres and SQLite today.
Declare a table, its fields and types (integer, string, uuid, json, datetime...) with options like primary key, unique, nullable and default — all in one place.
belongs_to, has_many and has_one describe relations between schemas and generate the right foreign keys.
Build queries with pipe: where / or_where / order_by / limit / offset / join (inner, left, right, full, cross) / group_by / having / distinct. Inspect the SQL with to_sql.
count, sum, avg, min and max as select expressions — typed and composable like the rest of the query.
all / get / get_by / insert / insert_all / update / delete through a supervised Repo. Wrap multi-step work in transaction and transaction_batch with rollback.
Versioned Migration structs with up/down lists; ensure_migrations_table, applied_migrations, migrate_up/down drive the schema forward safely.
require "lxdb_schema"
def user_schema do
lxdb_schema:new("users")
|> lxdb_schema:field(:name, :string, %{nullable: false})
|> lxdb_schema:field(:email, :string, %{unique: true})
|> lxdb_schema:field(:age, :integer)
|> lxdb_schema:has_many(:posts, :post_schema)
end
require "lxdb_query"
q = lxdb_query:from(user_schema())
|> lxdb_query:where({:ilike, :name, "a%"})
|> lxdb_query:order_desc(:name)
|> lxdb_query:limit(10)
{:ok, {sql, params}} = lxdb_query:to_sql(q)
# SELECT * FROM users WHERE name ILIKE ? ORDER BY name DESC LIMIT 10;
require "lxdb"
lxdb:insert(:lxdb_repo, user_schema(), %{name: "Ada", email: "ada@x.io", age: 36})
lxdb:update(:lxdb_repo, user_schema(), %{age: 37}, [{:==, :name, "Ada"}])
lxdb:all(:lxdb_repo, q)
lxdb:delete(:lxdb_repo, user_schema(), [{:==, :name, "Ada"}])
lxdb:transaction(:lxdb_repo, fn(_repo) do
lxdb:insert(:lxdb_repo, user_schema(), %{name: "A"})
lxdb:insert(:lxdb_repo, user_schema(), %{name: "B"})
end)
require "lxdb"
up = [
"CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);",
"CREATE INDEX idx_users_email ON users(email);"
]
m = %lxdb:Migration{version: 20260101000000, up: up, down: ["DROP TABLE users;"]}
lxdb:migrate_up(:lxdb_repo, m)
# project.yml
dependencies:
lxdb:
path: ../../lx_libs/lxdb
lxdb_postgres:
path: ../../lx_libs/lxdb/adapters/postgres
# or lxdb_sqlite for SQLite