mirror of
https://github.com/strapi/strapi.git
synced 2025-09-04 14:23:03 +00:00
fix: init dialect on every new connection in the pool (#18588)
This commit is contained in:
parent
3e3b3393e2
commit
7a48741483
@ -11,12 +11,34 @@ function isClientValid(config: { client?: unknown }): config is { client: keyof
|
|||||||
return Object.keys(clientMap).includes(config.client as string);
|
return Object.keys(clientMap).includes(config.client as string);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createConnection = (config: Knex.Config) => {
|
export const createConnection = (userConfig: Knex.Config, strapiConfig?: Partial<Knex.Config>) => {
|
||||||
if (!isClientValid(config)) {
|
if (!isClientValid(userConfig)) {
|
||||||
throw new Error(`Unsupported database client ${config.client}`);
|
throw new Error(`Unsupported database client ${userConfig.client}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const knexConfig = { ...config, client: (clientMap as any)[config.client] };
|
const knexConfig: Knex.Config = { ...userConfig, client: (clientMap as any)[userConfig.client] };
|
||||||
|
|
||||||
|
// initialization code to run upon opening a new connection
|
||||||
|
if (strapiConfig?.pool?.afterCreate) {
|
||||||
|
knexConfig.pool = knexConfig.pool || {};
|
||||||
|
// if the user has set their own afterCreate in config, we will replace it and call it
|
||||||
|
const userAfterCreate = knexConfig.pool?.afterCreate;
|
||||||
|
const strapiAfterCreate = strapiConfig.pool.afterCreate;
|
||||||
|
knexConfig.pool.afterCreate = (
|
||||||
|
conn: unknown,
|
||||||
|
done: (err: Error | null | undefined, connection: any) => void
|
||||||
|
) => {
|
||||||
|
strapiAfterCreate(conn, (err: Error | null | undefined, nativeConn: any) => {
|
||||||
|
if (err) {
|
||||||
|
return done(err, nativeConn);
|
||||||
|
}
|
||||||
|
if (userAfterCreate) {
|
||||||
|
return userAfterCreate(nativeConn, done);
|
||||||
|
}
|
||||||
|
return done(null, nativeConn);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return knex(knexConfig);
|
return knex(knexConfig);
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,10 @@ export default class Dialect {
|
|||||||
|
|
||||||
configure() {}
|
configure() {}
|
||||||
|
|
||||||
initialize() {}
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
async initialize(_nativeConnection?: unknown) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
getSqlType(type: unknown) {
|
getSqlType(type: unknown) {
|
||||||
return type;
|
return type;
|
||||||
|
@ -52,14 +52,19 @@ export default class MysqlDialect extends Dialect {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize() {
|
async initialize(nativeConnection: unknown) {
|
||||||
try {
|
try {
|
||||||
await this.db.connection.raw(`set session sql_require_primary_key = 0;`);
|
await this.db.connection
|
||||||
|
.raw(`set session sql_require_primary_key = 0;`)
|
||||||
|
.connection(nativeConnection);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Ignore error due to lack of session permissions
|
// Ignore error due to lack of session permissions
|
||||||
}
|
}
|
||||||
|
|
||||||
this.info = await this.databaseInspector.getInformation();
|
// We only need to get info on the first connection in the pool
|
||||||
|
if (!this.info) {
|
||||||
|
this.info = await this.databaseInspector.getInformation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async startSchemaUpdate() {
|
async startSchemaUpdate() {
|
||||||
|
@ -16,7 +16,7 @@ export default class PostgresDialect extends Dialect {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize() {
|
async initialize(nativeConnection: unknown) {
|
||||||
// Don't cast DATE string to Date()
|
// Don't cast DATE string to Date()
|
||||||
this.db.connection.client.driver.types.setTypeParser(
|
this.db.connection.client.driver.types.setTypeParser(
|
||||||
this.db.connection.client.driver.types.builtins.DATE,
|
this.db.connection.client.driver.types.builtins.DATE,
|
||||||
@ -34,6 +34,14 @@ export default class PostgresDialect extends Dialect {
|
|||||||
'text',
|
'text',
|
||||||
parseFloat
|
parseFloat
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If we're using a schema, set the default path for all table names in queries to use that schema
|
||||||
|
const schemaName = this.db.getSchemaName();
|
||||||
|
if (schemaName) {
|
||||||
|
await this.db.connection
|
||||||
|
.raw(`SET search_path TO "${schemaName}"`)
|
||||||
|
.connection(nativeConnection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
usesForeignKeys() {
|
usesForeignKeys() {
|
||||||
|
@ -33,8 +33,8 @@ export default class SqliteDialect extends Dialect {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialize() {
|
async initialize(nativeConnection: unknown) {
|
||||||
await this.db.connection.raw('pragma foreign_keys = on');
|
await this.db.connection.raw('pragma foreign_keys = on').connection(nativeConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
canAlterConstraints() {
|
canAlterConstraints() {
|
||||||
|
@ -69,9 +69,17 @@ class Database {
|
|||||||
this.dialect = getDialect(this);
|
this.dialect = getDialect(this);
|
||||||
this.dialect.configure();
|
this.dialect.configure();
|
||||||
|
|
||||||
this.connection = createConnection(this.config.connection);
|
const afterCreate = (
|
||||||
|
nativeConnection: unknown,
|
||||||
|
done: (error: Error | null, nativeConnection: unknown) => Promise<void>
|
||||||
|
) => {
|
||||||
|
// run initialize for it since commands such as postgres SET and sqlite PRAGMA are per-connection
|
||||||
|
this.dialect.initialize(nativeConnection).then(() => {
|
||||||
|
return done(null, nativeConnection);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
this.dialect.initialize();
|
this.connection = createConnection(this.config.connection, { pool: { afterCreate } });
|
||||||
|
|
||||||
this.schema = createSchemaProvider(this);
|
this.schema = createSchemaProvider(this);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user