Browse Source

Merge pull request #3570 from nocodb/chore/upgrade-knex

feat: upgrade knex
pull/4296/head
Pranav C 2 years ago committed by GitHub
parent
commit
a7c55a8430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      .github/workflows/release-executables.yml
  2. 16
      .github/workflows/release-timely-executables.yml
  3. 4
      packages/nc-gui/lib/constants.ts
  4. 9
      packages/nocodb/Dockerfile
  5. 3210
      packages/nocodb/package-lock.json
  6. 6
      packages/nocodb/package.json
  7. 2
      packages/nocodb/src/interface/config.ts
  8. 3
      packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts
  9. 177
      packages/nocodb/src/lib/db/sql-client/lib/mssql/MssqlClient.ts
  10. 6
      packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts
  11. 34
      packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts
  12. 23
      packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts
  13. 23
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts
  14. 187
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  15. 130
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts
  16. 18
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  17. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts
  18. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts
  19. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/mapFunctionName.ts
  20. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts
  21. 4
      packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts
  22. 2
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts
  23. 2
      packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts
  24. 2
      packages/nocodb/src/lib/migrations/v1/nc_002_add_m2m.ts
  25. 2
      packages/nocodb/src/lib/migrations/v1/nc_003_add_fkn_column.ts
  26. 2
      packages/nocodb/src/lib/migrations/v1/nc_004_add_view_type_column.ts
  27. 2
      packages/nocodb/src/lib/migrations/v1/nc_005_add_view_name_column.ts
  28. 2
      packages/nocodb/src/lib/migrations/v1/nc_006_alter_nc_shared_views.ts
  29. 2
      packages/nocodb/src/lib/migrations/v1/nc_007_alter_nc_shared_views_1.ts
  30. 2
      packages/nocodb/src/lib/migrations/v1/nc_008_add_nc_shared_bases.ts
  31. 2
      packages/nocodb/src/lib/migrations/v1/nc_009_add_model_order.ts
  32. 2
      packages/nocodb/src/lib/migrations/v1/nc_010_add_parent_title_column.ts
  33. 2
      packages/nocodb/src/lib/migrations/v1/nc_011_remove_old_ses_plugin.ts
  34. 2
      packages/nocodb/src/lib/migrations/v2/nc_012_alter_column_data_types.ts
  35. 2
      packages/nocodb/src/lib/migrations/v2/nc_013_sync_source.ts
  36. 2
      packages/nocodb/src/lib/migrations/v2/nc_014_alter_column_data_types.ts
  37. 2
      packages/nocodb/src/lib/migrations/v2/nc_015_add_meta_col_in_column_table.ts
  38. 2
      packages/nocodb/src/lib/migrations/v2/nc_016_alter_hooklog_payload_types.ts
  39. 2
      packages/nocodb/src/lib/migrations/v2/nc_017_add_user_token_version_column.ts
  40. 2
      packages/nocodb/src/lib/migrations/v2/nc_018_add_meta_in_view.ts
  41. 2
      packages/nocodb/src/lib/migrations/v2/nc_019_add_meta_in_meta_tables.ts
  42. 2
      packages/nocodb/src/lib/migrations/v2/nc_020_kanban_view.ts
  43. 2
      packages/nocodb/src/lib/services/test/TestResetService/index.ts
  44. 2
      packages/nocodb/src/lib/services/test/TestResetService/resetMetaSakilaSqliteProject.ts
  45. 16
      packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakilaProject.ts
  46. 8
      packages/nocodb/src/lib/services/test/TestResetService/resetPgSakilaProject.ts
  47. 2
      packages/nocodb/src/lib/utils/common/NcConnectionMgr.ts
  48. 6
      packages/nocodb/tests/unit/TestDbMngr.ts

11
.github/workflows/release-executables.yml

@ -84,8 +84,15 @@ jobs:
# install npm dependendencies
npm i
# Copy sqlite binaries
rsync -rvzhP ./binaries/binding/ ./node_modules/sqlite3/lib/binding/
# Build sqlite binaries for all platforms
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=win32 --fallback-to-build --target_arch=x64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=win32 --fallback-to-build --target_arch=ia32 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=darwin --fallback-to-build --target_arch=x64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=darwin --fallback-to-build --target_arch=arm64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=x64 --target_libc=glibc
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=arm64 --target_libc=glibc
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=x64 --target_libc=musl
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=arm64 --target_libc=musl
# clean up code to optimize size
npx modclean --patterns="default:*" --ignore="nc-lib-gui/**,dayjs/**,express-status-monitor/**,sqlite3/**" --run

16
.github/workflows/release-timely-executables.yml

@ -86,7 +86,21 @@ jobs:
npm i
# Copy sqlite binaries
rsync -rvzhP ./binaries/binding/ ./node_modules/sqlite3/lib/binding/
# rsync -rvzhP ./binaries/binding/ ./node_modules/sqlite3/lib/binding/
# Build sqlite binaries for all platforms
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=win32 --fallback-to-build --target_arch=x64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=win32 --fallback-to-build --target_arch=ia32 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=darwin --fallback-to-build --target_arch=x64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=darwin --fallback-to-build --target_arch=arm64 --target_libc=unknown
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=x64 --target_libc=glibc
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=arm64 --target_libc=glibc
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=x64 --target_libc=musl
./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=arm64 --target_libc=musl
# ./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=armv6 --target_libc=unknown
# ./node_modules/.bin/node-pre-gyp install --directory=./node_modules/sqlite3 --target_platform=linux --fallback-to-build --target_arch=armv7 --target_libc=unknown
# clean up code to optimize size
npx modclean --patterns="default:*" --ignore="nc-lib-gui-daily/**,dayjs/**,express-status-monitor/**,sqlite3/**" --run

4
packages/nc-gui/lib/constants.ts

