Skip to content
New issue

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

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

Already on GitHub? # to your account

created export command for drizzle-kit #3705

Merged
merged 4 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
168 changes: 167 additions & 1 deletion drizzle-kit/src/cli/commands/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import {
ResolveSelectNamed,
schema,
} from '../views';
import { GenerateConfig } from './utils';
import { ExportConfig, GenerateConfig } from './utils';

export type Named = {
name: string;
Expand Down Expand Up @@ -368,6 +368,44 @@ export const prepareAndMigratePg = async (config: GenerateConfig) => {
}
};

export const prepareAndExportPg = async (config: ExportConfig) => {
const schemaPath = config.schema;

try {
const { prev, cur } = await preparePgMigrationSnapshot(
[], // no snapshots before
schemaPath,
undefined,
);

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

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

const { sqlStatements } = await applyPgSnapshotsDiff(
squashedPrev,
squashedCur,
schemasResolver,
enumsResolver,
sequencesResolver,
policyResolver,
indPolicyResolver,
roleResolver,
tablesResolver,
columnsResolver,
viewsResolver,
validatedPrev,
validatedCur,
);

console.log(sqlStatements.join('\n'));
} catch (e) {
console.error(e);
}
};

export const preparePgPush = async (
cur: PgSchema,
prev: PgSchema,
Expand Down Expand Up @@ -697,6 +735,70 @@ export const prepareAndMigrateSingleStore = async (config: GenerateConfig) => {
}
};

export const prepareAndExportSinglestore = async (config: ExportConfig) => {
const schemaPath = config.schema;

try {
const { prev, cur } = await prepareSingleStoreMigrationSnapshot(
[],
schemaPath,
undefined,
);

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

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

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

console.log(sqlStatements.join('\n'));
} catch (e) {
console.error(e);
}
};

export const prepareAndExportMysql = async (config: ExportConfig) => {
const schemaPath = config.schema;

try {
const { prev, cur, custom } = await prepareMySqlMigrationSnapshot(
[],
schemaPath,
undefined,
);

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

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

const { sqlStatements, statements, _meta } = await applyMysqlSnapshotsDiff(
squashedPrev,
squashedCur,
tablesResolver,
columnsResolver,
mySqlViewsResolver,
validatedPrev,
validatedCur,
);

console.log(sqlStatements.join('\n'));
} catch (e) {
console.error(e);
}
};

export const prepareAndMigrateSqlite = async (config: GenerateConfig) => {
const outFolder = config.out;
const schemaPath = config.schema;
Expand Down Expand Up @@ -760,6 +862,38 @@ export const prepareAndMigrateSqlite = async (config: GenerateConfig) => {
}
};

export const prepareAndExportSqlite = async (config: ExportConfig) => {
const schemaPath = config.schema;

try {
const { prev, cur } = await prepareSqliteMigrationSnapshot(
[],
schemaPath,
undefined,
);

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

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

const { sqlStatements, _meta } = await applySqliteSnapshotsDiff(
squashedPrev,
squashedCur,
tablesResolver,
columnsResolver,
sqliteViewsResolver,
validatedPrev,
validatedCur,
);

console.log(sqlStatements.join('\n'));
} catch (e) {
console.error(e);
}
};

export const prepareAndMigrateLibSQL = async (config: GenerateConfig) => {
const outFolder = config.out;
const schemaPath = config.schema;
Expand Down Expand Up @@ -822,6 +956,38 @@ export const prepareAndMigrateLibSQL = async (config: GenerateConfig) => {
}
};

export const prepareAndExportLibSQL = async (config: ExportConfig) => {
const schemaPath = config.schema;

try {
const { prev, cur, custom } = await prepareSqliteMigrationSnapshot(
[],
schemaPath,
undefined,
);

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

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

const { sqlStatements, _meta } = await applyLibSQLSnapshotsDiff(
squashedPrev,
squashedCur,
tablesResolver,
columnsResolver,
sqliteViewsResolver,
validatedPrev,
validatedCur,
);

console.log(sqlStatements.join('\n'));
} catch (e) {
console.error(e);
}
};

