mysqlsyncr 1.1.4 → 1.1.6
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.
- package/dist/index.cjs +222 -120
- package/dist/index.js +222 -120
- package/package.json +1 -1
- package/src/apply.js +115 -19
package/dist/index.cjs
CHANGED
|
@@ -137,7 +137,10 @@ function _iterableToArrayLimit(r, l) {
|
|
|
137
137
|
f = true,
|
|
138
138
|
o = false;
|
|
139
139
|
try {
|
|
140
|
-
if (i = (t = t.call(r)).next, 0 === l)
|
|
140
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
141
|
+
if (Object(t) !== t) return;
|
|
142
|
+
f = !1;
|
|
143
|
+
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
141
144
|
} catch (r) {
|
|
142
145
|
o = true, n = r;
|
|
143
146
|
} finally {
|
|
@@ -3599,7 +3602,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3599
3602
|
_iterator = _createForOfIteratorHelper(differences);
|
|
3600
3603
|
_context2.prev = 2;
|
|
3601
3604
|
_loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
|
|
3602
|
-
var diff, createDatabaseSQL, tableName, createSQL, _tableName, dropTableSQL, addFieldSQL, modifyFieldSQL, defaultClause, _modifyFieldSQL, dropFieldSQL, _tableName2, field, isTimestamp, _defaultClause,
|
|
3605
|
+
var diff, createDatabaseSQL, tableName, createSQL, _tableName, dropTableSQL, addFieldSQL, modifyFieldSQL, defaultClause, _modifyFieldSQL, dropFieldSQL, _tableName2, field, currentField, needsBatchProcessing, addColumnSQL, totalUpdated, batchSize, batchCount, updateSQL, result, rowsAffected, verifySQL, _yield$connection$que, _yield$connection$que2, verifyResult, swapColumnsSQL, isTimestamp, _defaultClause, _currentField, hasOnUpdate, _modifyFieldSQL2, existingColumns, columnNames, missingColumns, indexColumns, primaryKeySQL, uniqueSQL, addIndexSQL, dropPrimaryKeySQL, dropIndexSQL, _tableName3, index, _dropPrimaryKeySQL, _dropIndexSQL, _uniqueSQL, addPrimaryKeySQL, _addIndexSQL, dropCurrentProcSQL, createProcSQL, dropViewSQL, createViewSQL, _dropViewSQL, _createViewSQL, _dropViewSQL2, createTriggerSQL, dropTriggerSQL, _createTriggerSQL, _dropTriggerSQL, _createDatabaseSQL;
|
|
3603
3606
|
return _regeneratorRuntime().wrap(function _loop$(_context) {
|
|
3604
3607
|
while (1) switch (_context.prev = _context.next) {
|
|
3605
3608
|
case 0:
|
|
@@ -3629,7 +3632,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3629
3632
|
_context.next = 16;
|
|
3630
3633
|
return connection.query(createSQL);
|
|
3631
3634
|
case 16:
|
|
3632
|
-
_context.next =
|
|
3635
|
+
_context.next = 249;
|
|
3633
3636
|
break;
|
|
3634
3637
|
case 18:
|
|
3635
3638
|
if (!(diff.type === 'extra_table')) {
|
|
@@ -3643,7 +3646,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3643
3646
|
_context.next = 25;
|
|
3644
3647
|
return connection.query(dropTableSQL);
|
|
3645
3648
|
case 25:
|
|
3646
|
-
_context.next =
|
|
3649
|
+
_context.next = 249;
|
|
3647
3650
|
break;
|
|
3648
3651
|
case 27:
|
|
3649
3652
|
if (!(diff.type === 'missing_field')) {
|
|
@@ -3675,7 +3678,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3675
3678
|
_context.next = 43;
|
|
3676
3679
|
return connection.query(_modifyFieldSQL);
|
|
3677
3680
|
case 43:
|
|
3678
|
-
_context.next =
|
|
3681
|
+
_context.next = 249;
|
|
3679
3682
|
break;
|
|
3680
3683
|
case 45:
|
|
3681
3684
|
if (!(diff.type === 'extra_field')) {
|
|
@@ -3687,33 +3690,132 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3687
3690
|
_context.next = 50;
|
|
3688
3691
|
return connection.query(dropFieldSQL);
|
|
3689
3692
|
case 50:
|
|
3690
|
-
_context.next =
|
|
3693
|
+
_context.next = 249;
|
|
3691
3694
|
break;
|
|
3692
3695
|
case 52:
|
|
3693
3696
|
if (!(diff.type === 'mismatched_field')) {
|
|
3694
|
-
_context.next =
|
|
3697
|
+
_context.next = 100;
|
|
3695
3698
|
break;
|
|
3696
3699
|
}
|
|
3697
|
-
_tableName2 = diff.tableName, field = diff.field;
|
|
3700
|
+
_tableName2 = diff.tableName, field = diff.field, currentField = diff.currentField; // Helper function to determine if we need batch processing
|
|
3701
|
+
needsBatchProcessing = function needsBatchProcessing() {
|
|
3702
|
+
var currentType = currentField.Type.toLowerCase();
|
|
3703
|
+
var newType = field.Type.toLowerCase();
|
|
3704
|
+
|
|
3705
|
+
// Decimal changes
|
|
3706
|
+
if (currentType.includes('decimal') && newType.includes('decimal')) {
|
|
3707
|
+
return true;
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3710
|
+
// VARCHAR/CHAR length reductions
|
|
3711
|
+
if ((currentType.includes('varchar') || currentType.includes('char')) && (newType.includes('varchar') || newType.includes('char'))) {
|
|
3712
|
+
var _currentType$match, _newType$match;
|
|
3713
|
+
var currentLength = parseInt(((_currentType$match = currentType.match(/\((\d+)\)/)) === null || _currentType$match === undefined ? undefined : _currentType$match[1]) || '0');
|
|
3714
|
+
var newLength = parseInt(((_newType$match = newType.match(/\((\d+)\)/)) === null || _newType$match === undefined ? undefined : _newType$match[1]) || '0');
|
|
3715
|
+
return newLength < currentLength;
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
// TEXT to VARCHAR conversions
|
|
3719
|
+
if (currentType.includes('text') && newType.includes('varchar')) {
|
|
3720
|
+
return true;
|
|
3721
|
+
}
|
|
3722
|
+
|
|
3723
|
+
// Numeric type downgrades
|
|
3724
|
+
var numericDowngrades = {
|
|
3725
|
+
'bigint': ['int', 'mediumint', 'smallint', 'tinyint'],
|
|
3726
|
+
'int': ['mediumint', 'smallint', 'tinyint'],
|
|
3727
|
+
'mediumint': ['smallint', 'tinyint'],
|
|
3728
|
+
'smallint': ['tinyint'],
|
|
3729
|
+
'double': ['float', 'decimal'],
|
|
3730
|
+
'float': ['decimal']
|
|
3731
|
+
};
|
|
3732
|
+
for (var _i = 0, _Object$entries = Object.entries(numericDowngrades); _i < _Object$entries.length; _i++) {
|
|
3733
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
3734
|
+
larger = _Object$entries$_i[0],
|
|
3735
|
+
smaller = _Object$entries$_i[1];
|
|
3736
|
+
if (currentType.includes(larger) && smaller.some(function (t) {
|
|
3737
|
+
return newType.includes(t);
|
|
3738
|
+
})) {
|
|
3739
|
+
return true;
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
return false;
|
|
3743
|
+
};
|
|
3744
|
+
if (!needsBatchProcessing()) {
|
|
3745
|
+
_context.next = 90;
|
|
3746
|
+
break;
|
|
3747
|
+
}
|
|
3748
|
+
// Step 1: Add new column
|
|
3749
|
+
addColumnSQL = "ALTER TABLE `".concat(_tableName2, "` ADD COLUMN `").concat(field.Field, "_new` ").concat(field.Type, " DEFAULT NULL;");
|
|
3750
|
+
logger("Adding new column for type conversion: ".concat(addColumnSQL));
|
|
3751
|
+
_context.next = 60;
|
|
3752
|
+
return connection.query(addColumnSQL);
|
|
3753
|
+
case 60:
|
|
3754
|
+
// Step 2: Copy data in batches
|
|
3755
|
+
totalUpdated = 0;
|
|
3756
|
+
batchSize = 10000;
|
|
3757
|
+
batchCount = 0;
|
|
3758
|
+
case 63:
|
|
3759
|
+
updateSQL = "\n UPDATE `".concat(_tableName2, "` \n SET `").concat(field.Field, "_new` = `").concat(field.Field, "`\n WHERE `").concat(field.Field, "_new` IS NULL \n AND `").concat(field.Field, "` IS NOT NULL\n LIMIT ").concat(batchSize, ";\n ");
|
|
3760
|
+
_context.next = 67;
|
|
3761
|
+
return connection.query(updateSQL);
|
|
3762
|
+
case 67:
|
|
3763
|
+
result = _context.sent;
|
|
3764
|
+
rowsAffected = result.affectedRows;
|
|
3765
|
+
if (!(rowsAffected === 0)) {
|
|
3766
|
+
_context.next = 71;
|
|
3767
|
+
break;
|
|
3768
|
+
}
|
|
3769
|
+
return _context.abrupt("break", 76);
|
|
3770
|
+
case 71:
|
|
3771
|
+
totalUpdated += rowsAffected;
|
|
3772
|
+
batchCount++;
|
|
3773
|
+
logger("Batch ".concat(batchCount, ": Converted ").concat(rowsAffected, " rows. Total converted: ").concat(totalUpdated));
|
|
3774
|
+
_context.next = 63;
|
|
3775
|
+
break;
|
|
3776
|
+
case 76:
|
|
3777
|
+
// Step 3: Verify data (optional)
|
|
3778
|
+
verifySQL = "\n SELECT COUNT(*) as mismatch FROM `".concat(_tableName2, "`\n WHERE `").concat(field.Field, "` IS NOT NULL \n AND `").concat(field.Field, "_new` IS NULL;\n ");
|
|
3779
|
+
_context.next = 79;
|
|
3780
|
+
return connection.query(verifySQL);
|
|
3781
|
+
case 79:
|
|
3782
|
+
_yield$connection$que = _context.sent;
|
|
3783
|
+
_yield$connection$que2 = _slicedToArray(_yield$connection$que, 1);
|
|
3784
|
+
verifyResult = _yield$connection$que2[0];
|
|
3785
|
+
if (verifyResult.mismatch > 0) {
|
|
3786
|
+
logger("Warning: ".concat(verifyResult.mismatch, " rows may have failed conversion"));
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
// Step 4: Swap columns
|
|
3790
|
+
swapColumnsSQL = "\n ALTER TABLE `".concat(_tableName2, "`\n DROP COLUMN `").concat(field.Field, "`,\n RENAME COLUMN `").concat(field.Field, "_new` TO `").concat(field.Field, "`\n ");
|
|
3791
|
+
logger("Swapping columns: ".concat(swapColumnsSQL));
|
|
3792
|
+
_context.next = 87;
|
|
3793
|
+
return connection.query(swapColumnsSQL);
|
|
3794
|
+
case 87:
|
|
3795
|
+
logger("Completed type conversion for ".concat(field.Field, ". Total rows converted: ").concat(totalUpdated));
|
|
3796
|
+
_context.next = 98;
|
|
3797
|
+
break;
|
|
3798
|
+
case 90:
|
|
3799
|
+
// Original mismatched field handling for simple changes
|
|
3698
3800
|
isTimestamp = field.Type.toLowerCase().includes('timestamp'); // Handle timestamp specific attributes
|
|
3699
3801
|
_defaultClause = field.Default === 'CURRENT_TIMESTAMP' ? 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' : field.Default === 'NULL' ? isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL' : field.Default !== undefined && field.Default !== null ? "DEFAULT '".concat(field.Default, "'") : isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL'; // Remove ON UPDATE CURRENT_TIMESTAMP if we're changing away from CURRENT_TIMESTAMP
|
|
3700
|
-
|
|
3701
|
-
hasOnUpdate = (
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
_context.next =
|
|
3705
|
-
return connection.query(
|
|
3706
|
-
case
|
|
3707
|
-
_context.next =
|
|
3802
|
+
_currentField = diff.currentField;
|
|
3803
|
+
hasOnUpdate = (_currentField === null || _currentField === undefined ? undefined : _currentField.Default) === 'CURRENT_TIMESTAMP' && field.Default !== 'CURRENT_TIMESTAMP';
|
|
3804
|
+
_modifyFieldSQL2 = "ALTER TABLE `".concat(_tableName2, "` CHANGE `").concat(field.Field, "` `").concat(field.Field, "` ").concat(field.Type, " ").concat(field.NotNull ? 'NOT NULL' : '', " ").concat(_defaultClause).concat(hasOnUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : '', ";");
|
|
3805
|
+
console.log("Executing: ".concat(_modifyFieldSQL2));
|
|
3806
|
+
_context.next = 98;
|
|
3807
|
+
return connection.query(_modifyFieldSQL2);
|
|
3808
|
+
case 98:
|
|
3809
|
+
_context.next = 249;
|
|
3708
3810
|
break;
|
|
3709
|
-
case
|
|
3811
|
+
case 100:
|
|
3710
3812
|
if (!(diff.type === 'missing_index')) {
|
|
3711
|
-
_context.next =
|
|
3813
|
+
_context.next = 132;
|
|
3712
3814
|
break;
|
|
3713
3815
|
}
|
|
3714
|
-
_context.next =
|
|
3816
|
+
_context.next = 103;
|
|
3715
3817
|
return connection.query("SHOW COLUMNS FROM `".concat(diff.tableName, "`"));
|
|
3716
|
-
case
|
|
3818
|
+
case 103:
|
|
3717
3819
|
existingColumns = _context.sent;
|
|
3718
3820
|
columnNames = existingColumns.map(function (col) {
|
|
3719
3821
|
return col.Field;
|
|
@@ -3722,260 +3824,260 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3722
3824
|
return !columnNames.includes(col);
|
|
3723
3825
|
}) : [];
|
|
3724
3826
|
if (!(missingColumns.length > 0)) {
|
|
3725
|
-
_context.next =
|
|
3827
|
+
_context.next = 109;
|
|
3726
3828
|
break;
|
|
3727
3829
|
}
|
|
3728
3830
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". Missing columns: ").concat(missingColumns.join(', ')));
|
|
3729
3831
|
return _context.abrupt("return", 0);
|
|
3730
|
-
case
|
|
3832
|
+
case 109:
|
|
3731
3833
|
// Prepare the index columns with proper formatting
|
|
3732
3834
|
indexColumns = diff.index.ColumnName.map(function (col) {
|
|
3733
3835
|
return "`".concat(col, "`");
|
|
3734
3836
|
}); // Format column names
|
|
3735
3837
|
// Handle PRIMARY index creation
|
|
3736
3838
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3737
|
-
_context.next =
|
|
3839
|
+
_context.next = 121;
|
|
3738
3840
|
break;
|
|
3739
3841
|
}
|
|
3740
3842
|
if (!(indexColumns.length > 0)) {
|
|
3741
|
-
_context.next =
|
|
3843
|
+
_context.next = 118;
|
|
3742
3844
|
break;
|
|
3743
3845
|
}
|
|
3744
3846
|
primaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` ADD PRIMARY KEY (").concat(indexColumns.join(', '), ");");
|
|
3745
3847
|
console.log("Executing: ".concat(primaryKeySQL));
|
|
3746
|
-
_context.next =
|
|
3848
|
+
_context.next = 116;
|
|
3747
3849
|
return connection.query(primaryKeySQL);
|
|
3748
|
-
case
|
|
3749
|
-
_context.next =
|
|
3850
|
+
case 116:
|
|
3851
|
+
_context.next = 119;
|
|
3750
3852
|
break;
|
|
3751
|
-
case
|
|
3853
|
+
case 118:
|
|
3752
3854
|
logger("Cannot create PRIMARY index on ".concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3753
|
-
case
|
|
3754
|
-
_context.next =
|
|
3855
|
+
case 119:
|
|
3856
|
+
_context.next = 130;
|
|
3755
3857
|
break;
|
|
3756
|
-
case
|
|
3858
|
+
case 121:
|
|
3757
3859
|
// Create the new index with UNIQUE if applicable
|
|
3758
3860
|
uniqueSQL = diff.index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3759
3861
|
if (!(indexColumns.length > 0)) {
|
|
3760
|
-
_context.next =
|
|
3862
|
+
_context.next = 129;
|
|
3761
3863
|
break;
|
|
3762
3864
|
}
|
|
3763
3865
|
addIndexSQL = "ALTER TABLE `".concat(diff.tableName, "` ADD ").concat(uniqueSQL, "INDEX `").concat(diff.index.Name, "` (").concat(indexColumns.join(', '), ");");
|
|
3764
3866
|
console.log("Executing: ".concat(addIndexSQL));
|
|
3765
|
-
_context.next =
|
|
3867
|
+
_context.next = 127;
|
|
3766
3868
|
return connection.query(addIndexSQL);
|
|
3767
|
-
case
|
|
3768
|
-
_context.next =
|
|
3869
|
+
case 127:
|
|
3870
|
+
_context.next = 130;
|
|
3769
3871
|
break;
|
|
3770
|
-
case
|
|
3872
|
+
case 129:
|
|
3771
3873
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3772
|
-
case
|
|
3773
|
-
_context.next =
|
|
3874
|
+
case 130:
|
|
3875
|
+
_context.next = 249;
|
|
3774
3876
|
break;
|
|
3775
|
-
case
|
|
3877
|
+
case 132:
|
|
3776
3878
|
if (!(diff.type === 'extra_index')) {
|
|
3777
|
-
_context.next =
|
|
3879
|
+
_context.next = 146;
|
|
3778
3880
|
break;
|
|
3779
3881
|
}
|
|
3780
3882
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3781
|
-
_context.next =
|
|
3883
|
+
_context.next = 140;
|
|
3782
3884
|
break;
|
|
3783
3885
|
}
|
|
3784
3886
|
dropPrimaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` DROP PRIMARY KEY;");
|
|
3785
3887
|
console.log("Executing: ".concat(dropPrimaryKeySQL));
|
|
3786
|
-
_context.next =
|
|
3888
|
+
_context.next = 138;
|
|
3787
3889
|
return connection.query(dropPrimaryKeySQL);
|
|
3788
|
-
case
|
|
3789
|
-
_context.next =
|
|
3890
|
+
case 138:
|
|
3891
|
+
_context.next = 144;
|
|
3790
3892
|
break;
|
|
3791
|
-
case
|
|
3893
|
+
case 140:
|
|
3792
3894
|
dropIndexSQL = "DROP INDEX `".concat(diff.index.Name, "` ON `").concat(diff.tableName, "`;");
|
|
3793
3895
|
console.log("Executing: ".concat(dropIndexSQL));
|
|
3794
|
-
_context.next =
|
|
3896
|
+
_context.next = 144;
|
|
3795
3897
|
return connection.query(dropIndexSQL);
|
|
3796
|
-
case
|
|
3797
|
-
_context.next =
|
|
3898
|
+
case 144:
|
|
3899
|
+
_context.next = 249;
|
|
3798
3900
|
break;
|
|
3799
|
-
case
|
|
3901
|
+
case 146:
|
|
3800
3902
|
if (!(diff.type === 'mismatched_index')) {
|
|
3801
|
-
_context.next =
|
|
3903
|
+
_context.next = 174;
|
|
3802
3904
|
break;
|
|
3803
3905
|
}
|
|
3804
3906
|
_tableName3 = diff.tableName, index = diff.index; // Drop the existing index
|
|
3805
3907
|
if (!(index.Name === 'PRIMARY')) {
|
|
3806
|
-
_context.next =
|
|
3908
|
+
_context.next = 155;
|
|
3807
3909
|
break;
|
|
3808
3910
|
}
|
|
3809
3911
|
_dropPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` DROP PRIMARY KEY;");
|
|
3810
3912
|
console.log("Executing: ".concat(_dropPrimaryKeySQL));
|
|
3811
|
-
_context.next =
|
|
3913
|
+
_context.next = 153;
|
|
3812
3914
|
return connection.query(_dropPrimaryKeySQL);
|
|
3813
|
-
case
|
|
3814
|
-
_context.next =
|
|
3915
|
+
case 153:
|
|
3916
|
+
_context.next = 159;
|
|
3815
3917
|
break;
|
|
3816
|
-
case
|
|
3918
|
+
case 155:
|
|
3817
3919
|
_dropIndexSQL = "DROP INDEX `".concat(index.Name, "` ON `").concat(_tableName3, "`;");
|
|
3818
3920
|
console.log("Executing: ".concat(_dropIndexSQL));
|
|
3819
|
-
_context.next =
|
|
3921
|
+
_context.next = 159;
|
|
3820
3922
|
return connection.query(_dropIndexSQL);
|
|
3821
|
-
case
|
|
3923
|
+
case 159:
|
|
3822
3924
|
console.log('index', index);
|
|
3823
3925
|
|
|
3824
3926
|
// Create the new index
|
|
3825
3927
|
_uniqueSQL = index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3826
3928
|
if (!(index.Name === 'PRIMARY')) {
|
|
3827
|
-
_context.next =
|
|
3929
|
+
_context.next = 168;
|
|
3828
3930
|
break;
|
|
3829
3931
|
}
|
|
3830
3932
|
addPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` ADD PRIMARY KEY (").concat(index.ColumnName.join(', '), ");");
|
|
3831
3933
|
console.log("Executing: ".concat(addPrimaryKeySQL));
|
|
3832
|
-
_context.next =
|
|
3934
|
+
_context.next = 166;
|
|
3833
3935
|
return connection.query(addPrimaryKeySQL);
|
|
3834
|
-
case
|
|
3835
|
-
_context.next =
|
|
3936
|
+
case 166:
|
|
3937
|
+
_context.next = 172;
|
|
3836
3938
|
break;
|
|
3837
|
-
case
|
|
3939
|
+
case 168:
|
|
3838
3940
|
_addIndexSQL = "ALTER TABLE `".concat(_tableName3, "` ADD ").concat(_uniqueSQL, "INDEX `").concat(index.Name, "` (").concat(index.ColumnName.join(', '), ");"); // Include UNIQUE if applicable
|
|
3839
3941
|
console.log("Executing: ".concat(_addIndexSQL));
|
|
3840
|
-
_context.next =
|
|
3942
|
+
_context.next = 172;
|
|
3841
3943
|
return connection.query(_addIndexSQL);
|
|
3842
|
-
case
|
|
3843
|
-
_context.next =
|
|
3944
|
+
case 172:
|
|
3945
|
+
_context.next = 249;
|
|
3844
3946
|
break;
|
|
3845
|
-
case
|
|
3947
|
+
case 174:
|
|
3846
3948
|
if (!(diff.type === 'missing_procedure' || diff.type === 'mismatched_procedure')) {
|
|
3847
|
-
_context.next =
|
|
3949
|
+
_context.next = 185;
|
|
3848
3950
|
break;
|
|
3849
3951
|
}
|
|
3850
3952
|
// Drop the procedure if it exists
|
|
3851
3953
|
dropCurrentProcSQL = "DROP PROCEDURE IF EXISTS `".concat(diff.Name, "`;");
|
|
3852
3954
|
console.log("Executing: ".concat(dropCurrentProcSQL));
|
|
3853
|
-
_context.next =
|
|
3955
|
+
_context.next = 179;
|
|
3854
3956
|
return connection.query(dropCurrentProcSQL);
|
|
3855
|
-
case
|
|
3957
|
+
case 179:
|
|
3856
3958
|
// Create the procedure
|
|
3857
3959
|
createProcSQL = diff.Definition;
|
|
3858
3960
|
console.log("Executing: ".concat(createProcSQL)); // Log the SQL statement
|
|
3859
|
-
_context.next =
|
|
3961
|
+
_context.next = 183;
|
|
3860
3962
|
return connection.query(createProcSQL);
|
|
3861
|
-
case
|
|
3862
|
-
_context.next =
|
|
3963
|
+
case 183:
|
|
3964
|
+
_context.next = 249;
|
|
3863
3965
|
break;
|
|
3864
|
-
case
|
|
3966
|
+
case 185:
|
|
3865
3967
|
if (!(diff.type === 'missing_view')) {
|
|
3866
|
-
_context.next =
|
|
3968
|
+
_context.next = 196;
|
|
3867
3969
|
break;
|
|
3868
3970
|
}
|
|
3869
3971
|
dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3870
3972
|
console.log("Executing: ".concat(dropViewSQL));
|
|
3871
|
-
_context.next =
|
|
3973
|
+
_context.next = 190;
|
|
3872
3974
|
return connection.query(dropViewSQL);
|
|
3873
|
-
case
|
|
3975
|
+
case 190:
|
|
3874
3976
|
createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3875
3977
|
console.log("Executing: ".concat(createViewSQL));
|
|
3876
|
-
_context.next =
|
|
3978
|
+
_context.next = 194;
|
|
3877
3979
|
return connection.query(createViewSQL);
|
|
3878
|
-
case
|
|
3879
|
-
_context.next =
|
|
3980
|
+
case 194:
|
|
3981
|
+
_context.next = 249;
|
|
3880
3982
|
break;
|
|
3881
|
-
case
|
|
3983
|
+
case 196:
|
|
3882
3984
|
if (!(diff.type === 'mismatched_view')) {
|
|
3883
|
-
_context.next =
|
|
3985
|
+
_context.next = 207;
|
|
3884
3986
|
break;
|
|
3885
3987
|
}
|
|
3886
3988
|
_dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3887
3989
|
console.log("Executing: ".concat(_dropViewSQL));
|
|
3888
|
-
_context.next =
|
|
3990
|
+
_context.next = 201;
|
|
3889
3991
|
return connection.query(_dropViewSQL);
|
|
3890
|
-
case
|
|
3992
|
+
case 201:
|
|
3891
3993
|
_createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3892
3994
|
console.log("Executing: ".concat(_createViewSQL));
|
|
3893
|
-
_context.next =
|
|
3995
|
+
_context.next = 205;
|
|
3894
3996
|
return connection.query(_createViewSQL);
|
|
3895
|
-
case
|
|
3896
|
-
_context.next =
|
|
3997
|
+
case 205:
|
|
3998
|
+
_context.next = 249;
|
|
3897
3999
|
break;
|
|
3898
|
-
case
|
|
4000
|
+
case 207:
|
|
3899
4001
|
if (!(diff.type === 'extra_view')) {
|
|
3900
|
-
_context.next =
|
|
4002
|
+
_context.next = 214;
|
|
3901
4003
|
break;
|
|
3902
4004
|
}
|
|
3903
4005
|
_dropViewSQL2 = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3904
4006
|
console.log("Executing: ".concat(_dropViewSQL2));
|
|
3905
|
-
_context.next =
|
|
4007
|
+
_context.next = 212;
|
|
3906
4008
|
return connection.query(_dropViewSQL2);
|
|
3907
|
-
case
|
|
3908
|
-
_context.next =
|
|
4009
|
+
case 212:
|
|
4010
|
+
_context.next = 249;
|
|
3909
4011
|
break;
|
|
3910
|
-
case
|
|
4012
|
+
case 214:
|
|
3911
4013
|
if (!(diff.type === 'missing_trigger')) {
|
|
3912
|
-
_context.next =
|
|
4014
|
+
_context.next = 222;
|
|
3913
4015
|
break;
|
|
3914
4016
|
}
|
|
3915
4017
|
createTriggerSQL = diff.trigger.Definition;
|
|
3916
4018
|
logger('fixing trigger', diff.trigger.Name);
|
|
3917
4019
|
console.log("Executing: ".concat(createTriggerSQL));
|
|
3918
|
-
_context.next =
|
|
4020
|
+
_context.next = 220;
|
|
3919
4021
|
return connection.query(createTriggerSQL);
|
|
3920
|
-
case
|
|
3921
|
-
_context.next =
|
|
4022
|
+
case 220:
|
|
4023
|
+
_context.next = 249;
|
|
3922
4024
|
break;
|
|
3923
|
-
case
|
|
4025
|
+
case 222:
|
|
3924
4026
|
if (!(diff.type === 'mismatched_trigger')) {
|
|
3925
|
-
_context.next =
|
|
4027
|
+
_context.next = 233;
|
|
3926
4028
|
break;
|
|
3927
4029
|
}
|
|
3928
4030
|
dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3929
4031
|
console.log("Executing: ".concat(dropTriggerSQL));
|
|
3930
|
-
_context.next =
|
|
4032
|
+
_context.next = 227;
|
|
3931
4033
|
return connection.query(dropTriggerSQL);
|
|
3932
|
-
case
|
|
4034
|
+
case 227:
|
|
3933
4035
|
_createTriggerSQL = diff.trigger.Definition;
|
|
3934
4036
|
console.log("Executing: ".concat(_createTriggerSQL));
|
|
3935
|
-
_context.next =
|
|
4037
|
+
_context.next = 231;
|
|
3936
4038
|
return connection.query(_createTriggerSQL);
|
|
3937
|
-
case
|
|
3938
|
-
_context.next =
|
|
4039
|
+
case 231:
|
|
4040
|
+
_context.next = 249;
|
|
3939
4041
|
break;
|
|
3940
|
-
case
|
|
4042
|
+
case 233:
|
|
3941
4043
|
if (!(diff.type === 'extra_trigger')) {
|
|
3942
|
-
_context.next =
|
|
4044
|
+
_context.next = 240;
|
|
3943
4045
|
break;
|
|
3944
4046
|
}
|
|
3945
4047
|
_dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3946
4048
|
console.log("Executing: ".concat(_dropTriggerSQL));
|
|
3947
|
-
_context.next =
|
|
4049
|
+
_context.next = 238;
|
|
3948
4050
|
return connection.query(_dropTriggerSQL);
|
|
3949
|
-
case
|
|
3950
|
-
_context.next =
|
|
4051
|
+
case 238:
|
|
4052
|
+
_context.next = 249;
|
|
3951
4053
|
break;
|
|
3952
|
-
case
|
|
4054
|
+
case 240:
|
|
3953
4055
|
if (!(diff.type === 'missing_database')) {
|
|
3954
|
-
_context.next =
|
|
4056
|
+
_context.next = 248;
|
|
3955
4057
|
break;
|
|
3956
4058
|
}
|
|
3957
4059
|
logger('fixing missing database', diff.database);
|
|
3958
4060
|
_createDatabaseSQL = "CREATE DATABASE `".concat(diff.database, "`;");
|
|
3959
4061
|
console.log("Executing: ".concat(_createDatabaseSQL));
|
|
3960
|
-
_context.next =
|
|
4062
|
+
_context.next = 246;
|
|
3961
4063
|
return connection.query(_createDatabaseSQL);
|
|
3962
|
-
case
|
|
3963
|
-
_context.next =
|
|
4064
|
+
case 246:
|
|
4065
|
+
_context.next = 249;
|
|
3964
4066
|
break;
|
|
3965
|
-
case
|
|
4067
|
+
case 248:
|
|
3966
4068
|
logger("Error applying difference of type:".concat(diff.type), diff);
|
|
3967
|
-
case
|
|
3968
|
-
_context.next =
|
|
4069
|
+
case 249:
|
|
4070
|
+
_context.next = 254;
|
|
3969
4071
|
break;
|
|
3970
|
-
case
|
|
3971
|
-
_context.prev =
|
|
4072
|
+
case 251:
|
|
4073
|
+
_context.prev = 251;
|
|
3972
4074
|
_context.t0 = _context["catch"](1);
|
|
3973
4075
|
logger("Error applying difference of type:".concat(diff.type, ". Error: ").concat(_context.t0.message), diff);
|
|
3974
|
-
case
|
|
4076
|
+
case 254:
|
|
3975
4077
|
case "end":
|
|
3976
4078
|
return _context.stop();
|
|
3977
4079
|
}
|
|
3978
|
-
}, _loop, null, [[1,
|
|
4080
|
+
}, _loop, null, [[1, 251]]);
|
|
3979
4081
|
});
|
|
3980
4082
|
_iterator.s();
|
|
3981
4083
|
case 5:
|
package/dist/index.js
CHANGED
|
@@ -134,7 +134,10 @@ function _iterableToArrayLimit(r, l) {
|
|
|
134
134
|
f = true,
|
|
135
135
|
o = false;
|
|
136
136
|
try {
|
|
137
|
-
if (i = (t = t.call(r)).next, 0 === l)
|
|
137
|
+
if (i = (t = t.call(r)).next, 0 === l) {
|
|
138
|
+
if (Object(t) !== t) return;
|
|
139
|
+
f = !1;
|
|
140
|
+
} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
|
|
138
141
|
} catch (r) {
|
|
139
142
|
o = true, n = r;
|
|
140
143
|
} finally {
|
|
@@ -3596,7 +3599,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3596
3599
|
_iterator = _createForOfIteratorHelper(differences);
|
|
3597
3600
|
_context2.prev = 2;
|
|
3598
3601
|
_loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
|
|
3599
|
-
var diff, createDatabaseSQL, tableName, createSQL, _tableName, dropTableSQL, addFieldSQL, modifyFieldSQL, defaultClause, _modifyFieldSQL, dropFieldSQL, _tableName2, field, isTimestamp, _defaultClause,
|
|
3602
|
+
var diff, createDatabaseSQL, tableName, createSQL, _tableName, dropTableSQL, addFieldSQL, modifyFieldSQL, defaultClause, _modifyFieldSQL, dropFieldSQL, _tableName2, field, currentField, needsBatchProcessing, addColumnSQL, totalUpdated, batchSize, batchCount, updateSQL, result, rowsAffected, verifySQL, _yield$connection$que, _yield$connection$que2, verifyResult, swapColumnsSQL, isTimestamp, _defaultClause, _currentField, hasOnUpdate, _modifyFieldSQL2, existingColumns, columnNames, missingColumns, indexColumns, primaryKeySQL, uniqueSQL, addIndexSQL, dropPrimaryKeySQL, dropIndexSQL, _tableName3, index, _dropPrimaryKeySQL, _dropIndexSQL, _uniqueSQL, addPrimaryKeySQL, _addIndexSQL, dropCurrentProcSQL, createProcSQL, dropViewSQL, createViewSQL, _dropViewSQL, _createViewSQL, _dropViewSQL2, createTriggerSQL, dropTriggerSQL, _createTriggerSQL, _dropTriggerSQL, _createDatabaseSQL;
|
|
3600
3603
|
return _regeneratorRuntime().wrap(function _loop$(_context) {
|
|
3601
3604
|
while (1) switch (_context.prev = _context.next) {
|
|
3602
3605
|
case 0:
|
|
@@ -3626,7 +3629,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3626
3629
|
_context.next = 16;
|
|
3627
3630
|
return connection.query(createSQL);
|
|
3628
3631
|
case 16:
|
|
3629
|
-
_context.next =
|
|
3632
|
+
_context.next = 249;
|
|
3630
3633
|
break;
|
|
3631
3634
|
case 18:
|
|
3632
3635
|
if (!(diff.type === 'extra_table')) {
|
|
@@ -3640,7 +3643,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3640
3643
|
_context.next = 25;
|
|
3641
3644
|
return connection.query(dropTableSQL);
|
|
3642
3645
|
case 25:
|
|
3643
|
-
_context.next =
|
|
3646
|
+
_context.next = 249;
|
|
3644
3647
|
break;
|
|
3645
3648
|
case 27:
|
|
3646
3649
|
if (!(diff.type === 'missing_field')) {
|
|
@@ -3672,7 +3675,7 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3672
3675
|
_context.next = 43;
|
|
3673
3676
|
return connection.query(_modifyFieldSQL);
|
|
3674
3677
|
case 43:
|
|
3675
|
-
_context.next =
|
|
3678
|
+
_context.next = 249;
|
|
3676
3679
|
break;
|
|
3677
3680
|
case 45:
|
|
3678
3681
|
if (!(diff.type === 'extra_field')) {
|
|
@@ -3684,33 +3687,132 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3684
3687
|
_context.next = 50;
|
|
3685
3688
|
return connection.query(dropFieldSQL);
|
|
3686
3689
|
case 50:
|
|
3687
|
-
_context.next =
|
|
3690
|
+
_context.next = 249;
|
|
3688
3691
|
break;
|
|
3689
3692
|
case 52:
|
|
3690
3693
|
if (!(diff.type === 'mismatched_field')) {
|
|
3691
|
-
_context.next =
|
|
3694
|
+
_context.next = 100;
|
|
3692
3695
|
break;
|
|
3693
3696
|
}
|
|
3694
|
-
_tableName2 = diff.tableName, field = diff.field;
|
|
3697
|
+
_tableName2 = diff.tableName, field = diff.field, currentField = diff.currentField; // Helper function to determine if we need batch processing
|
|
3698
|
+
needsBatchProcessing = function needsBatchProcessing() {
|
|
3699
|
+
var currentType = currentField.Type.toLowerCase();
|
|
3700
|
+
var newType = field.Type.toLowerCase();
|
|
3701
|
+
|
|
3702
|
+
// Decimal changes
|
|
3703
|
+
if (currentType.includes('decimal') && newType.includes('decimal')) {
|
|
3704
|
+
return true;
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
// VARCHAR/CHAR length reductions
|
|
3708
|
+
if ((currentType.includes('varchar') || currentType.includes('char')) && (newType.includes('varchar') || newType.includes('char'))) {
|
|
3709
|
+
var _currentType$match, _newType$match;
|
|
3710
|
+
var currentLength = parseInt(((_currentType$match = currentType.match(/\((\d+)\)/)) === null || _currentType$match === undefined ? undefined : _currentType$match[1]) || '0');
|
|
3711
|
+
var newLength = parseInt(((_newType$match = newType.match(/\((\d+)\)/)) === null || _newType$match === undefined ? undefined : _newType$match[1]) || '0');
|
|
3712
|
+
return newLength < currentLength;
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
// TEXT to VARCHAR conversions
|
|
3716
|
+
if (currentType.includes('text') && newType.includes('varchar')) {
|
|
3717
|
+
return true;
|
|
3718
|
+
}
|
|
3719
|
+
|
|
3720
|
+
// Numeric type downgrades
|
|
3721
|
+
var numericDowngrades = {
|
|
3722
|
+
'bigint': ['int', 'mediumint', 'smallint', 'tinyint'],
|
|
3723
|
+
'int': ['mediumint', 'smallint', 'tinyint'],
|
|
3724
|
+
'mediumint': ['smallint', 'tinyint'],
|
|
3725
|
+
'smallint': ['tinyint'],
|
|
3726
|
+
'double': ['float', 'decimal'],
|
|
3727
|
+
'float': ['decimal']
|
|
3728
|
+
};
|
|
3729
|
+
for (var _i = 0, _Object$entries = Object.entries(numericDowngrades); _i < _Object$entries.length; _i++) {
|
|
3730
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
3731
|
+
larger = _Object$entries$_i[0],
|
|
3732
|
+
smaller = _Object$entries$_i[1];
|
|
3733
|
+
if (currentType.includes(larger) && smaller.some(function (t) {
|
|
3734
|
+
return newType.includes(t);
|
|
3735
|
+
})) {
|
|
3736
|
+
return true;
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
return false;
|
|
3740
|
+
};
|
|
3741
|
+
if (!needsBatchProcessing()) {
|
|
3742
|
+
_context.next = 90;
|
|
3743
|
+
break;
|
|
3744
|
+
}
|
|
3745
|
+
// Step 1: Add new column
|
|
3746
|
+
addColumnSQL = "ALTER TABLE `".concat(_tableName2, "` ADD COLUMN `").concat(field.Field, "_new` ").concat(field.Type, " DEFAULT NULL;");
|
|
3747
|
+
logger("Adding new column for type conversion: ".concat(addColumnSQL));
|
|
3748
|
+
_context.next = 60;
|
|
3749
|
+
return connection.query(addColumnSQL);
|
|
3750
|
+
case 60:
|
|
3751
|
+
// Step 2: Copy data in batches
|
|
3752
|
+
totalUpdated = 0;
|
|
3753
|
+
batchSize = 10000;
|
|
3754
|
+
batchCount = 0;
|
|
3755
|
+
case 63:
|
|
3756
|
+
updateSQL = "\n UPDATE `".concat(_tableName2, "` \n SET `").concat(field.Field, "_new` = `").concat(field.Field, "`\n WHERE `").concat(field.Field, "_new` IS NULL \n AND `").concat(field.Field, "` IS NOT NULL\n LIMIT ").concat(batchSize, ";\n ");
|
|
3757
|
+
_context.next = 67;
|
|
3758
|
+
return connection.query(updateSQL);
|
|
3759
|
+
case 67:
|
|
3760
|
+
result = _context.sent;
|
|
3761
|
+
rowsAffected = result.affectedRows;
|
|
3762
|
+
if (!(rowsAffected === 0)) {
|
|
3763
|
+
_context.next = 71;
|
|
3764
|
+
break;
|
|
3765
|
+
}
|
|
3766
|
+
return _context.abrupt("break", 76);
|
|
3767
|
+
case 71:
|
|
3768
|
+
totalUpdated += rowsAffected;
|
|
3769
|
+
batchCount++;
|
|
3770
|
+
logger("Batch ".concat(batchCount, ": Converted ").concat(rowsAffected, " rows. Total converted: ").concat(totalUpdated));
|
|
3771
|
+
_context.next = 63;
|
|
3772
|
+
break;
|
|
3773
|
+
case 76:
|
|
3774
|
+
// Step 3: Verify data (optional)
|
|
3775
|
+
verifySQL = "\n SELECT COUNT(*) as mismatch FROM `".concat(_tableName2, "`\n WHERE `").concat(field.Field, "` IS NOT NULL \n AND `").concat(field.Field, "_new` IS NULL;\n ");
|
|
3776
|
+
_context.next = 79;
|
|
3777
|
+
return connection.query(verifySQL);
|
|
3778
|
+
case 79:
|
|
3779
|
+
_yield$connection$que = _context.sent;
|
|
3780
|
+
_yield$connection$que2 = _slicedToArray(_yield$connection$que, 1);
|
|
3781
|
+
verifyResult = _yield$connection$que2[0];
|
|
3782
|
+
if (verifyResult.mismatch > 0) {
|
|
3783
|
+
logger("Warning: ".concat(verifyResult.mismatch, " rows may have failed conversion"));
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3786
|
+
// Step 4: Swap columns
|
|
3787
|
+
swapColumnsSQL = "\n ALTER TABLE `".concat(_tableName2, "`\n DROP COLUMN `").concat(field.Field, "`,\n RENAME COLUMN `").concat(field.Field, "_new` TO `").concat(field.Field, "`\n ");
|
|
3788
|
+
logger("Swapping columns: ".concat(swapColumnsSQL));
|
|
3789
|
+
_context.next = 87;
|
|
3790
|
+
return connection.query(swapColumnsSQL);
|
|
3791
|
+
case 87:
|
|
3792
|
+
logger("Completed type conversion for ".concat(field.Field, ". Total rows converted: ").concat(totalUpdated));
|
|
3793
|
+
_context.next = 98;
|
|
3794
|
+
break;
|
|
3795
|
+
case 90:
|
|
3796
|
+
// Original mismatched field handling for simple changes
|
|
3695
3797
|
isTimestamp = field.Type.toLowerCase().includes('timestamp'); // Handle timestamp specific attributes
|
|
3696
3798
|
_defaultClause = field.Default === 'CURRENT_TIMESTAMP' ? 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' : field.Default === 'NULL' ? isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL' : field.Default !== undefined && field.Default !== null ? "DEFAULT '".concat(field.Default, "'") : isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL'; // Remove ON UPDATE CURRENT_TIMESTAMP if we're changing away from CURRENT_TIMESTAMP
|
|
3697
|
-
|
|
3698
|
-
hasOnUpdate = (
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
_context.next =
|
|
3702
|
-
return connection.query(
|
|
3703
|
-
case
|
|
3704
|
-
_context.next =
|
|
3799
|
+
_currentField = diff.currentField;
|
|
3800
|
+
hasOnUpdate = (_currentField === null || _currentField === undefined ? undefined : _currentField.Default) === 'CURRENT_TIMESTAMP' && field.Default !== 'CURRENT_TIMESTAMP';
|
|
3801
|
+
_modifyFieldSQL2 = "ALTER TABLE `".concat(_tableName2, "` CHANGE `").concat(field.Field, "` `").concat(field.Field, "` ").concat(field.Type, " ").concat(field.NotNull ? 'NOT NULL' : '', " ").concat(_defaultClause).concat(hasOnUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : '', ";");
|
|
3802
|
+
console.log("Executing: ".concat(_modifyFieldSQL2));
|
|
3803
|
+
_context.next = 98;
|
|
3804
|
+
return connection.query(_modifyFieldSQL2);
|
|
3805
|
+
case 98:
|
|
3806
|
+
_context.next = 249;
|
|
3705
3807
|
break;
|
|
3706
|
-
case
|
|
3808
|
+
case 100:
|
|
3707
3809
|
if (!(diff.type === 'missing_index')) {
|
|
3708
|
-
_context.next =
|
|
3810
|
+
_context.next = 132;
|
|
3709
3811
|
break;
|
|
3710
3812
|
}
|
|
3711
|
-
_context.next =
|
|
3813
|
+
_context.next = 103;
|
|
3712
3814
|
return connection.query("SHOW COLUMNS FROM `".concat(diff.tableName, "`"));
|
|
3713
|
-
case
|
|
3815
|
+
case 103:
|
|
3714
3816
|
existingColumns = _context.sent;
|
|
3715
3817
|
columnNames = existingColumns.map(function (col) {
|
|
3716
3818
|
return col.Field;
|
|
@@ -3719,260 +3821,260 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3719
3821
|
return !columnNames.includes(col);
|
|
3720
3822
|
}) : [];
|
|
3721
3823
|
if (!(missingColumns.length > 0)) {
|
|
3722
|
-
_context.next =
|
|
3824
|
+
_context.next = 109;
|
|
3723
3825
|
break;
|
|
3724
3826
|
}
|
|
3725
3827
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". Missing columns: ").concat(missingColumns.join(', ')));
|
|
3726
3828
|
return _context.abrupt("return", 0);
|
|
3727
|
-
case
|
|
3829
|
+
case 109:
|
|
3728
3830
|
// Prepare the index columns with proper formatting
|
|
3729
3831
|
indexColumns = diff.index.ColumnName.map(function (col) {
|
|
3730
3832
|
return "`".concat(col, "`");
|
|
3731
3833
|
}); // Format column names
|
|
3732
3834
|
// Handle PRIMARY index creation
|
|
3733
3835
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3734
|
-
_context.next =
|
|
3836
|
+
_context.next = 121;
|
|
3735
3837
|
break;
|
|
3736
3838
|
}
|
|
3737
3839
|
if (!(indexColumns.length > 0)) {
|
|
3738
|
-
_context.next =
|
|
3840
|
+
_context.next = 118;
|
|
3739
3841
|
break;
|
|
3740
3842
|
}
|
|
3741
3843
|
primaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` ADD PRIMARY KEY (").concat(indexColumns.join(', '), ");");
|
|
3742
3844
|
console.log("Executing: ".concat(primaryKeySQL));
|
|
3743
|
-
_context.next =
|
|
3845
|
+
_context.next = 116;
|
|
3744
3846
|
return connection.query(primaryKeySQL);
|
|
3745
|
-
case
|
|
3746
|
-
_context.next =
|
|
3847
|
+
case 116:
|
|
3848
|
+
_context.next = 119;
|
|
3747
3849
|
break;
|
|
3748
|
-
case
|
|
3850
|
+
case 118:
|
|
3749
3851
|
logger("Cannot create PRIMARY index on ".concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3750
|
-
case
|
|
3751
|
-
_context.next =
|
|
3852
|
+
case 119:
|
|
3853
|
+
_context.next = 130;
|
|
3752
3854
|
break;
|
|
3753
|
-
case
|
|
3855
|
+
case 121:
|
|
3754
3856
|
// Create the new index with UNIQUE if applicable
|
|
3755
3857
|
uniqueSQL = diff.index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3756
3858
|
if (!(indexColumns.length > 0)) {
|
|
3757
|
-
_context.next =
|
|
3859
|
+
_context.next = 129;
|
|
3758
3860
|
break;
|
|
3759
3861
|
}
|
|
3760
3862
|
addIndexSQL = "ALTER TABLE `".concat(diff.tableName, "` ADD ").concat(uniqueSQL, "INDEX `").concat(diff.index.Name, "` (").concat(indexColumns.join(', '), ");");
|
|
3761
3863
|
console.log("Executing: ".concat(addIndexSQL));
|
|
3762
|
-
_context.next =
|
|
3864
|
+
_context.next = 127;
|
|
3763
3865
|
return connection.query(addIndexSQL);
|
|
3764
|
-
case
|
|
3765
|
-
_context.next =
|
|
3866
|
+
case 127:
|
|
3867
|
+
_context.next = 130;
|
|
3766
3868
|
break;
|
|
3767
|
-
case
|
|
3869
|
+
case 129:
|
|
3768
3870
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3769
|
-
case
|
|
3770
|
-
_context.next =
|
|
3871
|
+
case 130:
|
|
3872
|
+
_context.next = 249;
|
|
3771
3873
|
break;
|
|
3772
|
-
case
|
|
3874
|
+
case 132:
|
|
3773
3875
|
if (!(diff.type === 'extra_index')) {
|
|
3774
|
-
_context.next =
|
|
3876
|
+
_context.next = 146;
|
|
3775
3877
|
break;
|
|
3776
3878
|
}
|
|
3777
3879
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3778
|
-
_context.next =
|
|
3880
|
+
_context.next = 140;
|
|
3779
3881
|
break;
|
|
3780
3882
|
}
|
|
3781
3883
|
dropPrimaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` DROP PRIMARY KEY;");
|
|
3782
3884
|
console.log("Executing: ".concat(dropPrimaryKeySQL));
|
|
3783
|
-
_context.next =
|
|
3885
|
+
_context.next = 138;
|
|
3784
3886
|
return connection.query(dropPrimaryKeySQL);
|
|
3785
|
-
case
|
|
3786
|
-
_context.next =
|
|
3887
|
+
case 138:
|
|
3888
|
+
_context.next = 144;
|
|
3787
3889
|
break;
|
|
3788
|
-
case
|
|
3890
|
+
case 140:
|
|
3789
3891
|
dropIndexSQL = "DROP INDEX `".concat(diff.index.Name, "` ON `").concat(diff.tableName, "`;");
|
|
3790
3892
|
console.log("Executing: ".concat(dropIndexSQL));
|
|
3791
|
-
_context.next =
|
|
3893
|
+
_context.next = 144;
|
|
3792
3894
|
return connection.query(dropIndexSQL);
|
|
3793
|
-
case
|
|
3794
|
-
_context.next =
|
|
3895
|
+
case 144:
|
|
3896
|
+
_context.next = 249;
|
|
3795
3897
|
break;
|
|
3796
|
-
case
|
|
3898
|
+
case 146:
|
|
3797
3899
|
if (!(diff.type === 'mismatched_index')) {
|
|
3798
|
-
_context.next =
|
|
3900
|
+
_context.next = 174;
|
|
3799
3901
|
break;
|
|
3800
3902
|
}
|
|
3801
3903
|
_tableName3 = diff.tableName, index = diff.index; // Drop the existing index
|
|
3802
3904
|
if (!(index.Name === 'PRIMARY')) {
|
|
3803
|
-
_context.next =
|
|
3905
|
+
_context.next = 155;
|
|
3804
3906
|
break;
|
|
3805
3907
|
}
|
|
3806
3908
|
_dropPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` DROP PRIMARY KEY;");
|
|
3807
3909
|
console.log("Executing: ".concat(_dropPrimaryKeySQL));
|
|
3808
|
-
_context.next =
|
|
3910
|
+
_context.next = 153;
|
|
3809
3911
|
return connection.query(_dropPrimaryKeySQL);
|
|
3810
|
-
case
|
|
3811
|
-
_context.next =
|
|
3912
|
+
case 153:
|
|
3913
|
+
_context.next = 159;
|
|
3812
3914
|
break;
|
|
3813
|
-
case
|
|
3915
|
+
case 155:
|
|
3814
3916
|
_dropIndexSQL = "DROP INDEX `".concat(index.Name, "` ON `").concat(_tableName3, "`;");
|
|
3815
3917
|
console.log("Executing: ".concat(_dropIndexSQL));
|
|
3816
|
-
_context.next =
|
|
3918
|
+
_context.next = 159;
|
|
3817
3919
|
return connection.query(_dropIndexSQL);
|
|
3818
|
-
case
|
|
3920
|
+
case 159:
|
|
3819
3921
|
console.log('index', index);
|
|
3820
3922
|
|
|
3821
3923
|
// Create the new index
|
|
3822
3924
|
_uniqueSQL = index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3823
3925
|
if (!(index.Name === 'PRIMARY')) {
|
|
3824
|
-
_context.next =
|
|
3926
|
+
_context.next = 168;
|
|
3825
3927
|
break;
|
|
3826
3928
|
}
|
|
3827
3929
|
addPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` ADD PRIMARY KEY (").concat(index.ColumnName.join(', '), ");");
|
|
3828
3930
|
console.log("Executing: ".concat(addPrimaryKeySQL));
|
|
3829
|
-
_context.next =
|
|
3931
|
+
_context.next = 166;
|
|
3830
3932
|
return connection.query(addPrimaryKeySQL);
|
|
3831
|
-
case
|
|
3832
|
-
_context.next =
|
|
3933
|
+
case 166:
|
|
3934
|
+
_context.next = 172;
|
|
3833
3935
|
break;
|
|
3834
|
-
case
|
|
3936
|
+
case 168:
|
|
3835
3937
|
_addIndexSQL = "ALTER TABLE `".concat(_tableName3, "` ADD ").concat(_uniqueSQL, "INDEX `").concat(index.Name, "` (").concat(index.ColumnName.join(', '), ");"); // Include UNIQUE if applicable
|
|
3836
3938
|
console.log("Executing: ".concat(_addIndexSQL));
|
|
3837
|
-
_context.next =
|
|
3939
|
+
_context.next = 172;
|
|
3838
3940
|
return connection.query(_addIndexSQL);
|
|
3839
|
-
case
|
|
3840
|
-
_context.next =
|
|
3941
|
+
case 172:
|
|
3942
|
+
_context.next = 249;
|
|
3841
3943
|
break;
|
|
3842
|
-
case
|
|
3944
|
+
case 174:
|
|
3843
3945
|
if (!(diff.type === 'missing_procedure' || diff.type === 'mismatched_procedure')) {
|
|
3844
|
-
_context.next =
|
|
3946
|
+
_context.next = 185;
|
|
3845
3947
|
break;
|
|
3846
3948
|
}
|
|
3847
3949
|
// Drop the procedure if it exists
|
|
3848
3950
|
dropCurrentProcSQL = "DROP PROCEDURE IF EXISTS `".concat(diff.Name, "`;");
|
|
3849
3951
|
console.log("Executing: ".concat(dropCurrentProcSQL));
|
|
3850
|
-
_context.next =
|
|
3952
|
+
_context.next = 179;
|
|
3851
3953
|
return connection.query(dropCurrentProcSQL);
|
|
3852
|
-
case
|
|
3954
|
+
case 179:
|
|
3853
3955
|
// Create the procedure
|
|
3854
3956
|
createProcSQL = diff.Definition;
|
|
3855
3957
|
console.log("Executing: ".concat(createProcSQL)); // Log the SQL statement
|
|
3856
|
-
_context.next =
|
|
3958
|
+
_context.next = 183;
|
|
3857
3959
|
return connection.query(createProcSQL);
|
|
3858
|
-
case
|
|
3859
|
-
_context.next =
|
|
3960
|
+
case 183:
|
|
3961
|
+
_context.next = 249;
|
|
3860
3962
|
break;
|
|
3861
|
-
case
|
|
3963
|
+
case 185:
|
|
3862
3964
|
if (!(diff.type === 'missing_view')) {
|
|
3863
|
-
_context.next =
|
|
3965
|
+
_context.next = 196;
|
|
3864
3966
|
break;
|
|
3865
3967
|
}
|
|
3866
3968
|
dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3867
3969
|
console.log("Executing: ".concat(dropViewSQL));
|
|
3868
|
-
_context.next =
|
|
3970
|
+
_context.next = 190;
|
|
3869
3971
|
return connection.query(dropViewSQL);
|
|
3870
|
-
case
|
|
3972
|
+
case 190:
|
|
3871
3973
|
createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3872
3974
|
console.log("Executing: ".concat(createViewSQL));
|
|
3873
|
-
_context.next =
|
|
3975
|
+
_context.next = 194;
|
|
3874
3976
|
return connection.query(createViewSQL);
|
|
3875
|
-
case
|
|
3876
|
-
_context.next =
|
|
3977
|
+
case 194:
|
|
3978
|
+
_context.next = 249;
|
|
3877
3979
|
break;
|
|
3878
|
-
case
|
|
3980
|
+
case 196:
|
|
3879
3981
|
if (!(diff.type === 'mismatched_view')) {
|
|
3880
|
-
_context.next =
|
|
3982
|
+
_context.next = 207;
|
|
3881
3983
|
break;
|
|
3882
3984
|
}
|
|
3883
3985
|
_dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3884
3986
|
console.log("Executing: ".concat(_dropViewSQL));
|
|
3885
|
-
_context.next =
|
|
3987
|
+
_context.next = 201;
|
|
3886
3988
|
return connection.query(_dropViewSQL);
|
|
3887
|
-
case
|
|
3989
|
+
case 201:
|
|
3888
3990
|
_createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3889
3991
|
console.log("Executing: ".concat(_createViewSQL));
|
|
3890
|
-
_context.next =
|
|
3992
|
+
_context.next = 205;
|
|
3891
3993
|
return connection.query(_createViewSQL);
|
|
3892
|
-
case
|
|
3893
|
-
_context.next =
|
|
3994
|
+
case 205:
|
|
3995
|
+
_context.next = 249;
|
|
3894
3996
|
break;
|
|
3895
|
-
case
|
|
3997
|
+
case 207:
|
|
3896
3998
|
if (!(diff.type === 'extra_view')) {
|
|
3897
|
-
_context.next =
|
|
3999
|
+
_context.next = 214;
|
|
3898
4000
|
break;
|
|
3899
4001
|
}
|
|
3900
4002
|
_dropViewSQL2 = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3901
4003
|
console.log("Executing: ".concat(_dropViewSQL2));
|
|
3902
|
-
_context.next =
|
|
4004
|
+
_context.next = 212;
|
|
3903
4005
|
return connection.query(_dropViewSQL2);
|
|
3904
|
-
case
|
|
3905
|
-
_context.next =
|
|
4006
|
+
case 212:
|
|
4007
|
+
_context.next = 249;
|
|
3906
4008
|
break;
|
|
3907
|
-
case
|
|
4009
|
+
case 214:
|
|
3908
4010
|
if (!(diff.type === 'missing_trigger')) {
|
|
3909
|
-
_context.next =
|
|
4011
|
+
_context.next = 222;
|
|
3910
4012
|
break;
|
|
3911
4013
|
}
|
|
3912
4014
|
createTriggerSQL = diff.trigger.Definition;
|
|
3913
4015
|
logger('fixing trigger', diff.trigger.Name);
|
|
3914
4016
|
console.log("Executing: ".concat(createTriggerSQL));
|
|
3915
|
-
_context.next =
|
|
4017
|
+
_context.next = 220;
|
|
3916
4018
|
return connection.query(createTriggerSQL);
|
|
3917
|
-
case
|
|
3918
|
-
_context.next =
|
|
4019
|
+
case 220:
|
|
4020
|
+
_context.next = 249;
|
|
3919
4021
|
break;
|
|
3920
|
-
case
|
|
4022
|
+
case 222:
|
|
3921
4023
|
if (!(diff.type === 'mismatched_trigger')) {
|
|
3922
|
-
_context.next =
|
|
4024
|
+
_context.next = 233;
|
|
3923
4025
|
break;
|
|
3924
4026
|
}
|
|
3925
4027
|
dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3926
4028
|
console.log("Executing: ".concat(dropTriggerSQL));
|
|
3927
|
-
_context.next =
|
|
4029
|
+
_context.next = 227;
|
|
3928
4030
|
return connection.query(dropTriggerSQL);
|
|
3929
|
-
case
|
|
4031
|
+
case 227:
|
|
3930
4032
|
_createTriggerSQL = diff.trigger.Definition;
|
|
3931
4033
|
console.log("Executing: ".concat(_createTriggerSQL));
|
|
3932
|
-
_context.next =
|
|
4034
|
+
_context.next = 231;
|
|
3933
4035
|
return connection.query(_createTriggerSQL);
|
|
3934
|
-
case
|
|
3935
|
-
_context.next =
|
|
4036
|
+
case 231:
|
|
4037
|
+
_context.next = 249;
|
|
3936
4038
|
break;
|
|
3937
|
-
case
|
|
4039
|
+
case 233:
|
|
3938
4040
|
if (!(diff.type === 'extra_trigger')) {
|
|
3939
|
-
_context.next =
|
|
4041
|
+
_context.next = 240;
|
|
3940
4042
|
break;
|
|
3941
4043
|
}
|
|
3942
4044
|
_dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3943
4045
|
console.log("Executing: ".concat(_dropTriggerSQL));
|
|
3944
|
-
_context.next =
|
|
4046
|
+
_context.next = 238;
|
|
3945
4047
|
return connection.query(_dropTriggerSQL);
|
|
3946
|
-
case
|
|
3947
|
-
_context.next =
|
|
4048
|
+
case 238:
|
|
4049
|
+
_context.next = 249;
|
|
3948
4050
|
break;
|
|
3949
|
-
case
|
|
4051
|
+
case 240:
|
|
3950
4052
|
if (!(diff.type === 'missing_database')) {
|
|
3951
|
-
_context.next =
|
|
4053
|
+
_context.next = 248;
|
|
3952
4054
|
break;
|
|
3953
4055
|
}
|
|
3954
4056
|
logger('fixing missing database', diff.database);
|
|
3955
4057
|
_createDatabaseSQL = "CREATE DATABASE `".concat(diff.database, "`;");
|
|
3956
4058
|
console.log("Executing: ".concat(_createDatabaseSQL));
|
|
3957
|
-
_context.next =
|
|
4059
|
+
_context.next = 246;
|
|
3958
4060
|
return connection.query(_createDatabaseSQL);
|
|
3959
|
-
case
|
|
3960
|
-
_context.next =
|
|
4061
|
+
case 246:
|
|
4062
|
+
_context.next = 249;
|
|
3961
4063
|
break;
|
|
3962
|
-
case
|
|
4064
|
+
case 248:
|
|
3963
4065
|
logger("Error applying difference of type:".concat(diff.type), diff);
|
|
3964
|
-
case
|
|
3965
|
-
_context.next =
|
|
4066
|
+
case 249:
|
|
4067
|
+
_context.next = 254;
|
|
3966
4068
|
break;
|
|
3967
|
-
case
|
|
3968
|
-
_context.prev =
|
|
4069
|
+
case 251:
|
|
4070
|
+
_context.prev = 251;
|
|
3969
4071
|
_context.t0 = _context["catch"](1);
|
|
3970
4072
|
logger("Error applying difference of type:".concat(diff.type, ". Error: ").concat(_context.t0.message), diff);
|
|
3971
|
-
case
|
|
4073
|
+
case 254:
|
|
3972
4074
|
case "end":
|
|
3973
4075
|
return _context.stop();
|
|
3974
4076
|
}
|
|
3975
|
-
}, _loop, null, [[1,
|
|
4077
|
+
}, _loop, null, [[1, 251]]);
|
|
3976
4078
|
});
|
|
3977
4079
|
_iterator.s();
|
|
3978
4080
|
case 5:
|
package/package.json
CHANGED
package/src/apply.js
CHANGED
|
@@ -82,26 +82,122 @@ export const applyDifferences = async (connection, database, differences) => {
|
|
|
82
82
|
await connection.query(dropFieldSQL);
|
|
83
83
|
|
|
84
84
|
} else if (diff.type === 'mismatched_field') {
|
|
85
|
-
const { tableName, field } = diff;
|
|
86
|
-
const isTimestamp = field.Type.toLowerCase().includes('timestamp');
|
|
85
|
+
const { tableName, field, currentField } = diff;
|
|
87
86
|
|
|
88
|
-
//
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
87
|
+
// Helper function to determine if we need batch processing
|
|
88
|
+
const needsBatchProcessing = () => {
|
|
89
|
+
const currentType = currentField.Type.toLowerCase();
|
|
90
|
+
const newType = field.Type.toLowerCase();
|
|
91
|
+
|
|
92
|
+
// Decimal changes
|
|
93
|
+
if (currentType.includes('decimal') && newType.includes('decimal')) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// VARCHAR/CHAR length reductions
|
|
98
|
+
if ((currentType.includes('varchar') || currentType.includes('char')) &&
|
|
99
|
+
(newType.includes('varchar') || newType.includes('char'))) {
|
|
100
|
+
const currentLength = parseInt(currentType.match(/\((\d+)\)/)?.[1] || '0');
|
|
101
|
+
const newLength = parseInt(newType.match(/\((\d+)\)/)?.[1] || '0');
|
|
102
|
+
return newLength < currentLength;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// TEXT to VARCHAR conversions
|
|
106
|
+
if (currentType.includes('text') && newType.includes('varchar')) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Numeric type downgrades
|
|
111
|
+
const numericDowngrades = {
|
|
112
|
+
'bigint': ['int', 'mediumint', 'smallint', 'tinyint'],
|
|
113
|
+
'int': ['mediumint', 'smallint', 'tinyint'],
|
|
114
|
+
'mediumint': ['smallint', 'tinyint'],
|
|
115
|
+
'smallint': ['tinyint'],
|
|
116
|
+
'double': ['float', 'decimal'],
|
|
117
|
+
'float': ['decimal']
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
for (const [larger, smaller] of Object.entries(numericDowngrades)) {
|
|
121
|
+
if (currentType.includes(larger) && smaller.some(t => newType.includes(t))) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return false;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (needsBatchProcessing()) {
|
|
130
|
+
// Step 1: Add new column
|
|
131
|
+
const addColumnSQL = `ALTER TABLE \`${tableName}\` ADD COLUMN \`${field.Field}_new\` ${field.Type} DEFAULT NULL;`;
|
|
132
|
+
logger(`Adding new column for type conversion: ${addColumnSQL}`);
|
|
133
|
+
await connection.query(addColumnSQL);
|
|
134
|
+
|
|
135
|
+
// Step 2: Copy data in batches
|
|
136
|
+
let totalUpdated = 0;
|
|
137
|
+
let batchSize = 10000;
|
|
138
|
+
let batchCount = 0;
|
|
139
|
+
|
|
140
|
+
while (true) {
|
|
141
|
+
const updateSQL = `
|
|
142
|
+
UPDATE \`${tableName}\`
|
|
143
|
+
SET \`${field.Field}_new\` = \`${field.Field}\`
|
|
144
|
+
WHERE \`${field.Field}_new\` IS NULL
|
|
145
|
+
AND \`${field.Field}\` IS NOT NULL
|
|
146
|
+
LIMIT ${batchSize};
|
|
147
|
+
`;
|
|
148
|
+
const result = await connection.query(updateSQL);
|
|
149
|
+
const rowsAffected = result.affectedRows;
|
|
150
|
+
|
|
151
|
+
if (rowsAffected === 0) break;
|
|
152
|
+
|
|
153
|
+
totalUpdated += rowsAffected;
|
|
154
|
+
batchCount++;
|
|
155
|
+
logger(`Batch ${batchCount}: Converted ${rowsAffected} rows. Total converted: ${totalUpdated}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Step 3: Verify data (optional)
|
|
159
|
+
const verifySQL = `
|
|
160
|
+
SELECT COUNT(*) as mismatch FROM \`${tableName}\`
|
|
161
|
+
WHERE \`${field.Field}\` IS NOT NULL
|
|
162
|
+
AND \`${field.Field}_new\` IS NULL;
|
|
163
|
+
`;
|
|
164
|
+
const [verifyResult] = await connection.query(verifySQL);
|
|
165
|
+
if (verifyResult.mismatch > 0) {
|
|
166
|
+
logger(`Warning: ${verifyResult.mismatch} rows may have failed conversion`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Step 4: Swap columns
|
|
170
|
+
const swapColumnsSQL = `
|
|
171
|
+
ALTER TABLE \`${tableName}\`
|
|
172
|
+
DROP COLUMN \`${field.Field}\`,
|
|
173
|
+
RENAME COLUMN \`${field.Field}_new\` TO \`${field.Field}\`
|
|
174
|
+
`;
|
|
175
|
+
logger(`Swapping columns: ${swapColumnsSQL}`);
|
|
176
|
+
await connection.query(swapColumnsSQL);
|
|
177
|
+
|
|
178
|
+
logger(`Completed type conversion for ${field.Field}. Total rows converted: ${totalUpdated}`);
|
|
179
|
+
} else {
|
|
180
|
+
// Original mismatched field handling for simple changes
|
|
181
|
+
const isTimestamp = field.Type.toLowerCase().includes('timestamp');
|
|
182
|
+
|
|
183
|
+
// Handle timestamp specific attributes
|
|
184
|
+
const defaultClause = field.Default === 'CURRENT_TIMESTAMP'
|
|
185
|
+
? 'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
|
|
186
|
+
: field.Default === 'NULL'
|
|
187
|
+
? isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL'
|
|
188
|
+
: field.Default !== undefined && field.Default !== null
|
|
189
|
+
? `DEFAULT '${field.Default}'`
|
|
190
|
+
: isTimestamp ? 'NULL DEFAULT NULL' : 'DEFAULT NULL';
|
|
191
|
+
|
|
192
|
+
// Remove ON UPDATE CURRENT_TIMESTAMP if we're changing away from CURRENT_TIMESTAMP
|
|
193
|
+
const currentField = diff.currentField;
|
|
194
|
+
const hasOnUpdate = currentField?.Default === 'CURRENT_TIMESTAMP' &&
|
|
195
|
+
field.Default !== 'CURRENT_TIMESTAMP';
|
|
196
|
+
|
|
197
|
+
const modifyFieldSQL = `ALTER TABLE \`${tableName}\` CHANGE \`${field.Field}\` \`${field.Field}\` ${field.Type} ${field.NotNull ? 'NOT NULL' : ''} ${defaultClause}${hasOnUpdate ? ' ON UPDATE CURRENT_TIMESTAMP' : ''};`;
|
|
198
|
+
console.log(`Executing: ${modifyFieldSQL}`);
|
|
199
|
+
await connection.query(modifyFieldSQL);
|
|
200
|
+
}
|
|
105
201
|
|
|
106
202
|
} else if (diff.type === 'missing_index') {
|
|
107
203
|
const existingColumns = await connection.query(`SHOW COLUMNS FROM \`${diff.tableName}\``);
|