Model
A Model is the table-level API returned by Toshihiko#define(). It creates Queries and Yukari rows and extends EventEmitter2.
const User = database.define('users', schema);Model is primarily a TypeScript type export. Applications normally obtain the runtime object from define().
class Model<
Name extends string,
Schema extends SchemaDefinition,
AdapterInstance extends AdapterLike = Adapter,
> extends EventEmitter2Metadata
| Property | Type | Description |
|---|---|---|
name | Name | Name passed to define() |
parent, toshihiko | Toshihiko<AdapterInstance> | Owning instance; toshihiko is a getter alias |
originalSchema | Schema | Definitions passed to define() |
schema | CompiledSchema<Schema> | Compiled fields |
primaryKeys | readonly Field<Schema[number]>[] | Fields marked primaryKey: true |
autoIncrementField, ai | Field<Schema[number]> | null | Auto-increment field; ai is a compatibility alias |
nameToColumn | NameToColumnMap<Schema> | Logical field name to storage column |
columnToName | Readonly<Record<string, FieldName<RowFromSchema<Schema>>>> | Storage column to logical field name |
fieldNamesMap | FieldNamesMap<Schema> | Logical field name to compiled Field |
fieldColumnsMap | Readonly<Record<string, Field<Schema[number]>>> | Storage column to compiled Field |
cache | Cache | null | Effective Model Cache |
options | ModelOptions | Options passed to define() |
A Model without primary keys emits a log warning during construction.
build()
build<const Input extends BuildInput<Schema>>(
fields: Input & Record<
Exclude<keyof Input, keyof RowFromSchema<Schema>>,
never
>,
): BuiltYukari<Name, Schema, Input, AdapterInstance>Creates a new Yukari without writing it. Input keys are restricted to schema fields.
const user = User.build({ name: 'Yukari' });
user.name; // string
user.id; // number | undefined when generated by the databaseFields supplied by the caller and fields with defaults are known on the returned type. Other schema fields remain optional until the row is loaded or assigned.
Query entry points
Each method creates a fresh Query<Name, Schema, AdapterInstance>.
where(condition: QueryWhere<RowFromSchema<Schema>>): Query<Name, Schema, AdapterInstance>
field(fields: string | readonly FieldName<RowFromSchema<Schema>>[]): Query<Name, Schema, AdapterInstance>
fields(fields: string | readonly FieldName<RowFromSchema<Schema>>[]): Query<Name, Schema, AdapterInstance>
limit(limit: number | string | readonly (number | string)[]): Query<Name, Schema, AdapterInstance>
limit(offset: number | string, count: number | string): Query<Name, Schema, AdapterInstance>
index(indexName: string): Query<Name, Schema, AdapterInstance>
order(order: QueryOrder<RowFromSchema<Schema>>): Query<Name, Schema, AdapterInstance>
orderBy(order: QueryOrder<RowFromSchema<Schema>>): Query<Name, Schema, AdapterInstance>
conn(connection: AdapterConnection<AdapterInstance> | null): Query<Name, Schema, AdapterInstance>const query = User
.where({ id: { $gte: 10 } })
.fields(['id', 'name'])
.orderBy({ id: 'desc' })
.limit(20);Immediate operations
These methods create a fresh Query and execute it immediately.
| Signature | Return type |
|---|---|
count() | Promise<number> |
update(data: Partial<RowFromSchema<Schema>>) | Promise<AdapterUpdateByQueryResult<AdapterInstance>> |
delete() | Promise<AdapterDeleteByQueryResult<AdapterInstance>> |
execute(...args: AdapterQueryExecuteArguments<AdapterInstance>) | Promise<AdapterExecuteResult<AdapterInstance>> |
Model.update() and Model.delete() have no condition. Use where() first unless the whole table is intentionally targeted.
find()
Model.find() has the same overloads as Query.find(). It creates a fresh Query before execution.
await User.find();
await User.find({ single: true });
await User.find(true);
await User.find({ noCache: true }, true);findOne()
findOne(): Promise<QueriedYukari<Name, Schema, AdapterInstance> | null>
findOne(toJSON: false): Promise<QueriedYukari<Name, Schema, AdapterInstance> | null>
findOne(toJSON: true): Promise<QueryJsonRow<Schema> | null>Creates a fresh Query and asks the Adapter for one row.
findById()
findById(id: FindByIdInput<Schema>): Promise<QueriedYukari<Name, Schema, AdapterInstance> | null>
findById(id: FindByIdInput<Schema>, toJSON: false): Promise<QueriedYukari<Name, Schema, AdapterInstance> | null>
findById(id: FindByIdInput<Schema>, toJSON: true): Promise<QueryJsonRow<Schema> | null>With one primary key, id may be that field's value. Composite keys use an object containing the key fields.
await User.findById(42);
await Membership.findById({ userId: 42, groupId: 7 });Transactions
The following methods exist only when the Adapter declares the corresponding transaction methods.
beginTransaction(): Promise<AdapterTransactionConnection<AdapterInstance>>
commit(connection: AdapterTransactionConnection<AdapterInstance>): Promise<AdapterCommitResult<AdapterInstance>>
rollback(connection: AdapterTransactionConnection<AdapterInstance>): Promise<AdapterRollbackResult<AdapterInstance>>The connection type comes from the selected Adapter. See Transactions.
Name and primary-key helpers
convertColumnToName()
convertColumnToName(column: string): FieldName | undefined
convertColumnToName(columns: readonly string[]): readonly (FieldName | undefined)[]
convertColumnToName(row: DataRow): DataRowUnknown columns are omitted from object input and become undefined for string or array input.
getPrimaryKeysName() and getPrimaryKeysColumn()
Each returns a string for one key, an array for multiple keys, or an empty array when the Model has no primary key.
Custom methods
Methods declared in define(..., { methods }) are copied onto the Model.
const User = database.define('users', schema, {
methods: {
async findByName(name: string) {
return this.where({ name }).find();
},
async findActive() {
return this.where({ active: true }).find();
},
},
});Inside either method, this contains the Model and both custom methods. The returned User exposes User.findByName() and User.findActive() with their inferred parameter and return types.
Related types
| Type | Purpose |
|---|---|
Model<Name, Schema, Adapter> | Model instance contract |
ModelOptions | Runtime Model options |
ModelDefinitionOptions | Options accepted by define() |
BuildInput<Schema> | Schema-restricted build() input |
BuiltRowFromSchema<Schema, Input> | Known and optional fields after build() |
InferModelRow<typeof Model> | Full row value type |
InferModelPrimaryKey<typeof Model> | Union of primary-key field names |
