SERVER / DATABASE

Database

Database is Dowe's Dowe-owned server data contract. One query syntax can target PostgreSQL, Cloudflare D1, or Dowe Database, while handles and credentials stay server-only.

1 / MENTAL MODEL

Declare a handle, then bind results

database declares the provider connection and query executes one operation. The HTTP request is already available as req inside the handler, just like env references; the binding returned by query is available to later server statements and can be projected into a response.

dowe
handler getBlog
  database db1 provider:"dowe" host:env.DOWE_HOST port:env.DOWE_PORT account:env.DOWE_USER secret:env.DOWE_PASSWORD name:"content"
  query blog conn:db1.read table:"blogs" where:{ id:req.params.id } required:true
  return json:{ ok:true data:blog }
Part
Example
Meaning

No data

There are no records to display

2 / OPERATIONS

Choose the data flow

Use list, read, insert, update, and delete for predictable record access. Use query for the supported SQL-like read grammar. The operation syntax stays the same when the provider changes.

Operation
Use it for
Documentation route

No data

There are no records to display

3 / PROVIDERS

Three adapters, one server contract

The provider selects the Dowe adapter used in production. host, port, account, secret, and name are server-only props; Dowe never sends them to a View.

Provider
Connection contract

No data

There are no records to display

The same query against each provider

dowe
database appDb provider:"postgres"
  host:env.POSTGRES_HOST
  port:env.POSTGRES_PORT
  account:env.POSTGRES_USER
  secret:env.POSTGRES_PASSWORD
  name:env.POSTGRES_DATABASE
  entities:[Users Blogs]
  seeders:[Bootstrap]
query blogs conn:appDb.list table:"blogs"

Cloudflare D1

dowe
database appDb provider:"d1"
  account:env.ACCOUNT_ID
  secret:env.CLOUDFLARE_API_TOKEN
  name:env.DATABASE_ID
  entities:[Users Blogs]
  seeders:[Bootstrap]
query blogs conn:appDb.list table:"blogs"

Dowe Database

dowe
database appDb provider:"dowe"
  host:env.DOWE_HOST
  port:env.DOWE_PORT
  account:env.DOWE_USER
  secret:env.DOWE_PASSWORD
  name:env.DOWE_DATABASE
  entities:[Users Blogs]
  seeders:[Bootstrap]
query blogs conn:appDb.list table:"blogs"

3 / PROJECT REGISTRY

Register handles in main.dowe

A Database declaration can live in any server configuration module. Import the handle into main.dowe and list it under server.databases so migrate and seeders receive one deterministic project catalog, even before a route uses that handle.

dowe
import IconDb from "@/server/config/database"

main
  server port:8081
    databases:[IconDb]

The registry accepts only imported Database handles. It does not copy provider credentials, open connections, or expose server-only values to Views.

4 / ENTITIES AND SEEDERS

Describe shape once, seed it deterministically

entity and seeder are importable server bindings. Run dowe database migrate after entity changes: Postgres and D1 append provider SQL, while Dowe records a dynamic no-SQL head. Production applies pending migrations and seeders automatically; local development applies seeders with dowe database seeders.

dowe
entity Users
  id:string primary:true
  name:string required:true
  email:string required:true unique:true

entity Blogs
  id:string primary:true
  title:string required:true
  ownerId:string required:true index:true

seeder Bootstrap
  insert entity:Users value:{ id:"01H00000000000000000000000" name:"Admin" email:"admin@example.com" }
Part
Responsibility

No data

There are no records to display

5 / DEVELOPMENT AND PRODUCTION

The same source behaves predictably in both environments

During dowe dev, all three providers use the embedded local Database under .dowe/db/<name> and resolve only name. Seeders are not loaded or executed automatically; run dowe database seeders when local records are needed. No account, secret, external network, Wrangler process, or second D1 port is used.

During production, Dowe validates the maintained migration graph, applies pending Postgres or D1 nodes atomically, runs pending seeders atomically, and only then starts accepting traffic. Dowe Database uses authenticated WebSocket operations and does not require SQL migrations.

dowe
query appointments conn:appDb.list table:"appointments"
query appointment conn:appDb.read table:"appointments" where:{ id:req.params.id } required:true