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

[SingleStore] Add SingleStore connector #3132

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
89ee201
[SingleStore] Add SingleStore connector (#32)
Rodriguespn Oct 2, 2024
b813ee5
rebase singlestore connector with last commit: https://github.com/dri…
Rodriguespn Oct 23, 2024
2f84354
skip view tests
Rodriguespn Oct 30, 2024
0a4ef87
Merge branch 'main' of https://github.com/drizzle-team/drizzle-orm in…
AndriiSherman Nov 4, 2024
3c34713
Merge branch 'beta' of https://github.com/drizzle-team/drizzle-orm in…
AndriiSherman Nov 4, 2024
456758b
Fix conflicts
AndriiSherman Nov 4, 2024
dab40c8
No fks?
AndriiSherman Nov 4, 2024
465a8a2
Fix after failed tests
AndriiSherman Nov 4, 2024
6b8676e
Add drizzleIntegration query header
apeng-singlestore Nov 6, 2024
feb0e60
Add a few test changes
AndriiSherman Nov 7, 2024
d2fb074
[SingleStore] Add SingleStore connector (#32)
Rodriguespn Oct 2, 2024
6e91991
rebase singlestore connector with last commit: https://github.com/dri…
Rodriguespn Oct 23, 2024
f5c662b
skip view tests
Rodriguespn Oct 30, 2024
67d0548
imports checker with OHM grammar
AlexBlokh Nov 3, 2024
beddb85
imports checker with OHM grammar + fix of imports issues
AlexBlokh Nov 3, 2024
a9ad0ae
Fix conflicts
AndriiSherman Nov 4, 2024
0414ecf
No fks?
AndriiSherman Nov 4, 2024
329638c
Fix after failed tests
AndriiSherman Nov 4, 2024
6c2e568
Add drizzleIntegration query header
apeng-singlestore Nov 6, 2024
1ddce27
Add a few test changes
AndriiSherman Nov 7, 2024
e9db7f1
fix some singlestore drizzle kit tests
Rodriguespn Nov 7, 2024
5f816d6
Merge branch 'feature/new-dialect-singlestore' of https://github.com/…
apeng-singlestore Nov 7, 2024
bb10615
Merge branch 'feature/new-dialect-singlestore' of github.com:singlest…
AndriiSherman Nov 11, 2024
7be73df
update SingleStore decimal column type
Rodriguespn Nov 11, 2024
198fbc2
remove unnecessary logs
Rodriguespn Nov 11, 2024
40e0037
Fixed type parsing
AndriiSherman Nov 11, 2024
7dd05e9
Merge branch 'feature/new-dialect-singlestore' of github.com:singlest…
AndriiSherman Nov 11, 2024
28d29f7
Fix decimal SingleStore
AndriiSherman Nov 11, 2024
997f94b
update SingleStore decimal column type
Rodriguespn Nov 11, 2024
643d83e
update SingleStore float column type
Rodriguespn Nov 11, 2024
df04b80
singlestore drizzle-kit test pass
Rodriguespn Nov 12, 2024
0b31d85
nit: missing files from main
Rodriguespn Nov 12, 2024
746e091
fix changelog files
Rodriguespn Nov 12, 2024
9a68340
fix drizzle-kit non singlestore files
Rodriguespn Nov 12, 2024
dc3d78c
remain fix of non singlestore files and common files
Rodriguespn Nov 13, 2024
28cd0e1
update drizzle-orm
Rodriguespn Nov 13, 2024
9e591e6
update singlestore-driver
Rodriguespn Nov 13, 2024
c9f780c
update singlestore-proxy
Rodriguespn Nov 13, 2024
d167aa8
cleaning singlestore drizzle-orm and passing tests
Rodriguespn Nov 13, 2024
0d204bf
remove views and generated columns from drizzle-kit
Rodriguespn Nov 13, 2024
2816180
remove mode from drizzle-orm
Rodriguespn Nov 14, 2024
0969a76
fix replica integration tests
Rodriguespn Nov 14, 2024
59979c3
Fixes for kit singlestore
AndriiSherman Nov 25, 2024
19baeea
Remove unsupported API
AndriiSherman Nov 25, 2024
b31050f
Merge branch 'beta' of https://github.com/drizzle-team/drizzle-orm in…
AndriiSherman Nov 25, 2024
2552c03
Fix build problems
AndriiSherman Nov 25, 2024
675e285
Clear drizzle-kit tests
AndriiSherman Nov 25, 2024
cc04576
Remove .only from tests
AndriiSherman Nov 25, 2024
f704bb8
Merge branch 'beta' of https://github.com/drizzle-team/drizzle-orm in…
AndriiSherman Nov 25, 2024
b71f896
Fix integration tests by removing RQB support for now
AndriiSherman Nov 28, 2024
6cd108e
Fix tests
AndriiSherman Nov 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
1 change: 1 addition & 0 deletions drizzle-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"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
102 changes: 102 additions & 0 deletions drizzle-kit/src/cli/commands/introspect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ import { render, renderWithTask } from 'hanji';
import { Minimatch } from 'minimatch';
import { join } from 'path';
import { plural, singular } from 'pluralize';
import { drySingleStore, SingleStoreSchema, squashSingleStoreScheme } from 'src/serializer/singlestoreSchema';
import { assertUnreachable, originUUID } from '../../global';
import { schemaToTypeScript as mysqlSchemaToTypeScript } from '../../introspect-mysql';
import { paramNameFor, schemaToTypeScript as postgresSchemaToTypeScript } from '../../introspect-pg';
import { schemaToTypeScript as singlestoreSchemaToTypeScript } from '../../introspect-singlestore';
import { schemaToTypeScript as sqliteSchemaToTypeScript } from '../../introspect-sqlite';
import { dryMySql, MySqlSchema, squashMysqlScheme } from '../../serializer/mysqlSchema';
import { fromDatabase as fromMysqlDatabase } from '../../serializer/mysqlSerializer';
import { dryPg, type PgSchema, squashPgScheme } from '../../serializer/pgSchema';
import { fromDatabase as fromPostgresDatabase } from '../../serializer/pgSerializer';
import { fromDatabase as fromSingleStoreDatabase } from '../../serializer/singlestoreSerializer';
import { drySQLite, type SQLiteSchema, squashSqliteScheme } from '../../serializer/sqliteSchema';
import { fromDatabase as fromSqliteDatabase } from '../../serializer/sqliteSerializer';
import {
applyLibSQLSnapshotsDiff,
applyMysqlSnapshotsDiff,
applyPgSnapshotsDiff,
applySingleStoreSnapshotsDiff,
applySqliteSnapshotsDiff,
} from '../../snapshotsDiffer';
import { prepareOutFolder } from '../../utils';
Expand All @@ -26,6 +30,7 @@ import type { Casing, Prefix } from '../validations/common';
import { LibSQLCredentials } from '../validations/libsql';
import type { MysqlCredentials } from '../validations/mysql';
import type { PostgresCredentials } from '../validations/postgres';
import { SingleStoreCredentials } from '../validations/singlestore';
import type { SqliteCredentials } from '../validations/sqlite';
import { IntrospectProgress } from '../views';
import {
Expand Down Expand Up @@ -280,6 +285,103 @@ export const introspectMysql = async (
process.exit(0);
};

export const introspectSingleStore = async (
casing: Casing,
out: string,
breakpoints: boolean,
credentials: SingleStoreCredentials,
tablesFilter: string[],
prefix: Prefix,
) => {
const { connectToSingleStore } = await import('../connections');
const { db, database } = await connectToSingleStore(credentials);

const matchers = tablesFilter.map((it) => {
return new Minimatch(it);
});

const filter = (tableName: string) => {
if (matchers.length === 0) return true;

let flags: boolean[] = [];

for (let matcher of matchers) {
if (matcher.negate) {
if (!matcher.match(tableName)) {
flags.push(false);
}
}

if (matcher.match(tableName)) {
flags.push(true);
}
}

if (flags.length > 0) {
return flags.every(Boolean);
}
return false;
};

const progress = new IntrospectProgress();
const res = await renderWithTask(
progress,
fromSingleStoreDatabase(db, database, filter, (stage, count, status) => {
progress.update(stage, count, status);
}),
);

const schema = { id: originUUID, prevId: '', ...res } as SingleStoreSchema;
const ts = singlestoreSchemaToTypeScript(schema, casing);
const { internal, ...schemaWithoutInternals } = schema;

const schemaFile = join(out, 'schema.ts');
writeFileSync(schemaFile, ts.file);
console.log();

const { snapshots, journal } = prepareOutFolder(out, 'postgresql');

if (snapshots.length === 0) {
const { sqlStatements, _meta } = await applySingleStoreSnapshotsDiff(
squashSingleStoreScheme(drySingleStore),
squashSingleStoreScheme(schema),
tablesResolver,
columnsResolver,
/* singleStoreViewsResolver, */
drySingleStore,
schema,
);

writeResult({
cur: schema,
sqlStatements,
journal,
_meta,
outFolder: out,
breakpoints,
type: 'introspect',
prefixMode: prefix,
});
} else {
render(
`[${
chalk.blue(
'i',
)
}] No SQL generated, you already have migrations in project`,
);
}

render(
`[${
chalk.green(
'✓',
)
}] You schema file is ready ➜ ${chalk.bold.underline.blue(schemaFile)} 🚀`,
);
process.exit(0);
};

export const introspectSqlite = async (
casing: Casing,
out: string,
Expand Down
Loading