Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* Add SingleStore dialect

* Add Durable Objects SQLite support

* Bug fixes

---------

Co-authored-by: Malone Hedges <[email protected]>
Co-authored-by: Pedro Rodrigues <[email protected]>
Co-authored-by: prodrigues <[email protected]>
Co-authored-by: apeng-singlestore <[email protected]>
Co-authored-by: Alex Blokh <[email protected]>
Co-authored-by: Aleksandr Sherman <[email protected]>
Co-authored-by: Sergey Reka <[email protected]>
  • Loading branch information
8 people authored Dec 3, 2024
1 parent 599da5e commit 9cf0ed2
Show file tree
Hide file tree
Showing 161 changed files with 38,945 additions and 780 deletions.
40 changes: 40 additions & 0 deletions changelogs/drizzle-kit/0.29.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# New Dialects

### 🎉 `SingleStore` dialect is now available in Drizzle

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

```ts
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
dialect: 'singlestore',
out: './drizzle',
schema: './src/db/schema.ts',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
```

You can check out our [Getting started guides](https://orm.drizzle.team/docs/get-started/singlestore-new) to try SingleStore!

# New Drivers

### 🎉 `SQLite Durable Objects` driver is now available in Drizzle

You can now query SQLite Durable Objects in Drizzle!

For the full example, please check our [Get Started](https://orm.drizzle.team/docs/get-started/do-new) Section

```ts
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
out: './drizzle',
schema: './src/db/schema.ts',
dialect: 'sqlite',
driver: 'durable-sqlite',
});
```
2 changes: 1 addition & 1 deletion changelogs/drizzle-orm/0.36.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
- [[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
- [[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
- [[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
- [[BUG]: Unable to Use BigInt Types with Bun and Drizzle](https://github.com/drizzle-team/drizzle-orm/issues/2603) - thanks @L-Mario564
- [[BUG]: Unable to Use BigInt Types with Bun and Drizzle](https://github.com/drizzle-team/drizzle-orm/issues/2603) - thanks @L-Mario564
98 changes: 98 additions & 0 deletions changelogs/drizzle-orm/0.37.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# New Dialects

### 🎉 `SingleStore` dialect is now available in Drizzle

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

```ts
import { int, singlestoreTable, varchar } from 'drizzle-orm/singlestore-core';
import { drizzle } from 'drizzle-orm/singlestore';

export const usersTable = singlestoreTable('users_table', {
id: int().primaryKey(),
name: varchar({ length: 255 }).notNull(),
age: int().notNull(),
email: varchar({ length: 255 }).notNull().unique(),
});

...

const db = drizzle(process.env.DATABASE_URL!);

db.select()...
```

You can check out our [Getting started guides](https://orm.drizzle.team/docs/get-started/singlestore-new) to try SingleStore!

# New Drivers

### 🎉 `SQLite Durable Objects` driver is now available in Drizzle

You can now query SQLite Durable Objects in Drizzle!

For the full example, please check our [Get Started](https://orm.drizzle.team/docs/get-started/do-new) Section

```ts
/// <reference types="@cloudflare/workers-types" />
import { drizzle, DrizzleSqliteDODatabase } from 'drizzle-orm/durable-sqlite';
import { DurableObject } from 'cloudflare:workers'
import { migrate } from 'drizzle-orm/durable-sqlite/migrator';
import migrations from '../drizzle/migrations';
import { usersTable } from './db/schema';

export class MyDurableObject1 extends DurableObject {
storage: DurableObjectStorage;
db: DrizzleSqliteDODatabase<any>;

constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
this.storage = ctx.storage;
this.db = drizzle(this.storage, { logger: false });
}

async migrate() {
migrate(this.db, migrations);
}

async insert(user: typeof usersTable.$inferInsert) {
await this.db.insert(usersTable).values(user);
}

async select() {
return this.db.select().from(usersTable);
}
}

export default {
/**
* This is the standard fetch handler for a Cloudflare Worker
*
* @param request - The request submitted to the Worker from the client
* @param env - The interface to reference bindings declared in wrangler.toml
* @param ctx - The execution context of the Worker
* @returns The response to be sent back to the client
*/
async fetch(request: Request, env: Env): Promise<Response> {
const id: DurableObjectId = env.MY_DURABLE_OBJECT1.idFromName('durable-object');
const stub = env.MY_DURABLE_OBJECT1.get(id);
await stub.migrate();

await stub.insert({
name: 'John',
age: 30,
email: '[email protected]',
})
console.log('New user created!')

const users = await stub.select();
console.log('Getting all users from the database: ', users)

return new Response();
}
}
```

# Bug fixes

- [[BUG]: $with is undefined on withReplicas](https://github.com/drizzle-team/drizzle-orm/issues/1834)
- [[BUG]: Neon serverless driver accepts authToken as a promise, but the $withAuth does not](https://github.com/drizzle-team/drizzle-orm/issues/3597)
3 changes: 2 additions & 1 deletion drizzle-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"name": "drizzle-kit",
"version": "0.28.1",
"version": "0.29.0",
"homepage": "https://orm.drizzle.team",
"keywords": [
"drizzle",
"orm",
"pg",
"mysql",
"singlestore",
"postgresql",
"postgres",
"sqlite",
Expand Down
114 changes: 114 additions & 0 deletions drizzle-kit/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { randomUUID } from 'crypto';
import { LibSQLDatabase } from 'drizzle-orm/libsql';
import type { MySql2Database } from 'drizzle-orm/mysql2';
import { PgDatabase } from 'drizzle-orm/pg-core';
import { SingleStoreDriverDatabase } from 'drizzle-orm/singlestore';
import {
columnsResolver,
enumsResolver,
Expand Down Expand Up @@ -30,12 +31,19 @@ import { generateMySqlSnapshot } from './serializer/mysqlSerializer';
import { prepareFromExports } from './serializer/pgImports';
import { PgSchema as PgSchemaKit, pgSchema, squashPgScheme } from './serializer/pgSchema';
import { generatePgSnapshot } from './serializer/pgSerializer';
import {
SingleStoreSchema as SingleStoreSchemaKit,
singlestoreSchema,
squashSingleStoreScheme,
} from './serializer/singlestoreSchema';
import { generateSingleStoreSnapshot } from './serializer/singlestoreSerializer';
import { SQLiteSchema as SQLiteSchemaKit, sqliteSchema, squashSqliteScheme } from './serializer/sqliteSchema';
import { generateSqliteSnapshot } from './serializer/sqliteSerializer';
import type { DB, SQLiteDB } from './utils';
export type DrizzleSnapshotJSON = PgSchemaKit;
export type DrizzleSQLiteSnapshotJSON = SQLiteSchemaKit;
export type DrizzleMySQLSnapshotJSON = MySQLSchemaKit;
export type DrizzleSingleStoreSnapshotJSON = SingleStoreSchemaKit;

export const generateDrizzleJson = (
imports: Record<string, unknown>,
Expand Down Expand Up @@ -374,6 +382,112 @@ export const pushMySQLSchema = async (
};
};

// SingleStore

export const generateSingleStoreDrizzleJson = async (
imports: Record<string, unknown>,
prevId?: string,
casing?: CasingType,
): Promise<SingleStoreSchemaKit> => {
const { prepareFromExports } = await import('./serializer/singlestoreImports');

const prepared = prepareFromExports(imports);

const id = randomUUID();

const snapshot = generateSingleStoreSnapshot(prepared.tables, /* prepared.views, */ casing);

return {
...snapshot,
id,
prevId: prevId ?? originUUID,
};
};

export const generateSingleStoreMigration = async (
prev: DrizzleSingleStoreSnapshotJSON,
cur: DrizzleSingleStoreSnapshotJSON,
) => {
const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer');

const validatedPrev = singlestoreSchema.parse(prev);
const validatedCur = singlestoreSchema.parse(cur);

const squashedPrev = squashSingleStoreScheme(validatedPrev);
const squashedCur = squashSingleStoreScheme(validatedCur);

const { sqlStatements } = await applySingleStoreSnapshotsDiff(
squashedPrev,
squashedCur,
tablesResolver,
columnsResolver,
/* singleStoreViewsResolver, */
validatedPrev,
validatedCur,
'push',
);

return sqlStatements;
};

export const pushSingleStoreSchema = async (
imports: Record<string, unknown>,
drizzleInstance: SingleStoreDriverDatabase<any>,
databaseName: string,
) => {
const { applySingleStoreSnapshotsDiff } = await import('./snapshotsDiffer');
const { logSuggestionsAndReturn } = await import(
'./cli/commands/singlestorePushUtils'
);
const { singlestorePushIntrospect } = await import(
'./cli/commands/singlestoreIntrospect'
);
const { sql } = await import('drizzle-orm');

const db: DB = {
query: async (query: string) => {
const res = await drizzleInstance.execute(sql.raw(query));
return res[0] as unknown as any[];
},
};
const cur = await generateSingleStoreDrizzleJson(imports);
const { schema: prev } = await singlestorePushIntrospect(db, databaseName, []);

const validatedPrev = singlestoreSchema.parse(prev);
const validatedCur = singlestoreSchema.parse(cur);

const squashedPrev = squashSingleStoreScheme(validatedPrev);
const squashedCur = squashSingleStoreScheme(validatedCur);

const { statements } = await applySingleStoreSnapshotsDiff(
squashedPrev,
squashedCur,
tablesResolver,
columnsResolver,
/* singleStoreViewsResolver, */
validatedPrev,
validatedCur,
'push',
);

const { shouldAskForApprove, statementsToExecute, infoToPrint } = await logSuggestionsAndReturn(
db,
statements,
validatedCur,
);

return {
hasDataLoss: shouldAskForApprove,
warnings: infoToPrint,
statementsToExecute,
apply: async () => {
for (const dStmnt of statementsToExecute) {
await db.query(dStmnt);
}
},
};
};

export const upPgSnapshot = (snapshot: Record<string, unknown>) => {
if (snapshot.version === '5') {
return upPgV7(upPgV6(snapshot));
Expand Down
Loading

0 comments on commit 9cf0ed2

Please sign in to comment.