Indexes & constraints
Single-column constraints usually live on the column itself
(.primaryKey(), .unique(), .references(). See
Tables). For anything composite or named, pass a
config callback as the third argument of table. It receives the table and
returns an object of constraints and indexes:
import {foreignKey, index, primaryKey, table, unique, uniqueIndex} from 'rado'
const Membership = table(
'membership',
{
userId: integer().notNull(),
groupId: integer().notNull(),
nickname: text()
},
self => ({
pk: primaryKey(self.userId, self.groupId),
uniqueNickname: unique().on(self.groupId, self.nickname),
byGroup: index().on(self.groupId),
userRef: foreignKey(self.userId).references(User.id)
})
)
The object keys (pk, uniqueNickname, ...) become the constraint/index
names unless a name is given explicitly.
Primary keys
// Composite primary key
primaryKey(self.userId, self.groupId)
// Or with an explicit name
primaryKey({name: 'membership_pk', columns: [self.userId, self.groupId]})
Unique constraints
unique().on(self.email)
unique('unique_email').on(self.email)
unique().on(self.groupId, self.nickname)
// PostgreSQL: treat nulls as equal
unique().on(self.email).nullsNotDistinct()
Foreign keys
Column-level .references() covers the common case. The table-level helper
handles composite keys and explicit naming:
foreignKey(self.userId).references(User.id)
foreignKey({
name: 'order_line_fk',
columns: [self.orderId, self.lineNumber],
foreignColumns: [OrderLine.orderId, OrderLine.number]
})
Indexes
index().on(self.groupId)
uniqueIndex().on(self.email)
// Composite, with per-column ordering
index().on(self.lastName, self.firstName)
Index builders support a fluent set of options (apply what your database understands):
index()
.on(self.title)
.using(sql`gin`) // index method (postgres)
.concurrently() // create index concurrently (postgres)
.where(isNotNull(self.title)) // partial index
Ordering helpers asc(), desc(), nullsFirst(), nullsLast() are also
available on the builder.
When do they apply?
Constraints and indexes are emitted by db.create(Table) and kept up to date
by db.migrate(Table). The migration diff adds, drops and recreates indexes
and constraints to match your definition. See
Migrations.