diff --git a/packages/nocodb/src/db/sql-client/lib/KnexClient.ts b/packages/nocodb/src/db/sql-client/lib/KnexClient.ts index c7f82f0101..50eb31cef4 100644 --- a/packages/nocodb/src/db/sql-client/lib/KnexClient.ts +++ b/packages/nocodb/src/db/sql-client/lib/KnexClient.ts @@ -1,4 +1,3 @@ -/* eslint-disable no-constant-condition */ import fs from 'fs'; import { promisify } from 'util'; import path from 'path'; @@ -93,484 +92,7 @@ const multilinestringTypes = ['multilinestring']; const multipolygonTypes = ['multipolygon']; const jsonTypes = ['json']; -function createPks(table, columns, pks) { - let pkCreate = 'table.primary(['; - for (let i = 0; i < pks.length; ++i) { - if (i) { - pkCreate += `"${columns[pks[i]].cn}"`; - } else { - pkCreate += `"${columns[pks[i]].cn}",`; - } - } - pkCreate += `])`; - - eval(`var inMemoryFunc = function(table) { - ${pkCreate} - }`); - console.log(pkCreate); - // @ts-ignore - inMemoryFunc(table); -} - -function columnCreate(sqlClient, table, colUiObj) { - let skip = false; - let column; - - // TODO : write a function - is the type char - if ( - colUiObj.dt === 'varchar' || - colUiObj.dt === 'char' || - colUiObj.dt === 'text' - ) { - colUiObj.cdf = colUiObj.cdf ? JSON.stringify(colUiObj.cdf) : null; - } else colUiObj.cdf = colUiObj.cdf === '' ? null : colUiObj.cdf; - - if (colUiObj.ai) { - if (colUiObj.dtx === 'bigInteger') { - column = table.bigIncrements(colUiObj.cn); - skip = true; - } else { - column = table.increments(colUiObj.cn); - skip = true; - } - } - - // specific type - if (colUiObj.dtx === 'specificType' && !skip) { - // console.log(colUiObj); - const precision = - colUiObj.dtxp && colUiObj.dtxp !== ' ' ? colUiObj.dtxp : null; - const scale = colUiObj.dtxs && colUiObj.dtxs !== ' ' ? colUiObj.dtxs : null; - if (precision && scale) { - column = table.specificType( - colUiObj.cn, - `${colUiObj.dt}(${precision},${scale})`, - ); - } else if (precision) { - column = table.specificType(colUiObj.cn, `${colUiObj.dt}(${precision})`); - } else { - column = table.specificType(colUiObj.cn, colUiObj.dt); - } - } else if (colUiObj.dtx === 'integer' && !skip) { - column = table.integer(colUiObj.cn); - } else if (colUiObj.dtx === 'bigInteger' && !skip) { - column = table.bigInteger(colUiObj.cn); - } else if (colUiObj.dtx === 'text' && !skip) { - column = table.text(colUiObj.cn); - } else if (colUiObj.dtx === 'string' && !skip) { - column = table.string(colUiObj.cn); - } else if (colUiObj.dtx === 'float' && !skip) { - column = table.float(colUiObj.cn); - } else if (colUiObj.dtx === 'decimal' && !skip) { - column = table.decimal(colUiObj.cn); - } else if (colUiObj.dtx === 'boolean' && !skip) { - column = table.boolean(colUiObj.cn); - } else if (colUiObj.dtx === 'date' && !skip) { - column = table.date(colUiObj.cn); - } else if (colUiObj.dtx === 'dateTime' && !skip) { - column = table.dateTime(colUiObj.cn); - } else if (colUiObj.dtx === 'time' && !skip) { - column = table.time(colUiObj.cn); - } else if (colUiObj.dtx === 'timestamp' && !skip) { - column = table.timestamp(colUiObj.cn); - } else if (colUiObj.dtx === 'enu' && !skip) { - column = table.enu(colUiObj.cn, JSON.stringify(colUiObj.enuValue || [])); - } else if (colUiObj.dtx === 'json' && !skip) { - column = table.json(colUiObj.cn); - } else if (colUiObj.dtx === 'uuid' && !skip) { - column = table.uuid(colUiObj.cn); - } - - if (colUiObj.pk) { - column.primary(); - } - - // log.debug(colUiObj.cn, colUiObj.nrqd); - if (!colUiObj.rqd) { - column.nullable(); - } else { - column.notNullable(); - } - - if (colUiObj.ck) { - column.unique(); - } - - if (colUiObj.un) { - column.unsigned(); - } - - if (colUiObj.cdf) { - column.defaultTo(sqlClient.raw(colUiObj.cdf)); - } - - // log.debug(colUiObj, colCreate); - // - // eval(`var inMemoryFunc = function(table) { - // ${colCreate} - // }`); - // console.log(colCreate); - // inMemoryFunc(table); -} - -function removeColumn(table, _n, _o) { - const colCreate = `table.dropColumn(n.cn)`; - - // log.debug(n, o, colCreate); - - eval(`var inMemoryFunc = function(table) { - ${colCreate} - }`); - - // @ts-ignore - inMemoryFunc(table); -} - -function renameColumn(_knexClient, connectionConfig, _table, o, n): any { - let upStatement = ``; - let downStatement = ``; - if (connectionConfig.client === 'mysql') { - const type = n.ct; - const nn = n.rqd ? 'NOT NULL' : ''; - const ai = n.ai ? 'AUTO_INCREMENT' : ''; - // const un = ''; - const _default = n.cdf ? `DEFAULT '${n.cdf}'` : ''; - - upStatement = `ALTER TABLE \`${n.tn}\` CHANGE COLUMN - \`${o.cn}\` \`${n.cn}\` ${type} ${nn} ${ai} ${_default}`; - - downStatement = `ALTER TABLE \`${n.tn}\` CHANGE COLUMN - \`${n.cn}\` \`${o.cn}\` ${type} ${nn} ${ai} ${_default}`; - - const obj = { - upStatement: [{ sql: upStatement }], - downStatement: [{ sql: downStatement }], - }; - - // console.log(obj); - - return obj; - } -} - -function pkUpdate(table, n, o) { - let colUpdate = 'table'; - // const skip = false; - // const skipColumnDefault = false; - // const skipColumnUnsigned = false; - - log.debug(n, o); - - colUpdate = ``; - let pkCount = 0; - for (let i = 0; i < o.length; ++i) { - if (o[i].pk) { - if (pkCount) { - colUpdate += `,"${o[i].cn}"`; - } else { - colUpdate += `table.dropPrimary(["${o[i].cn}"`; - } - - pkCount += 1; - log.debug(colUpdate); - } - } - if (pkCount) colUpdate += `]);\n`; - - colUpdate += ``; - pkCount = 0; - for (let i = 0; i < n.length; ++i) { - if (n[i].pk) { - if (pkCount) { - colUpdate += `,"${n[i].cn}"`; - } else { - colUpdate += `table.primary(["${n[i].cn}"`; - } - - pkCount += 1; - log.debug(colUpdate); - } - } - if (pkCount) colUpdate += `]);\n`; - - log.debug(colUpdate); - - eval(`var inMemoryFunc = function(table) { - ${colUpdate} - }`); - - // console.log(colUpdate); - - // @ts-ignore - inMemoryFunc(table); -} - -function columnUpdate(knexClient, table, n, o) { - let skip = false; - let skipColumnDefault = false; - let skipColumnUnsigned = false; - let skipNotNullable = false; - let column; - - // TODO : write a function - is the type char - if (n.dt === 'varchar' || n.dt === 'char' || n.dt === 'text') { - n.cdf = n.cdf ? JSON.stringify(n.cdf) : null; - } else { - n.cdf = n.cdf === '' ? null : n.cdf; - } - - if ('ai' in n && o && n.ai !== o.ai && n.ai) { - column = table.increments(n.cn); - skip = true; - } else if ('pk' in n && (!o || n.pk !== o.pk) && n.pk) { - column = table.primary(n.cn); - } else if ('pk' in n && o && n.pk !== o.pk && !n.pk) { - column = table.dropPrimary(n.cn); - } - - if ('dtx' in n && n.dtx === 'specificType' && !skip) { - const precision = n.dtxp && n.dtxp !== ' ' ? n.dtxp : null; - const scale = n.dtxs && n.dtxs !== ' ' ? n.dtxs : null; - if (precision && scale) { - column = table.specificType(n.cn, `${n.dt}(${precision},${scale})`); - } else if (precision) { - column = table.specificType(n.cn, `${n.dt}(${precision})`); - } else { - column = table.specificType(n.cn, n.dt); - } - } else if ('dtx' in n && n.dtx === 'integer' && !skip) { - if (!o) { - column = table.integer(n.cn); - } else { - column = table.integer(n.cn, n.dtxp); - } - } else if ('dtx' in n && n.dtx === 'bigInteger' && !skip) { - column = table.bigInteger(n.cn); - } else if ('dtx' in n && n.dtx === 'text' && !skip) { - column = table.text(n.cn); - } else if ('dtx' in n && n.dtx === 'string' && !skip) { - if (!o) { - column = table.string(n.cn); - } else { - column = table.string(n.cn, n.dtxp); - } - } else if ('dtx' in n && n.dtx === 'float' && !skip) { - if (!o) { - column = table.float(n.cn); - } else { - column = table.float(n.cn, n.dtxp, n.dtxs); - } - } else if ('dtx' in n && n.dtx === 'decimal' && !skip) { - if (!o) { - column = table.decimal(n.cn); - } else { - column = table.decimal(n.cn, n.dtxp, n.dtxs); - } - } else if ('dtx' in n && n.dtx === 'boolean' && !skip) { - column = table.boolean(n.cn); - } else if ('dtx' in n && n.dtx === 'binary' && !skip) { - column = table.binary(n.cn); - } else if ('dtx' in n && n.dtx === 'date' && !skip) { - column = table.date(n.cn); - } else if ('dtx' in n && n.dtx === 'dateTime' && !skip) { - column = table.dateTime(n.cn); - } else if ('dtx' in n && n.dtx === 'time' && !skip) { - column = table.time(n.cn); - } else if ('dtx' in n && n.dtx === 'timestamp' && !skip) { - column = table.timestamp(n.cn); - } else if ('dtx' in n && n.dtx === 'enu' && !skip) { - column = table.enu(n.cn, JSON.stringify(n.enuValue || [])); - } else if ('dtx' in n && n.dtx === 'json' && !skip) { - column = table.json(n.cn); - } else if ('dtx' in n && n.dtx === 'uuid' && !skip) { - column = table.uuid(n.cn); - } - - if (o) { - // updating existing column - /** - * if rqd is getting DISABLED and there is non_null value for default - * query builder has to include defaultTo() and unsigned() - */ - if (n.rqd !== o.rqd && !n.rqd) { - column.nullable(); - - if (n.cdf) { - column.defaultTo(knexClient.raw(n.cdf)); - skipColumnDefault = true; - } - - if (n.un) { - column.unsigned(); - skipColumnUnsigned = true; - } - } - - /** - * if rqd is getting ENABLED and there is non_null value for default - * query builder has to include defaultTo() - */ - if (n.rqd !== o.rqd && n.rqd && !skipNotNullable) { - column.notNullable(); - skipNotNullable = true; - - if (n.cdf && !skipColumnDefault) { - column.defaultTo(knexClient.raw(n.cdf)); - skipColumnDefault = true; - } - if (n.un && !skipColumnUnsigned) { - column.unsigned(); - skipColumnUnsigned = true; - } - } - - if (n.un !== o.un && !skipColumnUnsigned) { - if (n.un) column.unsigned(); - - if (n.cdf && !skipColumnDefault) { - column.defaultTo(knexClient.raw(n.cdf)); - skipColumnDefault = true; - } - if (n.rqd && !skipNotNullable) { - column.notNullable(); - skipNotNullable = true; - } - } - - /** - * if default is getting enabled and there is a rqd enabled - * query builder has to include defaultTo() - */ - if (n.cdf !== o.cdf && !skipColumnDefault) { - // console.log(knexClient.raw(n.cdf)) - column.defaultTo(n.cdf ? knexClient.raw(n.cdf) : null); - - if (n.rqd && !skipNotNullable) { - column.notNullable(); - skipNotNullable = true; - } - if (n.un && !skipColumnUnsigned) { - column.unsigned(); - skipColumnUnsigned = true; - } - } - - if ((!o || n.ck !== o.ck) && n.ck) { - column.unique(); - } - - if ((!o || n.ck !== o.ck) && !n.ck) { - column.dropUnique(n.cn); - } - } else { - // adding a new column - - if (n.rqd) { - column.notNullable(); - } else if (!n.rqd && !n.cdf) { - column.nullable(); - } - - if (n.un) { - column.unsigned(); - } - - if (n.cdf) { - column.defaultTo(knexClient.raw(n.cdf)); - } - } - - // /** - // * if rqd is getting DISABLED and there is non_null value for default - // * query builder has to include defaultTo() and unsigned() - // */ - // if ("rqd" in n && (!o || n.rqd !== o.rqd) && !n.rqd) { - // colUpdate += `.nullable()`; - // - // if (n.cdf) { - // colUpdate += `.defaultTo(knexClient.raw(\`${n.cdf}\`))`; - // } - // - // if (n.un) { - // colUpdate += `.unsigned()`; - // } - // } - // - // /** - // * if rqd is getting ENABLED and there is non_null value for default - // * query builder has to include defaultTo() - // */ - // if ("rqd" in n && - // (!o || n.rqd !== o.rqd) && - // !n.rqd === false) { - // colUpdate += `.notNullable()`; - // - // if (n.cdf && !skipColumnDefault) { - // colUpdate += `.defaultTo(knexClient.raw(\`${n.cdf}\`))`; - // skipColumnDefault = true; - // } - // if (n.un && !skipColumnDefault) { - // colUpdate += `.unsigned()`; - // skipColumnUnsigned = true; - // } - // - // } - // - // if ("ck" in n && - // (!o || n.ck !== o.ck) && - // n.ck) { - // colUpdate += `.unique()`; - // } - // - // if ("ck" in n && - // (o && n.ck !== o.ck) && - // !n.ck) { - // const dropUnique = `column.dropUnique(\"${n.cn}\");\n`; - // colUpdate = dropUnique + colUpdate; - // } - // - // if ("un" in n && (!o || n.un !== o.un) && !skipColumnUnsigned) { - // if (n.un) - // colUpdate += `.unsigned()`; - // - // if (n.cdf && !skipColumnDefault) { - // colUpdate += `.defaultTo(knexClient.raw(\`${n.cdf}\`))`; - // skipColumnDefault = true; - // } - // if (n.rqd) { - // colUpdate += `.notNullable()`; - // } - // } - // - // /** - // * if default is getting enabled and there is a rqd enabled - // * query builder has to include defaultTo() - // */ - // if ("cdf" in n && (o && n.cdf !== o.cdf) && !skipColumnDefault) { - // colUpdate += `.defaultTo(knexClient.raw(\`${n.cdf}\`))`; - // if (n.rqd) { - // colUpdate += `.notNullable()`; - // } - // if (n.un) { - // colUpdate += `.unsigned()`; - // skipColumnUnsigned = true; - // } - // - // } - - if (o && o.cno !== n.cn) { - column.renameColumn(n.cno, n.cn); - } - - if (n.altered & 1) { - // added - do nothing - } else if (n.altered & 2) { - // modified - column.alter(); - } -} - -class KnexClient extends SqlClient { +abstract class KnexClient extends SqlClient { private static ___ext: boolean; protected _connectionConfig: any; protected metaDb: any; @@ -646,15 +168,15 @@ class KnexClient extends SqlClient { }); } - async schemaCreateWithCredentials(_args): Promise {} + abstract schemaCreateWithCredentials(_args): Promise; - async sequenceList(_args = {}): Promise {} + abstract sequenceList(_args?: any): Promise; - async sequenceCreate(_args = {}): Promise {} + abstract sequenceCreate(_args?: any): Promise; - async sequenceUpdate(_args = {}): Promise {} + abstract sequenceUpdate(_args?: any): Promise; - async sequenceDelete(_args = {}): Promise {} + abstract sequenceDelete(_args?: any): Promise; _isColumnPrimary(columnObj) { if ( @@ -805,8 +327,6 @@ class KnexClient extends SqlClient { return Math.min(max, max1, max2, maxy); } - getColumnType(_dbType): any {} - getKnexDataTypeMock(databaseType) { try { const Type = databaseType; @@ -860,275 +380,10 @@ class KnexClient extends SqlClient { } } - getMinMax(_columnObject) {} - async mockDb(_args) { // todo: remove method } - async dbCacheInitAsyncKnex(_cbk = null) { - try { - const self = this; - let universalQuery = null; - let universalResults = []; - - // console.log(this.connectionConfig); - - if (this.connectionConfig.client === 'mysql') { - universalQuery = dataHelp.getMysqlSchemaQuery(); - - const results = await this.knex.raw(universalQuery, [ - this.connectionConfig.connection.database, - ]); - - if (results.length) { - universalResults = results[0]; - - // osx mysql server has limitations related to open_tables - await this.knex.raw('FLUSH TABLES', []); - - // cbk(null, null) - } else { - // console.log('Cache init failed during database reading') - console.log({}, results[0]); - // cbk(err, results) - } - } - - if (universalResults.length) { - for (let i = 0; i < universalResults.length; ++i) { - const keys = Object.keys(universalResults[i]); - for (let j = 0; j < keys.length; ++j) { - const value = universalResults[i][keys[j]]; - - universalResults[i][keys[j].toLowerCase()] = value; - - // console.log(value); - } - } - - self.iterateToCacheTables(universalResults); - self.iterateToCacheTablePks(universalResults); - self.iterateToCacheTableColumns(universalResults); - self.iterateToCacheTableFks(universalResults); - self.constructUiMeta(); - - console.log('erm atrix = = = = ='); - self.iterateToCacheErMatrix(universalResults); - console.log('erm atrix = = = = ='); - // await self.mockDb() - - // console.log(this.metaDb.tables['film'].columns); - - for (let i = 0; i < universalResults.length; ++i) { - if (universalResults[i].ck === 'PRI') { - console.log( - 'PK >> ', - universalResults[i].tn, - universalResults[i].cn, - universalResults[i].ext, - ); - } - } - } - } catch (e) { - console.log(e); - } - } - - getUiColumnObject(column) { - const uiColObj: any = {}; - - // console.log(column); - - uiColObj.cn = column.cn; - uiColObj.dt = column.dt; - uiColObj.data_type_knex = this.getKnexDataTypeMock(column.dt); - uiColObj.ct = column.ct; - uiColObj.nrqd = column.nrqd !== 'NO'; - uiColObj.ck = column.ck === 'MUL'; - uiColObj.pk = column.ck === 'PRI'; - uiColObj.un = column.ct.indexOf('unsigned') !== -1; - uiColObj.ai = column.ext.indexOf('auto_increment') !== -1; - - if (this.connectionConfig.client === 'mysql') { - uiColObj.cdf = column.cdf; - uiColObj.clen = column.clen; - uiColObj.np = column.np; - uiColObj.ns = column.ns; - uiColObj.dp = column.dp; - } - - return uiColObj; - } - - constructUiMeta() { - for (const tn in this.metaDb.tables) { - const table = this.metaDb.tables[tn]; - - for (let i = 0; i < table.columns.length; ++i) { - const column = table.columns[i]; - table.uiModel.columns[i] = this.getUiColumnObject(column); - } - } - } - - iterateToCacheTables(schemaResults) { - for (let i = 0; i < schemaResults.length; ++i) { - const schemaRow = schemaResults[i]; - if (0 && schemaRow.is_view) { - } else { - const tn = schemaRow.tn; - - if (!(tn in this.metaDb.tables)) { - this.metaDb.tables[tn] = {}; - this.metaDb.tables[tn].primaryKeys = []; - this.metaDb.tables[tn].foreignKeys = []; - this.metaDb.tables[tn].columns = []; - this.metaDb.tables[tn].indicies = []; - this.metaDb.tables[tn].is_view = schemaRow.is_view; - - const uiModel: any = {}; - uiModel.columns = []; - uiModel.primaryKeys = []; - uiModel.foreignKeys = []; - uiModel.indicies = []; - - this.metaDb.tables[tn].uiModel = uiModel; - } - } - } - } - - iterateToCacheTableColumns(schemaResults) { - for (let i = 0; i < schemaResults.length; ++i) { - const schemaRow = schemaResults[i]; - const tn = schemaRow.tn; - const col: any = {}; - - if (schemaRow.cn.split(' ').length > 1) { - // todo - // console.log('column skipped since it has a space in its name - seen it in a view'); - } else { - col.cn = schemaRow.cn; - col.op = schemaRow.op; - col.ck = schemaRow.ck; - col.dt = schemaRow.dt; - col.ct = schemaRow.ct; - col.rtn = schemaRow.rtn; - col.rcn = schemaRow.rcn; - col.nrqd = schemaRow.nrqd; - - if (this.connectionConfig.client === 'mysql') { - col.ext = schemaRow.ext; - col.cc = schemaRow.cc; - col.cdf = schemaRow.cdf; - col.clen = schemaRow.clen; - col.np = schemaRow.np; - col.ns = schemaRow.ns; - col.dp = schemaRow.dp; - } - - dataHelp.findOrInsertObjectArrayByKey( - col, - 'cn', - this.metaDb.tables[tn].columns, - ); - } - } - } - - iterateToCacheTableFks(schemaResults) { - for (let i = 0; i < schemaResults.length; ++i) { - const schemaRow = schemaResults[i]; - const tn = schemaRow.tn; - - if (schemaRow.rtn) { - const fk: any = {}; - - fk.cn = schemaRow.cn; - fk.tn = schemaRow.tn; - fk.rtn = schemaRow.rtn; - fk.rcn = schemaRow.rcn; - fk.dt = schemaRow.dt; - fk.ct = schemaRow.ct; - - dataHelp.findOrInsertObjectArrayByKey( - fk, - 'cn', - this.metaDb.tables[tn].foreignKeys, - ); - - // console.log(fk['rtn'],fk['rcn'],tn, schemaRow['cn'], this.metaDb.tables[tn]['foreignKeys'].length) - } - } - } - - iterateToCacheErMatrix(schemaResults) { - this.metaDb.erMatrix = []; - - // console.log('> > ',this.metaDb); - - const tablesAsArr = Object.keys(this.metaDb.tables); - const tablesIndex: any = {}; - const reverseTablesIndex: any = {}; - - console.log('< < < ', tablesAsArr); - - // get tables array indicies - helps to search - for (let i = 0; i < tablesAsArr.length; ++i) { - tablesIndex[tablesAsArr[i]] = i; - reverseTablesIndex[i] = tablesAsArr[i]; - } - - this.metaDb.erTablesAsArr = tablesAsArr; - this.metaDb.erTableIndexObj = tablesIndex; - this.metaDb.erIndexTableObj = reverseTablesIndex; - - // init the ermatrix - for (let i = 0; i < tablesAsArr.length; ++i) { - this.metaDb.erMatrix[i] = []; - for (let j = 0; j < tablesAsArr.length; ++j) { - this.metaDb.erMatrix[i].push(0); - } - } - - console.log(this.metaDb.erTableIndexObj, this.metaDb.erIndexTableObj); - - for (let i = 0; i < schemaResults.length; ++i) { - if (schemaResults[i].rtn !== null) { - // console.log(schemaResults[i]['rtn'], schemaResults[i]['tn']); - - const parentIndex = tablesIndex[schemaResults[i].rtn]; - const childIndex = tablesIndex[schemaResults[i].tn]; - this.metaDb.erMatrix[parentIndex][childIndex] = 1; - } - } - // console.log(this.metaDb.erMatrix); - } - - iterateToCacheTablePks(schemaResults) { - for (let i = 0; i < schemaResults.length; ++i) { - const schemaRow = schemaResults[i]; - const tn = schemaRow.tn; - - if (this._isColumnPrimary(schemaRow)) { - const pk: any = {}; - pk.cn = schemaRow.cn; - pk.op = schemaRow.op; - pk.ck = schemaRow.ck; - pk.dt = schemaRow.dt; - pk.ct = schemaRow.ct; - - dataHelp.findOrInsertObjectArrayByKey( - pk, - 'cn', - this.metaDb.tables[tn].primaryKeys, - ); - } - } - } - emit(data) { log.api(data); evt.evt.emit('UI', { @@ -1153,8 +408,6 @@ class KnexClient extends SqlClient { }); } - migrationInit(_args) {} - async selectAll(tn) { return await this.sqlClient.raw(this.sqlClient(tn).select().toQuery()); } @@ -1199,11 +452,9 @@ class KnexClient extends SqlClient { return result; } - executeSqlFiles() {} + abstract createDatabaseIfNotExists(_args): Promise; - async createDatabaseIfNotExists(_args): Promise {} - - async createTableIfNotExists(_args): Promise {} + abstract createTableIfNotExists(_args): Promise; async raw(statements, ...args) { const start = new Date().getTime(); @@ -1257,79 +508,11 @@ class KnexClient extends SqlClient { await this.sqlClient.raw(this.sqlClient(tn).del().where(where).toQuery()); } - hasTable(_tn) {} + abstract hasTable(_tn); - hasDatabase(_databaseName) {} + abstract hasDatabase(_databaseName); - getKnexDataTypes() { - const result = new Result(); - - // result.data.list = [ - // "integer", - // "bigInteger", - // "text", - // "string", - // "float", - // "decimal", - // "boolean", - // "date", - // // "datetime", - // "time", - // "timestamp", - // "binary", - // "enu", - // "json", - // "specificType" - // ]; - - result.data.list = [ - 'int', - 'tinyint', - 'smallint', - 'mediumint', - 'bigint', - 'float', - 'decimal', - 'double', - 'real', - 'bit', - 'boolean', - 'serial', - 'date', - 'datetime', - 'timestamp', - 'time', - 'year', - 'char', - 'varchar', - 'nchar', - // "nvarchar", - 'text', - 'tinytext', - 'mediumtext', - 'longtext', - 'binary', - 'varbinary', - 'blob', - 'tinyblob', - 'mediumblob', - 'longblob', - 'enum', - 'set', - 'time', - 'geometry', - 'point', - 'linestring', - 'polygon', - 'multipoint', - 'multilinestring', - 'multipolygon', - // "geometrycollection", - 'json', - ]; - - return result; - } + abstract getKnexDataTypes(); getKnexDataTypesAdvanced(args = {}) { const result = new Result(); @@ -1703,99 +886,9 @@ class KnexClient extends SqlClient { * @param {String} - args.columns[].cdf - * @param {String} - args.columns[].cc - * @param {String} - args.columns[].csn - - * @param {String} - args.columns[].dtx - * - value will be 'specificType' for all cols except ai - * - for ai it will be integer, bigInteger - * - tiny, small and medium Int auto increement is not supported - * @param {String} - args.columns[].dtxp - to use in UI - * @param {String} - args.columns[].dtxs - to use in UI * @returns {Promise<{upStatement, downStatement}>} */ - async tableCreate(args) { - const _func = this.tableCreate.name; - const result = new Result(); - log.api(`${_func}:args:`, args); - - try { - args.table = args.tn; - args.sqlClient = this.sqlClient; - - /** ************** create table *************** */ - const query = this.sqlClient.schema.createTable( - args.table, - function (table) { - const multiplePks = []; - const columns = JSON.parse(JSON.stringify(args.columns)); - - // copy PKs to new array and set PK metadata to false in original columns - for (let i = 0; i < columns.length; ++i) { - if (columns[i].pk) { - multiplePks.push(i); - columns[i].pk = false; - columns[i].ai = false; - } - } - - if (multiplePks.length > 1) { - for (let i = 0; i < columns.length; ++i) { - columnCreate(args.sqlClient, table, columns[i]); - } - - createPks(table, args.columns, multiplePks); - } else { - for (let i = 0; i < args.columns.length; ++i) { - columnCreate(args.sqlClient, table, args.columns[i]); - } - } - }, - ); - - await this.sqlClient.raw(query.toQuery()); - - /** ************** create up & down statements *************** */ - const upStatement = this.sqlClient.schema - .createTable(args.table, function (table) { - const multiplePks = []; - const columns = JSON.parse(JSON.stringify(args.columns)); - - for (let i = 0; i < columns.length; ++i) { - if (columns[i].pk) { - multiplePks.push(i); - columns[i].pk = false; - columns[i].ai = false; - } - } - - if (multiplePks.length > 1) { - for (let i = 0; i < columns.length; ++i) { - columnCreate(args.sqlClient, table, columns[i]); - } - - createPks(table, args.columns, multiplePks); - } else { - for (let i = 0; i < args.columns.length; ++i) { - columnCreate(args.sqlClient, table, args.columns[i]); - } - } - }) - .toSQL(); - - this.emit(`Success : ${upStatement}`); - - const downStatement = this.sqlClient.schema.dropTable(args.table).toSQL(); - - /** ************** return files *************** */ - result.data.object = { - upStatement, - downStatement, - }; - } catch (e) { - log.ppe(e, _func); - throw e; - } - - return result; - } + abstract tableCreate(args): Promise; /** * @@ -1973,225 +1066,7 @@ class KnexClient extends SqlClient { * @param {Number} - args.columns[].altered - 1,2,4 = addition,edited,deleted * @returns {Promise<{upStatement, downStatement}>} */ - async tableUpdate(args) { - const _func = this.tableUpdate.name; - const result = new Result(); - log.api(`${_func}:args:`, args); - let renamed = false; - let renamedUpDownStatement: any = {}; - - try { - args.table = args.tn; - const originalColumns = args.originalColumns; - args.connectionConfig = this._connectionConfig; - args.sqlClient = this.sqlClient; - - /** ************** START : has PK changed *************** */ - const numOfPksInOriginal = []; - const numOfPksInNew = []; - let pksChanged = 0; // > 1 for new pk and < 1 for pl removed - - for (let i = 0; i < args.columns.length; ++i) { - if (args.columns[i].pk) { - numOfPksInNew.push(i); - } - } - - for (let i = 0; i < args.originalColumns.length; ++i) { - if (args.originalColumns[i].pk) { - numOfPksInOriginal.push(i); - } - } - - if (numOfPksInNew.length > numOfPksInOriginal.length) { - /** - * new primary key - */ - pksChanged = numOfPksInNew.length - numOfPksInOriginal.length; - } else if (numOfPksInNew.length < numOfPksInOriginal.length) { - /** - * primary key removed - */ - pksChanged = numOfPksInNew.length - numOfPksInOriginal.length; - } else { - /** - * check if the pks are same - * exchanging one pk for another - we will catch it here - */ - for (let i = 0; i < numOfPksInNew.length; ++i) { - if (numOfPksInNew[i] !== numOfPksInOriginal[i]) { - pksChanged = 1; - } - } - } - - console.log('pksChanged:', pksChanged); - /** ************** END : has PK changed *************** */ - - /** ************** update table *************** */ - const query = this.sqlClient.schema.alterTable( - args.table, - function (table) { - if (pksChanged) { - pkUpdate(table, args.columns, args.originalColumns); - } else { - for (let i = 0; i < args.columns.length; ++i) { - const column = find(originalColumns, { - cn: args.columns[i].cno, - }); - - if (args.columns[i].altered & 8) { - // TODO: If a column is getting renamed then - // any change to column data type - // or changes to other columns are ignored - renamed = true; - renamedUpDownStatement = renameColumn( - args.sqlClient, - args.connectionConfig, - table, - column, - args.columns[i], - ); - result.data.object = renamedUpDownStatement; - } else if (args.columns[i].altered & 4) { - // col remove - removeColumn(table, args.columns[i], column); - } else if (args.columns[i].altered & 2) { - // col edit - columnUpdate(args.sqlClient, table, args.columns[i], column); - } else if (args.columns[i].altered & 1) { - // col addition - columnUpdate(args.sqlClient, table, args.columns[i], null); - } - } - } - }, - ); - - await this.sqlClient.raw(query.toQuery()); - - // log.debug('after column change', r); - - if (renamed) { - await this.sqlClient.raw(renamedUpDownStatement.upStatement); - result.data.object = renamedUpDownStatement; - } else { - /** ************** create up & down statements *************** */ - const upStatement = this.sqlClient.schema - .alterTable(args.table, function (table) { - if (pksChanged) { - pkUpdate(table, args.columns, args.originalColumns); - } else { - for (let i = 0; i < args.columns.length; ++i) { - const column = find(originalColumns, { - cn: args.columns[i].cno, - }); - if (args.columns[i].altered & 8) { - // col remove - // renameColumn(this.sqlClient, - // this.connectionConfig, - // table, - // args.columns[i].cno, - // args.columns[i].cn); - } else if (args.columns[i].altered & 4) { - // col remove - removeColumn(table, args.columns[i], column); - } else if (args.columns[i].altered & 2) { - // col edit - columnUpdate(args.sqlClient, table, args.columns[i], column); - } else if (args.columns[i].altered & 1) { - // col addition - columnUpdate(args.sqlClient, table, args.columns[i], null); - } - } - } - }) - .toSQL(); - // this.emit(`Success : ${upStatement}`) - - // log.debug(upStatement); - - const downStatement = this.sqlClient.schema - .alterTable(args.table, function (table) { - if (pksChanged) { - pkUpdate(table, args.columns, args.originalColumns); - } else { - for (let i = 0; i < args.columns.length; ++i) { - const column = find(originalColumns, { - cn: args.columns[i].cno, - }); - if (args.columns[i].altered & 8) { - // col remove - // renameColumn(this.sqlClient, - // this.connectionConfig, - // table, - // args.columns[i].cno, - // args.columns[i].cn); - } else if (args.columns[i].altered & 4) { - // col remove reverse - columnUpdate(args.sqlClient, table, column, null); - } else if (args.columns[i].altered & 1) { - // col addition reverse - removeColumn(table, args.columns[i], null); - } else if (args.columns[i].altered & 2) { - // col edit reverse - columnUpdate(args.sqlClient, table, column, args.columns[i]); - } - } - } - }) - .toSQL(); - - result.data.object = { - upStatement, - downStatement, - }; - } - } catch (e) { - log.ppe(e, _func); - throw e; - } - - return result; - } - - // /** - // * - // * @param {Object} - args - // * @param args.tn - // * @returns {Promise<{upStatement, downStatement}>} - // */ - // async tableDelete(args) { - // const _func = this.tableDelete.name; - // const result = new Result(); - // log.api(`${_func}:args:`, args); - // try { - // const {columns} = args; - // args.sqlClient = this.sqlClient; - // - // /** ************** create up & down statements *************** */ - // const upStatement = this.sqlClient.schema - // .dropTable(args.tn) - // .toSQL(); - // const downQuery = createTable(args); - // - // this.emit(`Success : ${upStatement}`); - // - // /** ************** drop tn *************** */ - // await this.sqlClient.schema.dropTable(args.tn); - // - // /** ************** return files *************** */ - // result.data.object = { - // upStatement, - // downStatement : [{sql: downQuery}] - // }; - // } catch (e) { - // log.ppe(e, _func); - // throw e; - // } - // - // return result; - // } + abstract tableUpdate(args): Promise; /** * @@ -2199,43 +1074,7 @@ class KnexClient extends SqlClient { * @param args.tn * @returns {Promise<{upStatement, downStatement}>} */ - async tableDelete(args) { - const _func = this.tableDelete.name; - const result = new Result(); - log.api(`${_func}:args:`, args); - try { - const { columns } = args; - args.sqlClient = this.sqlClient; - - /** ************** create up & down statements *************** */ - const upStatement = this.sqlClient.schema.dropTable(args.tn).toSQL(); - const downStatement = this.sqlClient.schema - .createTable(args.tn, function (tn) { - for (let i = 0; i < columns.length; ++i) { - columnCreate(args.sqlClient, tn, columns[i]); - } - }) - .toSQL(); - - this.emit(`Success : ${upStatement}`); - - /** ************** drop tn *************** */ - await this.sqlClient.raw( - this.sqlClient.schema.dropTable(args.tn).toQuery(), - ); - - /** ************** return files *************** */ - result.data.object = { - upStatement, - downStatement, - }; - } catch (e) { - log.ppe(e, _func); - throw e; - } - - return result; - } + abstract tableDelete(args): Promise; /** * @@ -2826,8 +1665,6 @@ class KnexClient extends SqlClient { /** ************** START : seed functions *************** */ - async _getmetaDb() {} - /** * * @param args @@ -2968,17 +1805,17 @@ class KnexClient extends SqlClient { /** ************** END : seed functions *************** */ - async tableCreateStatement(_args): Promise {} + abstract tableCreateStatement(_args): Promise; - async tableInsertStatement(_args): Promise {} + abstract tableInsertStatement(_args): Promise; - async tableUpdateStatement(_args): Promise {} + abstract tableUpdateStatement(_args): Promise; - async tableDeleteStatement(_args): Promise {} + abstract tableDeleteStatement(_args): Promise; - async tableTruncateStatement(_args): Promise {} + abstract tableTruncateStatement(_args): Promise; - async tableSelectStatement(_args): Promise {} + abstract tableSelectStatement(_args): Promise; async sequelizeModelCreate(_args): Promise {} diff --git a/packages/nocodb/src/db/sql-client/lib/mysql/MysqlClient.ts b/packages/nocodb/src/db/sql-client/lib/mysql/MysqlClient.ts index 4f6f4b51c3..548b073b71 100644 --- a/packages/nocodb/src/db/sql-client/lib/mysql/MysqlClient.ts +++ b/packages/nocodb/src/db/sql-client/lib/mysql/MysqlClient.ts @@ -2487,6 +2487,12 @@ class MysqlClient extends KnexClient { return result; } + async sequenceCreate(_args: any = {}): Promise {} + + async sequenceUpdate(_args: any = {}): Promise {} + + async sequenceDelete(_args: any = {}): Promise {} + alterTableRemoveColumn(n, _o, existingQuery) { let query = existingQuery ? ',' : ''; query += this.genQuery(` DROP COLUMN ??`, [n.cn]); diff --git a/packages/nocodb/src/db/sql-client/lib/oracle/OracleClient.ts b/packages/nocodb/src/db/sql-client/lib/oracle/OracleClient.ts index 5816d58f08..ccc80e7589 100644 --- a/packages/nocodb/src/db/sql-client/lib/oracle/OracleClient.ts +++ b/packages/nocodb/src/db/sql-client/lib/oracle/OracleClient.ts @@ -14,6 +14,16 @@ class OracleClient extends KnexClient { super(connectionConfig); } + async schemaCreateWithCredentials(_args): Promise {} + + async sequenceList(_args: any = {}): Promise {} + + async sequenceCreate(_args: any = {}): Promise {} + + async sequenceUpdate(_args: any = {}): Promise {} + + async sequenceDelete(_args: any = {}): Promise {} + getKnexDataTypes() { const result = new Result(); diff --git a/packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts b/packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts index 7971b1cdeb..f838d838ea 100644 --- a/packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts +++ b/packages/nocodb/src/db/sql-client/lib/sqlite/SqliteClient.ts @@ -25,6 +25,16 @@ class SqliteClient extends KnexClient { this._version = {}; } + async schemaCreateWithCredentials(_args): Promise {} + + async sequenceList(_args: any = {}): Promise {} + + async sequenceCreate(_args: any = {}): Promise {} + + async sequenceUpdate(_args: any = {}): Promise {} + + async sequenceDelete(_args: any = {}): Promise {} + getKnexDataTypes() { const result = new Result();