refactor the way database version is fetched

This commit is contained in:
Pierre Noël 2022-11-16 18:30:38 +01:00
parent 6103e4de1f
commit eba2da51af
14 changed files with 132 additions and 52 deletions

View File

@ -28,10 +28,22 @@ const mysql = {
},
};
const mariadb = {
client: 'mysql',
connection: {
database: 'strapi',
user: 'strapi',
password: 'strapi',
port: 3307,
host: 'localhost',
},
};
const db = {
mysql,
sqlite,
postgres,
mariadb,
};
module.exports = {

View File

@ -7,6 +7,8 @@ class Dialect {
configure() {}
getInfo() {}
initialize() {}
getSqlType(type) {

View File

@ -0,0 +1,28 @@
'use strict';
const { MARIADB, MYSQL } = require('../../utils/constants');
const SQL_QUERIES = {
VERSION: `SELECT version()`,
};
class MysqlDatabaseInspector {
constructor(db) {
this.db = db;
}
async getInformation() {
const [results] = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = results[0]['version()'];
const [versionNumber, databaseName] = version.split('-');
const database = databaseName && databaseName.toLowerCase() === 'mariadb' ? MARIADB : MYSQL;
return {
database,
version: versionNumber,
};
}
}
module.exports = MysqlDatabaseInspector;

View File

@ -2,12 +2,15 @@
const { Dialect } = require('../dialect');
const MysqlSchemaInspector = require('./schema-inspector');
const MysqlDatabaseInspector = require('./database-inspector');
class MysqlDialect extends Dialect {
constructor(db) {
super(db);
this.schemaInspector = new MysqlSchemaInspector(db);
this.databaseInspector = new MysqlDatabaseInspector(db);
this.info = null;
}
configure() {
@ -32,12 +35,17 @@ class MysqlDialect extends Dialect {
};
}
getInfo() {
return this.info;
}
async initialize() {
try {
await this.db.connection.raw(`set session sql_require_primary_key = 0;`);
} catch (err) {
// Ignore error due to lack of session permissions
}
this.info = await this.databaseInspector.getInformation();
}
async startSchemaUpdate() {

View File

@ -53,9 +53,6 @@ const SQL_QUERIES = {
AND rc.constraint_schema = database()
AND rc.table_name = ?;
`,
VERSION: /* sql */ `
SELECT version();
`,
};
const toStrapiType = (column) => {
@ -232,19 +229,6 @@ class MysqlSchemaInspector {
return Object.values(ret);
}
async getDatabaseInformation() {
const [results] = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = results[0]['version()'];
const [versionNumber, databaseName] = version.split('-');
const database = databaseName && databaseName.toLowerCase() === 'mariadb' ? 'MariaDB' : 'MySQL';
return {
database,
version: versionNumber,
};
}
}
module.exports = MysqlSchemaInspector;

View File

@ -0,0 +1,25 @@
'use strict';
const { POSTGRES } = require('../../utils/constants');
const SQL_QUERIES = {
VERSION: `SELECT current_setting('server_version')`,
};
class PostgresqlDatabaseInspector {
constructor(db) {
this.db = db;
}
async getInformation() {
const { rows } = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = rows[0].current_setting;
return {
database: POSTGRES,
version: version.split(' ')[0],
};
}
}
module.exports = PostgresqlDatabaseInspector;

View File

@ -3,21 +3,29 @@
const errors = require('../../errors');
const { Dialect } = require('../dialect');
const PostgresqlSchemaInspector = require('./schema-inspector');
const PostgresqlDatabaseInspector = require('./database-inspector');
class PostgresDialect extends Dialect {
constructor(db) {
super(db);
this.schemaInspector = new PostgresqlSchemaInspector(db);
this.databaseInspector = new PostgresqlDatabaseInspector(db);
this.info = null;
}
useReturning() {
return true;
}
initialize() {
getInfo() {
return this.info;
}
async initialize() {
this.db.connection.client.driver.types.setTypeParser(1082, 'text', (v) => v); // Don't cast DATE string to Date()
this.db.connection.client.driver.types.setTypeParser(1700, 'text', parseFloat);
this.info = await this.databaseInspector.getInformation();
}
usesForeignKeys() {

View File

@ -74,9 +74,6 @@ const SQL_QUERIES = {
FROM information_schema.key_column_usage rel_kcu
WHERE rel_kcu.constraint_name=?
AND rel_kcu.table_schema = ?
`,
VERSION: /* sql */ `
SELECT current_setting('server_version');
`,
};
@ -281,16 +278,6 @@ class PostgresqlSchemaInspector {
return Object.values(ret);
}
async getDatabaseInformation() {
const { rows } = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = rows[0].current_setting;
return {
database: 'Postgres',
version: version.split(' ')[0],
};
}
}
module.exports = PostgresqlSchemaInspector;

View File

@ -0,0 +1,25 @@
'use strict';
const { SQLITE } = require('../../utils/constants');
const SQL_QUERIES = {
VERSION: `SELECT sqlite_version()`,
};
class SqliteDatabaseInspector {
constructor(db) {
this.db = db;
}
async getInformation() {
const results = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = results[0]['sqlite_version()'];
return {
database: SQLITE,
version,
};
}
}
module.exports = SqliteDatabaseInspector;

View File

@ -5,13 +5,16 @@ const fse = require('fs-extra');
const errors = require('../../errors');
const { Dialect } = require('../dialect');
const SqliteSchmeaInspector = require('./schema-inspector');
const SqliteSchemaInspector = require('./schema-inspector');
const SqliteDatabaseInspector = require('./database-inspector');
class SqliteDialect extends Dialect {
constructor(db) {
super(db);
this.schemaInspector = new SqliteSchmeaInspector(db);
this.schemaInspector = new SqliteSchemaInspector(db);
this.databaseInspector = new SqliteDatabaseInspector(db);
this.info = null;
}
configure() {
@ -24,12 +27,17 @@ class SqliteDialect extends Dialect {
fse.ensureDirSync(dbDir);
}
getInfo() {
return this.info;
}
useReturning() {
return true;
}
async initialize() {
await this.db.connection.raw('pragma foreign_keys = on');
this.info = await this.databaseInspector.getInformation();
}
canAlterConstraints() {

View File

@ -6,7 +6,6 @@ const SQL_QUERIES = {
INDEX_LIST: 'pragma index_list(??)',
INDEX_INFO: 'pragma index_info(??)',
FOREIGN_KEY_LIST: 'pragma foreign_key_list(??)',
VERSION: `SELECT sqlite_version()`,
};
const toStrapiType = (column) => {
@ -147,16 +146,6 @@ class SqliteSchemaInspector {
return Object.values(ret);
}
async getDatabaseInformation() {
const results = await this.db.connection.raw(SQL_QUERIES.VERSION);
const version = results[0]['sqlite_version()'];
return {
database: 'SQLite',
version,
};
}
}
module.exports = SqliteSchemaInspector;

View File

@ -2,6 +2,7 @@
const { map, isEmpty } = require('lodash/fp');
const semver = require('semver');
const { MYSQL } = require('../utils/constants');
const {
isBidirectional,
isOneToAny,
@ -197,8 +198,8 @@ const cleanOrderColumns = async ({ id, attribute, db, inverseRelIds, transaction
}
// Handle databases that don't support window function ROW_NUMBER
const { database, version } = await strapi.db.getDatabaseInformation();
if (database === 'MySQL' && semver.lt(version, '8.0.0')) {
const { database, version } = strapi.db.getDatabaseInformation();
if (database === MYSQL && semver.lt(version, '8.0.0')) {
await cleanOrderColumnsForOldDatabases({ id, attribute, db, inverseRelIds, transaction: trx });
return;
}

View File

@ -37,8 +37,6 @@ class Database {
this.lifecycles = createLifecyclesProvider(this);
this.entityManager = createEntityManager(this);
this.databaseInformation = null;
}
query(uid) {
@ -60,11 +58,8 @@ class Database {
return schema ? trx.schema.withSchema(schema) : trx.schema;
}
async getDatabaseInformation() {
if (!this.databaseInformation) {
this.databaseInformation = await this.dialect.schemaInspector.getDatabaseInformation();
}
return this.databaseInformation;
getDatabaseInformation() {
return this.dialect.getInfo();
}
transaction() {

View File

@ -0,0 +1,8 @@
'use strict';
module.exports = {
SQLITE: 'SQLite',
POSTGRES: 'Postgres',
MYSQL: 'MySQL',
MARIADB: 'MariaDB',
};