Skip to content

Commit 9cf0ed2

Browse files
AndriiShermanmalonehedgesRodriguespnapeng-singlestoreAlexBlokh
authored
Beta (#3664)
* Add SingleStore dialect * Add Durable Objects SQLite support * Bug fixes --------- Co-authored-by: Malone Hedges <malonehedges@users.noreply.github.com> Co-authored-by: Pedro Rodrigues <44656907+Rodriguespn@users.noreply.github.com> Co-authored-by: prodrigues <prodrigues@singlestore.com> Co-authored-by: apeng-singlestore <127370261+apeng-singlestore@users.noreply.github.com> Co-authored-by: Alex Blokh <aleksandrblokh@gmail.com> Co-authored-by: Aleksandr Sherman <aleksandrserman@gmail.com> Co-authored-by: Sergey Reka <71607800+Sukairo-02@users.noreply.github.com>
1 parent 599da5e commit 9cf0ed2

File tree

161 files changed

+38945
-780
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+38945
-780
lines changed

changelogs/drizzle-kit/0.29.0.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# New Dialects
2+
3+
### 🎉 `SingleStore` dialect is now available in Drizzle
4+
5+
Thanks to the SingleStore team for creating a PR with all the necessary changes to support the MySQL-compatible part of SingleStore. You can already start using it with Drizzle. The SingleStore team will also help us iterate through updates and make more SingleStore-specific features available in Drizzle
6+
7+
```ts
8+
import 'dotenv/config';
9+
import { defineConfig } from 'drizzle-kit';
10+
11+
export default defineConfig({
12+
dialect: 'singlestore',
13+
out: './drizzle',
14+
schema: './src/db/schema.ts',
15+
dbCredentials: {
16+
url: process.env.DATABASE_URL!,
17+
},
18+
});
19+
```
20+
21+
You can check out our [Getting started guides](https://orm.drizzle.team/docs/get-started/singlestore-new) to try SingleStore!
22+
23+
# New Drivers
24+
25+
### 🎉 `SQLite Durable Objects` driver is now available in Drizzle
26+
27+
You can now query SQLite Durable Objects in Drizzle!
28+
29+
For the full example, please check our [Get Started](https://orm.drizzle.team/docs/get-started/do-new) Section
30+
31+
```ts
32+
import 'dotenv/config';
33+
import { defineConfig } from 'drizzle-kit';
34+
export default defineConfig({
35+
out: './drizzle',
36+
schema: './src/db/schema.ts',
37+
dialect: 'sqlite',
38+
driver: 'durable-sqlite',
39+
});
40+
```

changelogs/drizzle-orm/0.36.1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
- [[BUG]: Using sql.placeholder with limit and/or offset for a prepared statement produces TS error](https://github.com/drizzle-team/drizzle-orm/issues/2146) - thanks @L-Mario564
44
- [[BUG] If a query I am trying to modify with a dynamic query (....$dynamic()) contains any placeholders, I'm getting an error that says No value for placeholder.... provided](https://github.com/drizzle-team/drizzle-orm/issues/2272) - thanks @L-Mario564
55
- [[BUG]: Error thrown when trying to insert an array of new rows using generatedAlwaysAsIdentity() for the id column](https://github.com/drizzle-team/drizzle-orm/issues/2849) - thanks @L-Mario564
6-
- [[BUG]: Unable to Use BigInt Types with Bun and Drizzle](https://github.com/drizzle-team/drizzle-orm/issues/2603) - thanks @L-Mario564
6+
- [[BUG]: Unable to Use BigInt Types with Bun and Drizzle](https://github.com/drizzle-team/drizzle-orm/issues/2603) - thanks @L-Mario564

changelogs/drizzle-orm/0.37.0.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# New Dialects
2+
3+
### 🎉 `SingleStore` dialect is now available in Drizzle
4+
5+
Thanks to the SingleStore team for creating a PR with all the necessary changes to support the MySQL-compatible part of SingleStore. You can already start using it with Drizzle. The SingleStore team will also help us iterate through updates and make more SingleStore-specific features available in Drizzle
6+
7+
```ts
8+
import { int, singlestoreTable, varchar } from 'drizzle-orm/singlestore-core';
9+
import { drizzle } from 'drizzle-orm/singlestore';
10+
11+
export const usersTable = singlestoreTable('users_table', {
12+
id: int().primaryKey(),
13+
name: varchar({ length: 255 }).notNull(),
14+
age: int().notNull(),
15+
email: varchar({ length: 255 }).notNull().unique(),
16+
});
17+
18+
...
19+
20+
const db = drizzle(process.env.DATABASE_URL!);
21+
22+
db.select()...
23+
```
24+
25+
You can check out our [Getting started guides](https://orm.drizzle.team/docs/get-started/singlestore-new) to try SingleStore!
26+
27+
# New Drivers
28+
29+
### 🎉 `SQLite Durable Objects` driver is now available in Drizzle
30+
31+
You can now query SQLite Durable Objects in Drizzle!
32+
33+
For the full example, please check our [Get Started](https://orm.drizzle.team/docs/get-started/do-new) Section
34+
35+
```ts
36+
/// <reference types="@cloudflare/workers-types" />
37+
import { drizzle, DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite';
38+
import { DurableObject } from 'cloudflare:workers'
39+
import { migrate } from 'drizzle-orm/durable-sqlite/migrator';
40+
import migrations from '../drizzle/migrations';
41+
import { usersTable } from './db/schema';
42+
43+
export class MyDurableObject1 extends DurableObject {
44+
storage: DurableObjectStorage;
45+
db: DrizzleSqliteDODatabase<any>;
46+
47+
constructor(ctx: DurableObjectState, env: Env) {
48+
super(ctx, env);
49+
this.storage = ctx.storage;
50+
this.db = drizzle(this.storage, { logger: false });
51+
}
52+
53+
async migrate() {
54+
migrate(this.db, migrations);
55+
}
56+
57+
async insert(user: typeof usersTable.$inferInsert) {
58+
await this.db.insert(usersTable).values(user);
59+
}
60+
61+
async select() {
62+
return this.db.select().from(usersTable);
63+
}
64+
}
65+
66+
export default {
67+
/**
68+
* This is the standard fetch handler for a Cloudflare Worker
69+
*
70+
* @param request - The request submitted to the Worker from the client
71+
* @param env - The interface to reference bindings declared in wrangler.toml
72+
* @param ctx - The execution context of the Worker
73+
* @returns The response to be sent back to the client
74+
*/
75+
async fetch(request: Request, env: Env): Promise<Response> {
76+
const id: DurableObjectId = env.MY_DURABLE_OBJECT1.idFromName('durable-object');
77+
const stub = env.MY_DURABLE_OBJECT1.get(id);
78+
await stub.migrate();
79+
80+
await stub.insert({
81+
name: 'John',
82+
age: 30,
83+
email: 'john@example.com',
84+
})
85+
console.log('New user created!')
86+
87+
const users = await stub.select();
88+
console.log('Getting all users from the database: ', users)
89+
90+
return new Response();
91+
}
92+
}
93+
```
94+
95+
# Bug fixes
96+
97+
- [[BUG]: $with is undefined on withReplicas](https://github.com/drizzle-team/drizzle-orm/issues/1834)
98+
- [[BUG]: Neon serverless driver accepts authToken as a promise, but the $withAuth does not](https://github.com/drizzle-team/drizzle-orm/issues/3597)

drizzle-kit/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
{
22
"name": "drizzle-kit",
3-
"version": "0.28.1",
3+
"version": "0.29.0",
44
"homepage": "https://orm.drizzle.team",
55
"keywords": [
66
"drizzle",
77
"orm",
88
"pg",
99
"mysql",
10+
"singlestore",
1011
"postgresql",
1112
"postgres",
1213
"sqlite",

drizzle-kit/src/api.ts

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { randomUUID } from 'crypto';
22
import { LibSQLDatabase } from 'drizzle-orm/libsql';
33
import type { MySql2Database } from 'drizzle-orm/mysql2';
44
import { PgDatabase } from 'drizzle-orm/pg-core';
5+
import { SingleStoreDriverDatabase } from 'drizzle-orm/singlestore';
56
import {
67
columnsResolver,
78
enumsResolver,
@@ -30,12 +31,19 @@ import { generateMySqlSnapshot } from './serializer/mysqlSerializer';
3031
import { prepareFromExports } from './serializer/pgImports';
3132
import { PgSchema as PgSchemaKit, pgSchema, squashPgScheme } from './serializer/pgSchema';
3233
import { generatePgSnapshot } from './serializer/pgSerializer';
34+
import {
35+
SingleStoreSchema as SingleStoreSchemaKit,
36+
singlestoreSchema,
37+
squashSingleStoreScheme,
38+
} from './serializer/singlestoreSchema';
39+
import { generateSingleStoreSnapshot } from './serializer/singlestoreSerializer';
3340
import { SQLiteSchema as SQLiteSchemaKit, sqliteSchema, squashSqliteScheme } from './serializer/sqliteSchema';
3441
import { generateSqliteSnapshot } from './serializer/sqliteSerializer';
3542
import type { DB, SQLiteDB } from './utils';
3643
export type DrizzleSnapshotJSON = PgSchemaKit;
3744
export type DrizzleSQLiteSnapshotJSON = SQLiteSchemaKit;
3845
export type DrizzleMySQLSnapshotJSON = MySQLSchemaKit;
46+
export type DrizzleSingleStoreSnapshotJSON = SingleStoreSchemaKit;
3947

4048
export const generateDrizzleJson = (
4149
imports: Record<string, unknown>,
@@ -374,6 +382,112 @@ export const pushMySQLSchema = async (
374382
};
375383
};
376384

385+
// SingleStore
386+
387+
export const generateSingleStoreDrizzleJson = async (
388+
imports: Record<string, unknown>,
389+
prevId?: string,
390+
casing?: CasingType,
391+
): Promise<SingleStoreSchemaKit> => {
392+
const { prepareFromExports } = await import('./serializer/singlestoreImports');
393+
394+
const prepared = prepareFromExports(imports);
395+
396+
const id = randomUUID();
397+
398+
const snapshot = generateSingleStoreSnapshot(prepared.tables, /* prepared.views, */ casing);
399+
400+
return {
401+
...snapshot,
402+
id,
403+
prevId: prevId ?? originUUID,
404+
};
405+
};
406+
407+
export const generateSingleStoreMigration = async (
408+
prev: DrizzleSingleStoreSnapshotJSON,
409+
cur: DrizzleSingleStoreSnapshotJSON,
410+
) => {
411+
const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer');
412+
413+
const validatedPrev = singlestoreSchema.parse(prev);
414+
const validatedCur = singlestoreSchema.parse(cur);
415+
416+
const squashedPrev = squashSingleStoreScheme(validatedPrev);
417+
const squashedCur = squashSingleStoreScheme(validatedCur);
418+
419+
const { sqlStatements } = await applySingleStoreSnapshotsDiff(
420+
squashedPrev,
421+
squashedCur,
422+
tablesResolver,
423+
columnsResolver,
424+
/* singleStoreViewsResolver, */
425+
validatedPrev,
426+
validatedCur,
427+
'push',
428+
);
429+
430+
return sqlStatements;
431+
};
432+
433+
export const pushSingleStoreSchema = async (
434+
imports: Record<string, unknown>,
435+
drizzleInstance: SingleStoreDriverDatabase<any>,
436+
databaseName: string,
437+
) => {
438+
const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer');
439+
const { logSuggestionsAndReturn } = await import(
440+
'./cli/commands/singlestorePushUtils'
441+
);
442+
const { singlestorePushIntrospect } = await import(
443+
'./cli/commands/singlestoreIntrospect'
444+
);
445+
const { sql } = await import('drizzle-orm');
446+
447+
const db: DB = {
448+
query: async (query: string) => {
449+
const res = await drizzleInstance.execute(sql.raw(query));
450+
return res[0] as unknown as any[];
451+
},
452+
};
453+
const cur = await generateSingleStoreDrizzleJson(imports);
454+
const { schema: prev } = await singlestorePushIntrospect(db, databaseName, []);
455+
456+
const validatedPrev = singlestoreSchema.parse(prev);
457+
const validatedCur = singlestoreSchema.parse(cur);
458+
459+
const squashedPrev = squashSingleStoreScheme(validatedPrev);
460+
const squashedCur = squashSingleStoreScheme(validatedCur);
461+
462+
const { statements } = await applySingleStoreSnapshotsDiff(
463+
squashedPrev,
464+
squashedCur,
465+
tablesResolver,
466+
columnsResolver,
467+
/* singleStoreViewsResolver, */
468+
validatedPrev,
469+
validatedCur,
470+
'push',
471+
);
472+
473+
const { shouldAskForApprove, statementsToExecute, infoToPrint } = await logSuggestionsAndReturn(
474+
db,
475+
statements,
476+
validatedCur,
477+
);
478+
479+
return {
480+
hasDataLoss: shouldAskForApprove,
481+
warnings: infoToPrint,
482+
statementsToExecute,
483+
apply: async () => {
484+
for (const dStmnt of statementsToExecute) {
485+
await db.query(dStmnt);
486+
}
487+
},
488+
};
489+
};
490+
377491
export const upPgSnapshot = (snapshot: Record<string, unknown>) => {
378492
if (snapshot.version === '5') {
379493
return upPgV7(upPgV6(snapshot));

0 commit comments

Comments
 (0)