From a34b10a30e8be648ba6be39e60c7da5647b47f1c Mon Sep 17 00:00:00 2001 From: Pranav C Date: Tue, 10 Aug 2021 17:10:36 +0530 Subject: [PATCH] fix: MSSQL connection with different schema re #438 Signed-off-by: Pranav C --- packages/nocodb/package-lock.json | 8 ++-- packages/nocodb/package.json | 2 +- .../lib/dataMapper/lib/sql/BaseModelSql.ts | 46 +++++++++++-------- .../src/lib/dataMapper/lib/sql/CustomKnex.ts | 8 +++- .../migrator/SqlMigrator/lib/KnexMigrator.ts | 8 ++-- .../src/lib/noco/rest/RestApiBuilder.ts | 2 +- 6 files changed, 45 insertions(+), 29 deletions(-) diff --git a/packages/nocodb/package-lock.json b/packages/nocodb/package-lock.json index 0f2a59f09c..5b2f3cdd51 100644 --- a/packages/nocodb/package-lock.json +++ b/packages/nocodb/package-lock.json @@ -1,6 +1,6 @@ { "name": "nocodb", - "version": "0.11.11", + "version": "0.11.13", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -11817,9 +11817,9 @@ "integrity": "sha512-3AryS9uwa5NfISLxMciUonrH7YfXp+nlahB9T7girXIsLQrmwX4MdnuKs32akduCOGpKmjTJSWmATULbuMkbfw==" }, "nc-help": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.11.tgz", - "integrity": "sha512-588PlynqD01a6XXR1jX5mYqP2kXrkXeCv4bpPAElumiwJKdFZI/A5maaAQU7yVz/t7Qid1Lwz9TUyMG/XTptzg==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.12.tgz", + "integrity": "sha512-fuKK0EbtZr5L5Jil47D6M/CbVPvpSATYI6y745hIv2NsYKF4XXv+/YwJARXmrD/pTSCop8YyJ6DapLXpFJ700g==", "requires": { "axios": "^0.21.1", "boxen": "^4.2.0", diff --git a/packages/nocodb/package.json b/packages/nocodb/package.json index 30a768dc7c..d1e37d1672 100644 --- a/packages/nocodb/package.json +++ b/packages/nocodb/package.json @@ -145,7 +145,7 @@ "mysql2": "^2.2.5", "nanoid": "^3.1.20", "nc-common": "0.0.6", - "nc-help": "^0.2.11", + "nc-help": "^0.2.12", "nc-lib-gui": "^0.2.16", "nc-plugin": "^0.1.1", "nodemailer": "^6.4.10", diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts index 5e3c9dc8dd..92ded9ebd7 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts @@ -118,8 +118,14 @@ class BaseModelSql extends BaseModel { * * @returns {Object} knex instance attached to a table */ - get $db() { - return this.dbDriver(this.tn); + public get $db() { + return this.dbDriver(this.tnPath); + } + + public get tnPath(){ + const schema = (this.dbDriver as any).searchPath?.(); + const table = this.isMssql() && schema ? this.dbDriver.raw('??.??', [schema, this.tn]) : this.tn; + return table; } /** @@ -258,7 +264,7 @@ class BaseModelSql extends BaseModel { await this.validate(insertObj); - const query = driver(this.tn).insert(insertObj); + const query = driver(this.tnPath).insert(insertObj); if (this.isPg() || this.dbDriver.clientType() === 'mssql') { query.returning(Object.entries(this.aliasToColumn).map(([val, key]) => `${key} as ${val}`)); @@ -321,7 +327,7 @@ class BaseModelSql extends BaseModel { const driver = trx ? trx : this.dbDriver // this.validate(data); - const response = await this._run(driver(this.tn).update(mappedData).where(this._wherePk(id))); + const response = await this._run(driver(this.tnPath).update(mappedData).where(this._wherePk(id))); await this.afterUpdate(data, trx, cookie); return response; } catch (e) { @@ -345,7 +351,7 @@ class BaseModelSql extends BaseModel { const dbDriver = trx ? trx : this.dbDriver; - const response = await this._run(dbDriver(this.tn).del().where(this._wherePk(id))); + const response = await this._run(dbDriver(this.tnPath).del().where(this._wherePk(id))); await this.afterDelete({id}, trx, cookie); return response; } catch (e) { @@ -378,7 +384,7 @@ class BaseModelSql extends BaseModel { await this.validate(insertObj); Object.assign(insertObj, this._whereFk({parentId, tnp})) - const query = dbDriver(this.tn).insert(insertObj); + const query = dbDriver(this.tnPath).insert(insertObj); if (this.dbDriver.clientType() === 'pg' || this.dbDriver.clientType() === 'mssql') { query.returning(this.selectQuery('')); @@ -438,7 +444,7 @@ class BaseModelSql extends BaseModel { const dbDriver = trx ? trx : this.dbDriver; // this.validate(data); - const response = await this._run(dbDriver(this.tn).update(data).where(this._wherePk(id)).andWhere(this._whereFk({ + const response = await this._run(dbDriver(this.tnPath).update(data).where(this._wherePk(id)).andWhere(this._whereFk({ tnp, parentId }))); @@ -469,7 +475,7 @@ class BaseModelSql extends BaseModel { const driver = trx ? trx : this.dbDriver - const response = await this._run(driver(this.tn).update(data).xwhere(where, this.selectQuery('')).condition(condition, this.selectQuery(''))); + const response = await this._run(driver(this.tnPath).update(data).xwhere(where, this.selectQuery('')).condition(condition, this.selectQuery(''))); // await this.afterUpdate(data); return response; @@ -497,7 +503,7 @@ class BaseModelSql extends BaseModel { await this.beforeDelete({id, parentId, tnp}, trx, cookie); const dbDriver = trx ? trx : this.dbDriver; - const response = await this._run(dbDriver(this.tn).del().where(this._wherePk(id)).andWhere(this._whereFk({ + const response = await this._run(dbDriver(this.tnPath).del().where(this._wherePk(id)).andWhere(this._whereFk({ tnp, parentId }))); @@ -525,7 +531,7 @@ class BaseModelSql extends BaseModel { const driver = trx ? trx : this.dbDriver - const response = await this._run(driver(this.tn).del().xwhere(where, this.selectQuery('')).condition(condition, this.selectQuery(''))); + const response = await this._run(driver(this.tnPath).del().xwhere(where, this.selectQuery('')).condition(condition, this.selectQuery(''))); // await this.afterUpdate(data); return response; @@ -1123,7 +1129,7 @@ class BaseModelSql extends BaseModel { parent.map(p => { const query = this - .dbDriver(child) + .dbDriver(this.dbModels[child].tnPath) .where(cn, p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn]) .xwhere(where, this.dbModels[child].selectQuery('')) .select(this.dbModels[child].selectQuery(fields)) // ...fields.split(',')); @@ -1178,7 +1184,7 @@ class BaseModelSql extends BaseModel { parentIds.map(id => { const query = this - .dbDriver(child) + .dbDriver(this.dbModels[child].tnPath) .join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`) .where(`${vtn}.${vcn}`, id) // p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn]) .xwhere(where, this.dbModels[child].selectQuery('')) @@ -1221,7 +1227,7 @@ class BaseModelSql extends BaseModel { fields = `${child}.*` } - const query = this.dbDriver(child) + const query = this.dbDriver(this.dbModels[child].tnPath) // .select(...fields.split(',')) .select(this.dbModels?.[child]?.selectQuery(fields) || fields) .where(cn, parentId) @@ -1421,7 +1427,7 @@ class BaseModelSql extends BaseModel { .condition(condition, childModel.selectQuery('')) .conditionGraph(conditionGraph) .whereNotIn(rcn, - childModel.dbDriver(rtn) + childModel.dbDriver(this.dbModels[rtn].tnPath) .select(`${rtn}.${rcn}`) .join(vtn, `${rtn}.${rcn}`, `${vtn}.${vrcn}`) .where(`${vtn}.${vcn}`, pid) @@ -1450,7 +1456,7 @@ class BaseModelSql extends BaseModel { .condition(condition, childModel.selectQuery('')) .conditionGraph(conditionGraph) .whereNotIn(rcn, - childModel.dbDriver(rtn) + childModel.dbDriver(this.dbModels[rtn].tnPath) .select(`${rtn}.${rcn}`) .join(vtn, `${rtn}.${rcn}`, `${vtn}.${vrcn}`) .where(`${vtn}.${vcn}`, pid) @@ -1521,7 +1527,7 @@ class BaseModelSql extends BaseModel { } const parents = await this._run( - this.dbDriver(parent) + this.dbDriver(this.dbModels[parent].tnPath) // .select(...fields.split(',') .select( this.dbModels[parent].selectQuery(fields) @@ -1562,7 +1568,7 @@ class BaseModelSql extends BaseModel { const childs = await this._run(this._paginateAndSort(this.dbDriver.union( ids.map(p => { const query = this - .dbDriver(child) + .dbDriver(this.dbModels[child].tnPath) .where({[cn]: p}) .conditionGraph(conditionGraph) .xwhere(where, this.selectQuery('')) @@ -1588,6 +1594,10 @@ class BaseModelSql extends BaseModel { return this.clientType === 'sqlite3'; } + isMssql() { + return this.clientType === 'mssql'; + } + /** * Returns key value paired grouped children list * @@ -1609,7 +1619,7 @@ class BaseModelSql extends BaseModel { const childs = await this._run(this.dbDriver.unionAll( ids.map(p => { const query = this - .dbDriver(child) + .dbDriver(this.dbModels[child].tnPath) .where({[cn]: p}) .xwhere(where, this.selectQuery('')) .conditionGraph(conditionGraph) diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts index 65f0e5d240..2ad61d0177 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts @@ -678,7 +678,7 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) { type CustomKnex = Knex; -function CustomKnex(arg: string | Knex.Config): CustomKnex { +function CustomKnex(arg: string | Knex.Config|any): CustomKnex { const knex: any = Knex(arg); @@ -706,6 +706,12 @@ function CustomKnex(arg: string | Knex.Config): CustomKnex { return typeof arg === 'string' ? arg.match(/^(\w+):/) ?? [1] : arg.client; } }, + searchPath: { + enumerable: true, + value: () => { + return arg?.searchPath?.[0] + } + } }); /** diff --git a/packages/nocodb/src/lib/migrator/SqlMigrator/lib/KnexMigrator.ts b/packages/nocodb/src/lib/migrator/SqlMigrator/lib/KnexMigrator.ts index 74e901a849..4aa9e78623 100644 --- a/packages/nocodb/src/lib/migrator/SqlMigrator/lib/KnexMigrator.ts +++ b/packages/nocodb/src/lib/migrator/SqlMigrator/lib/KnexMigrator.ts @@ -501,7 +501,7 @@ export default class KnexMigrator extends SqlMigrator { args.env ); const sqlClient = args.sqlClient || SqlClientFactory.create(connection); - const migrations = await sqlClient.selectAll(connection.meta.tn); + const migrations = await sqlClient.selectAll(sqlClient.getTnPath(connection.meta.tn)); /** ************** END : get files and migrations *************** */ if (files.length === migrations.length) { @@ -667,7 +667,7 @@ export default class KnexMigrator extends SqlMigrator { vm.emit(`'${query}' : Executed SQL query`); } for (const data of metaTableInserts) { - await trx(connection.meta.tn).insert(data); + await trx(sqlClient.getTnPath(connection.meta.tn)).insert(data); vm.emit(`'${data.title}' : Updating bookkeeping of SQL UP migration - done`); } await trx.commit(); @@ -743,7 +743,7 @@ export default class KnexMigrator extends SqlMigrator { args.env ); const sqlClient = SqlClientFactory.create(connection); - const migrations = await sqlClient.selectAll(connection.meta.tn); + const migrations = await sqlClient.selectAll(sqlClient.getTnPath(connection.meta.tn)); if (migrations.length) { try { @@ -820,7 +820,7 @@ export default class KnexMigrator extends SqlMigrator { } for (const condition of metaDownDeletes) { vm.emit(`'${condition.titleDown}' : Updating bookkeeping of SQL DOWN migration - done`); - await trx(connection.meta.tn).where(condition).del(); + await trx(sqlClient.getTnPath(connection.meta.tn)).where(condition).del(); } diff --git a/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts b/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts index 81e9f69a4b..c22784a0f5 100644 --- a/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts +++ b/packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts @@ -1762,4 +1762,4 @@ export class RestApiBuilder extends BaseApiBuilder { * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * - */ \ No newline at end of file + */