cormo
Advanced tools
Comparing version 0.15.0 to 0.16.0
@@ -8,5 +8,9 @@ import { ColumnPropertyInternal } from '../model'; | ||
adapter_type_string?: string; | ||
description?: string; | ||
} | ||
export interface SchemasTable { | ||
[column_name: string]: SchemasColumn; | ||
columns: { | ||
[column_name: string]: SchemasColumn; | ||
}; | ||
description?: string; | ||
} | ||
@@ -13,0 +17,0 @@ export interface SchemasIndex { |
@@ -75,2 +75,10 @@ "use strict"; | ||
} | ||
/** Get query for creating a table | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getCreateTableQuery(model) { | ||
return null; | ||
} | ||
/** | ||
@@ -82,5 +90,30 @@ * Creates a table. | ||
*/ | ||
async createTable(model) { | ||
async createTable(model, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** Get query for updating a table description | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getUpdateTableDescriptionQuery(model) { | ||
return null; | ||
} | ||
/** | ||
* Update a table description. | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
async updateTableDescription(model, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** Get query for adding a column | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getAddColumnQuery(model, column_property) { | ||
return null; | ||
} | ||
/** Adds a column to a table | ||
@@ -91,5 +124,30 @@ * @abstract | ||
*/ | ||
async addColumn(model, column_property) { | ||
async addColumn(model, column_property, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** Get query for updating a column description | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getUpdateColumnDescriptionQuery(model, column_property) { | ||
return null; | ||
} | ||
/** | ||
* Update a column description. | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
async updateColumnDescription(model, column_property, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** Get query for creating an index | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getCreateIndexQuery(model_name, index) { | ||
return null; | ||
} | ||
/** Creates an index. | ||
@@ -100,5 +158,13 @@ * @abstract | ||
*/ | ||
async createIndex(model_name, index) { | ||
async createIndex(model_name, index, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** Get query for creating a foreign key | ||
* @abstract | ||
* @see Connection::applySchemas | ||
* @internal | ||
*/ | ||
getCreateForeignKeyQuery(model, column, type, references) { | ||
return null; | ||
} | ||
/** Creates a foreign key. | ||
@@ -109,6 +175,15 @@ * @abstract | ||
*/ | ||
async createForeignKey(model, column, type, references) { | ||
async createForeignKey(model, column, type, references, verbose = false) { | ||
return Promise.resolve(); | ||
} | ||
/** | ||
* Deletes all records with ignoring constraint | ||
* @abstract | ||
* @see BaseModel.drop | ||
* @internal | ||
*/ | ||
async deleteAllIgnoringConstraint(model_list) { | ||
return Promise.reject(new Error('not implemented')); | ||
} | ||
/** | ||
* Drops a model from the database | ||
@@ -115,0 +190,0 @@ * @abstract |
@@ -33,2 +33,3 @@ /// <reference types="node" /> | ||
reconnect_if_read_only?: boolean; | ||
hide_unknown_error?: boolean; | ||
} | ||
@@ -35,0 +36,0 @@ import { Connection } from '../connection'; |
@@ -44,3 +44,2 @@ "use strict"; | ||
const types = __importStar(require("../types")); | ||
const base_1 = require("./base"); | ||
const sql_base_1 = require("./sql_base"); | ||
@@ -88,18 +87,2 @@ function _typeToSQL(property, support_fractional_seconds) { | ||
} | ||
function _processSaveError(error) { | ||
if (error.code === 'ER_NO_SUCH_TABLE') { | ||
return new Error('table does not exist'); | ||
} | ||
else if (error.code === 'ER_DUP_ENTRY') { | ||
const key = error.message.match(/for key '([^']*)'/); | ||
return new Error('duplicated ' + (key && key[1])); | ||
} | ||
else if (error.code === 'ER_BAD_NULL_ERROR') { | ||
const key = error.message.match(/Column '([^']*)'/); | ||
return new Error(`'${key && key[1]}' is required`); | ||
} | ||
else { | ||
return base_1.AdapterBase.wrapError('unknown error', error); | ||
} | ||
} | ||
async function _tryCreateConnection(config, count = 0) { | ||
@@ -163,3 +146,4 @@ count++; | ||
for (const table of tables) { | ||
table_schemas[table] = await this._getSchema(table); | ||
table_schemas[table.name] = await this._getSchema(table.name); | ||
table_schemas[table.name].description = table.comment; | ||
} | ||
@@ -175,3 +159,3 @@ const indexes = await this._getIndexes(); | ||
/** @internal */ | ||
async createTable(model) { | ||
getCreateTableQuery(model) { | ||
const model_class = this._connection.models[model]; | ||
@@ -186,4 +170,7 @@ const table_name = model_class.table_name; | ||
else { | ||
const column_sql = _propertyToSQL(property, this.support_fractional_seconds); | ||
let column_sql = _propertyToSQL(property, this.support_fractional_seconds); | ||
if (column_sql) { | ||
if (property.description) { | ||
column_sql += ` COMMENT '${property.description}'`; | ||
} | ||
column_sqls.push(`\`${property._dbname_us}\` ${column_sql}`); | ||
@@ -193,27 +180,91 @@ } | ||
} | ||
let sql = `CREATE TABLE \`${table_name}\` ( ${column_sqls.join(',')} )`; | ||
sql += ` DEFAULT CHARSET=${this._settings.charset || 'utf8'}`; | ||
sql += ` COLLATE=${this._settings.collation || 'utf8_unicode_ci'}`; | ||
let query = `CREATE TABLE \`${table_name}\` ( ${column_sqls.join(',')} )`; | ||
query += ` DEFAULT CHARSET=${this._settings.charset || 'utf8'}`; | ||
query += ` COLLATE=${this._settings.collation || 'utf8_unicode_ci'}`; | ||
if (model_class.description) { | ||
query += ` COMMENT='${model_class.description}'`; | ||
} | ||
return query; | ||
} | ||
/** @internal */ | ||
async createTable(model, verbose = false) { | ||
const query = this.getCreateTableQuery(model); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(sql); | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
async addColumn(model, column_property) { | ||
getUpdateTableDescriptionQuery(model) { | ||
var _a; | ||
const model_class = this._connection.models[model]; | ||
const table_name = model_class.table_name; | ||
const column_sql = _propertyToSQL(column_property, this.support_fractional_seconds); | ||
const sql = `ALTER TABLE \`${table_name}\` ADD COLUMN \`${column_property._dbname_us}\` ${column_sql}`; | ||
return `ALTER TABLE ${table_name} COMMENT '${(_a = model_class.description) !== null && _a !== void 0 ? _a : ''}'`; | ||
} | ||
/** @internal */ | ||
async updateTableDescription(model, verbose = false) { | ||
const query = this.getUpdateTableDescriptionQuery(model); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(sql); | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
async createIndex(model_name, index) { | ||
getAddColumnQuery(model, column_property) { | ||
const model_class = this._connection.models[model]; | ||
const table_name = model_class.table_name; | ||
let column_sql = _propertyToSQL(column_property, this.support_fractional_seconds); | ||
if (column_property.description) { | ||
column_sql += ` COMMENT '${column_property.description}'`; | ||
} | ||
return `ALTER TABLE \`${table_name}\` ADD COLUMN \`${column_property._dbname_us}\` ${column_sql}`; | ||
} | ||
/** @internal */ | ||
async addColumn(model, column_property, verbose = false) { | ||
const query = this.getAddColumnQuery(model, column_property); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
getUpdateColumnDescriptionQuery(model, column_property) { | ||
const model_class = this._connection.models[model]; | ||
const table_name = model_class.table_name; | ||
let column_sql = _propertyToSQL(column_property, this.support_fractional_seconds); | ||
if (column_property.description) { | ||
column_sql += ` COMMENT '${column_property.description}'`; | ||
} | ||
return `ALTER TABLE \`${table_name}\` CHANGE COLUMN \`${column_property._dbname_us}\` \`${column_property._dbname_us}\` ${column_sql}`; | ||
} | ||
/** @internal */ | ||
async updateColumnDescription(model, column_property, verbose = false) { | ||
const query = this.getUpdateColumnDescriptionQuery(model, column_property); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
getCreateIndexQuery(model_name, index) { | ||
const model_class = this._connection.models[model_name]; | ||
@@ -228,12 +279,19 @@ const schema = model_class._schema; | ||
const unique = index.options.unique ? 'UNIQUE ' : ''; | ||
const sql = `CREATE ${unique}INDEX \`${index.options.name}\` ON \`${table_name}\` (${columns.join(',')})`; | ||
return `CREATE ${unique}INDEX \`${index.options.name}\` ON \`${table_name}\` (${columns.join(',')})`; | ||
} | ||
/** @internal */ | ||
async createIndex(model_name, index, verbose = false) { | ||
const query = this.getCreateIndexQuery(model_name, index); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(sql); | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
async createForeignKey(model, column, type, references) { | ||
getCreateForeignKeyQuery(model, column, type, references) { | ||
const model_class = this._connection.models[model]; | ||
@@ -253,12 +311,34 @@ const table_name = model_class.table_name; | ||
} | ||
const sql = `ALTER TABLE \`${table_name}\` ADD FOREIGN KEY (\`${column}\`) | ||
return `ALTER TABLE \`${table_name}\` ADD FOREIGN KEY (\`${column}\`) | ||
REFERENCES \`${references.table_name}\`(id) ON DELETE ${action}`; | ||
} | ||
/** @internal */ | ||
async createForeignKey(model, column, type, references, verbose = false) { | ||
const query = this.getCreateForeignKeyQuery(model, column, type, references); | ||
if (verbose) { | ||
console.log(` (${query})`); | ||
} | ||
try { | ||
await this._client.queryAsync(sql); | ||
await this._client.queryAsync(query); | ||
} | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
async deleteAllIgnoringConstraint(model_list) { | ||
const connection = await this.getConnection(); | ||
try { | ||
await connection.queryAsync('SET FOREIGN_KEY_CHECKS = 0'); | ||
await Promise.all(model_list.map(async (model) => { | ||
const table_name = this._connection.models[model].table_name; | ||
await connection.queryAsync(`TRUNCATE TABLE \`${table_name}\``); | ||
})); | ||
await connection.queryAsync('SET FOREIGN_KEY_CHECKS = 1'); | ||
} | ||
finally { | ||
await this.releaseConnection(connection); | ||
} | ||
} | ||
/** @internal */ | ||
async drop(model) { | ||
@@ -270,3 +350,3 @@ const table_name = this._connection.models[model].table_name; | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
@@ -289,3 +369,3 @@ } | ||
catch (error) { | ||
throw _processSaveError(error); | ||
throw this._processSaveError(error); | ||
} | ||
@@ -317,3 +397,3 @@ const id = result && result.insertId; | ||
catch (error) { | ||
throw _processSaveError(error); | ||
throw this._processSaveError(error); | ||
} | ||
@@ -339,3 +419,3 @@ const id = result && result.insertId; | ||
catch (error) { | ||
throw _processSaveError(error); | ||
throw this._processSaveError(error); | ||
} | ||
@@ -357,6 +437,6 @@ } | ||
catch (error) { | ||
throw _processSaveError(error); | ||
throw this._processSaveError(error); | ||
} | ||
if (result == null) { | ||
throw MySQLAdapter.wrapError('unknown error'); | ||
throw this._wrapError('unknown error'); | ||
} | ||
@@ -395,3 +475,3 @@ return result.affectedRows; | ||
catch (error) { | ||
throw _processSaveError(error); | ||
throw this._processSaveError(error); | ||
} | ||
@@ -413,3 +493,3 @@ } | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
@@ -437,3 +517,3 @@ if (result && result.length === 1) { | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
@@ -498,3 +578,3 @@ if (options.group_fields) { | ||
catch (error) { | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
@@ -522,6 +602,6 @@ if (result && result.length !== 1) { | ||
} | ||
throw MySQLAdapter.wrapError('unknown error', error); | ||
throw this._wrapError('unknown error', error); | ||
} | ||
if (result == null) { | ||
throw MySQLAdapter.wrapError('unknown error'); | ||
throw this._wrapError('unknown error'); | ||
} | ||
@@ -557,3 +637,3 @@ return result.affectedRows; | ||
} | ||
throw MySQLAdapter.wrapError('failed to connect', error); | ||
throw this._wrapError('failed to connect', error); | ||
} | ||
@@ -770,13 +850,12 @@ try { | ||
async _getTables() { | ||
let tables = await this._client.queryAsync('SHOW TABLES'); | ||
tables = tables.map((table) => { | ||
const key = Object.keys(table)[0]; | ||
return table[key]; | ||
}); | ||
return tables; | ||
const result = await this._client.queryAsync('SHOW TABLE STATUS'); | ||
return result.map((item) => ({ | ||
name: item.Name, | ||
comment: item.Comment, | ||
})); | ||
} | ||
/** @internal */ | ||
async _getSchema(table) { | ||
const columns = await this._client.queryAsync(`SHOW COLUMNS FROM \`${table}\``); | ||
const schema = {}; | ||
const columns = await this._client.queryAsync(`SHOW FULL COLUMNS FROM \`${table}\``); | ||
const schema = { columns: {} }; | ||
for (const column of columns) { | ||
@@ -790,6 +869,7 @@ const type = /^varchar\((\d*)\)/i.test(column.Type) ? new types.String(Number(RegExp.$1)) | ||
: /^text/i.test(column.Type) ? new types.Text() : undefined; | ||
schema[column.Field] = { | ||
schema.columns[column.Field] = { | ||
required: column.Null === 'NO', | ||
type, | ||
adapter_type_string: column.Type.toUpperCase(), | ||
description: column.Comment, | ||
}; | ||
@@ -961,3 +1041,3 @@ } | ||
catch (error2) { | ||
throw MySQLAdapter.wrapError('unknown error', error2); | ||
throw this._wrapError('unknown error', error2); | ||
} | ||
@@ -970,3 +1050,3 @@ return (await this._createDatabase(client)); | ||
: 'unknown error'; | ||
throw MySQLAdapter.wrapError(msg, error1); | ||
throw this._wrapError(msg, error1); | ||
} | ||
@@ -993,2 +1073,27 @@ } | ||
} | ||
/** @internal */ | ||
_processSaveError(error) { | ||
if (error.code === 'ER_NO_SUCH_TABLE') { | ||
return new Error('table does not exist'); | ||
} | ||
else if (error.code === 'ER_DUP_ENTRY') { | ||
const key = error.message.match(/for key '([^']*)'/); | ||
return new Error('duplicated ' + (key && key[1])); | ||
} | ||
else if (error.code === 'ER_BAD_NULL_ERROR') { | ||
const key = error.message.match(/Column '([^']*)'/); | ||
return new Error(`'${key && key[1]}' is required`); | ||
} | ||
else { | ||
return this._wrapError('unknown error', error); | ||
} | ||
} | ||
/** @internal */ | ||
_wrapError(msg, cause) { | ||
var _a; | ||
if (!((_a = this._settings) === null || _a === void 0 ? void 0 : _a.hide_unknown_error) && msg === 'unknown error' && cause) { | ||
return cause; | ||
} | ||
return MySQLAdapter.wrapError(msg, cause); | ||
} | ||
} | ||
@@ -995,0 +1100,0 @@ exports.MySQLAdapter = MySQLAdapter; |
@@ -222,2 +222,11 @@ "use strict"; | ||
/** @internal */ | ||
async deleteAllIgnoringConstraint(model_list) { | ||
await Promise.all(model_list.map(async (model) => { | ||
const table_name = this._connection.models[model].table_name; | ||
await this.query(`ALTER TABLE "${table_name}" DISABLE TRIGGER ALL`); | ||
await this.query(`DELETE FROM "${table_name}"`); | ||
await this.query(`ALTER TABLE "${table_name}" ENABLE TRIGGER ALL`); | ||
})); | ||
} | ||
/** @internal */ | ||
async drop(model) { | ||
@@ -582,3 +591,3 @@ const table_name = this._connection.models[model].table_name; | ||
const result = await this._pool.query(query, [table]); | ||
const schema = {}; | ||
const schema = { columns: {} }; | ||
for (const column of result.rows) { | ||
@@ -598,3 +607,3 @@ const type = column.data_type === 'character varying' ? new types.String(column.character_maximum_length) | ||
} | ||
schema[column.column_name] = { | ||
schema.columns[column.column_name] = { | ||
required: column.is_nullable === 'NO', | ||
@@ -601,0 +610,0 @@ type, |
@@ -189,2 +189,11 @@ "use strict"; | ||
/** @internal */ | ||
async deleteAllIgnoringConstraint(model_list) { | ||
await this._client.runAsync('PRAGMA foreign_keys=OFF'); | ||
await Promise.all(model_list.map(async (model) => { | ||
const table_name = this._connection.models[model].table_name; | ||
await this._client.runAsync(`DELETE FROM \`${table_name}\``); | ||
})); | ||
await this._client.runAsync('PRAGMA foreign_keys=ON'); | ||
} | ||
/** @internal */ | ||
async drop(model) { | ||
@@ -553,3 +562,3 @@ const table_name = this._connection.models[model].table_name; | ||
const columns = (await this._client.allAsync(`PRAGMA table_info(\`${table}\`)`)); | ||
const schema = {}; | ||
const schema = { columns: {} }; | ||
for (const column of columns) { | ||
@@ -562,3 +571,3 @@ const type = /^varchar\((\d*)\)/i.test(column.type) ? new types.String(Number(RegExp.$1)) | ||
: /^text/i.test(column.type) ? new types.Text() : undefined; | ||
schema[column.name] = { | ||
schema.columns[column.name] = { | ||
required: column.notnull === 1, | ||
@@ -565,0 +574,0 @@ type, |
@@ -62,2 +62,3 @@ /// <reference types="node" /> | ||
message: string; | ||
is_query?: boolean; | ||
ignorable?: boolean; | ||
@@ -64,0 +65,0 @@ } |
@@ -144,3 +144,3 @@ "use strict"; | ||
this._promise_schema_applied = this._promise_connection.then(async () => { | ||
var _a, _b, _c; | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
try { | ||
@@ -150,4 +150,4 @@ const current = await this._adapter.getSchemas(); | ||
const modelClass = this.models[model]; | ||
const currentTable = current.tables && current.tables[modelClass.table_name]; | ||
if (!currentTable || currentTable === 'NO SCHEMA') { | ||
const current_table = current.tables && current.tables[modelClass.table_name]; | ||
if (!current_table || current_table === 'NO SCHEMA') { | ||
continue; | ||
@@ -157,8 +157,13 @@ } | ||
const property = modelClass._schema[column]; | ||
if (!currentTable[property._dbname_us]) { | ||
const current_column = current_table.columns[property._dbname_us]; | ||
if (!current_column) { | ||
if (options.verbose) { | ||
console.log(`Adding column ${property._dbname_us} to ${modelClass.table_name}`); | ||
} | ||
await this._adapter.addColumn(model, property); | ||
await this._adapter.addColumn(model, property, options.verbose); | ||
continue; | ||
} | ||
if (((_a = current_column.description) !== null && _a !== void 0 ? _a : '') !== ((_b = property.description) !== null && _b !== void 0 ? _b : '')) { | ||
await this._adapter.updateColumnDescription(model, property, options.verbose); | ||
} | ||
} | ||
@@ -168,8 +173,15 @@ } | ||
const modelClass = this.models[model]; | ||
if (!current.tables[modelClass.table_name]) { | ||
const current_table = current.tables[modelClass.table_name]; | ||
if (!current_table) { | ||
if (options.verbose) { | ||
console.log(`Creating table ${modelClass.table_name}`); | ||
} | ||
await this._adapter.createTable(model); | ||
await this._adapter.createTable(model, options.verbose); | ||
} | ||
else if (current_table !== 'NO SCHEMA' && ((_c = current_table.description) !== null && _c !== void 0 ? _c : '') !== ((_d = modelClass.description) !== null && _d !== void 0 ? _d : '')) { | ||
if (options.verbose) { | ||
console.log(`Changing table ${modelClass.table_name}'s description to '${modelClass.description}'`); | ||
} | ||
await this._adapter.updateTableDescription(model, options.verbose); | ||
} | ||
} | ||
@@ -179,7 +191,7 @@ for (const model_name in this.models) { | ||
for (const index of modelClass._indexes) { | ||
if (!((_b = (_a = current.indexes) === null || _a === void 0 ? void 0 : _a[modelClass.table_name]) === null || _b === void 0 ? void 0 : _b[(_c = index.options.name) !== null && _c !== void 0 ? _c : ''])) { | ||
if (!((_f = (_e = current.indexes) === null || _e === void 0 ? void 0 : _e[modelClass.table_name]) === null || _f === void 0 ? void 0 : _f[(_g = index.options.name) !== null && _g !== void 0 ? _g : ''])) { | ||
if (options.verbose) { | ||
console.log(`Creating index on ${modelClass.table_name} ${Object.keys(index.columns)}`); | ||
} | ||
await this._adapter.createIndex(model_name, index); | ||
await this._adapter.createIndex(model_name, index, options.verbose); | ||
} | ||
@@ -210,3 +222,3 @@ } | ||
} | ||
await this._adapter.createForeignKey(model, integrity.column, type, integrity.parent); | ||
await this._adapter.createForeignKey(model, integrity.column, type, integrity.parent, options.verbose); | ||
} | ||
@@ -236,3 +248,3 @@ } | ||
async getSchemaChanges() { | ||
var _a, _b, _c, _d; | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
this._initializeModels(); | ||
@@ -246,4 +258,4 @@ this.applyAssociations(); | ||
const modelClass = this.models[model]; | ||
const currentTable = current.tables && current.tables[modelClass.table_name]; | ||
if (!currentTable || currentTable === 'NO SCHEMA') { | ||
const current_table = current.tables && current.tables[modelClass.table_name]; | ||
if (!current_table || current_table === 'NO SCHEMA') { | ||
continue; | ||
@@ -253,11 +265,16 @@ } | ||
const property = modelClass._schema[column]; | ||
if (!currentTable[property._dbname_us]) { | ||
const current_column = current_table.columns[property._dbname_us]; | ||
if (!current_column) { | ||
changes.push({ message: `Add column ${property._dbname_us} to ${modelClass.table_name}` }); | ||
const query = this._adapter.getAddColumnQuery(model, property); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
continue; | ||
} | ||
if (column !== 'id') { | ||
if (property.required && !currentTable[property._dbname_us].required) { | ||
if (property.required && !current_column.required) { | ||
changes.push({ message: `Change ${modelClass.table_name}.${property._dbname_us} to required`, ignorable: true }); | ||
} | ||
else if (!property.required && currentTable[property._dbname_us].required) { | ||
else if (!property.required && current_column.required) { | ||
changes.push({ message: `Change ${modelClass.table_name}.${column} to optional`, ignorable: true }); | ||
@@ -267,8 +284,15 @@ } | ||
const expected_type = this._adapter.getAdapterTypeString(property); | ||
const real_type = currentTable[property._dbname_us].adapter_type_string; | ||
const real_type = current_column.adapter_type_string; | ||
if (expected_type !== real_type) { | ||
changes.push({ message: `Type different ${modelClass.table_name}.${column}: expected=${expected_type}, real=${real_type}`, ignorable: true }); | ||
} | ||
if (((_a = current_column.description) !== null && _a !== void 0 ? _a : '') !== ((_b = property.description) !== null && _b !== void 0 ? _b : '')) { | ||
changes.push({ message: `Change ${modelClass.table_name}.${column}'s description to '${property.description}'` }); | ||
const query = this._adapter.getUpdateColumnDescriptionQuery(model, property); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
} | ||
} | ||
for (const column in currentTable) { | ||
for (const column in current_table.columns) { | ||
if (!lodash_1.default.find(modelClass._schema, { _dbname_us: column })) { | ||
@@ -281,5 +305,17 @@ changes.push({ message: `Remove column ${column} from ${modelClass.table_name}`, ignorable: true }); | ||
const modelClass = this.models[model]; | ||
if (!current.tables[modelClass.table_name]) { | ||
const current_table = current.tables[modelClass.table_name]; | ||
if (!current_table) { | ||
changes.push({ message: `Add table ${modelClass.table_name}` }); | ||
const query = this._adapter.getCreateTableQuery(model); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
} | ||
else if (current_table !== 'NO SCHEMA' && ((_c = current_table.description) !== null && _c !== void 0 ? _c : '') !== ((_d = modelClass.description) !== null && _d !== void 0 ? _d : '')) { | ||
changes.push({ message: `Change table ${modelClass.table_name}'s description to '${modelClass.description}'` }); | ||
const query = this._adapter.getUpdateTableDescriptionQuery(model); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
} | ||
} | ||
@@ -294,7 +330,11 @@ for (const table_name in current.tables) { | ||
for (const index of modelClass._indexes) { | ||
if (!((_b = (_a = current.indexes) === null || _a === void 0 ? void 0 : _a[modelClass.table_name]) === null || _b === void 0 ? void 0 : _b[(_c = index.options.name) !== null && _c !== void 0 ? _c : ''])) { | ||
if (!((_f = (_e = current.indexes) === null || _e === void 0 ? void 0 : _e[modelClass.table_name]) === null || _f === void 0 ? void 0 : _f[(_g = index.options.name) !== null && _g !== void 0 ? _g : ''])) { | ||
changes.push({ message: `Add index on ${modelClass.table_name} ${Object.keys(index.columns)}` }); | ||
const query = this._adapter.getCreateIndexQuery(model_name, index); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
} | ||
} | ||
for (const index in (_d = current.indexes) === null || _d === void 0 ? void 0 : _d[modelClass.table_name]) { | ||
for (const index in (_h = current.indexes) === null || _h === void 0 ? void 0 : _h[modelClass.table_name]) { | ||
// MySQL add index for foreign key, so does not need to remove if the index is defined in integrities | ||
@@ -326,2 +366,6 @@ if (!lodash_1.default.find(modelClass._indexes, (item) => item.options.name === index) && !lodash_1.default.find(modelClass._integrities, (item) => item.column === index)) { | ||
changes.push({ message: `Add foreign key ${table_name}.${integrity.column} to ${parent_table_name}` }); | ||
const query = this._adapter.getCreateForeignKeyQuery(model, integrity.column, type, integrity.parent); | ||
if (query) { | ||
changes.push({ message: ` (${query})`, is_query: true, ignorable: true }); | ||
} | ||
} | ||
@@ -724,7 +768,12 @@ } | ||
async _manipulateDeleteAllModels() { | ||
for (const model of Object.keys(this.models)) { | ||
if (model === '_Archive') { | ||
const model_list = Object.keys(this.models).filter((key) => key !== '_Archive'); | ||
try { | ||
await this.adapter.deleteAllIgnoringConstraint(model_list); | ||
} | ||
catch (error) { | ||
if (error.message === 'not implemented') { | ||
await Promise.all(model_list.map((model) => this.models[model].where().delete({ skip_log: true }))); | ||
return; | ||
} | ||
await this.models[model].where().delete({ skip_log: true }); | ||
throw error; | ||
} | ||
@@ -731,0 +780,0 @@ } |
{ | ||
"name": "cormo", | ||
"description": "ORM framework for Node.js", | ||
"version": "0.15.0", | ||
"version": "0.16.0", | ||
"keywords": [ | ||
@@ -42,13 +42,13 @@ "orm", | ||
"toposort-class": "^1.0.1", | ||
"yargs": "^16.0.3" | ||
"yargs": "^16.1.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.2.13", | ||
"@types/chai": "^4.2.14", | ||
"@types/inflected": "^1.1.29", | ||
"@types/lodash": "^4.14.162", | ||
"@types/mocha": "^8.0.3", | ||
"@types/mongodb": "^3.5.27", | ||
"@types/node": "^14.11.8", | ||
"@types/lodash": "^4.14.165", | ||
"@types/mocha": "^8.0.4", | ||
"@types/mongodb": "^3.5.33", | ||
"@types/node": "^14.14.7", | ||
"@types/sinon": "^9.0.8", | ||
"@types/yargs": "^15.0.8", | ||
"@types/yargs": "^15.0.9", | ||
"benchmark": "^2.1.4", | ||
@@ -59,16 +59,16 @@ "chai": "^4.2.0", | ||
"microtime": "^3.0.0", | ||
"mocha": "^8.1.3", | ||
"mongodb": "^3.5.9", | ||
"mocha": "^8.2.1", | ||
"mongodb": "^3.6.3", | ||
"mysql": "^2.18.1", | ||
"mysql2": "^2.2.5", | ||
"pg": "^8.4.1", | ||
"pg-query-stream": "^3.3.1", | ||
"pg": "^8.5.0", | ||
"pg-query-stream": "^3.4.1", | ||
"redis": "^3.0.2", | ||
"rimraf": "^3.0.2", | ||
"sinon": "^9.2.0", | ||
"sinon": "^9.2.1", | ||
"sqlite3": "^5.0.0", | ||
"ts-node": "^9.0.0", | ||
"typescript": "^4.0.3" | ||
"typescript": "^4.0.5" | ||
}, | ||
"gitHead": "44f9f0259a6355b0e7be6905723aeb159b53ed05" | ||
"gitHead": "da4645763552473f38101c3ab07db01a9aefb64f" | ||
} |
[![npm version](https://badge.fury.io/js/cormo.svg)](http://badge.fury.io/js/cormo) | ||
[![Build Status](https://travis-ci.org/croquiscom/cormo.svg?branch=master)](https://travis-ci.org/croquiscom/cormo) | ||
![test](https://github.com/croquiscom/cormo/workflows/test/badge.svg) | ||
@@ -4,0 +4,0 @@ # About |
341735
9353
Updatedyargs@^16.1.0