mythix-orm-sql-base 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -720,6 +720,56 @@ class SQLConnectionBase extends ConnectionBase {
|
|
|
720
720
|
let count = await this.count(queryEngine, null, options);
|
|
721
721
|
return (count > 0);
|
|
722
722
|
}
|
|
723
|
+
|
|
724
|
+
// Alter operations
|
|
725
|
+
|
|
726
|
+
async alterTable(Model, newModelAttributes, options) {
|
|
727
|
+
let queryGenerator = this.getQueryGenerator();
|
|
728
|
+
let sqlStatements = queryGenerator.generateAlterTableStatement(Model, newModelAttributes, options);
|
|
729
|
+
|
|
730
|
+
for (let i = 0, il = sqlStatements.length; i < il; i++) {
|
|
731
|
+
let sqlStr = sqlStatements[i];
|
|
732
|
+
await this.query(sqlStr, options);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
async dropColumn(Field, options) {
|
|
737
|
+
let queryGenerator = this.getQueryGenerator();
|
|
738
|
+
let sqlStr = queryGenerator.generateDropColumnStatement(Field, options);
|
|
739
|
+
if (sqlStr)
|
|
740
|
+
await this.query(sqlStr, options);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
async alterColumn(Field, newFieldAttributes, options) {
|
|
744
|
+
let queryGenerator = this.getQueryGenerator();
|
|
745
|
+
let sqlStatements = queryGenerator.generateAlterColumnStatement(Field, newFieldAttributes, options);
|
|
746
|
+
|
|
747
|
+
for (let i = 0, il = sqlStatements.length; i < il; i++) {
|
|
748
|
+
let sqlStr = sqlStatements[i];
|
|
749
|
+
await this.query(sqlStr, options);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
async addColumn(Field, options) {
|
|
754
|
+
let queryGenerator = this.getQueryGenerator();
|
|
755
|
+
let sqlStr = queryGenerator.generateAddColumnStatement(Field, options);
|
|
756
|
+
if (sqlStr)
|
|
757
|
+
await this.query(sqlStr, options);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
async addIndex(Model, indexFieldNames, options) {
|
|
761
|
+
let queryGenerator = this.getQueryGenerator();
|
|
762
|
+
let sqlStr = queryGenerator.generateCreateIndexStatement(Model, indexFieldNames, options);
|
|
763
|
+
if (sqlStr)
|
|
764
|
+
await this.query(sqlStr, options);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
async dropIndex(Model, indexFieldNames, options) {
|
|
768
|
+
let queryGenerator = this.getQueryGenerator();
|
|
769
|
+
let sqlStr = queryGenerator.generateDropIndexStatement(Model, indexFieldNames, options);
|
|
770
|
+
if (sqlStr)
|
|
771
|
+
await this.query(sqlStr, options);
|
|
772
|
+
}
|
|
723
773
|
}
|
|
724
774
|
|
|
725
775
|
module.exports = SQLConnectionBase;
|
|
@@ -93,15 +93,13 @@ declare class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
93
93
|
|
|
94
94
|
public generateIndexName(
|
|
95
95
|
Model: ModelClass,
|
|
96
|
-
|
|
97
|
-
index: string | true,
|
|
96
|
+
indexFieldNames: Array<string>,
|
|
98
97
|
options?: GenericObject
|
|
99
98
|
): string;
|
|
100
99
|
|
|
101
100
|
public generateColumnIndexes(
|
|
102
101
|
Model: ModelClass,
|
|
103
102
|
field: Field,
|
|
104
|
-
indexes: string | boolean | Array<string | boolean | Array<string>>,
|
|
105
103
|
options?: GenericObject,
|
|
106
104
|
): Array<string>;
|
|
107
105
|
|
|
@@ -162,6 +160,16 @@ declare class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
162
160
|
|
|
163
161
|
public generateDeleteStatement(Model: ModelClass, queryEngine: QueryEngine, options?: GenericObject): string;
|
|
164
162
|
public generateTruncateTableStatement(Model: ModelClass, options?: GenericObject): string;
|
|
163
|
+
public generateAlterTableStatement(Model: ModelClass, newModelAttributes, options?: GenericObject): string;
|
|
164
|
+
public generateDropColumnStatement(field: Field, options?: GenericObject): string;
|
|
165
|
+
public generateAlterColumnRenameStatement(field: Field, newField: Field, options?: GenericObject): string;
|
|
166
|
+
public generateAlterColumnSetOrDropNullConstraintStatement(field: Field, newField: Field, options?: GenericObject): string;
|
|
167
|
+
public generateAlterColumnSetDefaultStatement(field: Field, newField: Field, newDefaultValue: any, options?: GenericObject): string;
|
|
168
|
+
public generateAlterColumnChangeTypeStatement(field: Field, newField: Field, newFieldType: string, options?: GenericObject): string;
|
|
169
|
+
public generateAlterColumnChangePrimaryKeyConstraintStatement(field: Field, newField: Field, options?: GenericObject): string;
|
|
170
|
+
public generateAlterColumnChangeUniqueConstraintStatement(field: Field, newField: Field, options?: GenericObject): string;
|
|
171
|
+
public generateAlterColumnStatements(field: Field, newFieldAttributes: GenericObject, options?: GenericObject): Array<string>;
|
|
172
|
+
public generateAddColumnStatement(field: Field, options?: GenericObject): string;
|
|
165
173
|
|
|
166
174
|
public _collectRemoteReturningFields(Model: ModelClass): Array<string>;
|
|
167
175
|
public _collectReturningFields(
|
|
@@ -7,6 +7,7 @@ const {
|
|
|
7
7
|
Utils,
|
|
8
8
|
Literals,
|
|
9
9
|
Model: ModelBase,
|
|
10
|
+
Field,
|
|
10
11
|
QueryGeneratorBase,
|
|
11
12
|
} = require('mythix-orm');
|
|
12
13
|
|
|
@@ -664,31 +665,36 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
664
665
|
}
|
|
665
666
|
|
|
666
667
|
// eslint-disable-next-line no-unused-vars
|
|
667
|
-
generateIndexName(Model,
|
|
668
|
-
|
|
669
|
-
return '';
|
|
668
|
+
generateIndexName(Model, _indexFieldNames, options) {
|
|
669
|
+
let indexFieldNames = Nife.toArray(_indexFieldNames).filter((index) => {
|
|
670
|
+
return (Nife.instanceOf(index, 'string') && Nife.isNotEmpty(index));
|
|
671
|
+
});
|
|
670
672
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
return this.escapeID(`idx_${tableName}_${field.columnName}`.replace(/\W+/g, '_'));
|
|
673
|
+
if (indexFieldNames.length === 0)
|
|
674
|
+
return '';
|
|
674
675
|
|
|
675
|
-
let
|
|
676
|
-
|
|
677
|
-
let
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
throw new Error(`${this.constructor.name}::generateIndexName: Unable to find field named "${indexFieldName}".`);
|
|
676
|
+
let tableName = Model.getTableName(this.connection);
|
|
677
|
+
let columnNames = indexFieldNames.map((fieldName) => {
|
|
678
|
+
let field = Model.getField(fieldName);
|
|
679
|
+
if (!field)
|
|
680
|
+
throw new Error(`${this.constructor.name}::generateIndexName: Unable to find field named "${fieldName}".`);
|
|
681
681
|
|
|
682
|
-
|
|
683
|
-
}
|
|
682
|
+
return field.columnName;
|
|
683
|
+
});
|
|
684
684
|
|
|
685
|
-
return this.escapeID(`idx_${tableName}_${
|
|
685
|
+
return this.escapeID(`idx_${tableName}_${columnNames.sort().join('_')}`);
|
|
686
686
|
}
|
|
687
687
|
|
|
688
|
-
|
|
689
|
-
let
|
|
690
|
-
|
|
691
|
-
|
|
688
|
+
generateCreateIndexStatement(Model, _indexFieldNames, _options) {
|
|
689
|
+
let indexFieldNames = Nife.toArray(_indexFieldNames).filter((fieldName) => {
|
|
690
|
+
if (Nife.isEmpty(fieldName))
|
|
691
|
+
return false;
|
|
692
|
+
|
|
693
|
+
return Nife.instanceOf(fieldName, 'string');
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
if (Nife.isEmpty(indexFieldNames))
|
|
697
|
+
return '';
|
|
692
698
|
|
|
693
699
|
let options = _options || {};
|
|
694
700
|
let escapedTableName = this.getEscapedTableName(Model, options);
|
|
@@ -702,20 +708,69 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
702
708
|
|
|
703
709
|
flags = flags.join(' ');
|
|
704
710
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
711
|
+
let indexName = this.generateIndexName(Model, indexFieldNames, options);
|
|
712
|
+
let escapedColumnNames = indexFieldNames.map((fieldName) => {
|
|
713
|
+
let thisField = Model.getField(fieldName);
|
|
714
|
+
if (!thisField)
|
|
715
|
+
throw new Error(`${this.constructor.name}::generateCreateIndexStatement: Unable to find field named "${fieldName}".`);
|
|
709
716
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (!thisField)
|
|
713
|
-
throw new Error(`${this.constructor.name}::generateColumnIndexes: Unable to find field named "${fieldName}".`);
|
|
717
|
+
return this.getEscapedColumnName(Model, thisField, { ...options, columnNameOnly: true });
|
|
718
|
+
});
|
|
714
719
|
|
|
715
|
-
|
|
716
|
-
|
|
720
|
+
return `CREATE INDEX${(flags) ? ` ${flags}` : ''} ${indexName} ON ${escapedTableName} (${escapedColumnNames.join(',')})`;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
generateDropIndexStatement(Model, _indexFieldNames, _options) {
|
|
724
|
+
let indexFieldNames = Nife.toArray(_indexFieldNames).filter((fieldName) => {
|
|
725
|
+
if (Nife.isEmpty(fieldName))
|
|
726
|
+
return false;
|
|
717
727
|
|
|
718
|
-
return
|
|
728
|
+
return Nife.instanceOf(fieldName, 'string');
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
if (Nife.isEmpty(indexFieldNames))
|
|
732
|
+
return '';
|
|
733
|
+
|
|
734
|
+
let options = _options || {};
|
|
735
|
+
let flags = [];
|
|
736
|
+
let postFlags = [];
|
|
737
|
+
|
|
738
|
+
if (options.concurrently)
|
|
739
|
+
flags.push('CONCURRENTLY');
|
|
740
|
+
|
|
741
|
+
if (options.ifExists)
|
|
742
|
+
flags.push('IF EXISTS');
|
|
743
|
+
|
|
744
|
+
if (options.cascade !== false)
|
|
745
|
+
postFlags.push('CASCADE');
|
|
746
|
+
else
|
|
747
|
+
postFlags.push('RESTRICT');
|
|
748
|
+
|
|
749
|
+
flags = flags.join(' ');
|
|
750
|
+
postFlags = postFlags.join(' ');
|
|
751
|
+
|
|
752
|
+
let indexName = this.generateIndexName(Model, indexFieldNames, options);
|
|
753
|
+
return `DROP INDEX${(flags) ? ` ${flags}` : ''} ${indexName}${(postFlags) ? ` ${postFlags}` : ''}`;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
generateColumnIndexes(Model, field, _options) {
|
|
757
|
+
let indexes = Nife.toArray(field.index).filter((index) => {
|
|
758
|
+
if (index === true)
|
|
759
|
+
return true;
|
|
760
|
+
|
|
761
|
+
return (Nife.instanceOf(index, 'string', 'array') && Nife.isNotEmpty(index));
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
if (indexes.length === 0)
|
|
765
|
+
return [];
|
|
766
|
+
|
|
767
|
+
let options = _options || {};
|
|
768
|
+
return indexes.map((indexNames) => {
|
|
769
|
+
let fieldIndexNames = [ field.fieldName ];
|
|
770
|
+
if (indexNames !== true)
|
|
771
|
+
fieldIndexNames = fieldIndexNames.concat(indexNames);
|
|
772
|
+
|
|
773
|
+
return this.generateCreateIndexStatement(Model, fieldIndexNames, options);
|
|
719
774
|
});
|
|
720
775
|
}
|
|
721
776
|
|
|
@@ -729,7 +784,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
729
784
|
|
|
730
785
|
flags = flags.join(' ');
|
|
731
786
|
|
|
732
|
-
return `DROP TABLE ${flags} ${escapedTableName}${(options.cascade
|
|
787
|
+
return `DROP TABLE ${flags} ${escapedTableName}${(options.cascade !== false) ? ' CASCADE' : ''}`;
|
|
733
788
|
}
|
|
734
789
|
|
|
735
790
|
generateForeignKeyConstraint(field, type, options) {
|
|
@@ -799,58 +854,57 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
799
854
|
if (!field.index)
|
|
800
855
|
return;
|
|
801
856
|
|
|
802
|
-
let
|
|
803
|
-
|
|
804
|
-
for (let i = 0, il = indexes.length; i < il; i++) {
|
|
805
|
-
let index = indexes[i];
|
|
806
|
-
let result = this.generateColumnIndexes(Model, field, index, options);
|
|
807
|
-
if (Nife.isNotEmpty(result))
|
|
808
|
-
fieldParts.push(result.join('\n\n'));
|
|
809
|
-
}
|
|
857
|
+
let result = this.generateColumnIndexes(Model, field, { ...options, ifNotExists: true });
|
|
858
|
+
fieldParts = fieldParts.concat(result);
|
|
810
859
|
});
|
|
811
860
|
|
|
812
|
-
return fieldParts;
|
|
861
|
+
return Nife.uniq(fieldParts);
|
|
813
862
|
}
|
|
814
863
|
|
|
815
|
-
|
|
816
|
-
let options
|
|
817
|
-
let
|
|
818
|
-
|
|
819
|
-
Model.iterateFields(({ field, fieldName }) => {
|
|
820
|
-
if (field.type.isVirtual())
|
|
821
|
-
return;
|
|
864
|
+
generateColumnDeclarationStatement(Model, field, _options) {
|
|
865
|
+
let options = _options || {};
|
|
866
|
+
let constraintParts = [];
|
|
867
|
+
let defaultValue = this.getFieldDefaultValue(field, field.fieldName, { remoteOnly: true });
|
|
822
868
|
|
|
823
|
-
|
|
824
|
-
|
|
869
|
+
if (field.primaryKey) {
|
|
870
|
+
if (LiteralBase.isLiteral(field.primaryKey))
|
|
871
|
+
constraintParts.push(field.primaryKey.toString(this.connection));
|
|
872
|
+
else
|
|
873
|
+
constraintParts.push('PRIMARY KEY');
|
|
825
874
|
|
|
826
|
-
if (
|
|
827
|
-
|
|
828
|
-
|
|
875
|
+
if (defaultValue !== 'AUTOINCREMENT')
|
|
876
|
+
constraintParts.push('NOT NULL');
|
|
877
|
+
} else {
|
|
878
|
+
if (field.unique) {
|
|
879
|
+
if (LiteralBase.isLiteral(field.unique))
|
|
880
|
+
constraintParts.push(field.unique.toString(this.connection));
|
|
829
881
|
else
|
|
830
|
-
constraintParts.push('
|
|
882
|
+
constraintParts.push('UNIQUE');
|
|
883
|
+
}
|
|
831
884
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
if (field.unique) {
|
|
836
|
-
if (LiteralBase.isLiteral(field.unique))
|
|
837
|
-
constraintParts.push(field.unique.toString(this.connection));
|
|
838
|
-
else
|
|
839
|
-
constraintParts.push('UNIQUE');
|
|
840
|
-
}
|
|
885
|
+
if (field.allowNull === false)
|
|
886
|
+
constraintParts.push('NOT NULL');
|
|
887
|
+
}
|
|
841
888
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
}
|
|
889
|
+
if (defaultValue != null && defaultValue !== '' && !(defaultValue === 'AUTOINCREMENT' && options.noAutoIncrementDefault === true))
|
|
890
|
+
constraintParts.push(defaultValue);
|
|
845
891
|
|
|
846
|
-
|
|
847
|
-
|
|
892
|
+
constraintParts = constraintParts.join(' ');
|
|
893
|
+
if (Nife.isNotEmpty(constraintParts))
|
|
894
|
+
constraintParts = ` ${constraintParts}`;
|
|
848
895
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
896
|
+
return `${this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true })} ${field.type.toConnectionType(this.connection, { ...options, createTable: true, defaultValue })}${constraintParts}`;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
generateCreateTableStatement(Model, _options) {
|
|
900
|
+
let options = _options || {};
|
|
901
|
+
let fieldParts = [];
|
|
902
|
+
|
|
903
|
+
Model.iterateFields(({ field }) => {
|
|
904
|
+
if (field.type.isVirtual())
|
|
905
|
+
return;
|
|
852
906
|
|
|
853
|
-
fieldParts.push(` ${this.
|
|
907
|
+
fieldParts.push(` ${this.generateColumnDeclarationStatement(Model, field, options)}`);
|
|
854
908
|
});
|
|
855
909
|
|
|
856
910
|
let ifNotExists = '';
|
|
@@ -861,7 +915,7 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
861
915
|
if (Nife.isNotEmpty(trailingParts))
|
|
862
916
|
fieldParts = fieldParts.concat(trailingParts.map((part) => ` ${part.trim()}`));
|
|
863
917
|
|
|
864
|
-
let finalStatement = `CREATE TABLE ${ifNotExists}${this.getEscapedTableName(Model)} (${fieldParts.join(',\n')}\n)
|
|
918
|
+
let finalStatement = `CREATE TABLE ${ifNotExists}${this.getEscapedTableName(Model)} (\n${fieldParts.join(',\n')}\n)`;
|
|
865
919
|
return finalStatement;
|
|
866
920
|
}
|
|
867
921
|
|
|
@@ -1192,6 +1246,194 @@ class SQLQueryGeneratorBase extends QueryGeneratorBase {
|
|
|
1192
1246
|
return `TRUNCATE TABLE ${escapedTableName}`;
|
|
1193
1247
|
}
|
|
1194
1248
|
|
|
1249
|
+
generateAlterTableStatement(Model, newModelAttributes, options) {
|
|
1250
|
+
if (Nife.isEmpty(newModelAttributes))
|
|
1251
|
+
return [];
|
|
1252
|
+
|
|
1253
|
+
let statements = [];
|
|
1254
|
+
|
|
1255
|
+
if (Nife.isNotEmpty(newModelAttributes.tableName)) {
|
|
1256
|
+
let currentTableName = Model.getTableName();
|
|
1257
|
+
if (currentTableName !== newModelAttributes.tableName)
|
|
1258
|
+
statements.push(`ALTER TABLE ${this.getEscapedTableName(Model, options)} RENAME TO ${this.escapeID(newModelAttributes.tableName)}`);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
return statements;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
generateDropColumnStatement(field, _options) {
|
|
1265
|
+
let Model = field.Model;
|
|
1266
|
+
let options = _options || {};
|
|
1267
|
+
|
|
1268
|
+
return `ALTER TABLE ${this.getEscapedTableName(Model, options)} DROP COLUMN${(options.ifExists) ? ' IF EXISTS' : ''} ${this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true })} ${(options.cascade !== false) ? 'CASCADE' : 'RESTRICT'}`;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
generateAlterColumnRenameStatement(field, newField, _options) {
|
|
1272
|
+
let Model = field.Model;
|
|
1273
|
+
let options = _options || {};
|
|
1274
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1275
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1276
|
+
|
|
1277
|
+
return `${prefix} RENAME COLUMN ${escapedColumnName} TO ${this.escapeID(newField.columnName)}`;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
generateAlterColumnSetOrDropNullConstraintStatement(field, newField, _options) {
|
|
1281
|
+
let Model = field.Model;
|
|
1282
|
+
let options = _options || {};
|
|
1283
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1284
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1285
|
+
|
|
1286
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} ${(newField.allowNull) ? 'DROP' : 'SET'} NOT NULL`;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
generateAlterColumnSetDefaultStatement(field, newField, newDefaultValue, _options) {
|
|
1290
|
+
let Model = field.Model;
|
|
1291
|
+
let options = _options || {};
|
|
1292
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1293
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1294
|
+
|
|
1295
|
+
if (newDefaultValue === undefined)
|
|
1296
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} DROP DEFAULT`;
|
|
1297
|
+
else
|
|
1298
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} SET DEFAULT ${newDefaultValue}`;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
generateAlterColumnChangeTypeStatement(field, newField, newFieldType, _options) {
|
|
1302
|
+
let Model = field.Model;
|
|
1303
|
+
let options = _options || {};
|
|
1304
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1305
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1306
|
+
|
|
1307
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} SET DATA TYPE ${newFieldType}`;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
generateAlterColumnChangePrimaryKeyConstraintStatement(field, newField, _options) {
|
|
1311
|
+
let Model = field.Model;
|
|
1312
|
+
let options = _options || {};
|
|
1313
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1314
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1315
|
+
|
|
1316
|
+
if (newField.primaryKey)
|
|
1317
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} ADD CONSTRAINT PRIMARY KEY`;
|
|
1318
|
+
else
|
|
1319
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} DROP CONSTRAINT PRIMARY KEY`;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
generateAlterColumnChangeUniqueConstraintStatement(field, newField, _options) {
|
|
1323
|
+
let Model = field.Model;
|
|
1324
|
+
let options = _options || {};
|
|
1325
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1326
|
+
let escapedColumnName = this.getEscapedColumnName(Model, field, { ...options, columnNameOnly: true });
|
|
1327
|
+
|
|
1328
|
+
if (newField.unique)
|
|
1329
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} ADD CONSTRAINT UNIQUE`;
|
|
1330
|
+
else
|
|
1331
|
+
return `${prefix} ALTER COLUMN ${escapedColumnName} DROP CONSTRAINT UNIQUE`;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
generateAlterColumnStatements(field, _newFieldAttributes, _options) {
|
|
1335
|
+
if (Nife.isEmpty(_newFieldAttributes))
|
|
1336
|
+
return [];
|
|
1337
|
+
|
|
1338
|
+
const generateIndexFieldNames = (field) => {
|
|
1339
|
+
let indexes = Nife.toArray(field.index).filter((index) => {
|
|
1340
|
+
if (index === true)
|
|
1341
|
+
return true;
|
|
1342
|
+
|
|
1343
|
+
return (Nife.instanceOf(index, 'string', 'array') && Nife.isNotEmpty(index));
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
if (indexes.length === 0)
|
|
1347
|
+
return {};
|
|
1348
|
+
|
|
1349
|
+
let indexMap = {};
|
|
1350
|
+
|
|
1351
|
+
for (let i = 0, il = indexes.length; i < il; i++) {
|
|
1352
|
+
let indexFieldName = indexes[i];
|
|
1353
|
+
let fieldNames = [ field.fieldName ];
|
|
1354
|
+
|
|
1355
|
+
if (indexFieldName !== true)
|
|
1356
|
+
fieldNames = fieldNames.concat(indexFieldName);
|
|
1357
|
+
|
|
1358
|
+
let indexName = this.generateIndexName(Model, fieldNames, options);
|
|
1359
|
+
indexMap[indexName] = fieldNames;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
return indexMap;
|
|
1363
|
+
};
|
|
1364
|
+
|
|
1365
|
+
const calculateIndexDifferences = () => {
|
|
1366
|
+
let currentColumnIndexes = generateIndexFieldNames(field);
|
|
1367
|
+
let currentIndexNames = Object.keys(currentColumnIndexes);
|
|
1368
|
+
let newColumnIndexes = generateIndexFieldNames(newField);
|
|
1369
|
+
let newIndexNames = Object.keys(newColumnIndexes);
|
|
1370
|
+
|
|
1371
|
+
let dropIndexes = Nife.arraySubtract(currentIndexNames, newIndexNames);
|
|
1372
|
+
let addIndexes = Nife.arraySubtract(newIndexNames, currentIndexNames);
|
|
1373
|
+
|
|
1374
|
+
if (addIndexes.length) {
|
|
1375
|
+
for (let i = 0, il = addIndexes.length; i < il; i++) {
|
|
1376
|
+
let indexName = addIndexes[i];
|
|
1377
|
+
let indexFieldNames = newColumnIndexes[indexName];
|
|
1378
|
+
|
|
1379
|
+
statements.push(this.generateCreateIndexStatement(Model, indexFieldNames, options));
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
if (dropIndexes.length) {
|
|
1384
|
+
for (let i = 0, il = dropIndexes.length; i < il; i++) {
|
|
1385
|
+
let indexName = dropIndexes[i];
|
|
1386
|
+
let indexFieldNames = currentColumnIndexes[indexName];
|
|
1387
|
+
|
|
1388
|
+
statements.push(this.generateDropIndexStatement(Model, indexFieldNames, options));
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
};
|
|
1392
|
+
|
|
1393
|
+
let newField = (Field.isField(_newFieldAttributes)) ? _newFieldAttributes : new Field({ ...field, ..._newFieldAttributes });
|
|
1394
|
+
newField.setModel(field.Model);
|
|
1395
|
+
|
|
1396
|
+
let Model = field.Model;
|
|
1397
|
+
let options = _options || {};
|
|
1398
|
+
let statements = [];
|
|
1399
|
+
|
|
1400
|
+
if (newField.allowNull !== field.allowNull)
|
|
1401
|
+
statements.push(this.generateAlterColumnSetOrDropNullConstraintStatement(field, newField, options));
|
|
1402
|
+
|
|
1403
|
+
let currentDefaultValue = this.getFieldDefaultValue(field, field.fieldName, { useDefaultKeyword: false, escape: true, remoteOnly: true });
|
|
1404
|
+
let newDefaultValue = this.getFieldDefaultValue(newField, newField.fieldName, { useDefaultKeyword: false, escape: true, remoteOnly: true });
|
|
1405
|
+
|
|
1406
|
+
let currentFieldType = field.type.toConnectionType(this.connection, { createTable: true, defaultValue: currentDefaultValue });
|
|
1407
|
+
let newFieldType = field.type.toConnectionType(this.connection, { createTable: true, defaultValue: newDefaultValue });
|
|
1408
|
+
if (newFieldType !== currentFieldType)
|
|
1409
|
+
statements.push(this.generateAlterColumnChangeTypeStatement(field, newField, newFieldType, _options));
|
|
1410
|
+
|
|
1411
|
+
if (newDefaultValue !== currentDefaultValue)
|
|
1412
|
+
statements.push(this.generateAlterColumnSetDefaultStatement(field, newField, newDefaultValue, options));
|
|
1413
|
+
|
|
1414
|
+
if (newField.primaryKey !== field.primaryKey)
|
|
1415
|
+
statements.push(this.generateAlterColumnChangePrimaryKeyConstraintStatement(field, newField, options));
|
|
1416
|
+
|
|
1417
|
+
if (newField.unique !== field.unique)
|
|
1418
|
+
statements.push(this.generateAlterColumnChangeUniqueConstraintStatement(field, newField, options));
|
|
1419
|
+
|
|
1420
|
+
if (field.index !== newField.index)
|
|
1421
|
+
calculateIndexDifferences();
|
|
1422
|
+
|
|
1423
|
+
if (newField.columnName !== field.columnName)
|
|
1424
|
+
statements.push(this.generateAlterColumnRenameStatement(field, newField, options));
|
|
1425
|
+
|
|
1426
|
+
return statements.filter(Boolean);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
generateAddColumnStatement(field, _options) {
|
|
1430
|
+
let Model = field.Model;
|
|
1431
|
+
let options = _options || {};
|
|
1432
|
+
let prefix = `ALTER TABLE ${this.getEscapedTableName(Model, options)}`;
|
|
1433
|
+
|
|
1434
|
+
return `${prefix} ADD COLUMN ${this.generateColumnDeclarationStatement(Model, field, options)}`;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1195
1437
|
toConnectionString(queryEngine, options) {
|
|
1196
1438
|
return this.generateSelectStatement(queryEngine, options);
|
|
1197
1439
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mythix-orm-sql-base",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "SQL base support for Mythix ORM",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -33,9 +33,10 @@
|
|
|
33
33
|
},
|
|
34
34
|
"homepage": "https://github.com/th317erd/mythix-orm-sql-base#readme",
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"mythix-orm": "^1.
|
|
36
|
+
"mythix-orm": "^1.7.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"luxon": "^3.0.4",
|
|
39
40
|
"nife": "^1.12.1",
|
|
40
41
|
"uuid": "^9.0.0"
|
|
41
42
|
},
|
|
@@ -44,7 +45,6 @@
|
|
|
44
45
|
"better-sqlite3": "^7.6.2",
|
|
45
46
|
"eslint": "^8.23.1",
|
|
46
47
|
"jasmine": "^4.4.0",
|
|
47
|
-
"moment": "^2.29.4",
|
|
48
48
|
"nyc": "^15.1.0"
|
|
49
49
|
},
|
|
50
50
|
"nyc": {
|