Rado GitHub

Universal column types

Import from rado/universal. These columns emit the right SQL type for whatever database the query lands on, letting you define one schema that runs on SQLite, PostgreSQL and MySQL. The database is chosen at runtime.

import {table} from 'rado'
import {boolean, id, integer, json, text} from 'rado/universal'

const User = table('user', {
  id: id(),
  name: text().notNull(),
  active: boolean(),
  settings: json<{theme: string}>()
})

Available types

ColumnJavaScript typeSQLitePostgreSQLMySQL
id()numberinteger (rowid)integer generated always as identityint not null auto_increment
text()stringtexttexttext
varchar({length})stringvarchar(n)varchar(n)varchar(n)
integer()numberintegerintegerinteger
number()numbernumericnumericdouble
boolean()booleaninteger 0/1booleantinyint(1)
json<T>()Ttextjsonjson
jsonb<T>()Tjsonbjsonbjson
blob()Uint8Arrayblobbyteablob

id() creates an auto-incrementing, non-null primary key on every dialect, with the boilerplate spelled correctly for each.

How it works

Universal columns are built on sql.universal, which carries a different SQL fragment per dialect and picks the right one when the query is emitted:

sql.universal({
  sqlite: sql`integer`,
  postgres: sql`integer generated always as identity`,
  mysql: sql`int not null auto_increment`
})

You can use the same mechanism for your own custom column types or even inside queries. See The sql tag.

Universal functions and transactions

rado/universal also exports a small set of cross-dialect SQL functions and transaction helpers used by rado internally and available to you. When you need something dialect-specific, drop down to the dialect module or the sql tag.

When to use universal columns

  • Libraries that ship with embedded database support but let users bring their own database (this is why rado exists; Alinea needed it)
  • Test suites that run the same logic against multiple engines
  • Apps that start on SQLite and want a believable Postgres exit strategy

For the full pattern of defining once and connecting differently per environment, see Universal queries.