Skip to content

Commit d9d234e

Browse files
Merge branch 'beta' into feature/mysql-force-index
2 parents 1abaaf8 + 21dab20 commit d9d234e

File tree

10 files changed

+351
-11
lines changed

10 files changed

+351
-11
lines changed

changelogs/drizzle-orm/0.38.1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Closed [[FEATURE]: Add more flexible typing for usage with exactOptionalPropertyTypes](https://github.com/drizzle-team/drizzle-orm/issues/2742)

drizzle-kit/src/cli/commands/migrate.ts

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import {
5454
ResolveSelectNamed,
5555
schema,
5656
} from '../views';
57-
import { GenerateConfig } from './utils';
57+
import { ExportConfig, GenerateConfig } from './utils';
5858

5959
export type Named = {
6060
name: string;
@@ -368,6 +368,44 @@ export const prepareAndMigratePg = async (config: GenerateConfig) => {
368368
}
369369
};
370370

371+
export const prepareAndExportPg = async (config: ExportConfig) => {
372+
const schemaPath = config.schema;
373+
374+
try {
375+
const { prev, cur } = await preparePgMigrationSnapshot(
376+
[], // no snapshots before
377+
schemaPath,
378+
undefined,
379+
);
380+
381+
const validatedPrev = pgSchema.parse(prev);
382+
const validatedCur = pgSchema.parse(cur);
383+
384+
const squashedPrev = squashPgScheme(validatedPrev);
385+
const squashedCur = squashPgScheme(validatedCur);
386+
387+
const { sqlStatements } = await applyPgSnapshotsDiff(
388+
squashedPrev,
389+
squashedCur,
390+
schemasResolver,
391+
enumsResolver,
392+
sequencesResolver,
393+
policyResolver,
394+
indPolicyResolver,
395+
roleResolver,
396+
tablesResolver,
397+
columnsResolver,
398+
viewsResolver,
399+
validatedPrev,
400+
validatedCur,
401+
);
402+
403+
console.log(sqlStatements.join('\n'));
404+
} catch (e) {
405+
console.error(e);
406+
}
407+
};
408+
371409
export const preparePgPush = async (
372410
cur: PgSchema,
373411
prev: PgSchema,
@@ -697,6 +735,70 @@ export const prepareAndMigrateSingleStore = async (config: GenerateConfig) => {
697735
}
698736
};
699737

738+
export const prepareAndExportSinglestore = async (config: ExportConfig) => {
739+
const schemaPath = config.schema;
740+
741+
try {
742+
const { prev, cur } = await prepareSingleStoreMigrationSnapshot(
743+
[],
744+
schemaPath,
745+
undefined,
746+
);
747+
748+
const validatedPrev = singlestoreSchema.parse(prev);
749+
const validatedCur = singlestoreSchema.parse(cur);
750+
751+
const squashedPrev = squashSingleStoreScheme(validatedPrev);
752+
const squashedCur = squashSingleStoreScheme(validatedCur);
753+
754+
const { sqlStatements, _meta } = await applySingleStoreSnapshotsDiff(
755+
squashedPrev,
756+
squashedCur,
757+
tablesResolver,
758+
columnsResolver,
759+
/* singleStoreViewsResolver, */
760+
validatedPrev,
761+
validatedCur,
762+
);
763+
764+
console.log(sqlStatements.join('\n'));
765+
} catch (e) {
766+
console.error(e);
767+
}
768+
};
769+
770+
export const prepareAndExportMysql = async (config: ExportConfig) => {
771+
const schemaPath = config.schema;
772+
773+
try {
774+
const { prev, cur, custom } = await prepareMySqlMigrationSnapshot(
775+
[],
776+
schemaPath,
777+
undefined,
778+
);
779+
780+
const validatedPrev = mysqlSchema.parse(prev);
781+
const validatedCur = mysqlSchema.parse(cur);
782+
783+
const squashedPrev = squashMysqlScheme(validatedPrev);
784+
const squashedCur = squashMysqlScheme(validatedCur);
785+
786+
const { sqlStatements, statements, _meta } = await applyMysqlSnapshotsDiff(
787+
squashedPrev,
788+
squashedCur,
789+
tablesResolver,
790+
columnsResolver,
791+
mySqlViewsResolver,
792+
validatedPrev,
793+
validatedCur,
794+
);
795+
796+
console.log(sqlStatements.join('\n'));
797+
} catch (e) {
798+
console.error(e);
799+
}
800+
};
801+
700802
export const prepareAndMigrateSqlite = async (config: GenerateConfig) => {
701803
const outFolder = config.out;
702804
const schemaPath = config.schema;
@@ -760,6 +862,38 @@ export const prepareAndMigrateSqlite = async (config: GenerateConfig) => {
760862
}
761863
};
762864

865+
export const prepareAndExportSqlite = async (config: ExportConfig) => {
866+
const schemaPath = config.schema;
867+
868+
try {
869+
const { prev, cur } = await prepareSqliteMigrationSnapshot(
870+
[],
871+
schemaPath,
872+
undefined,
873+
);
874+
875+
const validatedPrev = sqliteSchema.parse(prev);
876+
const validatedCur = sqliteSchema.parse(cur);
877+
878+
const squashedPrev = squashSqliteScheme(validatedPrev);
879+
const squashedCur = squashSqliteScheme(validatedCur);
880+
881+
const { sqlStatements, _meta } = await applySqliteSnapshotsDiff(
882+
squashedPrev,
883+
squashedCur,
884+
tablesResolver,
885+
columnsResolver,
886+
sqliteViewsResolver,
887+
validatedPrev,
888+
validatedCur,
889+
);
890+
891+
console.log(sqlStatements.join('\n'));
892+
} catch (e) {
893+
console.error(e);
894+
}
895+
};
896+
763897
export const prepareAndMigrateLibSQL = async (config: GenerateConfig) => {
764898
const outFolder = config.out;
765899
const schemaPath = config.schema;
@@ -822,6 +956,38 @@ export const prepareAndMigrateLibSQL = async (config: GenerateConfig) => {
822956
}
823957
};
824958

959+
export const prepareAndExportLibSQL = async (config: ExportConfig) => {
960+
const schemaPath = config.schema;
961+
962+
try {
963+
const { prev, cur, custom } = await prepareSqliteMigrationSnapshot(
964+
[],
965+
schemaPath,
966+
undefined,
967+
);
968+
969+
const validatedPrev = sqliteSchema.parse(prev);
970+
const validatedCur = sqliteSchema.parse(cur);
971+
972+
const squashedPrev = squashSqliteScheme(validatedPrev);
973+
const squashedCur = squashSqliteScheme(validatedCur);
974+
975+
const { sqlStatements, _meta } = await applyLibSQLSnapshotsDiff(
976+
squashedPrev,
977+
squashedCur,
978+
tablesResolver,
979+
columnsResolver,
980+
sqliteViewsResolver,
981+
validatedPrev,
982+
validatedCur,
983+
);
984+
985+
console.log(sqlStatements.join('\n'));
986+
} catch (e) {
987+
console.error(e);
988+
}
989+
};
990+
825991
export const prepareSQLitePush = async (
826992
schemaPath: string | string[],
827993
snapshot: SQLiteSchema,

drizzle-kit/src/cli/commands/utils.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,12 @@ export type GenerateConfig = {
135135
driver?: Driver;
136136
};
137137

138+
export type ExportConfig = {
139+
dialect: Dialect;
140+
schema: string | string[];
141+
sql: boolean;
142+
};
143+
138144
export const prepareGenerateConfig = async (
139145
options: {
140146
config?: string;
@@ -185,6 +191,38 @@ export const prepareGenerateConfig = async (
185191
};
186192
};
187193

194+
export const prepareExportConfig = async (
195+
options: {
196+
config?: string;
197+
schema?: string;
198+
dialect?: Dialect;
199+
sql: boolean;
200+
},
201+
from: 'config' | 'cli',
202+
): Promise<ExportConfig> => {
203+
const config = from === 'config' ? await drizzleConfigFromFile(options.config, true) : options;
204+
205+
const { schema, dialect, sql } = config;
206+
207+
if (!schema || !dialect) {
208+
console.log(error('Please provide required params:'));
209+
console.log(wrapParam('schema', schema));
210+
console.log(wrapParam('dialect', dialect));
211+
process.exit(1);
212+
}
213+
214+
const fileNames = prepareFilenames(schema);
215+
if (fileNames.length === 0) {
216+
render(`[${chalk.blue('i')}] No schema file in ${schema} was found`);
217+
process.exit(0);
218+
}
219+
return {
220+
dialect: dialect,
221+
schema: schema,
222+
sql: sql,
223+
};
224+
};
225+
188226
export const flattenDatabaseCredentials = (config: any) => {
189227
if ('dbCredentials' in config) {
190228
const { dbCredentials, ...rest } = config;
@@ -768,6 +806,7 @@ export const prepareMigrateConfig = async (configPath: string | undefined) => {
768806

769807
export const drizzleConfigFromFile = async (
770808
configPath?: string,
809+
isExport?: boolean,
771810
): Promise<CliConfig> => {
772811
const prefix = process.env.TEST_CONFIG_PATH_PREFIX || '';
773812

@@ -783,7 +822,7 @@ export const drizzleConfigFromFile = async (
783822
? 'drizzle.config.js'
784823
: 'drizzle.config.json';
785824

786-
if (!configPath) {
825+
if (!configPath && !isExport) {
787826
console.log(
788827
chalk.gray(
789828
`No config path provided, using default '${defaultConfigPath}'`,
@@ -798,7 +837,8 @@ export const drizzleConfigFromFile = async (
798837
process.exit(1);
799838
}
800839

801-
console.log(chalk.grey(`Reading config file '${path}'`));
840+
if (!isExport) console.log(chalk.grey(`Reading config file '${path}'`));
841+
802842
const { unregister } = await safeRegister();
803843
const required = require(`${path}`);
804844
const content = required.default ?? required;

drizzle-kit/src/cli/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { command, run } from '@drizzle-team/brocli';
22
import chalk from 'chalk';
3-
import { check, drop, generate, migrate, pull, push, studio, up } from './schema';
3+
import { check, drop, exportRaw, generate, migrate, pull, push, studio, up } from './schema';
44
import { ormCoreVersions } from './utils';
55

66
const version = async () => {
@@ -42,7 +42,7 @@ const legacy = [
4242
legacyCommand('check:sqlite', 'check'),
4343
];
4444

45-
run([generate, migrate, pull, push, studio, up, check, drop, ...legacy], {
45+
run([generate, migrate, pull, push, studio, up, check, drop, exportRaw, ...legacy], {
4646
name: 'drizzle-kit',
4747
version: version,
4848
});

drizzle-kit/src/cli/schema.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { upSqliteHandler } from './commands/sqliteUp';
1818
import {
1919
prepareCheckParams,
2020
prepareDropParams,
21+
prepareExportConfig,
2122
prepareGenerateConfig,
2223
prepareMigrateConfig,
2324
preparePullConfig,
@@ -747,3 +748,47 @@ export const studio = command({
747748
}
748749
},
749750
});
751+
752+
export const exportRaw = command({
753+
name: 'export',
754+
desc: 'Generate diff between current state and empty state in specified formats: sql',
755+
options: {
756+
sql: boolean('sql').default(true).desc('Generate as sql'),
757+
config: optionConfig,
758+
dialect: optionDialect,
759+
schema: string().desc('Path to a schema file or folder'),
760+
},
761+
transform: async (opts) => {
762+
const from = assertCollisions('export', opts, ['sql'], ['dialect', 'schema']);
763+
return prepareExportConfig(opts, from);
764+
},
765+
handler: async (opts) => {
766+
await assertOrmCoreVersion();
767+
await assertPackages('drizzle-orm');
768+
769+
const {
770+
prepareAndExportPg,
771+
prepareAndExportMysql,
772+
prepareAndExportSqlite,
773+
prepareAndExportLibSQL,
774+
prepareAndExportSinglestore,
775+
} = await import(
776+
'./commands/migrate'
777+
);
778+
779+
const dialect = opts.dialect;
780+
if (dialect === 'postgresql') {
781+
await prepareAndExportPg(opts);
782+
} else if (dialect === 'mysql') {
783+
await prepareAndExportMysql(opts);
784+
} else if (dialect === 'sqlite') {
785+
await prepareAndExportSqlite(opts);
786+
} else if (dialect === 'turso') {
787+
await prepareAndExportLibSQL(opts);
788+
} else if (dialect === 'singlestore') {
789+
await prepareAndExportSinglestore(opts);
790+
} else {
791+
assertUnreachable(dialect);
792+
}
793+
},
794+
});

drizzle-kit/src/cli/validations/common.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export type Commands =
1010
| 'check'
1111
| 'up'
1212
| 'drop'
13-
| 'push';
13+
| 'push'
14+
| 'export';
1415

1516
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
1617
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
@@ -111,6 +112,7 @@ export const configCommonSchema = object({
111112
migrations: configMigrations,
112113
dbCredentials: any().optional(),
113114
casing: casingType.optional(),
115+
sql: boolean().default(true),
114116
}).passthrough();
115117

116118
export const casing = union([literal('camel'), literal('preserve')]).default(

0 commit comments

Comments
 (0)