|
|
@ -5,8 +5,12 @@ import KnexClient from '../KnexClient'; |
|
|
|
import Debug from '../../../util/Debug'; |
|
|
|
import Debug from '../../../util/Debug'; |
|
|
|
import Result from '../../../util/Result'; |
|
|
|
import Result from '../../../util/Result'; |
|
|
|
import queries from './sqlite.queries'; |
|
|
|
import queries from './sqlite.queries'; |
|
|
|
import lodash from 'lodash'; |
|
|
|
import isEmpty from 'lodash/isEmpty'; |
|
|
|
import _ from 'lodash'; |
|
|
|
import mapKeys from 'lodash/mapKeys'; |
|
|
|
|
|
|
|
import find from 'lodash/find'; |
|
|
|
|
|
|
|
import { customAlphabet } from 'nanoid'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 6); |
|
|
|
|
|
|
|
|
|
|
|
const log = new Debug('SqliteClient'); |
|
|
|
const log = new Debug('SqliteClient'); |
|
|
|
|
|
|
|
|
|
|
@ -678,7 +682,7 @@ class SqliteClient extends KnexClient { |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
let fn = response[0][i]; |
|
|
|
let fn = response[0][i]; |
|
|
|
fn = _.mapKeys(fn, function (_v, k) { |
|
|
|
fn = mapKeys(fn, function (_v, k) { |
|
|
|
return k.toLowerCase(); |
|
|
|
return k.toLowerCase(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
fn.function_name = fn.name; |
|
|
|
fn.function_name = fn.name; |
|
|
@ -732,7 +736,7 @@ class SqliteClient extends KnexClient { |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
let procedure = response[0][i]; |
|
|
|
let procedure = response[0][i]; |
|
|
|
procedure = _.mapKeys(procedure, function (_v, k) { |
|
|
|
procedure = mapKeys(procedure, function (_v, k) { |
|
|
|
return k.toLowerCase(); |
|
|
|
return k.toLowerCase(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
procedure.procedure_name = procedure.name; |
|
|
|
procedure.procedure_name = procedure.name; |
|
|
@ -816,7 +820,7 @@ class SqliteClient extends KnexClient { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
let _function = response[0][i]; |
|
|
|
let _function = response[0][i]; |
|
|
|
|
|
|
|
|
|
|
|
_function = _.mapKeys(_function, function (_v, k) { |
|
|
|
_function = mapKeys(_function, function (_v, k) { |
|
|
|
return k.toLowerCase(); |
|
|
|
return k.toLowerCase(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
@ -868,7 +872,7 @@ class SqliteClient extends KnexClient { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
for (let i = 0; i < response[0].length; ++i) { |
|
|
|
let procedure = response[0][i]; |
|
|
|
let procedure = response[0][i]; |
|
|
|
|
|
|
|
|
|
|
|
procedure = _.mapKeys(procedure, function (_v, k) { |
|
|
|
procedure = mapKeys(procedure, function (_v, k) { |
|
|
|
return k.toLowerCase(); |
|
|
|
return k.toLowerCase(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
@ -1031,7 +1035,7 @@ class SqliteClient extends KnexClient { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
async _getQuery(args) { |
|
|
|
async _getQuery(args) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
if (_.isEmpty(this._version)) { |
|
|
|
if (isEmpty(this._version)) { |
|
|
|
const result = await this.version(); |
|
|
|
const result = await this.version(); |
|
|
|
this._version = result.data.object; |
|
|
|
this._version = result.data.object; |
|
|
|
log.debug( |
|
|
|
log.debug( |
|
|
@ -1491,11 +1495,11 @@ class SqliteClient extends KnexClient { |
|
|
|
let downQuery = ''; |
|
|
|
let downQuery = ''; |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < args.columns.length; ++i) { |
|
|
|
for (let i = 0; i < args.columns.length; ++i) { |
|
|
|
const oldColumn = lodash.find(originalColumns, { |
|
|
|
const oldColumn = find(originalColumns, { |
|
|
|
cn: args.columns[i].cno, |
|
|
|
cn: args.columns[i].cno, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (args.columns[i].altered & 4) { |
|
|
|
if (!args.columns[i].pk && args.columns[i].altered & 4) { |
|
|
|
// col remove
|
|
|
|
// col remove
|
|
|
|
upQuery += this.alterTableRemoveColumn( |
|
|
|
upQuery += this.alterTableRemoveColumn( |
|
|
|
args.table, |
|
|
|
args.table, |
|
|
@ -1544,15 +1548,46 @@ class SqliteClient extends KnexClient { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
upQuery += this.alterTablePK( |
|
|
|
const pkQuery = this.alterTablePK(args.columns, args.originalColumns, upQuery); |
|
|
|
args.columns, |
|
|
|
|
|
|
|
args.originalColumns, |
|
|
|
|
|
|
|
upQuery, |
|
|
|
|
|
|
|
this.sqlClient |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
//downQuery += alterTablePK(args.originalColumns, args.columns, downQuery);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await this.sqlClient.raw(upQuery); |
|
|
|
await this.sqlClient.raw('PRAGMA foreign_keys = OFF;'); |
|
|
|
|
|
|
|
await this.sqlClient.raw('PRAGMA legacy_alter_table = ON;'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const trx = await this.sqlClient.transaction(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
const queries = upQuery.split(';'); |
|
|
|
|
|
|
|
for (let i = 0; i < queries.length; i++) { |
|
|
|
|
|
|
|
if (queries[i].trim() !== '') { |
|
|
|
|
|
|
|
await trx.raw(queries[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pkQuery) { |
|
|
|
|
|
|
|
await trx.schema.alterTable(args.table, (table) => { |
|
|
|
|
|
|
|
for (const pk of pkQuery.oldPks.filter((el) => !pkQuery.newPks.includes(el))) { |
|
|
|
|
|
|
|
table.dropPrimary(pk); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const pk of pkQuery.dropPks) { |
|
|
|
|
|
|
|
table.dropColumn(pk); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pkQuery.newPks.length) { |
|
|
|
|
|
|
|
table.primary(pkQuery.newPks); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await trx.commit(); |
|
|
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
await trx.rollback(); |
|
|
|
|
|
|
|
log.ppe(e, _func); |
|
|
|
|
|
|
|
throw e; |
|
|
|
|
|
|
|
} finally { |
|
|
|
|
|
|
|
await this.sqlClient.raw('PRAGMA foreign_keys = ON;'); |
|
|
|
|
|
|
|
await this.sqlClient.raw('PRAGMA legacy_alter_table = OFF;'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
console.log(upQuery); |
|
|
|
console.log(upQuery); |
|
|
|
|
|
|
|
|
|
|
@ -1861,50 +1896,61 @@ class SqliteClient extends KnexClient { |
|
|
|
return result; |
|
|
|
return result; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
alterTablePK(n, o, _existingQuery, createTable = false) { |
|
|
|
createTablePK(n, _existingQuery) { |
|
|
|
const numOfPksInOriginal = []; |
|
|
|
const newPks = []; |
|
|
|
const numOfPksInNew = []; |
|
|
|
|
|
|
|
let pksChanged = 0; |
|
|
|
for (let i = 0; i < n.length; ++i) { |
|
|
|
|
|
|
|
if (n[i].pk) { |
|
|
|
|
|
|
|
if (n[i].altered !== 4) newPks.push(n[i].cn); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let query = ''; |
|
|
|
|
|
|
|
if (newPks.length) { |
|
|
|
|
|
|
|
query += this.genQuery(`, PRIMARY KEY(??)`, [newPks]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return query; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
alterTablePK(n, o, _existingQuery) { |
|
|
|
|
|
|
|
const newPks = []; |
|
|
|
|
|
|
|
const oldPks = []; |
|
|
|
|
|
|
|
const dropPks = []; |
|
|
|
|
|
|
|
let pksChanged = false; |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < n.length; ++i) { |
|
|
|
for (let i = 0; i < n.length; ++i) { |
|
|
|
if (n[i].pk) { |
|
|
|
if (n[i].pk) { |
|
|
|
if (n[i].altered !== 4) numOfPksInNew.push(n[i].cn); |
|
|
|
if (n[i].altered !== 4) { |
|
|
|
|
|
|
|
newPks.push(n[i].cn); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
dropPks.push(n[i].cn); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pksChanged = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < o.length; ++i) { |
|
|
|
for (let i = 0; i < o.length; ++i) { |
|
|
|
if (o[i].pk) { |
|
|
|
if (o[i].pk) { |
|
|
|
numOfPksInOriginal.push(o[i].cn); |
|
|
|
oldPks.push(o[i].cn); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (numOfPksInNew.length === numOfPksInOriginal.length) { |
|
|
|
if (newPks.length === oldPks.length) { |
|
|
|
for (let i = 0; i < numOfPksInNew.length; ++i) { |
|
|
|
if (newPks.every((pk) => oldPks.includes(pk)) && dropPks.length === 0) { |
|
|
|
if (numOfPksInOriginal[i] !== numOfPksInNew[i]) { |
|
|
|
pksChanged = false; |
|
|
|
pksChanged = 1; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
|
|
|
|
pksChanged = numOfPksInNew.length - numOfPksInOriginal.length; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let query = ''; |
|
|
|
if (pksChanged) { |
|
|
|
if (!numOfPksInNew.length && !numOfPksInOriginal.length) { |
|
|
|
return { |
|
|
|
// do nothing
|
|
|
|
newPks, |
|
|
|
} else if (pksChanged) { |
|
|
|
oldPks, |
|
|
|
query += numOfPksInOriginal.length ? ',DROP PRIMARY KEY' : ''; |
|
|
|
dropPks, |
|
|
|
|
|
|
|
|
|
|
|
if (numOfPksInNew.length) { |
|
|
|
|
|
|
|
if (createTable) { |
|
|
|
|
|
|
|
query += this.genQuery(`, PRIMARY KEY(??)`, [numOfPksInNew]); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
query += this.genQuery(`, ADD PRIMARY KEY(??)`, [numOfPksInNew]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return query; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
alterTableRemoveColumn(t, n, _o, existingQuery) { |
|
|
|
alterTableRemoveColumn(t, n, _o, existingQuery) { |
|
|
@ -1937,7 +1983,7 @@ class SqliteClient extends KnexClient { |
|
|
|
query += this.createTableColumn(table, args.columns[i], null, query); |
|
|
|
query += this.createTableColumn(table, args.columns[i], null, query); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
query += this.alterTablePK(args.columns, [], query, true); |
|
|
|
query += this.createTablePK(args.columns, query); |
|
|
|
|
|
|
|
|
|
|
|
query = this.genQuery(`CREATE TABLE ?? (${query});`, [args.tn]); |
|
|
|
query = this.genQuery(`CREATE TABLE ?? (${query});`, [args.tn]); |
|
|
|
|
|
|
|
|
|
|
@ -1950,19 +1996,32 @@ class SqliteClient extends KnexClient { |
|
|
|
const defaultValue = getDefaultValue(n); |
|
|
|
const defaultValue = getDefaultValue(n); |
|
|
|
let shouldSanitize = true; |
|
|
|
let shouldSanitize = true; |
|
|
|
if (change === 2) { |
|
|
|
if (change === 2) { |
|
|
|
query += this.genQuery( |
|
|
|
const suffix = nanoid(); |
|
|
|
`ALTER TABLE ?? RENAME COLUMN ?? TO ??`, |
|
|
|
|
|
|
|
[t, o.cn, n.cn], |
|
|
|
let backupOldColumnQuery = this.genQuery( |
|
|
|
|
|
|
|
`ALTER TABLE ?? RENAME COLUMN ?? TO ??;`, |
|
|
|
|
|
|
|
[t, o.cn, `${o.cno}_nc_${suffix}`], |
|
|
|
shouldSanitize |
|
|
|
shouldSanitize |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let addNewColumnQuery = '' |
|
|
|
|
|
|
|
addNewColumnQuery += this.genQuery(` ADD ?? ${n.dt}`, [n.cn], shouldSanitize); |
|
|
|
|
|
|
|
addNewColumnQuery += n.dtxp && n.dt !== 'text' ? `(${n.dtxp})` : ''; |
|
|
|
|
|
|
|
addNewColumnQuery += n.cdf ? ` DEFAULT ${n.cdf}` : !n.rqd ? ' ' : ` DEFAULT ''`; |
|
|
|
|
|
|
|
addNewColumnQuery += n.rqd ? ` NOT NULL` : ' '; |
|
|
|
|
|
|
|
addNewColumnQuery = this.genQuery(`ALTER TABLE ?? ${addNewColumnQuery};`, [t], shouldSanitize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let updateNewColumnQuery = this.genQuery(`UPDATE ?? SET ?? = ??;`, [t, n.cn, `${o.cno}_nc_${suffix}`], shouldSanitize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let dropOldColumnQuery = this.genQuery(`ALTER TABLE ?? DROP COLUMN ??;`, [t, `${o.cno}_nc_${suffix}`], shouldSanitize); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
query = `${backupOldColumnQuery}${addNewColumnQuery}${updateNewColumnQuery}${dropOldColumnQuery}`; |
|
|
|
} else if (change === 0) { |
|
|
|
} else if (change === 0) { |
|
|
|
query = existingQuery ? ',' : ''; |
|
|
|
query = existingQuery ? ',' : ''; |
|
|
|
query += this.genQuery(`?? ${n.dt}`, [n.cn], shouldSanitize); |
|
|
|
query += this.genQuery(`?? ${n.dt}`, [n.cn], shouldSanitize); |
|
|
|
query += n.dtxp && n.dt !== 'text' ? `(${n.dtxp})` : ''; |
|
|
|
query += n.dtxp && n.dt !== 'text' ? `(${n.dtxp})` : ''; |
|
|
|
query += n.cdf |
|
|
|
query += n.cdf |
|
|
|
? n.cdf.includes(',') |
|
|
|
? ` DEFAULT ${n.cdf}` |
|
|
|
? ` DEFAULT ('${n.cdf}')` |
|
|
|
|
|
|
|
: ` DEFAULT ${n.cdf}` |
|
|
|
|
|
|
|
: ' '; |
|
|
|
: ' '; |
|
|
|
query += n.rqd ? ` NOT NULL` : ' '; |
|
|
|
query += n.rqd ? ` NOT NULL` : ' '; |
|
|
|
} else if (change === 1) { |
|
|
|
} else if (change === 1) { |
|
|
@ -1970,10 +2029,8 @@ class SqliteClient extends KnexClient { |
|
|
|
query += this.genQuery(` ADD ?? ${n.dt}`, [n.cn], shouldSanitize); |
|
|
|
query += this.genQuery(` ADD ?? ${n.dt}`, [n.cn], shouldSanitize); |
|
|
|
query += n.dtxp && n.dt !== 'text' ? `(${n.dtxp})` : ''; |
|
|
|
query += n.dtxp && n.dt !== 'text' ? `(${n.dtxp})` : ''; |
|
|
|
query += n.cdf |
|
|
|
query += n.cdf |
|
|
|
? n.cdf.includes(',') |
|
|
|
? ` DEFAULT ${n.cdf}` |
|
|
|
? ` DEFAULT ('${n.cdf}')` |
|
|
|
: !n.rqd ? ' ' : ` DEFAULT ''`; |
|
|
|
: ` DEFAULT ${n.cdf}` |
|
|
|
|
|
|
|
: ' '; |
|
|
|
|
|
|
|
query += n.rqd ? ` NOT NULL` : ' '; |
|
|
|
query += n.rqd ? ` NOT NULL` : ' '; |
|
|
|
query = this.genQuery(`ALTER TABLE ?? ${query};`, [t], shouldSanitize); |
|
|
|
query = this.genQuery(`ALTER TABLE ?? ${query};`, [t], shouldSanitize); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|