export const prepareSQLitePush = async (
schemaPath: string | string[],
snapshot: SQLiteSchema,
Expand Down
44 changes: 42 additions & 2 deletions drizzle-kit/src/cli/commands/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ export type GenerateConfig = {
driver?: Driver;
};

export type ExportConfig = {
dialect: Dialect;
schema: string | string[];
sql: boolean;
};

export const prepareGenerateConfig = async (
options: {
config?: string;
Expand Down Expand Up @@ -185,6 +191,38 @@ export const prepareGenerateConfig = async (
};
};

export const prepareExportConfig = async (
options: {
config?: string;
schema?: string;
dialect?: Dialect;
sql: boolean;
},
from: 'config' | 'cli',
): Promise<ExportConfig> => {
const config = from === 'config' ? await drizzleConfigFromFile(options.config, true) : options;

const { schema, dialect, sql } = config;

if (!schema || !dialect) {
console.log(error('Please provide required params:'));
console.log(wrapParam('schema', schema));
console.log(wrapParam('dialect', dialect));
process.exit(1);
}

const fileNames = prepareFilenames(schema);
if (fileNames.length === 0) {
render(`[${chalk.blue('i')}] No schema file in ${schema} was found`);
process.exit(0);
}
return {
dialect: dialect,
schema: schema,
sql: sql,
};
};

export const flattenDatabaseCredentials = (config: any) => {
if ('dbCredentials' in config) {
const { dbCredentials, ...rest } = config;
Expand Down Expand Up @@ -768,6 +806,7 @@ export const prepareMigrateConfig = async (configPath: string | undefined) => {

export const drizzleConfigFromFile = async (
configPath?: string,
isExport?: boolean,
): Promise<CliConfig> => {
const prefix = process.env.TEST_CONFIG_PATH_PREFIX || '';

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

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

console.log(chalk.grey(`Reading config file '${path}'`));
if (!isExport) console.log(chalk.grey(`Reading config file '${path}'`));

const { unregister } = await safeRegister();
const required = require(`${path}`);
const content = required.default ?? required;
Expand Down
4 changes: 2 additions & 2 deletions drizzle-kit/src/cli/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { command, run } from '@drizzle-team/brocli';
import chalk from 'chalk';
import { check, drop, generate, migrate, pull, push, studio, up } from './schema';
import { check, drop, exportRaw, generate, migrate, pull, push, studio, up } from './schema';
import { ormCoreVersions } from './utils';

const version = async () => {
Expand Down Expand Up @@ -42,7 +42,7 @@ const legacy = [
legacyCommand('check:sqlite', 'check'),
];

run([generate, migrate, pull, push, studio, up, check, drop, ...legacy], {
run([generate, migrate, pull, push, studio, up, check, drop, exportRaw, ...legacy], {
name: 'drizzle-kit',
version: version,
});
45 changes: 45 additions & 0 deletions drizzle-kit/src/cli/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { upSqliteHandler } from './commands/sqliteUp';
import {
prepareCheckParams,
prepareDropParams,
prepareExportConfig,
prepareGenerateConfig,
prepareMigrateConfig,
preparePullConfig,
Expand Down Expand Up @@ -747,3 +748,47 @@ export const studio = command({
}
},
});

export const exportRaw = command({
name: 'export',
desc: 'Generate diff between current state and empty state in specified formats: sql',
options: {
sql: boolean('sql').default(true).desc('Generate as sql'),
config: optionConfig,
dialect: optionDialect,
schema: string().desc('Path to a schema file or folder'),
},
transform: async (opts) => {
const from = assertCollisions('export', opts, ['sql'], ['dialect', 'schema']);
return prepareExportConfig(opts, from);
},
handler: async (opts) => {
await assertOrmCoreVersion();
await assertPackages('drizzle-orm');

const {
prepareAndExportPg,
prepareAndExportMysql,
prepareAndExportSqlite,
prepareAndExportLibSQL,
prepareAndExportSinglestore,
} = await import(
'./commands/migrate'
);

const dialect = opts.dialect;
if (dialect === 'postgresql') {
await prepareAndExportPg(opts);
} else if (dialect === 'mysql') {
await prepareAndExportMysql(opts);
} else if (dialect === 'sqlite') {
await prepareAndExportSqlite(opts);
} else if (dialect === 'turso') {
await prepareAndExportLibSQL(opts);
} else if (dialect === 'singlestore') {
await prepareAndExportSinglestore(opts);
} else {
assertUnreachable(dialect);
}
},
});
4 changes: 3 additions & 1 deletion drizzle-kit/src/cli/validations/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export type Commands =
| 'check'
| 'up'
| 'drop'
| 'push';
| 'push'
| 'export';

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

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