Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta #2008

Merged
merged 10 commits into from
Mar 14, 2024
9 changes: 9 additions & 0 deletions changelogs/drizzle-orm/0.30.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Improvements

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

> 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.

## Bug fixed

- [Sqlite] Fix findFirst query for bun:sqlite #1885 - thanks @shaileshaanand
4 changes: 2 additions & 2 deletions drizzle-orm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drizzle-orm",
"version": "0.30.1",
"version": "0.30.2",
"description": "Drizzle ORM package for SQL databases",
"type": "module",
"scripts": {
Expand Down Expand Up @@ -141,7 +141,7 @@
"devDependencies": {
"@aws-sdk/client-rds-data": "^3.344.0",
"@cloudflare/workers-types": "^4.20230904.0",
"@libsql/client": "^0.1.6",
"@libsql/client": "^0.5.6",
"@neondatabase/serverless": "^0.4.24",
"@op-engineering/op-sqlite": "^2.0.16",
"@opentelemetry/api": "^1.4.1",
Expand Down
2 changes: 1 addition & 1 deletion drizzle-orm/src/bun-sqlite/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export class PreparedQuery<T extends PreparedQueryConfig = PreparedQueryConfig>
get(placeholderValues?: Record<string, unknown>): T['get'] {
const params = fillPlaceholders(this.query.params, placeholderValues ?? {});
this.logger.logQuery(this.query.sql, params);
const row = this.stmt.get(...params);
const row = this.stmt.values(...params)[0];

if (!row) {
return undefined;
Expand Down
44 changes: 42 additions & 2 deletions drizzle-orm/src/libsql/migrator.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
import type { MigrationConfig } from '~/migrator.ts';
import { readMigrationFiles } from '~/migrator.ts';
import { sql } from '~/sql/sql.ts';
import type { LibSQLDatabase } from './driver.ts';

export function migrate<TSchema extends Record<string, unknown>>(
export async function migrate<TSchema extends Record<string, unknown>>(
db: LibSQLDatabase<TSchema>,
config: MigrationConfig,
) {
const migrations = readMigrationFiles(config);
return db.dialect.migrate(migrations, db.session, config);
const migrationsTable = config === undefined
? '__drizzle_migrations'
: typeof config === 'string'
? '__drizzle_migrations'
: config.migrationsTable ?? '__drizzle_migrations';

const migrationTableCreate = sql`
CREATE TABLE IF NOT EXISTS ${sql.identifier(migrationsTable)} (
id SERIAL PRIMARY KEY,
hash text NOT NULL,
created_at numeric
)
`;
await db.session.run(migrationTableCreate);

const dbMigrations = await db.values<[number, string, string]>(
sql`SELECT id, hash, created_at FROM ${sql.identifier(migrationsTable)} ORDER BY created_at DESC LIMIT 1`,
);

const lastDbMigration = dbMigrations[0] ?? undefined;

const statementToBatch = [];

for (const migration of migrations) {
if (!lastDbMigration || Number(lastDbMigration[2])! < migration.folderMillis) {
for (const stmt of migration.sql) {
statementToBatch.push(db.run(sql.raw(stmt)));
}

statementToBatch.push(
db.run(
sql`INSERT INTO ${
sql.identifier(migrationsTable)
} ("hash", "created_at") VALUES(${migration.hash}, ${migration.folderMillis})`,
),
);
}
}

await db.session.batch(statementToBatch);
}
2 changes: 1 addition & 1 deletion integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"dependencies": {
"@aws-sdk/client-rds-data": "^3.345.0",
"@aws-sdk/credential-providers": "^3.345.0",
"@libsql/client": "^0.1.6",
"@libsql/client": "^0.5.6",
"@miniflare/d1": "^2.14.0",
"@miniflare/shared": "^2.14.0",
"@planetscale/database": "^1.16.0",
Expand Down
14 changes: 7 additions & 7 deletions integration-tests/tests/libsql-batch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ test('batch api example', async () => {
invitedBy: null,
}]);

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

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

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

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

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

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

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

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

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

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

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

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

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

expect(batchResponse[2]).toEqual([
{ id: 1, invitedBy: null },
Expand Down
Loading
Loading