Skip to content

Commit ab1cfdf

Browse files
Merge pull request #2008 from drizzle-team/beta
Beta
2 parents 2f7d3e7 + 29e6b46 commit ab1cfdf

File tree

7 files changed

+174
-42
lines changed

7 files changed

+174
-42
lines changed

changelogs/drizzle-orm/0.30.2.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Improvements
2+
3+
LibSQL migrations have been updated to utilize batch execution instead of transactions. As stated in the [documentation](https://docs.turso.tech/sdk/ts/reference#batch-transactions), LibSQL now supports batch operations
4+
5+
> A batch consists of multiple SQL statements executed sequentially within an implicit transaction. The backend handles the transaction: success commits all changes, while any failure results in a full rollback with no modifications.
6+
7+
## Bug fixed
8+
9+
- [Sqlite] Fix findFirst query for bun:sqlite #1885 - thanks @shaileshaanand

drizzle-orm/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drizzle-orm",
3-
"version": "0.30.1",
3+
"version": "0.30.2",
44
"description": "Drizzle ORM package for SQL databases",
55
"type": "module",
66
"scripts": {
@@ -141,7 +141,7 @@
141141
"devDependencies": {
142142
"@aws-sdk/client-rds-data": "^3.344.0",
143143
"@cloudflare/workers-types": "^4.20230904.0",
144-
"@libsql/client": "^0.1.6",
144+
"@libsql/client": "^0.5.6",
145145
"@neondatabase/serverless": "^0.4.24",
146146
"@op-engineering/op-sqlite": "^2.0.16",
147147
"@opentelemetry/api": "^1.4.1",

drizzle-orm/src/bun-sqlite/session.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export class PreparedQuery<T extends PreparedQueryConfig = PreparedQueryConfig>
133133
get(placeholderValues?: Record<string, unknown>): T['get'] {
134134
const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
135135
this.logger.logQuery(this.query.sql, params);
136-
const row = this.stmt.get(...params);
136+
const row = this.stmt.values(...params)[0];
137137

138138
if (!row) {
139139
return undefined;

drizzle-orm/src/libsql/migrator.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,51 @@
11
import type { MigrationConfig } from '~/migrator.ts';
22
import { readMigrationFiles } from '~/migrator.ts';
3+
import { sql } from '~/sql/sql.ts';
34
import type { LibSQLDatabase } from './driver.ts';
45

5-
export function migrate<TSchema extends Record<string, unknown>>(
6+
export async function migrate<TSchema extends Record<string, unknown>>(
67
db: LibSQLDatabase<TSchema>,
78
config: MigrationConfig,
89
) {
910
const migrations = readMigrationFiles(config);
10-
return db.dialect.migrate(migrations, db.session, config);
11+
const migrationsTable = config === undefined
12+
? '__drizzle_migrations'
13+
: typeof config === 'string'
14+
? '__drizzle_migrations'
15+
: config.migrationsTable ?? '__drizzle_migrations';
16+
17+
const migrationTableCreate = sql`
18+
CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsTable)} (
19+
id SERIAL PRIMARY KEY,
20+
hash text NOT NULL,
21+
created_at numeric
22+
)
23+
`;
24+
await db.session.run(migrationTableCreate);
25+
26+
const dbMigrations = await db.values<[number, string, string]>(
27+
sql`SELECT id, hash, created_at FROM ${sql.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`,
28+
);
29+
30+
const lastDbMigration = dbMigrations[0] ?? undefined;
31+
32+
const statementToBatch = [];
33+
34+
for (const migration of migrations) {
35+
if (!lastDbMigration || Number(lastDbMigration[2])! < migration.folderMillis) {
36+
for (const stmt of migration.sql) {
37+
statementToBatch.push(db.run(sql.raw(stmt)));
38+
}
39+
40+
statementToBatch.push(
41+
db.run(
42+
sql`INSERT INTO ${
43+
sql.identifier(migrationsTable)
44+
} ("hash", "created_at") VALUES(${migration.hash}, ${migration.folderMillis})`,
45+
),
46+
);
47+
}
48+
}
49+
50+
await db.session.batch(statementToBatch);
1151
}

integration-tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"dependencies": {
6363
"@aws-sdk/client-rds-data": "^3.345.0",
6464
"@aws-sdk/credential-providers": "^3.345.0",
65-
"@libsql/client": "^0.1.6",
65+
"@libsql/client": "^0.5.6",
6666
"@miniflare/d1": "^2.14.0",
6767
"@miniflare/shared": "^2.14.0",
6868
"@planetscale/database": "^1.16.0",

integration-tests/tests/libsql-batch.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ test('batch api example', async () => {
276276
invitedBy: null,
277277
}]);
278278

279-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
279+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
280280

281281
expect(batchResponse[2]).toEqual([
282282
{ id: 1, name: 'John', verified: 0, invitedBy: null },
@@ -311,7 +311,7 @@ test('insert + findMany', async () => {
311311
id: 1,
312312
}]);
313313

314-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
314+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
315315

316316
expect(batchResponse[2]).toEqual([
317317
{ id: 1, name: 'John', verified: 0, invitedBy: null },
@@ -353,7 +353,7 @@ test('insert + findMany + findFirst', async () => {
353353
id: 1,
354354
}]);
355355

356-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
356+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
357357

358358
expect(batchResponse[2]).toEqual([
359359
{ id: 1, name: 'John', verified: 0, invitedBy: null },
@@ -400,7 +400,7 @@ test('insert + db.all + db.get + db.values + db.run', async () => {
400400
id: 1,
401401
}]);
402402

403-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
403+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
404404

405405
expect(batchResponse[2]).toEqual([
406406
{ id: 1, name: 'John', verified: 0, invited_by: null },
@@ -451,7 +451,7 @@ test('insert + findManyWith + db.all', async () => {
451451
id: 1,
452452
}]);
453453

454-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
454+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
455455

456456
expect(batchResponse[2]).toEqual([
457457
{ id: 1, name: 'John', verified: 0, invitedBy: null },
@@ -503,7 +503,7 @@ test('insert + update + select + select partial', async () => {
503503
id: 1,
504504
}]);
505505

506-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 1n });
506+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 1n });
507507

508508
expect(batchResponse[2]).toEqual([
509509
{ id: 1, name: 'Dan', verified: 0, invitedBy: null },
@@ -553,7 +553,7 @@ test('insert + delete + select + select partial', async () => {
553553
id: 1,
554554
}]);
555555

556-
expect(batchResponse[1]).toEqual({ columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
556+
expect(batchResponse[1]).toEqual({ columnTypes: [], columns: [], rows: [], rowsAffected: 1, lastInsertRowid: 2n });
557557

558558
expect(batchResponse[2]).toEqual([
559559
{ id: 1, invitedBy: null },

0 commit comments

Comments
 (0)