エンティティ
エンティティは Class かオブジェクトリテラル(Interface)のいずれかであり、必ず主キーを持ちます。
エンティティには、@deepkit/type
の型アノテーションを用いて必要な情報が付与されます。例えば、主キー、各フィールド、その検証制約などを定義します。これらのフィールドはデータベース構造(通常はテーブルまたはコレクション)を反映します。
Mapped<'name'>
のような特別な型アノテーションにより、フィールド名をデータベース内の別名にマッピングすることもできます。
Class
import { entity, PrimaryKey, AutoIncrement, Unique, MinLength, MaxLength } from '@deepkit/type'; @entity.name('user') class User { id: number & PrimaryKey & AutoIncrement = 0; created: Date = new Date; firstName?: string; lastName?: string; constructor( public username: string & Unique & MinLength<2> & MaxLength<16>, public email: string & Unique, ) {} } const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]); await database.migrate(); await database.persist(new User('Peter')); const allUsers = await database.query(User).find(); console.log('all users', allUsers);
Interface
import { PrimaryKey, AutoIncrement, Unique, MinLength, MaxLength } from '@deepkit/type'; interface User { id: number & PrimaryKey & AutoIncrement = 0; created: Date = new Date; firstName?: string; lastName?: string; username: string & Unique & MinLength<2> & MaxLength<16>; } const database = new Database(new SQLiteDatabaseAdapter(':memory:')); database.register<User>({name: 'user'}); await database.migrate(); const user: User = {id: 0, created: new Date, username: 'Peter'}; await database.persist(user); const allUsers = await database.query<User>().find(); console.log('all users', allUsers);
プリミティブ
String、Number(bigint)、Boolean のようなプリミティブデータ型は一般的なデータベース型にマッピングされます。TypeScript の型のみが使用されます。
interface User { logins: number; username: string; pro: boolean; }
主キー
各エンティティには主キーがちょうど1つ必要です。複数主キーはサポートされていません。
主キーの基底の型は任意で、一般的には number や UUID が使われます。 MongoDB では MongoId または ObjectID がよく使われます。
number の場合は AutoIncrement
を使用できます。
import { PrimaryKey } from '@deepkit/type'; interface User { id: number & PrimaryKey; }
オートインクリメント
挿入時に自動的にインクリメントされるべきフィールドには AutoIncrement
デコレータを付与します。すべてのアダプタがオートインクリメント値をサポートします。MongoDB アダプタはカウンタを管理するために追加のコレクションを使用します。
オートインクリメントフィールドは自動カウンタであり、主キーにのみ適用できます。データベースは ID が一度しか使用されないことを自動的に保証します。
import { PrimaryKey, AutoIncrement } from '@deepkit/type'; interface User { id: number & PrimaryKey & AutoIncrement; }
UUID
UUID(v4)型であるべきフィールドには UUID デコレータを付与します。実行時の型は string
で、データベース内では多くの場合バイナリです。新しい UUID v4 を作成するには uuid()
関数を使用します。
import { uuid, UUID, PrimaryKey } from '@deepkit/type'; class User { id: UUID & PrimaryKey = uuid(); }
MongoDB ObjectID
MongoDB で ObjectID 型であるべきフィールドには MongoId
デコレータを付与します。実行時の型は string
で、データベース内では ObjectId
(バイナリ)です。
MongoID フィールドは挿入時に自動的に新しい値が割り当てられます。フィールド名として _id
を使用する必要はありません。任意の名前にできます。
import { PrimaryKey, MongoId } from '@deepkit/type'; class User { id: MongoId & PrimaryKey = ''; }
Optional / Nullable
Optional なフィールドは、TypeScript の型として title?: string
または title: string | null
のように宣言します。これらのうちどちらか一方のみを使用するべきで、通常は undefined
とともに動作する Optional の ?
構文を用います。
どちらの書き方でも、すべての SQL アダプタにおいてデータベース型は NULLABLE
になります。したがって、この2つの記法の違いは、実行時に表す値が異なる点だけです。
次の例では、modified フィールドは Optional であるため実行時には undefined になり得ますが、データベースでは常に NULL として表現されます。
import { PrimaryKey } from '@deepkit/type'; class User { id: number & PrimaryKey = 0; modified?: Date; }
この例は nullable な型がどのように機能するかを示しています。データベースと JavaScript の実行時の両方で NULL が使用されます。これは modified?: Date
よりも冗長であり、一般的には使用されません。
import { PrimaryKey } from '@deepkit/type'; class User { id: number & PrimaryKey = 0; modified: Date | null = null; }
データベース型マッピング
|=== |実行時の型|SQLite|MySQL|Postgres|Mongo
|string|text|longtext|text|string |number|float|double|double precision|int/number |boolean|integer(1)|boolean|boolean|boolean |date|text|datetime|timestamp|datetime |array|text|json|jsonb|array |map|text|json|jsonb|object |map|text|json|jsonb|object |union|text|json|jsonb|T |uuid|blob|binary(16)|uuid|binary |ArrayBuffer/Uint8Array/...|blob|longblob|bytea|binary |===
DatabaseField
を使用すると、フィールドを任意のデータベース型にマッピングできます。型は有効な SQL 文でなければならず、そのままマイグレーションシステムに渡されます。
import { DatabaseField } from '@deepkit/type'; interface User { title: string & DatabaseField<{type: 'VARCHAR(244)'}>; }
特定のデータベース向けにフィールドをマッピングするには、SQLite
、MySQL
、Postgres
のいずれかを使用できます。
SQLite
import { SQLite } from '@deepkit/type'; interface User { title: string & SQLite<{type: 'text'}>; }
MySQL
import { MySQL } from '@deepkit/type'; interface User { title: string & MySQL<{type: 'text'}>; }
Postgres
import { Postgres } from '@deepkit/type'; interface User { title: string & Postgres<{type: 'text'}>; }