Browse Source

fix: MSSQL connection with different schema

re #438

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/445/head
Pranav C 3 years ago
parent
commit
a34b10a30e
  1. 8
      packages/nocodb/package-lock.json
  2. 2
      packages/nocodb/package.json
  3. 46
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts
  4. 8
      packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts
  5. 8
      packages/nocodb/src/lib/migrator/SqlMigrator/lib/KnexMigrator.ts
  6. 2
      packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts

8
packages/nocodb/package-lock.json generated

@ -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",

2
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",

46
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)

8
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<any>): CustomKnex {
function CustomKnex(arg: string | Knex.Config<any>|any): CustomKnex {
const knex: any = Knex(arg);
@ -706,6 +706,12 @@ function CustomKnex(arg: string | Knex.Config<any>): CustomKnex {
return typeof arg === 'string' ? arg.match(/^(\w+):/) ?? [1] : arg.client;
}
},
searchPath: {
enumerable: true,
value: () => {
return arg?.searchPath?.[0]
}
}
});
/**

8
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();
}

2
packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts

@ -1762,4 +1762,4 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
*/

Loading…
Cancel
Save