@ -4,9 +4,7 @@ export const NOCO = 'noco'
export const SYSTEM_COLUMNS = ['id', 'title', 'created_at', 'updated_at']
export const BASE_URL =
import.meta.env.NC_BACKEND_URL || (import.meta.env.NODE_ENV === 'production' ? '..' : 'http://localhost:8080')
export const BASE_URL = import.meta.env.NC_BACKEND_URL || (process.env.NODE_ENV === 'production' ? '..' : 'http://localhost:8080')
/**
* Each permission value means the following
* `*` - which is wildcard, means all permissions are allowed

9
packages/nocodb/Dockerfile

@ -18,9 +18,12 @@ RUN cp $GOPATH/bin/litestream /usr/src/lt
###########
# Builder
###########
FROM node:12 as builder
FROM node:16.17.0-alpine3.15 as builder
WORKDIR /usr/src/app
# install node-gyp dependencies
RUN apk add --no-cache python3 make g++
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm ci on every code change.
@ -32,7 +35,7 @@ COPY ./docker/start-litestream.sh /usr/src/appEntry/start.sh
# install production dependencies,
# reduce node_module size with modclean & removing sqlite deps,
# package built code into app.tar.gz & add execute permission to start.sh
RUN npm ci --production --quiet \
RUN npm ci --omit=dev --quiet \
&& npx modclean --patterns="default:*" --ignore="nc-lib-gui/**,dayjs/**,express-status-monitor/**" --run \
&& rm -rf ./node_modules/sqlite3/deps \
&& tar -czf ../appEntry/app.tar.gz ./* \
@ -41,7 +44,7 @@ RUN npm ci --production --quiet \
##########
# Runner
##########
FROM alpine:3.12
FROM alpine:3.15
WORKDIR /usr/src/app
ENV NC_DOCKER 0.6

3210
packages/nocodb/package-lock.json generated

File diff suppressed because it is too large Load Diff

6
packages/nocodb/package.json

@ -95,7 +95,7 @@
"jsep": "^1.3.6",
"jsonfile": "^6.1.0",
"jsonwebtoken": "^8.5.1",
"knex": "^0.21.2",
"knex": "^2.2.0",
"lodash": "^4.17.19",
"lru-cache": "^6.0.0",
"mailersend": "^1.1.0",
@ -124,11 +124,13 @@
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pg": "^8.3.0",
"request": "^2.88.2",
"request-ip": "^2.1.3",
"rmdir": "^1.2.0",
"slash": "^3.0.0",
"socket.io": "^4.4.1",
"sqlite3": "5.0.0",
"sqlite3": "5.1.2",
"tedious": "^15.0.0",
"tinycolor2": "^1.4.2",
"twilio": "^3.55.1",
"unique-names-generator": "^4.3.1",

2
packages/nocodb/src/interface/config.ts

@ -1,6 +1,6 @@
import { Handler } from 'express';
import * as e from 'express';
import Knex from 'knex';
import { Knex } from 'knex';
export interface Route {
path: string;

3
packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts

@ -1,10 +1,9 @@
/* eslint-disable no-constant-condition */
import Knex from 'knex';
import { knex, Knex } from 'knex'
import Debug from '../../util/Debug';
import Emit from '../../util/emit';
import Result from '../../util/Result';
import knex from 'knex';
import lodash from 'lodash';
import fs from 'fs';
import { promisify } from 'util';

177
packages/nocodb/src/lib/db/sql-client/lib/mssql/MssqlClient.ts

