Skip to content

Commit

Permalink
feat(mysql): Support customIndex
Browse files Browse the repository at this point in the history
  • Loading branch information
dengfuping committed Dec 17, 2024
1 parent 10d2230 commit 9f7cdc4
Show file tree
Hide file tree
Showing 6 changed files with 318 additions and 255 deletions.
24 changes: 17 additions & 7 deletions drizzle-kit/src/serializer/mysqlSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const index = object({
using: enumType(['btree', 'hash']).optional(),
algorithm: enumType(['default', 'inplace', 'copy']).optional(),
lock: enumType(['default', 'none', 'shared', 'exclusive']).optional(),
raw: string().optional(),
}).strict();

const fk = object({
Expand Down Expand Up @@ -219,22 +220,32 @@ export type CheckConstraint = TypeOf<typeof checkConstraint>;
export type View = TypeOf<typeof view>;
export type ViewSquashed = TypeOf<typeof viewSquashed>;

/**
* encode from `;` to `%3B` to avoid split error
*/
export const encodeRaw = (raw?: string) => raw?.replaceAll(';', '%3B');

/**
* decode from `%3B` to `;` to recover original value
*/
export const decodeRaw = (raw?: string) => raw?.replaceAll('%3B', ';');

export const MySqlSquasher = {
squashIdx: (idx: Index) => {
index.parse(idx);
return `${idx.name};${idx.columns.join(',')};${idx.isUnique};${idx.using ?? ''};${idx.algorithm ?? ''};${
idx.lock ?? ''
}`;
return `${idx.name};${idx.columns.join(',')};${idx.isUnique};${idx.using ?? ''};${idx.algorithm ?? ''};${idx.lock ?? ''
};${idx.raw ? encodeRaw(idx.raw) : ''}`;
},
unsquashIdx: (input: string): Index => {
const [name, columnsString, isUnique, using, algorithm, lock] = input.split(';');
const [name, columnsString, isUnique, using, algorithm, lock, raw] = input.split(';');
const destructed = {
name,
columns: columnsString.split(','),
isUnique: isUnique === 'true',
using: using ? using : undefined,
algorithm: algorithm ? algorithm : undefined,
lock: lock ? lock : undefined,
raw: raw ? raw : undefined,
};
return index.parse(destructed);
},
Expand All @@ -253,9 +264,8 @@ export const MySqlSquasher = {
return { name, columns: columns.split(',') };
},
squashFK: (fk: ForeignKey) => {
return `${fk.name};${fk.tableFrom};${fk.columnsFrom.join(',')};${fk.tableTo};${fk.columnsTo.join(',')};${
fk.onUpdate ?? ''
};${fk.onDelete ?? ''}`;
return `${fk.name};${fk.tableFrom};${fk.columnsFrom.join(',')};${fk.tableTo};${fk.columnsTo.join(',')};${fk.onUpdate ?? ''
};${fk.onDelete ?? ''}`;
},
unsquashFK: (input: string): ForeignKey => {
const [
Expand Down
190 changes: 83 additions & 107 deletions drizzle-kit/src/serializer/mysqlSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ export const generateMySqlSnapshot = (
as: is(generated.as, SQL)
? dialect.sqlToQuery(generated.as as SQL).sql
: typeof generated.as === 'function'
? dialect.sqlToQuery(generated.as() as SQL).sql
: (generated.as as any),
? dialect.sqlToQuery(generated.as() as SQL).sql
: (generated.as as any),
type: generated.mode ?? 'stored',
}
: undefined,
Expand All @@ -115,24 +115,19 @@ export const generateMySqlSnapshot = (
const existingUnique = uniqueConstraintObject[column.uniqueName!];
if (typeof existingUnique !== 'undefined') {
console.log(
`\n${
withStyle.errorWarning(`We\'ve found duplicated unique constraint names in ${
chalk.underline.blue(
tableName,
)
`\n${withStyle.errorWarning(`We\'ve found duplicated unique constraint names in ${chalk.underline.blue(
tableName,
)
} table.
The unique constraint ${
chalk.underline.blue(
column.uniqueName,
)
} on the ${
chalk.underline.blue(
name,
)
} column is confilcting with a unique constraint name already defined for ${
chalk.underline.blue(
existingUnique.columns.join(','),
)
The unique constraint ${chalk.underline.blue(
column.uniqueName,
)
} on the ${chalk.underline.blue(
name,
)
} column is confilcting with a unique constraint name already defined for ${chalk.underline.blue(
existingUnique.columns.join(','),
)
} columns\n`)
}`,
);
Expand Down Expand Up @@ -160,12 +155,11 @@ export const generateMySqlSnapshot = (
sqlTypeLowered.startsWith('datetime')
|| sqlTypeLowered.startsWith('timestamp')
) {
columnToSet.default = `'${
column.default
.toISOString()
.replace('T', ' ')
.slice(0, 23)
}'`;
columnToSet.default = `'${column.default
.toISOString()
.replace('T', ' ')
.slice(0, 23)
}'`;
}
} else {
columnToSet.default = column.default;
Expand Down Expand Up @@ -209,26 +203,21 @@ export const generateMySqlSnapshot = (
const existingUnique = uniqueConstraintObject[name];
if (typeof existingUnique !== 'undefined') {
console.log(
`\n${
withStyle.errorWarning(
`We\'ve found duplicated unique constraint names in ${
chalk.underline.blue(
tableName,
)
} table. \nThe unique constraint ${
chalk.underline.blue(
name,
)
} on the ${
chalk.underline.blue(
columnNames.join(','),
)
} columns is confilcting with a unique constraint name already defined for ${
chalk.underline.blue(
existingUnique.columns.join(','),
)
} columns\n`,
`\n${withStyle.errorWarning(
`We\'ve found duplicated unique constraint names in ${chalk.underline.blue(
tableName,
)
} table. \nThe unique constraint ${chalk.underline.blue(
name,
)
} on the ${chalk.underline.blue(
columnNames.join(','),
)
} columns is confilcting with a unique constraint name already defined for ${chalk.underline.blue(
existingUnique.columns.join(','),
)
} columns\n`,
)
}`,
);
process.exit(1);
Expand Down Expand Up @@ -314,46 +303,38 @@ export const generateMySqlSnapshot = (
if (value.config.unique) {
if (typeof uniqueConstraintObject[name] !== 'undefined') {
console.log(
`\n${
withStyle.errorWarning(
`We\'ve found duplicated unique constraint names in ${
chalk.underline.blue(
tableName,
)
} table. \nThe unique index ${
chalk.underline.blue(
name,
)
} on the ${
chalk.underline.blue(
indexColumns.join(','),
)
} columns is confilcting with a unique constraint name already defined for ${
chalk.underline.blue(
uniqueConstraintObject[name].columns.join(','),
)
} columns\n`,
`\n${withStyle.errorWarning(
`We\'ve found duplicated unique constraint names in ${chalk.underline.blue(
tableName,
)
} table. \nThe unique index ${chalk.underline.blue(
name,
)
} on the ${chalk.underline.blue(
indexColumns.join(','),
)
} columns is confilcting with a unique constraint name already defined for ${chalk.underline.blue(
uniqueConstraintObject[name].columns.join(','),
)
} columns\n`,
)
}`,
);
process.exit(1);
}
} else {
if (typeof foreignKeysObject[name] !== 'undefined') {
console.log(
`\n${
withStyle.errorWarning(
`In MySQL, when creating a foreign key, an index is automatically generated with the same name as the foreign key constraint.\n\nWe have encountered a collision between the index name on columns ${
chalk.underline.blue(
indexColumns.join(','),
)
} and the foreign key on columns ${
chalk.underline.blue(
foreignKeysObject[name].columnsFrom.join(','),
)
}. Please change either the index name or the foreign key name. For more information, please refer to https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html\n
`,
`\n${withStyle.errorWarning(
`In MySQL, when creating a foreign key, an index is automatically generated with the same name as the foreign key constraint.\n\nWe have encountered a collision between the index name on columns ${chalk.underline.blue(
indexColumns.join(','),
)
} and the foreign key on columns ${chalk.underline.blue(
foreignKeysObject[name].columnsFrom.join(','),
)
}. Please change either the index name or the foreign key name. For more information, please refer to https://dev.mysql.com/doc/refman/8.0/en/constraint-foreign-key.html\n
`,
)
}`,
);
process.exit(1);
Expand All @@ -367,6 +348,7 @@ export const generateMySqlSnapshot = (
using: value.config.using,
algorithm: value.config.algorythm,
lock: value.config.lock,
raw: value.config.raw
};
});

Expand All @@ -376,18 +358,15 @@ export const generateMySqlSnapshot = (
if (typeof checksInTable[tableName] !== 'undefined') {
if (checksInTable[tableName].includes(check.name)) {
console.log(
`\n${
withStyle.errorWarning(
`We\'ve found duplicated check constraint name in ${
chalk.underline.blue(
tableName,
)
}. Please rename your check constraint in the ${
chalk.underline.blue(
tableName,
)
} table`,
`\n${withStyle.errorWarning(
`We\'ve found duplicated check constraint name in ${chalk.underline.blue(
tableName,
)
}. Please rename your check constraint in the ${chalk.underline.blue(
tableName,
)
} table`,
)
}`,
);
process.exit(1);
Expand Down Expand Up @@ -434,14 +413,12 @@ export const generateMySqlSnapshot = (
const existingView = resultViews[name];
if (typeof existingView !== 'undefined') {
console.log(
`\n${
withStyle.errorWarning(
`We\'ve found duplicated view name across ${
chalk.underline.blue(
schema ?? 'public',
)
} schema. Please rename your view`,
`\n${withStyle.errorWarning(
`We\'ve found duplicated view name across ${chalk.underline.blue(
schema ?? 'public',
)
} schema. Please rename your view`,
)
}`,
);
process.exit(1);
Expand Down Expand Up @@ -473,8 +450,8 @@ export const generateMySqlSnapshot = (
as: is(generated.as, SQL)
? dialect.sqlToQuery(generated.as as SQL).sql
: typeof generated.as === 'function'
? dialect.sqlToQuery(generated.as() as SQL).sql
: (generated.as as any),
? dialect.sqlToQuery(generated.as() as SQL).sql
: (generated.as as any),
type: generated.mode ?? 'stored',
}
: undefined,
Expand All @@ -496,12 +473,11 @@ export const generateMySqlSnapshot = (
sqlTypeLowered.startsWith('datetime')
|| sqlTypeLowered.startsWith('timestamp')
) {
columnToSet.default = `'${
column.default
.toISOString()
.replace('T', ' ')
.slice(0, 23)
}'`;
columnToSet.default = `'${column.default
.toISOString()
.replace('T', ' ')
.slice(0, 23)
}'`;
}
} else {
columnToSet.default = column.default;
Expand Down Expand Up @@ -676,11 +652,11 @@ export const fromDatabase = async (
default: columnDefault === null || columnDefault === undefined
? undefined
: /^-?[\d.]+(?:e-?\d+)?$/.test(columnDefault)
&& !['decimal', 'char', 'varchar'].some((type) => columnType.startsWith(type))
? Number(columnDefault)
: isDefaultAnExpression
? clearDefaults(columnDefault, collation)
: `'${escapeSingleQuotes(columnDefault)}'`,
&& !['decimal', 'char', 'varchar'].some((type) => columnType.startsWith(type))
? Number(columnDefault)
: isDefaultAnExpression
? clearDefaults(columnDefault, collation)
: `'${escapeSingleQuotes(columnDefault)}'`,
autoincrement: isAutoincrement,
name: columnName,
type: changedType,
Expand Down Expand Up @@ -708,7 +684,7 @@ export const fromDatabase = async (
} else {
if (
typeof internals!.tables![tableName]!.columns[columnName]
=== 'undefined'
=== 'undefined'
) {
internals!.tables![tableName]!.columns[columnName] = {
isDefaultAnExpression: true,
Expand Down
Loading

0 comments on commit 9f7cdc4

Please sign in to comment.