@lunarhue/expo-wa-sqlite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +9 -0
- package/.lovely-docs.yaml +11 -0
- package/LICENSE +21 -0
- package/demo/next.config.mjs +17 -0
- package/demo/package.json +26 -0
- package/demo/scripts/copy-wasm.mjs +14 -0
- package/demo/src/app/layout.tsx +16 -0
- package/demo/src/app/page.tsx +16 -0
- package/demo/src/app/todos.tsx +118 -0
- package/demo/src/db/schema.ts +7 -0
- package/demo/tsconfig.json +18 -0
- package/lovely-docs/drizzle-orm/arktype.md +113 -0
- package/lovely-docs/drizzle-orm/batch-api.md +35 -0
- package/lovely-docs/drizzle-orm/cache.md +145 -0
- package/lovely-docs/drizzle-orm/check-migrations.md +52 -0
- package/lovely-docs/drizzle-orm/column_types/mysql-column-types.md +76 -0
- package/lovely-docs/drizzle-orm/column_types/postgresql_column_types.md +314 -0
- package/lovely-docs/drizzle-orm/column_types/singlestore-column-types.md +171 -0
- package/lovely-docs/drizzle-orm/column_types/sqlite_column_types.md +132 -0
- package/lovely-docs/drizzle-orm/column_types.md +76 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/case-insensitive-unique-email.md +113 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/conditional-filters-in-query.md +69 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/count-rows.md +76 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/cursor-based-pagination.md +142 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/d1_http_api_configuration.md +49 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/decrementing-a-value.md +36 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/empty-array-default-value.md +43 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/full-text-search-with-generated-columns.md +73 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/gel-auth-extension.md +89 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/include-or-exclude-columns.md +51 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/incrementing-a-value.md +36 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/limit-offset-pagination.md +104 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/mysql-local-setup.md +55 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/point-datatype-psql.md +79 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgis-geometry-point.md +115 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgresql-full-text-search.md +150 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/postgresql-local-setup.md +55 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/seeding-with-option.md +69 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/seeding-with-partially-exposed-schema.md +60 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/select-parent-rows-with-at-least-one-related-child-row.md +74 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/timestamp-default-value.md +93 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/toggling-a-boolean-field.md +20 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/update-many-with-different-values.md +50 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/upsert.md +169 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes/vector-similarity-search.md +79 -0
- package/lovely-docs/drizzle-orm/common_patterns_&_recipes.md +787 -0
- package/lovely-docs/drizzle-orm/connect-aws-data-api-pg.md +47 -0
- package/lovely-docs/drizzle-orm/connect-bun-sql.md +35 -0
- package/lovely-docs/drizzle-orm/connect-bun-sqlite.md +42 -0
- package/lovely-docs/drizzle-orm/connect-cloudflare-d1.md +61 -0
- package/lovely-docs/drizzle-orm/connect-cloudflare-do.md +86 -0
- package/lovely-docs/drizzle-orm/connect-neon.md +72 -0
- package/lovely-docs/drizzle-orm/connect-nile.md +84 -0
- package/lovely-docs/drizzle-orm/connect-pglite.md +39 -0
- package/lovely-docs/drizzle-orm/connect-planetscale.md +37 -0
- package/lovely-docs/drizzle-orm/connect-prisma-postgres.md +48 -0
- package/lovely-docs/drizzle-orm/connect-sqlite-cloud.md +29 -0
- package/lovely-docs/drizzle-orm/connect-supabase.md +45 -0
- package/lovely-docs/drizzle-orm/connect-tidb-serverless.md +35 -0
- package/lovely-docs/drizzle-orm/connect-turso-database.md +28 -0
- package/lovely-docs/drizzle-orm/connect-turso.md +60 -0
- package/lovely-docs/drizzle-orm/connect-vercel-postgres.md +37 -0
- package/lovely-docs/drizzle-orm/connect-xata.md +29 -0
- package/lovely-docs/drizzle-orm/custom-migrations.md +40 -0
- package/lovely-docs/drizzle-orm/custom-types.md +137 -0
- package/lovely-docs/drizzle-orm/database-connection-overview.md +89 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/bun-sql-existing.md +59 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/bun-sqlite-existing.md +48 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/bun-sqlite-new.md +34 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/d1-new.md +74 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/expo-sqlite-setup.md +169 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/gel-existing-project.md +81 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/get-started-bun-sql.md +29 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/getting_started_with_gel.md +85 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/mysql-existing-project.md +32 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/mysql-setup.md +43 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/neon-existing-project.md +39 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/neon-setup.md +45 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/nile-existing-project.md +66 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/nile-setup.md +59 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/op-sqlite_setup_guide.md +135 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/pglite-existing-project.md +67 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/pglite-setup.md +33 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/planetscale-existing-project.md +70 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/planetscale-setup.md +46 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/postgresql-existing-project.md +57 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/postgresql-setup.md +44 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/singlestore-existing-project.md +22 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/singlestore-setup.md +37 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-cloud-existing-project.md +52 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-cloud-setup.md +53 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-durable-objects-setup.md +163 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-existing-project.md +36 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/sqlite-new.md +28 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/supabase-existing-project.md +32 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/tidb-existing-project.md +25 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/tidb-serverless-setup.md +41 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/turso-database-existing.md +61 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/turso-database-setup.md +60 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/turso-existing.md +74 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/turso-new.md +78 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/vercel-postgres-existing-project.md +71 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/vercel-postgres-setup.md +46 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/xata-existing-project.md +32 -0
- package/lovely-docs/drizzle-orm/database_setup_guides/xata-new.md +30 -0
- package/lovely-docs/drizzle-orm/database_setup_guides.md +144 -0
- package/lovely-docs/drizzle-orm/delete.md +57 -0
- package/lovely-docs/drizzle-orm/drizzle-config-file.md +252 -0
- package/lovely-docs/drizzle-orm/drizzle-kit-up.md +43 -0
- package/lovely-docs/drizzle-orm/dynamic-query-building.md +68 -0
- package/lovely-docs/drizzle-orm/eslint-plugin.md +76 -0
- package/lovely-docs/drizzle-orm/expo-sqlite.md +101 -0
- package/lovely-docs/drizzle-orm/export.md +88 -0
- package/lovely-docs/drizzle-orm/faq.md +28 -0
- package/lovely-docs/drizzle-orm/filter-and-conditional-operators.md +169 -0
- package/lovely-docs/drizzle-orm/gel-setup.md +37 -0
- package/lovely-docs/drizzle-orm/generate.md +119 -0
- package/lovely-docs/drizzle-orm/generated-columns.md +128 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/drizzle-with-turso.md +159 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/drizzle_with_nile_database.md +195 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/neon_postgres_integration.md +157 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/supabase_integration.md +150 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/vercel-postgres-setup.md +152 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations/xata_integration.md +143 -0
- package/lovely-docs/drizzle-orm/getting_started/database_integrations.md +117 -0
- package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/drizzle_with_vercel_edge_functions.md +220 -0
- package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/netlify_edge_functions_with_neon_postgres.md +120 -0
- package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/netlify_edge_functions_with_supabase.md +94 -0
- package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration/supabase_edge_functions_integration.md +116 -0
- package/lovely-docs/drizzle-orm/getting_started/edge_functions_integration.md +63 -0
- package/lovely-docs/drizzle-orm/getting_started/todo_app_with_neon_postgres.md +323 -0
- package/lovely-docs/drizzle-orm/getting_started.md +443 -0
- package/lovely-docs/drizzle-orm/graphql.md +107 -0
- package/lovely-docs/drizzle-orm/http-proxy-driver.md +138 -0
- package/lovely-docs/drizzle-orm/indexes-constraints.md +135 -0
- package/lovely-docs/drizzle-orm/insert.mdx.md +118 -0
- package/lovely-docs/drizzle-orm/joins.md +145 -0
- package/lovely-docs/drizzle-orm/kit-overview.md +81 -0
- package/lovely-docs/drizzle-orm/migrate.md +54 -0
- package/lovely-docs/drizzle-orm/migration_guides/migrate-from-sequelize.md +335 -0
- package/lovely-docs/drizzle-orm/migration_guides/migrate-from-typeorm.md +317 -0
- package/lovely-docs/drizzle-orm/migration_guides/migrate_from_prisma_to_drizzle.md +258 -0
- package/lovely-docs/drizzle-orm/migration_guides.md +201 -0
- package/lovely-docs/drizzle-orm/migrations.md +50 -0
- package/lovely-docs/drizzle-orm/mysql-setup.md +51 -0
- package/lovely-docs/drizzle-orm/op-sqlite-setup.md +80 -0
- package/lovely-docs/drizzle-orm/overview.md +69 -0
- package/lovely-docs/drizzle-orm/postgresql-setup.md +71 -0
- package/lovely-docs/drizzle-orm/postgresql_extensions.md +93 -0
- package/lovely-docs/drizzle-orm/prepared-statements.md +77 -0
- package/lovely-docs/drizzle-orm/prisma-extension.md +46 -0
- package/lovely-docs/drizzle-orm/pull.md +134 -0
- package/lovely-docs/drizzle-orm/push.md +129 -0
- package/lovely-docs/drizzle-orm/queries-and-crud.md +72 -0
- package/lovely-docs/drizzle-orm/quick-start.md +63 -0
- package/lovely-docs/drizzle-orm/react-native-sqlite-setup.md +1 -0
- package/lovely-docs/drizzle-orm/read-replicas.md +66 -0
- package/lovely-docs/drizzle-orm/relational-queries.md +271 -0
- package/lovely-docs/drizzle-orm/relations.md +194 -0
- package/lovely-docs/drizzle-orm/release_notes/live-queries.md +27 -0
- package/lovely-docs/drizzle-orm/release_notes/pglite_driver_support.md +14 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.11.0_release.md +139 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.16.2_release_notes.md +86 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.23.2_release.md +5 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.27.2_-_unique_constraints_support.md +66 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.0_release_notes.md +80 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.1_release.md +7 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.2_release_notes.md +18 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.3_release_notes.md +48 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.4_release.md +8 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.5_release_notes.md +7 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.28.6_release_notes.md +54 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.0_release_notes.md +143 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.1_release_notes.md +72 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.2_release_notes.md +95 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.3_release.md +7 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.4_release_notes.md +40 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.29.5_release_notes.md +69 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.0_release_notes.md +31 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.10_release.md +18 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.1_release_notes.md +16 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.2_release_notes.md +7 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.3_release_notes.md +8 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.5_release_notes.md +20 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.7_release.md +5 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.8_release_notes.md +36 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.30.9_release.md +29 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.31.0_release_notes.md +186 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.31.2_tidb_cloud_serverless_support.md +16 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.31.3_release.md +19 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.31.4_release.md +1 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.32.0_release_notes.md +136 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.32.1_release_notes.md +15 -0
- package/lovely-docs/drizzle-orm/release_notes/v0.32.2_release.md +13 -0
- package/lovely-docs/drizzle-orm/release_notes/xata-http-driver-support.md +27 -0
- package/lovely-docs/drizzle-orm/release_notes.md +25 -0
- package/lovely-docs/drizzle-orm/rls.mdx.md +385 -0
- package/lovely-docs/drizzle-orm/schema-declaration.md +239 -0
- package/lovely-docs/drizzle-orm/schemas.md +63 -0
- package/lovely-docs/drizzle-orm/seed-generators.md +220 -0
- package/lovely-docs/drizzle-orm/seed-limitations.md +3 -0
- package/lovely-docs/drizzle-orm/seed-overview.md +155 -0
- package/lovely-docs/drizzle-orm/seed-versioning.md +85 -0
- package/lovely-docs/drizzle-orm/select.md +411 -0
- package/lovely-docs/drizzle-orm/sequences.md +62 -0
- package/lovely-docs/drizzle-orm/serverless-performance.md +21 -0
- package/lovely-docs/drizzle-orm/set-operations.md +127 -0
- package/lovely-docs/drizzle-orm/singlestore-setup.md +57 -0
- package/lovely-docs/drizzle-orm/sql-template.md +127 -0
- package/lovely-docs/drizzle-orm/sqlite-setup.md +65 -0
- package/lovely-docs/drizzle-orm/studio.md +47 -0
- package/lovely-docs/drizzle-orm/transactions.md +83 -0
- package/lovely-docs/drizzle-orm/type-helpers-and-utilities.md +160 -0
- package/lovely-docs/drizzle-orm/typebox.md +110 -0
- package/lovely-docs/drizzle-orm/update.md +79 -0
- package/lovely-docs/drizzle-orm/upgrade-to-0.21.0.md +40 -0
- package/lovely-docs/drizzle-orm/valibot.md +115 -0
- package/lovely-docs/drizzle-orm/views.md +135 -0
- package/lovely-docs/drizzle-orm/why-drizzle.md +66 -0
- package/lovely-docs/drizzle-orm/zod.md +113 -0
- package/lovely-docs/drizzle-orm.md +60 -0
- package/package.json +24 -0
- package/src/index.ts +186 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
## Constraints
|
|
2
|
+
|
|
3
|
+
**DEFAULT**: Specifies default value for a column if no value provided on INSERT. Can be a constant, expression, or NULL.
|
|
4
|
+
```typescript
|
|
5
|
+
integer('col').default(42)
|
|
6
|
+
integer('col').default(sql`'42'::integer`)
|
|
7
|
+
uuid('col').defaultRandom()
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
**NOT NULL**: Enforces column to not accept NULL values.
|
|
11
|
+
```typescript
|
|
12
|
+
integer('col').notNull()
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**UNIQUE**: Ensures all values in column are different. Can be single or composite (multiple columns). Supports custom names and NULLS NOT DISTINCT (PostgreSQL 15+).
|
|
16
|
+
```typescript
|
|
17
|
+
integer('id').unique()
|
|
18
|
+
integer('id').unique('custom_name')
|
|
19
|
+
// Composite
|
|
20
|
+
pgTable('table', { id: integer('id'), name: text('name') }, (t) => [
|
|
21
|
+
unique().on(t.id, t.name),
|
|
22
|
+
unique('custom_name').on(t.id, t.name),
|
|
23
|
+
unique().on(t.id).nullsNotDistinct() // PG 15+
|
|
24
|
+
])
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**CHECK**: Limits value range for a column or based on multiple columns.
|
|
28
|
+
```typescript
|
|
29
|
+
pgTable('users', {
|
|
30
|
+
id: uuid().defaultRandom().primaryKey(),
|
|
31
|
+
username: text().notNull(),
|
|
32
|
+
age: integer(),
|
|
33
|
+
}, (table) => [
|
|
34
|
+
check('age_check1', sql`${table.age} > 21`)
|
|
35
|
+
])
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**PRIMARY KEY**: Uniquely identifies each record. Must be UNIQUE and NOT NULL. Only one per table, can be single or composite column.
|
|
39
|
+
```typescript
|
|
40
|
+
serial('id').primaryKey()
|
|
41
|
+
text('cuid').primaryKey()
|
|
42
|
+
// Composite
|
|
43
|
+
pgTable('books_to_authors', {
|
|
44
|
+
authorId: integer('author_id'),
|
|
45
|
+
bookId: integer('book_id'),
|
|
46
|
+
}, (table) => [
|
|
47
|
+
primaryKey({ columns: [table.bookId, table.authorId] }),
|
|
48
|
+
primaryKey({ name: 'custom_name', columns: [table.bookId, table.authorId] })
|
|
49
|
+
])
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**FOREIGN KEY**: References PRIMARY KEY in another table. Prevents actions that destroy links between tables. Can be declared inline or standalone.
|
|
53
|
+
```typescript
|
|
54
|
+
// Inline
|
|
55
|
+
integer('author_id').references(() => user.id)
|
|
56
|
+
|
|
57
|
+
// Self-reference (requires explicit return type)
|
|
58
|
+
integer('parent_id').references((): AnyPgColumn => user.id)
|
|
59
|
+
|
|
60
|
+
// Standalone
|
|
61
|
+
pgTable('user', {
|
|
62
|
+
id: serial('id'),
|
|
63
|
+
name: text('name'),
|
|
64
|
+
parentId: integer('parent_id'),
|
|
65
|
+
}, (table) => [
|
|
66
|
+
foreignKey({
|
|
67
|
+
columns: [table.parentId],
|
|
68
|
+
foreignColumns: [table.id],
|
|
69
|
+
name: 'custom_fk'
|
|
70
|
+
})
|
|
71
|
+
])
|
|
72
|
+
|
|
73
|
+
// Multicolumn
|
|
74
|
+
pgTable('profile', {
|
|
75
|
+
id: serial('id'),
|
|
76
|
+
userFirstName: text('user_first_name'),
|
|
77
|
+
userLastName: text('user_last_name'),
|
|
78
|
+
}, (table) => [
|
|
79
|
+
foreignKey({
|
|
80
|
+
columns: [table.userFirstName, table.userLastName],
|
|
81
|
+
foreignColumns: [user.firstName, user.lastName],
|
|
82
|
+
name: 'custom_fk'
|
|
83
|
+
})
|
|
84
|
+
])
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Indexes
|
|
88
|
+
|
|
89
|
+
Drizzle ORM supports `index()` and `uniqueIndex()` declarations.
|
|
90
|
+
|
|
91
|
+
**Basic usage**:
|
|
92
|
+
```typescript
|
|
93
|
+
pgTable('user', {
|
|
94
|
+
id: serial('id').primaryKey(),
|
|
95
|
+
name: text('name'),
|
|
96
|
+
email: text('email'),
|
|
97
|
+
}, (table) => [
|
|
98
|
+
index('name_idx').on(table.name),
|
|
99
|
+
uniqueIndex('email_idx').on(table.email)
|
|
100
|
+
])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**PostgreSQL (0.31.0+)** supports advanced index API:
|
|
104
|
+
```typescript
|
|
105
|
+
// With .on()
|
|
106
|
+
index('name')
|
|
107
|
+
.on(table.column1.asc(), table.column2.nullsFirst())
|
|
108
|
+
.concurrently()
|
|
109
|
+
.where(sql`condition`)
|
|
110
|
+
.with({ fillfactor: '70' })
|
|
111
|
+
|
|
112
|
+
// With .using()
|
|
113
|
+
index('name')
|
|
114
|
+
.using('btree', table.column1.asc(), sql`lower(${table.column2})`)
|
|
115
|
+
.where(sql`condition`)
|
|
116
|
+
.with({ fillfactor: '70' })
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**MySQL** supports:
|
|
120
|
+
```typescript
|
|
121
|
+
index('name')
|
|
122
|
+
.on(table.name)
|
|
123
|
+
.algorythm('default' | 'copy' | 'inplace')
|
|
124
|
+
.using('btree' | 'hash')
|
|
125
|
+
.lock('none' | 'default' | 'exclusive' | 'shared')
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**SQLite** supports:
|
|
129
|
+
```typescript
|
|
130
|
+
index('name')
|
|
131
|
+
.on(table.name)
|
|
132
|
+
.where(sql`condition`)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Supported across PostgreSQL, MySQL, SQLite, and SingleStore (with varying feature support).
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
## Insert one row
|
|
2
|
+
```typescript
|
|
3
|
+
await db.insert(users).values({ name: 'Andrew' });
|
|
4
|
+
```
|
|
5
|
+
Type inference: `type NewUser = typeof users.$inferInsert;`
|
|
6
|
+
|
|
7
|
+
## Insert returning
|
|
8
|
+
Supported in PostgreSQL and SQLite:
|
|
9
|
+
```typescript
|
|
10
|
+
await db.insert(users).values({ name: "Dan" }).returning();
|
|
11
|
+
await db.insert(users).values({ name: "Partial Dan" }).returning({ insertedId: users.id });
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Insert $returningId
|
|
15
|
+
MySQL and SingleStore alternative (no native RETURNING support). Returns inserted IDs for autoincrement primary keys:
|
|
16
|
+
```typescript
|
|
17
|
+
const result = await db.insert(usersTable).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
|
|
18
|
+
// ^? { id: number }[]
|
|
19
|
+
```
|
|
20
|
+
Also works with custom primary keys using `$defaultFn`:
|
|
21
|
+
```typescript
|
|
22
|
+
const usersTableDefFn = mysqlTable('users_default_fn', {
|
|
23
|
+
customId: varchar('id', { length: 256 }).primaryKey().$defaultFn(createId),
|
|
24
|
+
name: text('name').notNull(),
|
|
25
|
+
});
|
|
26
|
+
const result = await db.insert(usersTableDefFn).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
|
|
27
|
+
// ^? { customId: string }[]
|
|
28
|
+
```
|
|
29
|
+
If no primary keys exist, type is `{}[]`.
|
|
30
|
+
|
|
31
|
+
## Insert multiple rows
|
|
32
|
+
```typescript
|
|
33
|
+
await db.insert(users).values([{ name: 'Andrew' }, { name: 'Dan' }]);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## On conflict do nothing
|
|
37
|
+
PostgreSQL and SQLite:
|
|
38
|
+
```typescript
|
|
39
|
+
await db.insert(users).values({ id: 1, name: 'John' }).onConflictDoNothing();
|
|
40
|
+
await db.insert(users).values({ id: 1, name: 'John' }).onConflictDoNothing({ target: users.id });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## On conflict do update
|
|
44
|
+
PostgreSQL and SQLite:
|
|
45
|
+
```typescript
|
|
46
|
+
await db.insert(users).values({ id: 1, name: 'Dan' }).onConflictDoUpdate({ target: users.id, set: { name: 'John' } });
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
With `where` clauses using `targetWhere` (partial indexes) and `setWhere` (update conditions):
|
|
50
|
+
```typescript
|
|
51
|
+
await db.insert(employees).values({ employeeId: 123, name: 'John Doe' }).onConflictDoUpdate({
|
|
52
|
+
target: employees.employeeId,
|
|
53
|
+
targetWhere: sql`name <> 'John Doe'`,
|
|
54
|
+
set: { name: sql`excluded.name` }
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await db.insert(employees).values({ employeeId: 123, name: 'John Doe' }).onConflictDoUpdate({
|
|
58
|
+
target: employees.employeeId,
|
|
59
|
+
set: { name: 'John Doe' },
|
|
60
|
+
setWhere: sql`name <> 'John Doe'`
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Composite indexes/primary keys:
|
|
65
|
+
```typescript
|
|
66
|
+
await db.insert(users).values({ firstName: 'John', lastName: 'Doe' }).onConflictDoUpdate({
|
|
67
|
+
target: [users.firstName, users.lastName],
|
|
68
|
+
set: { firstName: 'John1' }
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## On duplicate key update
|
|
73
|
+
MySQL and SingleStore (automatically determines conflict target from primary key and unique indexes):
|
|
74
|
+
```typescript
|
|
75
|
+
await db.insert(users).values({ id: 1, name: 'John' }).onDuplicateKeyUpdate({ set: { name: 'John' } });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
No-op on conflict by setting a column to itself:
|
|
79
|
+
```typescript
|
|
80
|
+
await db.insert(users).values({ id: 1, name: 'John' }).onDuplicateKeyUpdate({ set: { id: sql`id` } });
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## WITH clause
|
|
84
|
+
```typescript
|
|
85
|
+
const userCount = db.$with('user_count').as(
|
|
86
|
+
db.select({ value: sql`count(*)`.as('value') }).from(users)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const result = await db.with(userCount).insert(users).values([
|
|
90
|
+
{ username: 'user1', admin: sql`((select * from ${userCount}) = 0)` }
|
|
91
|
+
]).returning({ admin: users.admin });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Insert into ... select
|
|
95
|
+
Three approaches:
|
|
96
|
+
|
|
97
|
+
Query builder:
|
|
98
|
+
```typescript
|
|
99
|
+
const insertedEmployees = await db.insert(employees).select(
|
|
100
|
+
db.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
|
|
101
|
+
).returning({ id: employees.id, name: employees.name });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Callback:
|
|
105
|
+
```typescript
|
|
106
|
+
await db.insert(employees).select(
|
|
107
|
+
() => db.select({ name: users.name }).from(users).where(eq(users.role, 'employee'))
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
SQL template tag:
|
|
112
|
+
```typescript
|
|
113
|
+
await db.insert(employees).select(
|
|
114
|
+
sql`select "users"."name" as "name" from "users" where "users"."role" = 'employee'`
|
|
115
|
+
);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Note: For upsert clauses, SELECT must include WHERE clause (even `WHERE true`) to avoid parsing ambiguity.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
## Join Types
|
|
2
|
+
|
|
3
|
+
Drizzle ORM supports: `INNER JOIN [LATERAL]`, `FULL JOIN`, `LEFT JOIN [LATERAL]`, `RIGHT JOIN`, `CROSS JOIN [LATERAL]`.
|
|
4
|
+
|
|
5
|
+
### Left Join
|
|
6
|
+
```typescript
|
|
7
|
+
const result = await db.select().from(users).leftJoin(pets, eq(users.id, pets.ownerId))
|
|
8
|
+
// Result: { user: {...}, pets: {...} | null }[]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Left Join Lateral
|
|
12
|
+
```typescript
|
|
13
|
+
const subquery = db.select().from(pets).where(gte(users.age, 16)).as('userPets')
|
|
14
|
+
const result = await db.select().from(users).leftJoinLateral(subquery, sql`true`)
|
|
15
|
+
// Result: { user: {...}, userPets: {...} | null }[]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Right Join
|
|
19
|
+
```typescript
|
|
20
|
+
const result = await db.select().from(users).rightJoin(pets, eq(users.id, pets.ownerId))
|
|
21
|
+
// Result: { user: {...} | null, pets: {...} }[]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Inner Join
|
|
25
|
+
```typescript
|
|
26
|
+
const result = await db.select().from(users).innerJoin(pets, eq(users.id, pets.ownerId))
|
|
27
|
+
// Result: { user: {...}, pets: {...} }[]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Inner Join Lateral
|
|
31
|
+
```typescript
|
|
32
|
+
const subquery = db.select().from(pets).where(gte(users.age, 16)).as('userPets')
|
|
33
|
+
const result = await db.select().from(users).innerJoinLateral(subquery, sql`true`)
|
|
34
|
+
// Result: { user: {...}, userPets: {...} }[]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Full Join
|
|
38
|
+
```typescript
|
|
39
|
+
const result = await db.select().from(users).fullJoin(pets, eq(users.id, pets.ownerId))
|
|
40
|
+
// Result: { user: {...} | null, pets: {...} | null }[]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Cross Join
|
|
44
|
+
```typescript
|
|
45
|
+
const result = await db.select().from(users).crossJoin(pets)
|
|
46
|
+
// Result: { user: {...}, pets: {...} }[]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Cross Join Lateral
|
|
50
|
+
```typescript
|
|
51
|
+
const subquery = db.select().from(pets).where(gte(users.age, 16)).as('userPets')
|
|
52
|
+
const result = await db.select().from(users).crossJoinLateral(subquery)
|
|
53
|
+
// Result: { user: {...}, userPets: {...} }[]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Partial Select
|
|
57
|
+
|
|
58
|
+
Select specific fields to flatten response type:
|
|
59
|
+
```typescript
|
|
60
|
+
await db.select({
|
|
61
|
+
userId: users.id,
|
|
62
|
+
petId: pets.id,
|
|
63
|
+
}).from(users).leftJoin(pets, eq(users.id, pets.ownerId))
|
|
64
|
+
// Result: { userId: number, petId: number | null }[]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
When using `sql` operator with joins, explicitly type nullable fields:
|
|
68
|
+
```typescript
|
|
69
|
+
const result = await db.select({
|
|
70
|
+
userId: users.id,
|
|
71
|
+
petId: pets.id,
|
|
72
|
+
petName1: sql`upper(${pets.name})`,
|
|
73
|
+
petName2: sql<string | null>`upper(${pets.name})`,
|
|
74
|
+
}).from(users).leftJoin(pets, eq(users.id, pets.ownerId))
|
|
75
|
+
// Result: { userId: number, petId: number | null, petName1: unknown, petName2: string | null }[]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use nested select object syntax to make entire object nullable instead of individual fields:
|
|
79
|
+
```typescript
|
|
80
|
+
await db.select({
|
|
81
|
+
userId: users.id,
|
|
82
|
+
userName: users.name,
|
|
83
|
+
pet: {
|
|
84
|
+
id: pets.id,
|
|
85
|
+
name: pets.name,
|
|
86
|
+
upperName: sql<string>`upper(${pets.name})`
|
|
87
|
+
}
|
|
88
|
+
}).from(users).fullJoin(pets, eq(users.id, pets.ownerId))
|
|
89
|
+
// Result: { userId: number | null, userName: string | null, pet: {...} | null }[]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Aliases & Self-joins
|
|
93
|
+
|
|
94
|
+
Use `alias()` for self-joins:
|
|
95
|
+
```typescript
|
|
96
|
+
import { alias } from 'drizzle-orm';
|
|
97
|
+
const parent = alias(user, "parent");
|
|
98
|
+
const result = db.select().from(user).leftJoin(parent, eq(parent.id, user.parentId))
|
|
99
|
+
// Result: { user: {...}, parent: {...} | null }[]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Aggregating Results
|
|
103
|
+
|
|
104
|
+
Map join results to aggregate related data:
|
|
105
|
+
```typescript
|
|
106
|
+
type User = typeof users.$inferSelect;
|
|
107
|
+
type Pet = typeof pets.$inferSelect;
|
|
108
|
+
|
|
109
|
+
const rows = db.select({ user: users, pet: pets })
|
|
110
|
+
.from(users).leftJoin(pets, eq(users.id, pets.ownerId)).all();
|
|
111
|
+
|
|
112
|
+
const result = rows.reduce<Record<number, { user: User; pets: Pet[] }>>(
|
|
113
|
+
(acc, row) => {
|
|
114
|
+
const user = row.user;
|
|
115
|
+
const pet = row.pet;
|
|
116
|
+
if (!acc[user.id]) acc[user.id] = { user, pets: [] };
|
|
117
|
+
if (pet) acc[user.id].pets.push(pet);
|
|
118
|
+
return acc;
|
|
119
|
+
},
|
|
120
|
+
{}
|
|
121
|
+
);
|
|
122
|
+
// Result: Record<number, { user: User; pets: Pet[] }>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Many-to-One Example
|
|
126
|
+
```typescript
|
|
127
|
+
const cities = sqliteTable('cities', { id: integer('id').primaryKey(), name: text('name') });
|
|
128
|
+
const users = sqliteTable('users', { id: integer('id').primaryKey(), name: text('name'), cityId: integer('city_id').references(() => cities.id) });
|
|
129
|
+
|
|
130
|
+
const result = db.select().from(cities).leftJoin(users, eq(cities.id, users.cityId)).all();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Many-to-Many Example
|
|
134
|
+
```typescript
|
|
135
|
+
const users = sqliteTable('users', { id: integer('id').primaryKey(), name: text('name') });
|
|
136
|
+
const chatGroups = sqliteTable('chat_groups', { id: integer('id').primaryKey(), name: text('name') });
|
|
137
|
+
const usersToChatGroups = sqliteTable('usersToChatGroups', { userId: integer('user_id').references(() => users.id), groupId: integer('group_id').references(() => chatGroups.id) });
|
|
138
|
+
|
|
139
|
+
db.select()
|
|
140
|
+
.from(usersToChatGroups)
|
|
141
|
+
.leftJoin(users, eq(usersToChatGroups.userId, users.id))
|
|
142
|
+
.leftJoin(chatGroups, eq(usersToChatGroups.groupId, chatGroups.id))
|
|
143
|
+
.where(eq(chatGroups.id, 1))
|
|
144
|
+
.all();
|
|
145
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
## Drizzle Kit Overview
|
|
2
|
+
|
|
3
|
+
Drizzle Kit is a CLI tool for managing SQL database migrations with Drizzle ORM.
|
|
4
|
+
|
|
5
|
+
### Installation
|
|
6
|
+
```
|
|
7
|
+
npm install -D drizzle-kit
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
### Core Commands
|
|
11
|
+
|
|
12
|
+
- **drizzle-kit generate** - Generate SQL migration files based on your Drizzle schema (initial or subsequent changes)
|
|
13
|
+
- **drizzle-kit migrate** - Apply generated SQL migration files to your database
|
|
14
|
+
- **drizzle-kit push** - Push your Drizzle schema directly to database (without generating migration files)
|
|
15
|
+
- **drizzle-kit pull** - Introspect database schema, convert to Drizzle schema, save to codebase
|
|
16
|
+
- **drizzle-kit studio** - Connect to database and spin up proxy server for Drizzle Studio for database browsing
|
|
17
|
+
- **drizzle-kit check** - Walk through all generated migrations and check for race conditions/collisions
|
|
18
|
+
- **drizzle-kit up** - Upgrade snapshots of previously generated migrations
|
|
19
|
+
|
|
20
|
+
### Configuration
|
|
21
|
+
|
|
22
|
+
Drizzle Kit is configured via `drizzle.config.ts` file. Minimum required: `dialect` and `schema` path.
|
|
23
|
+
|
|
24
|
+
Simple config:
|
|
25
|
+
```ts
|
|
26
|
+
import { defineConfig } from "drizzle-kit";
|
|
27
|
+
|
|
28
|
+
export default defineConfig({
|
|
29
|
+
dialect: "postgresql",
|
|
30
|
+
schema: "./src/schema.ts",
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Extended config with all options:
|
|
35
|
+
```ts
|
|
36
|
+
import { defineConfig } from "drizzle-kit";
|
|
37
|
+
|
|
38
|
+
export default defineConfig({
|
|
39
|
+
out: "./drizzle",
|
|
40
|
+
dialect: "postgresql",
|
|
41
|
+
schema: "./src/schema.ts",
|
|
42
|
+
driver: "pglite",
|
|
43
|
+
dbCredentials: {
|
|
44
|
+
url: "./database/",
|
|
45
|
+
},
|
|
46
|
+
extensionsFilters: ["postgis"],
|
|
47
|
+
schemaFilter: "public",
|
|
48
|
+
tablesFilter: "*",
|
|
49
|
+
introspect: {
|
|
50
|
+
casing: "camel",
|
|
51
|
+
},
|
|
52
|
+
migrations: {
|
|
53
|
+
prefix: "timestamp",
|
|
54
|
+
table: "__drizzle_migrations__",
|
|
55
|
+
schema: "public",
|
|
56
|
+
},
|
|
57
|
+
breakpoints: true,
|
|
58
|
+
strict: true,
|
|
59
|
+
verbose: true,
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Multiple Configurations
|
|
64
|
+
|
|
65
|
+
Provide config path via CLI for different database stages:
|
|
66
|
+
```
|
|
67
|
+
drizzle-kit push --config=drizzle-dev.config.ts
|
|
68
|
+
drizzle-kit push --config=drizzle-prod.config.ts
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Project structure example:
|
|
72
|
+
```
|
|
73
|
+
📦 <project root>
|
|
74
|
+
├ 📂 drizzle
|
|
75
|
+
├ 📂 src
|
|
76
|
+
├ 📜 .env
|
|
77
|
+
├ 📜 drizzle-dev.config.ts
|
|
78
|
+
├ 📜 drizzle-prod.config.ts
|
|
79
|
+
├ 📜 package.json
|
|
80
|
+
└ 📜 tsconfig.json
|
|
81
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
## Purpose
|
|
2
|
+
`drizzle-kit migrate` applies SQL migrations generated by `drizzle-kit generate`. It implements the code-first approach to managing migrations.
|
|
3
|
+
|
|
4
|
+
## How it works
|
|
5
|
+
1. Reads all `.sql` migration files from the migrations folder
|
|
6
|
+
2. Connects to database and fetches entries from the drizzle migrations log table (`__drizzle_migrations`)
|
|
7
|
+
3. Determines which migrations haven't been applied yet
|
|
8
|
+
4. Runs new SQL migrations and logs them to the migrations table
|
|
9
|
+
|
|
10
|
+
## Configuration
|
|
11
|
+
Requires `dialect` and database connection credentials via `drizzle.config.ts` or CLI options:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// drizzle.config.ts
|
|
15
|
+
import { defineConfig } from "drizzle-kit";
|
|
16
|
+
|
|
17
|
+
export default defineConfig({
|
|
18
|
+
dialect: "postgresql",
|
|
19
|
+
schema: "./src/schema.ts",
|
|
20
|
+
dbCredentials: {
|
|
21
|
+
url: "postgresql://user:password@host:port/dbname"
|
|
22
|
+
},
|
|
23
|
+
migrations: {
|
|
24
|
+
table: '__drizzle_migrations', // customizable
|
|
25
|
+
schema: 'drizzle', // PostgreSQL only
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
npx drizzle-kit migrate
|
|
32
|
+
# or with CLI options
|
|
33
|
+
npx drizzle-kit migrate --dialect=postgresql --url=postgresql://user:password@host:port/dbname
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Multiple configurations
|
|
37
|
+
Support multiple config files for different database stages:
|
|
38
|
+
```shell
|
|
39
|
+
npx drizzle-kit migrate --config=drizzle-dev.config.ts
|
|
40
|
+
npx drizzle-kit migrate --config=drizzle-prod.config.ts
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Example workflow
|
|
44
|
+
1. Define schema in `src/schema.ts`:
|
|
45
|
+
```ts
|
|
46
|
+
import * as p from "drizzle-orm/pg-core";
|
|
47
|
+
export const users = p.pgTable("users", {
|
|
48
|
+
id: p.serial().primaryKey(),
|
|
49
|
+
name: p.text(),
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
2. Generate migration: `npx drizzle-kit generate --name=init` creates `0000_init.sql`
|
|
54
|
+
3. Apply migration: `npx drizzle-kit migrate` runs the SQL and logs it to database
|