@ -356,13 +356,11 @@ class MssqlClient extends KnexClient {
try {
/** ************** START : create _evolution table if not exists *************** */
const exists = await this.sqlClient.schema.hasTable(
this.getTnPath(args.tn)
);
const exists = await this.sqlClient.schema.withSchema(this.schema).hasTable(args.tn);
if (!exists) {
await this.sqlClient.schema.createTable(
this.getTnPath(args.tn),
await this.sqlClient.schema.withSchema(this.schema).createTable(
args.tn,
function (table) {
table.increments();
table.string('title').notNullable();
@ -396,9 +394,7 @@ class MssqlClient extends KnexClient {
log.api(`${_func}:args:`, args);
try {
result.data.value = await this.sqlClient.schema.hasTable(
this.getTnPath(args.tn)
);
result.data.value = await this.sqlClient.schema.withSchema(this.schema).hasTable(args.tn);
} catch (e) {
log.ppe(e, _func);
throw e;
@ -1599,9 +1595,10 @@ class MssqlClient extends KnexClient {
const result = new Result();
log.api(`${func}:args:`, args);
try {
const query = `CREATE TRIGGER ${args.trigger_name} on ${this.getTnPath(
args.tn
)} \n${args.timing} ${args.event}\n as\n${args.statement}`;
const query = this.genQuery(
`CREATE TRIGGER ?? on ?? \n${args.timing} ${args.event}\n as\n${args.statement}`,
[args.trigger_name, this.getTnPath(args.tn)]
);
await this.sqlClient.raw(query);
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
@ -1817,7 +1814,7 @@ class MssqlClient extends KnexClient {
const downStatement =
this.querySeparator() +
this.sqlClient.schema.dropTable(args.table).toString();
this.sqlClient.schema.withSchema(this.schema).dropTable(args.table).toString();
this.emit(`Success : ${upQuery}`);
@ -1850,15 +1847,17 @@ class MssqlClient extends KnexClient {
for (let i = 0; i < args.columns.length; i++) {
const column = args.columns[i];
if (column.au) {
const triggerName = `xc_trigger_${args.table_name}_${column.column_name}`;
const triggerName = `[${this.schema}].[xc_trigger_${args.table_name}_${column.column_name}]`;
const triggerCreateQuery =
this.querySeparator() +
`CREATE TRIGGER ${this.schema}.${triggerName} ON ${this.schema}.${args.table_name} AFTER UPDATE
this.genQuery(
`CREATE TRIGGER ?? ON ?? AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE ${this.schema}.${args.table_name} Set ${column.column_name} = GetDate() where ${pk.column_name} in (SELECT ${pk.column_name} FROM Inserted)
END;`;
UPDATE ?? Set ?? = GetDate() where ?? in (SELECT ?? FROM Inserted)
END;`, [triggerName, this.getTnPath(args.table_name), this.getTnPath(args.table_name), column.column_name, pk.column_name, pk.column_name]
);
upQuery += triggerCreateQuery;
@ -1888,11 +1887,11 @@ class MssqlClient extends KnexClient {
const triggerName = `xc_trigger_${args.table_name}_${column.column_name}`;
const triggerCreateQuery =
this.querySeparator() +
`CREATE TRIGGER ${this.schema}.${triggerName} ON ${this.schema}.${args.table_name} AFTER UPDATE
`CREATE TRIGGER [${this.schema}].[${triggerName}] ON [${this.schema}].[${args.table_name}] AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE ${this.schema}.${args.table_name} Set ${column.column_name} = GetDate() where ${pk.column_name} in (SELECT ${pk.column_name} FROM Inserted)
UPDATE [${this.schema}].[${args.table_name}] Set [${column.column_name}] = GetDate() where [${pk.column_name}] in (SELECT [${pk.column_name}] FROM Inserted)
END;`;
upQuery += triggerCreateQuery;
@ -1901,7 +1900,7 @@ class MssqlClient extends KnexClient {
downQuery +=
this.querySeparator() +
`DROP TRIGGER IF EXISTS ${this.schema}.${triggerName};`;
`DROP TRIGGER IF EXISTS [${this.schema}].[${triggerName}];`;
}
}
result.upStatement[0] = { sql: upQuery };
@ -2059,13 +2058,13 @@ class MssqlClient extends KnexClient {
/** ************** create up & down statements *************** */
const upStatement =
this.querySeparator() +
this.sqlClient.schema.dropTable(this.getTnPath(args.tn)).toString();
this.sqlClient.schema.withSchema(this.schema).dropTable(args.tn).toString();
let downQuery = this.querySeparator() + this.createTable(args.tn, args);
this.emit(`Success : ${upStatement}`);
let relationsList: any = await this.relationList({
tn: this.getTnPath(args.tn),
tn: args.tn,
});
relationsList = relationsList.data.list;
@ -2073,12 +2072,12 @@ class MssqlClient extends KnexClient {
for (const relation of relationsList) {
downQuery +=
this.querySeparator() +
(await this.sqlClient.schema
.table(this.getTnPath(relation.tn), function (table) {
(await this.sqlClient.withSchema(this.schema).schema
.table(relation.tn, (table) => {
table = table
.foreign(relation.cn, null)
.references(relation.rcn)
.on(relation.rtn);
.on(this.getTnPath(relation.rtn));
if (relation.ur) {
table = table.onUpdate(relation.ur);
@ -2117,7 +2116,7 @@ class MssqlClient extends KnexClient {
)) {
downQuery +=
this.querySeparator() +
this.sqlClient.schema
this.sqlClient.schema.withSchema(this.schema)
.table(tn, function (table) {
if (non_unique) {
table.index(columns, key_name);
@ -2129,7 +2128,7 @@ class MssqlClient extends KnexClient {
}
/** ************** drop tn *************** */
await this.sqlClient.schema.dropTable(this.getTnPath(args.tn));
await this.sqlClient.schema.withSchema(this.schema).dropTable(args.tn);
/** ************** return files *************** */
result.data.object = {
@ -2144,6 +2143,132 @@ class MssqlClient extends KnexClient {
return result;
}
/**
*
* @param {Object} - args
* @param {String} - args.parentTable
* @param {String} - args.parentColumn
* @param {String} - args.childColumn
* @param {String} - args.childTable
* @returns {Promise<{upStatement, downStatement}>}
*/
async relationCreate(args) {
const _func = this.relationCreate.name;
const result = new Result();
log.api(`${_func}:args:`, args);
const foreignKeyName = args.foreignKeyName || null;
try {
const self = this;
await this.sqlClient.schema.table(this.getTnPath(args.childTable), function (table) {
table = table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
.on(self.getTnPath(args.parentTable));
if (args.onUpdate) {
table = table.onUpdate(args.onUpdate);
}
if (args.onDelete) {
table = table.onDelete(args.onDelete);
}
});
const upStatement =
this.querySeparator() +
(await this.sqlClient.schema
.table(this.getTnPath(args.childTable), function (table) {
table = table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
.on(self.getTnPath(args.parentTable));
if (args.onUpdate) {
table = table.onUpdate(args.onUpdate);
}
if (args.onDelete) {
table = table.onDelete(args.onDelete);
}
})
.toQuery());
this.emit(`Success : ${upStatement}`);
const downStatement =
this.querySeparator() +
this.sqlClient.schema
.table(this.getTnPath(args.childTable), function (table) {
table = table.dropForeign(args.childColumn, foreignKeyName);
})
.toQuery();
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
throw e;
}
return result;
}
/**
*
* @param {Object} - args
* @param {String} - args.parentTable
* @param {String} - args.parentColumn
* @param {String} - args.childColumn
* @param {String} - args.childTable
* @param {String} - args.foreignKeyName
* @returns {Promise<{upStatement, downStatement}>}
*/
async relationDelete(args) {
const _func = this.relationDelete.name;
const result = new Result();
log.api(`${_func}:args:`, args);
const foreignKeyName = args.foreignKeyName || null;
try {
const self = this;
await this.sqlClient.schema.table(this.getTnPath(args.childTable), function (table) {
table.dropForeign(args.childColumn, foreignKeyName);
});
const upStatement =
this.querySeparator() +
this.sqlClient.schema
.table(this.getTnPath(args.childTable), function (table) {
table.dropForeign(args.childColumn, foreignKeyName);
})
.toQuery();
const downStatement =
this.querySeparator() +
(await this.sqlClient.schema
.table(this.getTnPath(args.childTable), function (table) {
table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
.on(self.getTnPath(args.parentTable));
})
.toQuery());
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
throw e;
}
return result;
}
/**
*
* @param args

6
packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts

@ -2102,7 +2102,7 @@ class PGClient extends KnexClient {
this.genQuery(`DROP FUNCTION IF EXISTS ??()`, [triggerFnName]);
}
}
await this.sqlClient.raw(upQuery);
if (upQuery !== '') await this.sqlClient.raw(upQuery);
result.upStatement[0] = { sql: upQuery };
result.downStatement[0] = { sql: downQuery };
@ -2153,7 +2153,7 @@ class PGClient extends KnexClient {
this.genQuery(`DROP FUNCTION IF EXISTS ??()`, [triggerFnName]);
}
}
await this.sqlClient.raw(upQuery);
if (upQuery !== '') await this.sqlClient.raw(upQuery);
result.upStatement[0] = { sql: upQuery };
result.downStatement[0] = { sql: downQuery };
@ -2273,7 +2273,7 @@ class PGClient extends KnexClient {
//downQuery = `ALTER TABLE "${args.columns[0].tn}" ${downQuery};`;
}
await this.sqlClient.raw(upQuery);
if (upQuery !== '') await this.sqlClient.raw(upQuery);
// console.log(upQuery);

34
packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts

@ -1497,7 +1497,7 @@ class SqliteClient extends KnexClient {
if (args.columns[i].altered & 4) {
// col remove
upQuery += await this.alterTableRemoveColumn(
upQuery += this.alterTableRemoveColumn(
args.table,
args.columns[i],
oldColumn,
@ -1552,18 +1552,7 @@ class SqliteClient extends KnexClient {
);
//downQuery += alterTablePK(args.originalColumns, args.columns, downQuery);
if (upQuery) {
//upQuery = `ALTER TABLE ${args.columns[0].tn} ${upQuery};`;
//downQuery = `ALTER TABLE ${args.columns[0].tn} ${downQuery};`;
}
await Promise.all(
upQuery.split(';').map(async (query) => {
if (query.trim().length) await this.sqlClient.raw(query);
})
);
// await this.sqlClient.raw(upQuery);
await this.sqlClient.raw(upQuery);
console.log(upQuery);
@ -1918,16 +1907,15 @@ class SqliteClient extends KnexClient {
return query;
}
async alterTableRemoveColumn(t, n, _o, _existingQuery) {
// let query = existingQuery ? "," : "";
// query += ` DROP COLUMN ${n.cn}`;
// query = existingQuery ? query : `ALTER TABLE "${t}" ${query};`;
// return query;
await this.sqlClient.schema.alterTable(t, (tb) => {
tb.dropColumn(n.cn);
});
return '';
alterTableRemoveColumn(t, n, _o, existingQuery) {
const shouldSanitize = true;
let query = existingQuery ? ';' : '';
query += this.genQuery(
`ALTER TABLE ?? DROP COLUMN ??`,
[t, n.cn],
shouldSanitize
);
return query;
}
createTableColumn(t, n, o, existingQuery) {

23
packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/ban-types,prefer-const */
import Knex from 'knex';
import { Knex } from 'knex';
import Filter from '../../../models/Filter';
import Sort from '../../../models/Sort';
@ -112,7 +112,7 @@ abstract class BaseModel {
timeout: 25000,
};
this.clientType = this.dbDriver.clientType();
this.clientType = this.dbDriver.client;
autoBind(this);
}
@ -221,8 +221,8 @@ abstract class BaseModel {
const query = this.$db.insert(data);
if (
this.dbDriver.clientType() === 'pg' ||
this.dbDriver.clientType() === 'mssql'
this.dbDriver.client === 'pg' ||
this.dbDriver.client === 'mssql'
) {
query.returning('*');
response = await this._run(query);
@ -266,8 +266,8 @@ abstract class BaseModel {
const query = this.$db.insert(data);
if (
this.dbDriver.clientType() === 'pg' ||
this.dbDriver.clientType() === 'mssql'
this.dbDriver.client === 'pg' ||
this.dbDriver.client === 'mssql'
) {
query.returning('*');
response = await this._run(query);
@ -302,10 +302,13 @@ abstract class BaseModel {
for (const d of data) {
await this.validate(d);
}
const response = await this.dbDriver
.batchInsert(this.tn, data, 50)
.returning(this.pks?.[0]?.cn || '*');
const response = (this.dbDriver.client === 'pg' || this.dbDriver.client === 'mssql') ?
this.dbDriver
.batchInsert(this.tn, data, 50)
.returning(this.pks?.[0]?.cn || '*') :
this.dbDriver
.batchInsert(this.tn, data, 50);
await this.afterInsertb(data);

23
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts

@ -89,7 +89,7 @@ class BaseModelSql extends BaseModel {
timeout: 25000,
};
this.clientType = this.dbDriver.clientType();
this.clientType = this.dbDriver.client;
this.dbModels = dbModels;
this._tn = _tn;
autoBind(this);
@ -281,7 +281,7 @@ class BaseModelSql extends BaseModel {
const query = driver(this.tnPath).insert(insertObj);
if (this.isPg() || this.dbDriver.clientType() === 'mssql') {
if (this.isPg() || this.dbDriver.client === 'mssql') {
query.returning(
Object.entries(this.aliasToColumn).map(
([val, key]) => `${key} as ${val}`
@ -332,7 +332,7 @@ class BaseModelSql extends BaseModel {
}
private isPg() {
return this.dbDriver.clientType() === 'pg';
return this.dbDriver.client === 'pg';
}
/**
@ -418,8 +418,8 @@ class BaseModelSql extends BaseModel {
const query = dbDriver(this.tnPath).insert(insertObj);
if (
this.dbDriver.clientType() === 'pg' ||
this.dbDriver.clientType() === 'mssql'
this.dbDriver.client === 'pg' ||
this.dbDriver.client === 'mssql'
) {
query.returning(this.selectQuery(''));
response = await this._run(query);
@ -608,9 +608,12 @@ class BaseModelSql extends BaseModel {
await this.validate(d1);
}
const response = await this.dbDriver
.batchInsert(this.tn, insertDatas, 50)
.returning(this.pks[0].cn);
const response = (this.dbDriver.client === 'pg' || this.dbDriver.client === 'mssql') ?
await this.dbDriver
.batchInsert(this.tn, insertDatas, 50)
.returning(this.pks[0].cn) :
await this.dbDriver
.batchInsert(this.tn, insertDatas, 50);
await this.afterInsertb(insertDatas, null);
@ -1708,7 +1711,7 @@ class BaseModelSql extends BaseModel {
const query = driver(this.tnPath).insert(insertObj);
if (this.isPg() || this.dbDriver.clientType() === 'mssql') {
if (this.isPg() || this.dbDriver.client === 'mssql') {
query.returning(
Object.entries(this.aliasToColumn).map(
([val, key]) => `${key} as ${val}`
@ -2096,7 +2099,7 @@ class BaseModelSql extends BaseModel {
}
isMssql() {
return this.dbDriver.clientType() === 'mssql';
return this.dbDriver.client === 'mssql';
}
/**

187
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -17,7 +17,7 @@ import Sort from '../../../../models/Sort';
import FormulaColumn from '../../../../models/FormulaColumn';
import genRollupSelectv2 from './genRollupSelectv2';
import formulaQueryBuilderv2 from './formulav2/formulaQueryBuilderv2';
import { QueryBuilder } from 'knex';
import { Knex } from 'knex';
import View from '../../../../models/View';
import {
AuditOperationSubTypes,
@ -390,8 +390,11 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver,
});
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const qb = this.dbDriver(childTable.table_name);
const qb = this.dbDriver(childTn);
await childModel.selectObject({ qb });
await this.applySortAndFilter({ table: childTable, where, qb, sort });
@ -404,7 +407,7 @@ class BaseModelSqlv2 {
.select(this.dbDriver.raw('? as ??', [p, GROUP_COL]))
.whereIn(
chilCol.column_name,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentCol.column_name)
// .where(parentTable.primaryKey.cn, p)
.where(_wherePk(parentTable.primaryKeys, p))
@ -477,13 +480,16 @@ class BaseModelSqlv2 {
const parentTable = await parentCol.getModel();
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const children = await this.dbDriver.unionAll(
ids.map((p) => {
const query = this.dbDriver(childTable.table_name)
const query = this.dbDriver(childTn)
.count(`${chilCol?.column_name} as count`)
.whereIn(
chilCol.column_name,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentCol.column_name)
// .where(parentTable.primaryKey.cn, p)
.where(_wherePk(parentTable.primaryKeys, p))
@ -525,12 +531,15 @@ class BaseModelSqlv2 {
});
await parentTable.getColumns();
const qb = this.dbDriver(childTable.table_name);
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const qb = this.dbDriver(childTn);
await this.applySortAndFilter({ table: childTable, where, qb, sort });
qb.whereIn(
chilCol.column_name,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentCol.column_name)
// .where(parentTable.primaryKey.cn, p)
.where(_wherePk(parentTable.primaryKeys, id))
@ -576,11 +585,14 @@ class BaseModelSqlv2 {
const parentTable = await parentCol.getModel();
await parentTable.getColumns();
const query = this.dbDriver(childTable.table_name)
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const query = this.dbDriver(childTn)
.count(`${chilCol?.column_name} as count`)
.whereIn(
chilCol.column_name,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentCol.column_name)
.where(_wherePk(parentTable.primaryKeys, id))
)
@ -607,7 +619,8 @@ class BaseModelSqlv2 {
// const tn = this.model.tn;
// const cn = (await relColOptions.getChildColumn()).title;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
@ -619,7 +632,11 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver,
model: childTable,
});
const rtn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const rtnId = childTable.id;
const qb = this.dbDriver(rtn).join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`);
@ -634,7 +651,7 @@ class BaseModelSqlv2 {
.clone()
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, id)
.where(_wherePk(parentTable.primaryKeys, id))
@ -680,7 +697,8 @@ class BaseModelSqlv2 {
// const tn = this.model.tn;
// const cn = (await relColOptions.getChildColumn()).title;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
@ -692,14 +710,18 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver,
model: childTable,
});
const rtn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const rtnId = childTable.id;
const qb = this.dbDriver(rtn)
.join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`)
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, id)
.where(_wherePk(parentTable.primaryKeys, parentId))
@ -731,16 +753,21 @@ class BaseModelSqlv2 {
const relColOptions =
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
const cn = (await relColOptions.getChildColumn()).column_name;
const childTable = await (await relColOptions.getParentColumn()).getModel();
const rtn = childTable.table_name;
const parentTable = await (await relColOptions.getChildColumn()).getModel();
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const qb = this.dbDriver(rtn)
.join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`)
// .select({
@ -755,7 +782,7 @@ class BaseModelSqlv2 {
.clone()
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, id)
.where(_wherePk(parentTable.primaryKeys, id))
@ -778,16 +805,21 @@ class BaseModelSqlv2 {
const relColOptions =
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
const cn = (await relColOptions.getChildColumn()).column_name;
const childTable = await (await relColOptions.getParentColumn()).getModel();
const rtn = childTable.table_name;
const parentTable = await (await relColOptions.getChildColumn()).getModel();
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const qb = this.dbDriver(rtn)
.join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`)
// .select({
@ -796,7 +828,7 @@ class BaseModelSqlv2 {
.count(`${vtn}.${vcn}`, { as: 'count' })
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, id)
.where(_wherePk(parentTable.primaryKeys, parentId))
@ -820,7 +852,8 @@ class BaseModelSqlv2 {
const relColOptions =
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
@ -828,7 +861,11 @@ class BaseModelSqlv2 {
const childTable = await (await relColOptions.getParentColumn()).getModel();
const parentTable = await (await relColOptions.getChildColumn()).getModel();
await parentTable.getColumns();
const rtn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const qb = this.dbDriver(rtn)
.count(`*`, { as: 'count' })
.where((qb) => {
@ -839,7 +876,7 @@ class BaseModelSqlv2 {
.join(vtn, `${rtn}.${rcn}`, `${vtn}.${vrcn}`)
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, pid)
.where(_wherePk(parentTable.primaryKeys, pid))
@ -866,7 +903,8 @@ class BaseModelSqlv2 {
const relColOptions =
(await relColumn.getColOptions()) as LinkToAnotherRecordColumn;
const vtn = (await relColOptions.getMMModel()).table_name;
const mmTable = await relColOptions.getMMModel();
const vtn = this.getTnPath(mmTable);
const vcn = (await relColOptions.getMMChildColumn()).column_name;
const vrcn = (await relColOptions.getMMParentColumn()).column_name;
const rcn = (await relColOptions.getParentColumn()).column_name;
@ -878,7 +916,11 @@ class BaseModelSqlv2 {
});
const parentTable = await (await relColOptions.getChildColumn()).getModel();
await parentTable.getColumns();
const rtn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = childTn;
const qb = this.dbDriver(rtn).where((qb) =>
qb
@ -889,7 +931,7 @@ class BaseModelSqlv2 {
.join(vtn, `${rtn}.${rcn}`, `${vtn}.${vrcn}`)
.whereIn(
`${vtn}.${vcn}`,
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(cn)
// .where(parentTable.primaryKey.cn, pid)
.where(_wherePk(parentTable.primaryKeys, pid))
@ -945,8 +987,12 @@ class BaseModelSqlv2 {
const parentTable = await (
await relColOptions.getParentColumn()
).getModel();
const tn = childTable.table_name;
const rtn = parentTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const tn = childTn;
const rtn = parentTn;
await parentTable.getColumns();
const qb = this.dbDriver(tn)
@ -993,8 +1039,11 @@ class BaseModelSqlv2 {
});
await parentTable.getColumns();
const tn = childTable.table_name;
const rtn = parentTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const tn = childTn;
const rtn = parentTn;
const qb = this.dbDriver(tn).where((qb) => {
qb.whereNotIn(
@ -1054,8 +1103,11 @@ class BaseModelSqlv2 {
const cn = (await relColOptions.getChildColumn()).column_name;
const childTable = await (await relColOptions.getChildColumn()).getModel();
const rtn = parentTable.table_name;
const tn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = parentTn;
const tn = childTn;
await childTable.getColumns();
const qb = this.dbDriver(rtn)
@ -1100,8 +1152,12 @@ class BaseModelSqlv2 {
dbDriver: this.dbDriver,
model: parentTable,
});
const rtn = parentTable.table_name;
const tn = childTable.table_name;
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
const rtn = parentTn;
const tn = childTn;
await childTable.getColumns();
const qb = this.dbDriver(rtn).where((qb) => {
@ -1336,7 +1392,7 @@ class BaseModelSqlv2 {
return obj;
}
public async shuffle({ qb }: { qb: QueryBuilder }): Promise<void> {
public async shuffle({ qb }: { qb: Knex.QueryBuilder }): Promise<void> {
if (this.isMySQL) {
qb.orderByRaw('RAND()');
} else if (this.isPg || this.isSqlite) {
@ -1350,7 +1406,7 @@ class BaseModelSqlv2 {
qb,
columns: _columns,
}: {
qb: QueryBuilder;
qb: Knex.QueryBuilder;
columns?: Column[];
}): Promise<void> {
const res = {};
@ -1569,15 +1625,19 @@ class BaseModelSqlv2 {
return _wherePk(this.model.primaryKeys, id);
}
public get tnPath() {
private getTnPath(tb: Model) {
const schema = (this.dbDriver as any).searchPath?.();
const table =
this.isMssql && schema
? this.dbDriver.raw('??.??', [schema, this.model.table_name])
: this.model.table_name;
this.isMssql && schema
? this.dbDriver.raw('??.??', [schema, tb.table_name])
: tb.table_name;
return table;
}
public get tnPath() {
return this.getTnPath(this.model);
}
get isSqlite() {
return this.clientType === 'sqlite3';
}
@ -1766,9 +1826,12 @@ class BaseModelSqlv2 {
// refer : https://www.sqlite.org/limits.html
const chunkSize = this.isSqlite ? 10 : _chunkSize;
const response = await this.dbDriver
.batchInsert(this.model.table_name, insertDatas, chunkSize)
.returning(this.model.primaryKey?.column_name);
const response = (this.isPg || this.isMssql) ?
await this.dbDriver
.batchInsert(this.model.table_name, insertDatas, chunkSize)
.returning(this.model.primaryKey?.column_name) :
await this.dbDriver
.batchInsert(this.model.table_name, insertDatas, chunkSize);
await this.afterBulkInsert(insertDatas, this.dbDriver, cookie);
@ -2230,6 +2293,9 @@ class BaseModelSqlv2 {
await childTable.getColumns();
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
switch (colOptions.type) {
case RelationTypes.MANY_TO_MANY:
{
@ -2237,12 +2303,14 @@ class BaseModelSqlv2 {
const vParentCol = await colOptions.getMMParentColumn();
const vTable = await colOptions.getMMModel();
await this.dbDriver(vTable.table_name).insert({
[vParentCol.column_name]: this.dbDriver(parentTable.table_name)
const vTn = this.getTnPath(vTable);
await this.dbDriver(vTn).insert({
[vParentCol.column_name]: this.dbDriver(parentTn)
.select(parentColumn.column_name)
.where(_wherePk(parentTable.primaryKeys, childId))
.first(),
[vChildCol.column_name]: this.dbDriver(childTable.table_name)
[vChildCol.column_name]: this.dbDriver(childTn)
.select(childColumn.column_name)
.where(_wherePk(childTable.primaryKeys, rowId))
.first(),
@ -2251,10 +2319,10 @@ class BaseModelSqlv2 {
break;
case RelationTypes.HAS_MANY:
{
await this.dbDriver(childTable.table_name)
await this.dbDriver(childTn)
.update({
[childColumn.column_name]: this.dbDriver.from(
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentColumn.column_name)
.where(_wherePk(parentTable.primaryKeys, rowId))
.first()
@ -2266,10 +2334,10 @@ class BaseModelSqlv2 {
break;
case RelationTypes.BELONGS_TO:
{
await this.dbDriver(childTable.table_name)
await this.dbDriver(childTn)
.update({
[childColumn.column_name]: this.dbDriver.from(
this.dbDriver(parentTable.table_name)
this.dbDriver(parentTn)
.select(parentColumn.column_name)
.where(_wherePk(parentTable.primaryKeys, childId))
.first()
@ -2325,6 +2393,9 @@ class BaseModelSqlv2 {
await childTable.getColumns();
await parentTable.getColumns();
const childTn = this.getTnPath(childTable);
const parentTn = this.getTnPath(parentTable);
switch (colOptions.type) {
case RelationTypes.MANY_TO_MANY:
{
@ -2332,13 +2403,15 @@ class BaseModelSqlv2 {
const vParentCol = await colOptions.getMMParentColumn();
const vTable = await colOptions.getMMModel();
await this.dbDriver(vTable.table_name)
const vTn = this.getTnPath(vTable);
await this.dbDriver(vTn)
.where({
[vParentCol.column_name]: this.dbDriver(parentTable.table_name)
[vParentCol.column_name]: this.dbDriver(parentTn)
.select(parentColumn.column_name)
.where(_wherePk(parentTable.primaryKeys, childId))
.first(),
[vChildCol.column_name]: this.dbDriver(childTable.table_name)
[vChildCol.column_name]: this.dbDriver(childTn)
.select(childColumn.column_name)
.where(_wherePk(childTable.primaryKeys, rowId))
.first(),
@ -2348,7 +2421,7 @@ class BaseModelSqlv2 {
break;
case RelationTypes.HAS_MANY:
{
await this.dbDriver(childTable.table_name)
await this.dbDriver(childTn)
// .where({
// [childColumn.cn]: this.dbDriver(parentTable.tn)
// .select(parentColumn.cn)
@ -2361,7 +2434,7 @@ class BaseModelSqlv2 {
break;
case RelationTypes.BELONGS_TO:
{
await this.dbDriver(childTable.table_name)
await this.dbDriver(childTn)
// .where({
// [childColumn.cn]: this.dbDriver(parentTable.tn)
// .select(parentColumn.cn)
@ -2629,7 +2702,7 @@ class BaseModelSqlv2 {
return await qb;
}
private async extractRawQueryAndExec(qb: QueryBuilder) {
private async extractRawQueryAndExec(qb: Knex.QueryBuilder) {
let query = qb.toQuery();
if (!this.isPg && !this.isMssql) {
query = unsanitize(qb.toQuery());

130
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts

@ -1,4 +1,4 @@
import Knex, { QueryBuilder } from 'knex';
import { Knex, knex } from 'knex';
const types = require('pg').types;
// override parsing date column to Date()
@ -464,70 +464,72 @@ const appendWhereCondition = function (
};
declare module 'knex' {
interface QueryInterface {
clientType(): string;
}
export type XcConditionObjVal = {
[key in 'eq' | 'neq' | 'lt' | 'gt' | 'ge' | 'le' | 'like' | 'nlike']:
| string
| number
| any;
};
export interface XcXonditionObj {
_or: XcXonditionObj[];
_and: XcXonditionObj[];
_not: XcXonditionObj;
namespace Knex {
interface QueryInterface {
clientType(): string;
}
[key: string]:
| XcXonditionObj
| XcXonditionObj[]
| XcConditionObjVal
| XcConditionObjVal[];
}
export type XcConditionObjVal = {
[key in 'eq' | 'neq' | 'lt' | 'gt' | 'ge' | 'le' | 'like' | 'nlike']:
| string
| number
| any;
};
export interface XcXonditionObj {
_or: XcXonditionObj[];
_and: XcXonditionObj[];
_not: XcXonditionObj;
[key: string]:
| XcXonditionObj
| XcXonditionObj[]
| XcConditionObjVal
| XcConditionObjVal[];
}
interface QueryBuilder {
xwhere<TRecord, TResult>(
value: string,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
interface QueryBuilder {
xwhere<TRecord, TResult>(
value: string,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
condition<TRecord, TResult>(
conditionObj: XcXonditionObj,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
condition<TRecord, TResult>(
conditionObj: XcXonditionObj,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
conditionv2<TRecord, TResult>(
conditionObj: Filter
): Knex.QueryBuilder<TRecord, TResult>;
conditionv2<TRecord, TResult>(
conditionObj: Filter
): Knex.QueryBuilder<TRecord, TResult>;
concat<TRecord, TResult>(
cn: string | any
): Knex.QueryBuilder<TRecord, TResult>;
concat<TRecord, TResult>(
cn: string | any
): Knex.QueryBuilder<TRecord, TResult>;
conditionGraph<TRecord, TResult>(condition: {
condition: XcXonditionObj;
models: { [key: string]: BaseModelSql };
}): Knex.QueryBuilder<TRecord, TResult>;
conditionGraph<TRecord, TResult>(condition: {
condition: XcXonditionObj;
models: { [key: string]: BaseModelSql };
}): Knex.QueryBuilder<TRecord, TResult>;
xhaving<TRecord, TResult>(
value: string,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
xhaving<TRecord, TResult>(
value: string,
columnAliases?: {
[columnAlias: string]: string;
}
): Knex.QueryBuilder<TRecord, TResult>;
}
}
}
/**
* Append xwhere to knex query builder
*/
Knex.QueryBuilder.extend(
knex.QueryBuilder.extend(
'xwhere',
function (
conditionString,
@ -542,7 +544,7 @@ Knex.QueryBuilder.extend(
/**
* Append concat to knex query builder
*/
Knex.QueryBuilder.extend('concat', function (cn: any) {
knex.QueryBuilder.extend('concat', function (cn: any) {
switch (this?.client?.config?.client) {
case 'pg':
this.select(this.client.raw(`STRING_AGG(?? , ',')`, [cn]));
@ -564,7 +566,7 @@ Knex.QueryBuilder.extend('concat', function (cn: any) {
/**
* Append xhaving to knex query builder
*/
Knex.QueryBuilder.extend(
knex.QueryBuilder.extend(
'xhaving',
function (
conditionString,
@ -580,7 +582,7 @@ Knex.QueryBuilder.extend(
/**
* Append custom where condition(nested object) to knex query builder
*/
Knex.QueryBuilder.extend('condition', function (conditionObj, columnAliases) {
knex.QueryBuilder.extend('condition', function (conditionObj, columnAliases) {
if (!conditionObj || typeof conditionObj !== 'object') {
return this;
}
@ -661,7 +663,7 @@ const parseCondition = (obj, columnAliases, qb, pKey?) => {
};
// todo: optimize
Knex.QueryBuilder.extend(
knex.QueryBuilder.extend(
'conditionGraph',
function (args: { condition; models }) {
if (!args) {
@ -986,9 +988,9 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) {
type CustomKnex = Knex;
function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
const knex: any = Knex(arg);
const kn: any = knex(arg);
const knexRaw = knex.raw;
const knexRaw = kn.raw;
/**
* Wrapper for knex.raw
@ -1000,11 +1002,11 @@ function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
// return knexRaw.apply(knex, args);
// };
Object.defineProperties(knex, {
Object.defineProperties(kn, {
raw: {
enumerable: true,
value: (...args) => {
return knexRaw.apply(knex, args);
return knexRaw.apply(kn, args);
},
},
clientType: {
@ -1032,11 +1034,11 @@ function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
// return typeof arg === 'string' ? arg.match(/^(\w+):/) ?? [1] : arg.client;
// };
return knex;
return kn;
}
// todo: optimize
Knex.QueryBuilder.extend(
knex.QueryBuilder.extend(
'conditionGraphv2',
function (args: { condition; models }) {
if (!args) {
@ -1227,14 +1229,14 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
/**
* Append custom where condition(nested object) to knex query builder
*/
Knex.QueryBuilder.extend('conditionv2', function (conditionObj: Filter) {
knex.QueryBuilder.extend('conditionv2', function (conditionObj: Filter) {
if (!conditionObj || typeof conditionObj !== 'object') {
return this;
}
return parseConditionv2(conditionObj, this);
} as any);
const parseConditionv2 = (obj: Filter, qb: QueryBuilder) => {
const parseConditionv2 = (obj: Filter, qb: Knex.QueryBuilder) => {
if (obj.is_group) {
qb = qb.where(function () {
const children = obj.children;

18
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts

@ -1,6 +1,6 @@
import Filter from '../../../../models/Filter';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import { QueryBuilder } from 'knex';
import { Knex } from 'knex';
import { XKnex } from '../../index';
import Column from '../../../../models/Column';
import LookupColumn from '../../../../models/LookupColumn';
@ -14,7 +14,7 @@ import { sanitize } from './helpers/sanitize';
export default async function conditionV2(
conditionObj: Filter | Filter[],
qb: QueryBuilder,
qb: Knex.QueryBuilder,
knex: XKnex
) {
if (!conditionObj || typeof conditionObj !== 'object') {
@ -127,7 +127,7 @@ const parseConditionV2 = async (
)
)(selectQb);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(parentColumn.column_name, selectQb);
else qbP.whereIn(parentColumn.column_name, selectQb);
@ -162,7 +162,7 @@ const parseConditionV2 = async (
)
)(selectQb);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(childColumn.column_name, selectQb);
else qbP.whereIn(childColumn.column_name, selectQb);
@ -217,7 +217,7 @@ const parseConditionV2 = async (
)
)(selectQb);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(childColumn.column_name, selectQb);
else qbP.whereIn(childColumn.column_name, selectQb);
@ -428,7 +428,7 @@ async function generateLookupCondition(
aliasCount
);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(parentColumn.column_name, qb);
else qbP.whereIn(parentColumn.column_name, qb);
@ -451,7 +451,7 @@ async function generateLookupCondition(
aliasCount
);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(childColumn.column_name, qb);
else qbP.whereIn(childColumn.column_name, qb);
@ -485,7 +485,7 @@ async function generateLookupCondition(
aliasCount
);
return (qbP: QueryBuilder) => {
return (qbP: Knex.QueryBuilder) => {
if (filter.comparison_op in negatedMapping)
qbP.whereNotIn(childColumn.column_name, qb);
else qbP.whereIn(childColumn.column_name, qb);
@ -497,7 +497,7 @@ async function generateLookupCondition(
async function nestedConditionJoin(
filter: Filter,
lookupColumn: Column,
qb: QueryBuilder,
qb: Knex.QueryBuilder,
knex,
alias: string,
aliasCount: { count: number }

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { RelationTypes } from 'nocodb-sdk';
export default function ({

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts

@ -1,7 +1,7 @@
import RollupColumn from '../../../../models/RollupColumn';
import { XKnex } from '../../index';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import { QueryBuilder } from 'knex';
import { Knex } from 'knex';
import { RelationTypes } from 'nocodb-sdk';
export default async function ({
@ -14,7 +14,7 @@ export default async function ({
knex: XKnex;
alias?: string;
columnOptions: RollupColumn;
}): Promise<{ builder: QueryBuilder | any }> {
}): Promise<{ builder: Knex.QueryBuilder | any }> {
const relationColumn = await columnOptions.getRelationColumn();
const relationColumnOption: LinkToAnotherRecordColumn =
(await relationColumn.getColOptions()) as LinkToAnotherRecordColumn;

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/mapFunctionName.ts

@ -3,7 +3,7 @@ import mssql from './functionMappings/mssql';
import mysql from './functionMappings/mysql';
import pg from './functionMappings/pg';
import sqlite from './functionMappings/sqlite';
import { QueryBuilder } from 'knex';
import { Knex } from 'knex';
export interface MapFnArgs {
pt: any;
@ -11,7 +11,7 @@ export interface MapFnArgs {
knex: XKnex;
alias: string;
a?: string;
fn: (...args: any) => QueryBuilder | any;
fn: (...args: any) => Knex.QueryBuilder | any;
colAlias: string;
prevBinaryOp?: any;
}

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts

@ -1,4 +1,4 @@
import { QueryBuilder } from 'knex';
import { Knex } from 'knex';
import { XKnex } from '../../index';
import Sort from '../../../../models/Sort';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
@ -12,7 +12,7 @@ import { sanitize } from './helpers/sanitize';
export default async function sortV2(
sortList: Sort[],
qb: QueryBuilder,
qb: Knex.QueryBuilder,
knex: XKnex
) {
if (!sortList?.length) {

4
packages/nocodb/src/lib/db/sql-mgr/v2/SqlMgrv2Trans.ts

@ -1,13 +1,13 @@
import SqlMgrv2 from './SqlMgrv2';
import Base from '../../../models/Base';
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2';
import { Transaction } from 'knex';
import { Knex } from 'knex';
import { XKnex } from '../../sql-data-mapper';
import NcMetaIO from '../../../meta/NcMetaIO';
import KnexMigratorv2Tans from '../../sql-migrator/lib/KnexMigratorv2Tans';
export default class SqlMgrv2Trans extends SqlMgrv2 {
protected trx: Transaction;
protected trx: Knex.Transaction;
protected ncMeta: NcMetaIO;
protected projectId: string;
protected base: Base;

2
packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

@ -270,7 +270,7 @@ async function getGroupedDataList(model, view: View, req) {
data = data.map((item) => {
// todo: use map to avoid loop
const count =
countArr.find((countItem) => countItem.key === item.key)?.count ?? 0;
countArr.find((countItem: any) => countItem.key === item.key)?.count ?? 0;
item.value = new PagedResponseImpl(item.value, {
...req.query,

2
packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts

@ -157,7 +157,7 @@ async function getGroupedDataList(model, view: View, req) {
data = data.map((item) => {
// todo: use map to avoid loop
const count =
countArr.find((countItem) => countItem.key === item.key)?.count ?? 0;
countArr.find((countItem: any) => countItem.key === item.key)?.count ?? 0;
item.value = new PagedResponseImpl(item.value, {
...req.query,

2
packages/nocodb/src/lib/migrations/v1/nc_002_add_m2m.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_models', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_003_add_fkn_column.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_relations', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_004_add_view_type_column.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_shared_views', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_005_add_view_name_column.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_shared_views', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_006_alter_nc_shared_views.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_shared_views', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_007_alter_nc_shared_views_1.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_shared_views', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_008_add_nc_shared_bases.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.createTable('nc_shared_bases', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_009_add_model_order.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_models', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_010_add_parent_title_column.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_disabled_models_for_role', (table) => {

2
packages/nocodb/src/lib/migrations/v1/nc_011_remove_old_ses_plugin.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import ses from '../../v1-legacy/plugins/ses';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_012_alter_column_data_types.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_013_sync_source.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_014_alter_column_data_types.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_015_add_meta_col_in_column_table.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_016_alter_hooklog_payload_types.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_017_add_user_token_version_column.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_users_v2', (table) => {

2
packages/nocodb/src/lib/migrations/v2/nc_018_add_meta_in_view.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_019_add_meta_in_meta_tables.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/migrations/v2/nc_020_kanban_view.ts

@ -1,4 +1,4 @@
import Knex from 'knex';
import { Knex } from 'knex';
import { MetaTable } from '../../utils/globals';
const up = async (knex: Knex) => {

2
packages/nocodb/src/lib/services/test/TestResetService/index.ts

@ -1,6 +1,6 @@
import Noco from '../../../Noco';
import Knex from 'knex';
import { Knex } from 'knex';
import axios from 'axios';
import Project from '../../../models/Project';
import NcConnectionMgrv2 from '../../../utils/common/NcConnectionMgrv2';

2
packages/nocodb/src/lib/services/test/TestResetService/resetMetaSakilaSqliteProject.ts

@ -1,5 +1,5 @@
import axios from 'axios';
import Knex from 'knex';
import { Knex } from 'knex';
import { promises as fs } from 'fs';
import { sakilaTableNames } from '../../../utils/globals';

16
packages/nocodb/src/lib/services/test/TestResetService/resetMysqlSakilaProject.ts

@ -1,5 +1,5 @@
import axios from 'axios';
import Knex from 'knex';
import { Knex, knex } from 'knex';
import { promises as fs } from 'fs';
import Audit from '../../../models/Audit';
@ -119,20 +119,20 @@ const resetMysqlSakilaProject = async ({
oldProject?: Project | undefined;
isEmptyProject: boolean;
}) => {
const knex = Knex(config);
const nc_knex = knex(config);
try {
await knex.raw(`USE test_sakila_${parallelId}`);
await nc_knex.raw(`USE test_sakila_${parallelId}`);
} catch (e) {
await knex.raw(`CREATE DATABASE test_sakila_${parallelId}`);
await knex.raw(`USE test_sakila_${parallelId}`);
await nc_knex.raw(`CREATE DATABASE test_sakila_${parallelId}`);
await nc_knex.raw(`USE test_sakila_${parallelId}`);
}
if (
isEmptyProject ||
(await isSakilaMysqlToBeReset(knex, parallelId, oldProject))
(await isSakilaMysqlToBeReset(nc_knex, parallelId, oldProject))
) {
await resetSakilaMysql(knex, parallelId, isEmptyProject);
await resetSakilaMysql(nc_knex, parallelId, isEmptyProject);
}
const response = await axios.post(
@ -148,7 +148,7 @@ const resetMysqlSakilaProject = async ({
console.error('Error creating project', response.data);
}
await knex.destroy();
await nc_knex.destroy();
};
export default resetMysqlSakilaProject;

8
packages/nocodb/src/lib/services/test/TestResetService/resetPgSakilaProject.ts

@ -1,5 +1,5 @@
import axios from 'axios';
import Knex from 'knex';
import { Knex, knex } from 'knex';
import { promises as fs } from 'fs';
const util = require('util');
@ -81,7 +81,7 @@ const resetSakilaPg = async (
if (isEmptyProject) return;
const sakilaKnex = Knex(sakilaKnexConfig(parallelId));
const sakilaKnex = knex(sakilaKnexConfig(parallelId));
const schemaFile = await fs.readFile(
`${testsDir}/pg-sakila-db/03-postgres-sakila-schema.sql`
@ -117,13 +117,13 @@ const resetPgSakilaProject = async ({
oldProject?: Project | undefined;
isEmptyProject: boolean;
}) => {
const pgknex = Knex(config);
const pgknex = knex(config);
try {
await pgknex.raw(`CREATE DATABASE sakila_${parallelId}`);
} catch (e) {}
const sakilaKnex = Knex(sakilaKnexConfig(parallelId));
const sakilaKnex = knex(sakilaKnexConfig(parallelId));
if (isEmptyProject || (await isSakilaPgToBeReset(sakilaKnex, oldProject))) {
await sakilaKnex.destroy();

2
packages/nocodb/src/lib/utils/common/NcConnectionMgr.ts

@ -2,7 +2,7 @@ import SqlClientFactory from '../../db/sql-client/lib/SqlClientFactory';
import { XKnex } from '../../db/sql-data-mapper';
import { NcConfig } from '../../../interface/config';
import fs from 'fs';
import Knex from 'knex';
import { Knex } from 'knex';
import NcMetaIO from '../../meta/NcMetaIO';
import { defaultConnectionConfig } from '../NcConfigFactory';

6
packages/nocodb/tests/unit/TestDbMngr.ts

@ -2,14 +2,14 @@ import { DbConfig } from "../../src/interface/config";
import { NcConfigFactory } from "../../src/lib";
import SqlMgrv2 from "../../src/lib/db/sql-mgr/v2/SqlMgrv2";
import fs from 'fs';
import knex from "knex";
import { Knex, knex } from "knex";
import process from "process";
export default class TestDbMngr {
public static readonly dbName = 'test_meta';
public static readonly sakilaDbName = 'test_sakila';
public static metaKnex: knex;
public static sakilaKnex: knex;
public static metaKnex: Knex;
public static sakilaKnex: Knex;
public static defaultConnection = {
user: 'root',

Loading…
Cancel
Save