Skip to content
Open
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
5 changes: 2 additions & 3 deletions drizzle-kit/src/serializer/mysqlSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ export const indexName = (tableName: string, columns: string[]) => {
};

const handleEnumType = (type: string) => {
let str = type.split('(')[1];
str = str.substring(0, str.length - 1);
const values = str.split(',').map((v) => `'${escapeSingleQuotes(v.substring(1, v.length - 1))}'`);
const str = type.split('(')[1].slice(0, -1);
const values = [...str.matchAll(/'((?:[^']|'')*)'/g)].map((m) => `'${escapeSingleQuotes(m[1])}'`);
return `enum(${values.join(',')})`;
};

Expand Down
32 changes: 32 additions & 0 deletions drizzle-kit/tests/mysql.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -896,3 +896,35 @@ test('add table with ts enum', async () => {
checkConstraints: [],
});
});

test('add table with enum value containing comma', async () => {
const to = {
users: mysqlTable('users', {
enum: mysqlEnum('enum', ['a,b', 'c']),
}),
};

const { statements } = await diffTestSchemasMysql({}, to, []);

expect(statements.length).toBe(1);
expect(statements[0]).toStrictEqual({
type: 'create_table',
tableName: 'users',
schema: undefined,
columns: [{
autoincrement: false,
name: 'enum',
notNull: false,
primaryKey: false,
type: "enum('a,b','c')",
}],
compositePKs: [],
internals: {
tables: {},
indexes: {},
},
uniqueConstraints: [],
compositePkName: '',
checkConstraints: [],
});
});
6 changes: 2 additions & 4 deletions drizzle-orm/src/gel-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,8 @@ export abstract class GelPreparedQuery<T extends PreparedQueryConfig> implements
) && this.queryMetadata.tables.length > 0
) {
try {
const [res] = await Promise.all([
query(),
this.cache.onMutate({ tables: this.queryMetadata.tables }),
]);
const res = await query();
await this.cache.onMutate({ tables: this.queryMetadata.tables });
return res;
} catch (e) {
throw new DrizzleQueryError(queryString, params, e as Error);
Expand Down
6 changes: 2 additions & 4 deletions drizzle-orm/src/mysql-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,8 @@ export abstract class MySqlPreparedQuery<T extends MySqlPreparedQueryConfig> {
) && this.queryMetadata.tables.length > 0
) {
try {
const [res] = await Promise.all([
query(),
this.cache.onMutate({ tables: this.queryMetadata.tables }),
]);
const res = await query();
await this.cache.onMutate({ tables: this.queryMetadata.tables });
return res;
} catch (e) {
throw new DrizzleQueryError(queryString, params, e as Error);
Expand Down
6 changes: 2 additions & 4 deletions drizzle-orm/src/pg-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,8 @@ export abstract class PgPreparedQuery<T extends PreparedQueryConfig> implements
) && this.queryMetadata.tables.length > 0
) {
try {
const [res] = await Promise.all([
query(),
this.cache.onMutate({ tables: this.queryMetadata.tables }),
]);
const res = await query();
await this.cache.onMutate({ tables: this.queryMetadata.tables });
return res;
} catch (e) {
throw new DrizzleQueryError(queryString, params, e as Error);
Expand Down
6 changes: 2 additions & 4 deletions drizzle-orm/src/singlestore-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,8 @@ export abstract class SingleStorePreparedQuery<T extends SingleStorePreparedQuer
) && this.queryMetadata.tables.length > 0
) {
try {
const [res] = await Promise.all([
query(),
this.cache.onMutate({ tables: this.queryMetadata.tables }),
]);
const res = await query();
await this.cache.onMutate({ tables: this.queryMetadata.tables });
return res;
} catch (e) {
throw new DrizzleQueryError(queryString, params, e as Error);
Expand Down
6 changes: 2 additions & 4 deletions drizzle-orm/src/sqlite-core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,8 @@ export abstract class SQLitePreparedQuery<T extends PreparedQueryConfig> impleme
) && this.queryMetadata.tables.length > 0
) {
try {
const [res] = await Promise.all([
query(),
this.cache.onMutate({ tables: this.queryMetadata.tables }),
]);
const res = await query();
await this.cache.onMutate({ tables: this.queryMetadata.tables });
return res;
} catch (e) {
throw new DrizzleQueryError(queryString, params, e as Error);
Expand Down
32 changes: 32 additions & 0 deletions integration-tests/tests/pg/pg-common-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,38 @@ export function tests() {
expect(spyInvalidate).toHaveBeenCalledTimes(1);
});

test('write: db query resolves before onMutate (no concurrent cache race)', async (ctx) => {
const { db } = ctx.cachedPg;

// Track invocation order to verify the DB write commits before cache invalidation.
const callOrder: string[] = [];

// @ts-expect-error
vi.spyOn(db.$cache, 'onMutate').mockImplementation(async () => {
callOrder.push('onMutate');
});

// Patch the underlying session.query to record when the DB write resolves.
const session = (db as any).session;
const originalQuery = session?.query?.bind(session);
if (originalQuery) {
vi.spyOn(session, 'query').mockImplementation(async (...args: any[]) => {
callOrder.push('query:start');
const result = await originalQuery(...args);
callOrder.push('query:end');
return result;
});
}

await db.insert(usersTable).values({ name: 'Jane' });

const queryEndIdx = callOrder.indexOf('query:end');
const onMutateIdx = callOrder.indexOf('onMutate');
expect(queryEndIdx).toBeGreaterThanOrEqual(0);
expect(onMutateIdx).toBeGreaterThanOrEqual(0);
expect(queryEndIdx).toBeLessThan(onMutateIdx);
});

test('default global config + enable cache on select + disable invalidate: get, put', async (ctx) => {
const { db } = ctx.cachedPg;

Expand Down