March Docs

Depot.DbRepo

lib/api/depot_db_repo.march Depot.DbRepo: named, configured database repo registry.

An app registers a repo by name (a String), then uses that name everywhere instead of managing pool pids or sqlite conns directly.

Quick start (in your app's init or main function):

Depot.DbRepo.start_from_env("my_repo", "DATABASE_URL",
                             "postgres://localhost/myapp_dev")
Depot.DbRepo.migrate("my_repo", MyApp.Migrations.all())

Defining a thin App.Repo wrapper (Ecto-style):

mod MyApp.Repo do
  pfn name() do "my_repo" end
  fn start()         do Depot.DbRepo.start_from_env(name(), "DATABASE_URL",
                                                    "sqlite::memory:") end
  fn migrate(ms)     do Depot.DbRepo.migrate(name(), ms) end
  fn query(q)        do Depot.DbRepo.query(name(), q) end
  fn transaction(cb) do Depot.DbRepo.transaction(name(), cb) end
end

Test setup (SQLite in-memory, no server required):

let _ = Depot.DbRepo.start("test_repo", "sqlite::memory:")
let _ = Depot.DbRepo.migrate("test_repo", MyApp.Migrations.all())

Internal storage design

Two Vault tables serve as discriminated repo registries: "depot.dbrepo.sqlite" maps name -> DbConn (SQLite repos only) "depot.dbrepo.pool" maps name -> Pid (Pool repos only) Presence in a table determines repo kind — no ADT constructors in Vault, which avoids March's dynamic-dispatch issues with sum-type values.

Functions

fnmigratemigrate(name, migration_list)#
fnqueryquery(name, depot_query)#
fnstartstart(name, url)#
fnstart_from_envstart_from_env(name, env_var, default_url)#
fnstopstop(name)#
fntransactiontransaction(name, txcb)#
fnwith_connwith_conn(name, wcb)#