mysqlsyncr 1.1.2 → 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 +224 -119
- package/dist/index.js +224 -119
- package/package.json +1 -1
- package/src/apply.js +115 -11
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, _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,30 +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;
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
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;
|
|
3705
3797
|
break;
|
|
3706
|
-
case
|
|
3798
|
+
case 90:
|
|
3799
|
+
// Original mismatched field handling for simple changes
|
|
3800
|
+
isTimestamp = field.Type.toLowerCase().includes('timestamp'); // Handle timestamp specific attributes
|
|
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
|
|
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;
|
|
3810
|
+
break;
|
|
3811
|
+
case 100:
|
|
3707
3812
|
if (!(diff.type === 'missing_index')) {
|
|
3708
|
-
_context.next =
|
|
3813
|
+
_context.next = 132;
|
|
3709
3814
|
break;
|
|
3710
3815
|
}
|
|
3711
|
-
_context.next =
|
|
3816
|
+
_context.next = 103;
|
|
3712
3817
|
return connection.query("SHOW COLUMNS FROM `".concat(diff.tableName, "`"));
|
|
3713
|
-
case
|
|
3818
|
+
case 103:
|
|
3714
3819
|
existingColumns = _context.sent;
|
|
3715
3820
|
columnNames = existingColumns.map(function (col) {
|
|
3716
3821
|
return col.Field;
|
|
@@ -3719,260 +3824,260 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3719
3824
|
return !columnNames.includes(col);
|
|
3720
3825
|
}) : [];
|
|
3721
3826
|
if (!(missingColumns.length > 0)) {
|
|
3722
|
-
_context.next =
|
|
3827
|
+
_context.next = 109;
|
|
3723
3828
|
break;
|
|
3724
3829
|
}
|
|
3725
3830
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". Missing columns: ").concat(missingColumns.join(', ')));
|
|
3726
3831
|
return _context.abrupt("return", 0);
|
|
3727
|
-
case
|
|
3832
|
+
case 109:
|
|
3728
3833
|
// Prepare the index columns with proper formatting
|
|
3729
3834
|
indexColumns = diff.index.ColumnName.map(function (col) {
|
|
3730
3835
|
return "`".concat(col, "`");
|
|
3731
3836
|
}); // Format column names
|
|
3732
3837
|
// Handle PRIMARY index creation
|
|
3733
3838
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3734
|
-
_context.next =
|
|
3839
|
+
_context.next = 121;
|
|
3735
3840
|
break;
|
|
3736
3841
|
}
|
|
3737
3842
|
if (!(indexColumns.length > 0)) {
|
|
3738
|
-
_context.next =
|
|
3843
|
+
_context.next = 118;
|
|
3739
3844
|
break;
|
|
3740
3845
|
}
|
|
3741
3846
|
primaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` ADD PRIMARY KEY (").concat(indexColumns.join(', '), ");");
|
|
3742
3847
|
console.log("Executing: ".concat(primaryKeySQL));
|
|
3743
|
-
_context.next =
|
|
3848
|
+
_context.next = 116;
|
|
3744
3849
|
return connection.query(primaryKeySQL);
|
|
3745
|
-
case
|
|
3746
|
-
_context.next =
|
|
3850
|
+
case 116:
|
|
3851
|
+
_context.next = 119;
|
|
3747
3852
|
break;
|
|
3748
|
-
case
|
|
3853
|
+
case 118:
|
|
3749
3854
|
logger("Cannot create PRIMARY index on ".concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3750
|
-
case
|
|
3751
|
-
_context.next =
|
|
3855
|
+
case 119:
|
|
3856
|
+
_context.next = 130;
|
|
3752
3857
|
break;
|
|
3753
|
-
case
|
|
3858
|
+
case 121:
|
|
3754
3859
|
// Create the new index with UNIQUE if applicable
|
|
3755
3860
|
uniqueSQL = diff.index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3756
3861
|
if (!(indexColumns.length > 0)) {
|
|
3757
|
-
_context.next =
|
|
3862
|
+
_context.next = 129;
|
|
3758
3863
|
break;
|
|
3759
3864
|
}
|
|
3760
3865
|
addIndexSQL = "ALTER TABLE `".concat(diff.tableName, "` ADD ").concat(uniqueSQL, "INDEX `").concat(diff.index.Name, "` (").concat(indexColumns.join(', '), ");");
|
|
3761
3866
|
console.log("Executing: ".concat(addIndexSQL));
|
|
3762
|
-
_context.next =
|
|
3867
|
+
_context.next = 127;
|
|
3763
3868
|
return connection.query(addIndexSQL);
|
|
3764
|
-
case
|
|
3765
|
-
_context.next =
|
|
3869
|
+
case 127:
|
|
3870
|
+
_context.next = 130;
|
|
3766
3871
|
break;
|
|
3767
|
-
case
|
|
3872
|
+
case 129:
|
|
3768
3873
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3769
|
-
case
|
|
3770
|
-
_context.next =
|
|
3874
|
+
case 130:
|
|
3875
|
+
_context.next = 249;
|
|
3771
3876
|
break;
|
|
3772
|
-
case
|
|
3877
|
+
case 132:
|
|
3773
3878
|
if (!(diff.type === 'extra_index')) {
|
|
3774
|
-
_context.next =
|
|
3879
|
+
_context.next = 146;
|
|
3775
3880
|
break;
|
|
3776
3881
|
}
|
|
3777
3882
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3778
|
-
_context.next =
|
|
3883
|
+
_context.next = 140;
|
|
3779
3884
|
break;
|
|
3780
3885
|
}
|
|
3781
3886
|
dropPrimaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` DROP PRIMARY KEY;");
|
|
3782
3887
|
console.log("Executing: ".concat(dropPrimaryKeySQL));
|
|
3783
|
-
_context.next =
|
|
3888
|
+
_context.next = 138;
|
|
3784
3889
|
return connection.query(dropPrimaryKeySQL);
|
|
3785
|
-
case
|
|
3786
|
-
_context.next =
|
|
3890
|
+
case 138:
|
|
3891
|
+
_context.next = 144;
|
|
3787
3892
|
break;
|
|
3788
|
-
case
|
|
3893
|
+
case 140:
|
|
3789
3894
|
dropIndexSQL = "DROP INDEX `".concat(diff.index.Name, "` ON `").concat(diff.tableName, "`;");
|
|
3790
3895
|
console.log("Executing: ".concat(dropIndexSQL));
|
|
3791
|
-
_context.next =
|
|
3896
|
+
_context.next = 144;
|
|
3792
3897
|
return connection.query(dropIndexSQL);
|
|
3793
|
-
case
|
|
3794
|
-
_context.next =
|
|
3898
|
+
case 144:
|
|
3899
|
+
_context.next = 249;
|
|
3795
3900
|
break;
|
|
3796
|
-
case
|
|
3901
|
+
case 146:
|
|
3797
3902
|
if (!(diff.type === 'mismatched_index')) {
|
|
3798
|
-
_context.next =
|
|
3903
|
+
_context.next = 174;
|
|
3799
3904
|
break;
|
|
3800
3905
|
}
|
|
3801
3906
|
_tableName3 = diff.tableName, index = diff.index; // Drop the existing index
|
|
3802
3907
|
if (!(index.Name === 'PRIMARY')) {
|
|
3803
|
-
_context.next =
|
|
3908
|
+
_context.next = 155;
|
|
3804
3909
|
break;
|
|
3805
3910
|
}
|
|
3806
3911
|
_dropPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` DROP PRIMARY KEY;");
|
|
3807
3912
|
console.log("Executing: ".concat(_dropPrimaryKeySQL));
|
|
3808
|
-
_context.next =
|
|
3913
|
+
_context.next = 153;
|
|
3809
3914
|
return connection.query(_dropPrimaryKeySQL);
|
|
3810
|
-
case
|
|
3811
|
-
_context.next =
|
|
3915
|
+
case 153:
|
|
3916
|
+
_context.next = 159;
|
|
3812
3917
|
break;
|
|
3813
|
-
case
|
|
3918
|
+
case 155:
|
|
3814
3919
|
_dropIndexSQL = "DROP INDEX `".concat(index.Name, "` ON `").concat(_tableName3, "`;");
|
|
3815
3920
|
console.log("Executing: ".concat(_dropIndexSQL));
|
|
3816
|
-
_context.next =
|
|
3921
|
+
_context.next = 159;
|
|
3817
3922
|
return connection.query(_dropIndexSQL);
|
|
3818
|
-
case
|
|
3923
|
+
case 159:
|
|
3819
3924
|
console.log('index', index);
|
|
3820
3925
|
|
|
3821
3926
|
// Create the new index
|
|
3822
3927
|
_uniqueSQL = index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3823
3928
|
if (!(index.Name === 'PRIMARY')) {
|
|
3824
|
-
_context.next =
|
|
3929
|
+
_context.next = 168;
|
|
3825
3930
|
break;
|
|
3826
3931
|
}
|
|
3827
3932
|
addPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` ADD PRIMARY KEY (").concat(index.ColumnName.join(', '), ");");
|
|
3828
3933
|
console.log("Executing: ".concat(addPrimaryKeySQL));
|
|
3829
|
-
_context.next =
|
|
3934
|
+
_context.next = 166;
|
|
3830
3935
|
return connection.query(addPrimaryKeySQL);
|
|
3831
|
-
case
|
|
3832
|
-
_context.next =
|
|
3936
|
+
case 166:
|
|
3937
|
+
_context.next = 172;
|
|
3833
3938
|
break;
|
|
3834
|
-
case
|
|
3939
|
+
case 168:
|
|
3835
3940
|
_addIndexSQL = "ALTER TABLE `".concat(_tableName3, "` ADD ").concat(_uniqueSQL, "INDEX `").concat(index.Name, "` (").concat(index.ColumnName.join(', '), ");"); // Include UNIQUE if applicable
|
|
3836
3941
|
console.log("Executing: ".concat(_addIndexSQL));
|
|
3837
|
-
_context.next =
|
|
3942
|
+
_context.next = 172;
|
|
3838
3943
|
return connection.query(_addIndexSQL);
|
|
3839
|
-
case
|
|
3840
|
-
_context.next =
|
|
3944
|
+
case 172:
|
|
3945
|
+
_context.next = 249;
|
|
3841
3946
|
break;
|
|
3842
|
-
case
|
|
3947
|
+
case 174:
|
|
3843
3948
|
if (!(diff.type === 'missing_procedure' || diff.type === 'mismatched_procedure')) {
|
|
3844
|
-
_context.next =
|
|
3949
|
+
_context.next = 185;
|
|
3845
3950
|
break;
|
|
3846
3951
|
}
|
|
3847
3952
|
// Drop the procedure if it exists
|
|
3848
3953
|
dropCurrentProcSQL = "DROP PROCEDURE IF EXISTS `".concat(diff.Name, "`;");
|
|
3849
3954
|
console.log("Executing: ".concat(dropCurrentProcSQL));
|
|
3850
|
-
_context.next =
|
|
3955
|
+
_context.next = 179;
|
|
3851
3956
|
return connection.query(dropCurrentProcSQL);
|
|
3852
|
-
case
|
|
3957
|
+
case 179:
|
|
3853
3958
|
// Create the procedure
|
|
3854
3959
|
createProcSQL = diff.Definition;
|
|
3855
3960
|
console.log("Executing: ".concat(createProcSQL)); // Log the SQL statement
|
|
3856
|
-
_context.next =
|
|
3961
|
+
_context.next = 183;
|
|
3857
3962
|
return connection.query(createProcSQL);
|
|
3858
|
-
case
|
|
3859
|
-
_context.next =
|
|
3963
|
+
case 183:
|
|
3964
|
+
_context.next = 249;
|
|
3860
3965
|
break;
|
|
3861
|
-
case
|
|
3966
|
+
case 185:
|
|
3862
3967
|
if (!(diff.type === 'missing_view')) {
|
|
3863
|
-
_context.next =
|
|
3968
|
+
_context.next = 196;
|
|
3864
3969
|
break;
|
|
3865
3970
|
}
|
|
3866
3971
|
dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3867
3972
|
console.log("Executing: ".concat(dropViewSQL));
|
|
3868
|
-
_context.next =
|
|
3973
|
+
_context.next = 190;
|
|
3869
3974
|
return connection.query(dropViewSQL);
|
|
3870
|
-
case
|
|
3975
|
+
case 190:
|
|
3871
3976
|
createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3872
3977
|
console.log("Executing: ".concat(createViewSQL));
|
|
3873
|
-
_context.next =
|
|
3978
|
+
_context.next = 194;
|
|
3874
3979
|
return connection.query(createViewSQL);
|
|
3875
|
-
case
|
|
3876
|
-
_context.next =
|
|
3980
|
+
case 194:
|
|
3981
|
+
_context.next = 249;
|
|
3877
3982
|
break;
|
|
3878
|
-
case
|
|
3983
|
+
case 196:
|
|
3879
3984
|
if (!(diff.type === 'mismatched_view')) {
|
|
3880
|
-
_context.next =
|
|
3985
|
+
_context.next = 207;
|
|
3881
3986
|
break;
|
|
3882
3987
|
}
|
|
3883
3988
|
_dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3884
3989
|
console.log("Executing: ".concat(_dropViewSQL));
|
|
3885
|
-
_context.next =
|
|
3990
|
+
_context.next = 201;
|
|
3886
3991
|
return connection.query(_dropViewSQL);
|
|
3887
|
-
case
|
|
3992
|
+
case 201:
|
|
3888
3993
|
_createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3889
3994
|
console.log("Executing: ".concat(_createViewSQL));
|
|
3890
|
-
_context.next =
|
|
3995
|
+
_context.next = 205;
|
|
3891
3996
|
return connection.query(_createViewSQL);
|
|
3892
|
-
case
|
|
3893
|
-
_context.next =
|
|
3997
|
+
case 205:
|
|
3998
|
+
_context.next = 249;
|
|
3894
3999
|
break;
|
|
3895
|
-
case
|
|
4000
|
+
case 207:
|
|
3896
4001
|
if (!(diff.type === 'extra_view')) {
|
|
3897
|
-
_context.next =
|
|
4002
|
+
_context.next = 214;
|
|
3898
4003
|
break;
|
|
3899
4004
|
}
|
|
3900
4005
|
_dropViewSQL2 = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3901
4006
|
console.log("Executing: ".concat(_dropViewSQL2));
|
|
3902
|
-
_context.next =
|
|
4007
|
+
_context.next = 212;
|
|
3903
4008
|
return connection.query(_dropViewSQL2);
|
|
3904
|
-
case
|
|
3905
|
-
_context.next =
|
|
4009
|
+
case 212:
|
|
4010
|
+
_context.next = 249;
|
|
3906
4011
|
break;
|
|
3907
|
-
case
|
|
4012
|
+
case 214:
|
|
3908
4013
|
if (!(diff.type === 'missing_trigger')) {
|
|
3909
|
-
_context.next =
|
|
4014
|
+
_context.next = 222;
|
|
3910
4015
|
break;
|
|
3911
4016
|
}
|
|
3912
4017
|
createTriggerSQL = diff.trigger.Definition;
|
|
3913
4018
|
logger('fixing trigger', diff.trigger.Name);
|
|
3914
4019
|
console.log("Executing: ".concat(createTriggerSQL));
|
|
3915
|
-
_context.next =
|
|
4020
|
+
_context.next = 220;
|
|
3916
4021
|
return connection.query(createTriggerSQL);
|
|
3917
|
-
case
|
|
3918
|
-
_context.next =
|
|
4022
|
+
case 220:
|
|
4023
|
+
_context.next = 249;
|
|
3919
4024
|
break;
|
|
3920
|
-
case
|
|
4025
|
+
case 222:
|
|
3921
4026
|
if (!(diff.type === 'mismatched_trigger')) {
|
|
3922
|
-
_context.next =
|
|
4027
|
+
_context.next = 233;
|
|
3923
4028
|
break;
|
|
3924
4029
|
}
|
|
3925
4030
|
dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3926
4031
|
console.log("Executing: ".concat(dropTriggerSQL));
|
|
3927
|
-
_context.next =
|
|
4032
|
+
_context.next = 227;
|
|
3928
4033
|
return connection.query(dropTriggerSQL);
|
|
3929
|
-
case
|
|
4034
|
+
case 227:
|
|
3930
4035
|
_createTriggerSQL = diff.trigger.Definition;
|
|
3931
4036
|
console.log("Executing: ".concat(_createTriggerSQL));
|
|
3932
|
-
_context.next =
|
|
4037
|
+
_context.next = 231;
|
|
3933
4038
|
return connection.query(_createTriggerSQL);
|
|
3934
|
-
case
|
|
3935
|
-
_context.next =
|
|
4039
|
+
case 231:
|
|
4040
|
+
_context.next = 249;
|
|
3936
4041
|
break;
|
|
3937
|
-
case
|
|
4042
|
+
case 233:
|
|
3938
4043
|
if (!(diff.type === 'extra_trigger')) {
|
|
3939
|
-
_context.next =
|
|
4044
|
+
_context.next = 240;
|
|
3940
4045
|
break;
|
|
3941
4046
|
}
|
|
3942
4047
|
_dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3943
4048
|
console.log("Executing: ".concat(_dropTriggerSQL));
|
|
3944
|
-
_context.next =
|
|
4049
|
+
_context.next = 238;
|
|
3945
4050
|
return connection.query(_dropTriggerSQL);
|
|
3946
|
-
case
|
|
3947
|
-
_context.next =
|
|
4051
|
+
case 238:
|
|
4052
|
+
_context.next = 249;
|
|
3948
4053
|
break;
|
|
3949
|
-
case
|
|
4054
|
+
case 240:
|
|
3950
4055
|
if (!(diff.type === 'missing_database')) {
|
|
3951
|
-
_context.next =
|
|
4056
|
+
_context.next = 248;
|
|
3952
4057
|
break;
|
|
3953
4058
|
}
|
|
3954
4059
|
logger('fixing missing database', diff.database);
|
|
3955
4060
|
_createDatabaseSQL = "CREATE DATABASE `".concat(diff.database, "`;");
|
|
3956
4061
|
console.log("Executing: ".concat(_createDatabaseSQL));
|
|
3957
|
-
_context.next =
|
|
4062
|
+
_context.next = 246;
|
|
3958
4063
|
return connection.query(_createDatabaseSQL);
|
|
3959
|
-
case
|
|
3960
|
-
_context.next =
|
|
4064
|
+
case 246:
|
|
4065
|
+
_context.next = 249;
|
|
3961
4066
|
break;
|
|
3962
|
-
case
|
|
4067
|
+
case 248:
|
|
3963
4068
|
logger("Error applying difference of type:".concat(diff.type), diff);
|
|
3964
|
-
case
|
|
3965
|
-
_context.next =
|
|
4069
|
+
case 249:
|
|
4070
|
+
_context.next = 254;
|
|
3966
4071
|
break;
|
|
3967
|
-
case
|
|
3968
|
-
_context.prev =
|
|
4072
|
+
case 251:
|
|
4073
|
+
_context.prev = 251;
|
|
3969
4074
|
_context.t0 = _context["catch"](1);
|
|
3970
4075
|
logger("Error applying difference of type:".concat(diff.type, ". Error: ").concat(_context.t0.message), diff);
|
|
3971
|
-
case
|
|
4076
|
+
case 254:
|
|
3972
4077
|
case "end":
|
|
3973
4078
|
return _context.stop();
|
|
3974
4079
|
}
|
|
3975
|
-
}, _loop, null, [[1,
|
|
4080
|
+
}, _loop, null, [[1, 251]]);
|
|
3976
4081
|
});
|
|
3977
4082
|
_iterator.s();
|
|
3978
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, _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,30 +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;
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
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;
|
|
3702
3794
|
break;
|
|
3703
|
-
case
|
|
3795
|
+
case 90:
|
|
3796
|
+
// Original mismatched field handling for simple changes
|
|
3797
|
+
isTimestamp = field.Type.toLowerCase().includes('timestamp'); // Handle timestamp specific attributes
|
|
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
|
|
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;
|
|
3807
|
+
break;
|
|
3808
|
+
case 100:
|
|
3704
3809
|
if (!(diff.type === 'missing_index')) {
|
|
3705
|
-
_context.next =
|
|
3810
|
+
_context.next = 132;
|
|
3706
3811
|
break;
|
|
3707
3812
|
}
|
|
3708
|
-
_context.next =
|
|
3813
|
+
_context.next = 103;
|
|
3709
3814
|
return connection.query("SHOW COLUMNS FROM `".concat(diff.tableName, "`"));
|
|
3710
|
-
case
|
|
3815
|
+
case 103:
|
|
3711
3816
|
existingColumns = _context.sent;
|
|
3712
3817
|
columnNames = existingColumns.map(function (col) {
|
|
3713
3818
|
return col.Field;
|
|
@@ -3716,260 +3821,260 @@ var applyDifferences = /*#__PURE__*/function () {
|
|
|
3716
3821
|
return !columnNames.includes(col);
|
|
3717
3822
|
}) : [];
|
|
3718
3823
|
if (!(missingColumns.length > 0)) {
|
|
3719
|
-
_context.next =
|
|
3824
|
+
_context.next = 109;
|
|
3720
3825
|
break;
|
|
3721
3826
|
}
|
|
3722
3827
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". Missing columns: ").concat(missingColumns.join(', ')));
|
|
3723
3828
|
return _context.abrupt("return", 0);
|
|
3724
|
-
case
|
|
3829
|
+
case 109:
|
|
3725
3830
|
// Prepare the index columns with proper formatting
|
|
3726
3831
|
indexColumns = diff.index.ColumnName.map(function (col) {
|
|
3727
3832
|
return "`".concat(col, "`");
|
|
3728
3833
|
}); // Format column names
|
|
3729
3834
|
// Handle PRIMARY index creation
|
|
3730
3835
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3731
|
-
_context.next =
|
|
3836
|
+
_context.next = 121;
|
|
3732
3837
|
break;
|
|
3733
3838
|
}
|
|
3734
3839
|
if (!(indexColumns.length > 0)) {
|
|
3735
|
-
_context.next =
|
|
3840
|
+
_context.next = 118;
|
|
3736
3841
|
break;
|
|
3737
3842
|
}
|
|
3738
3843
|
primaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` ADD PRIMARY KEY (").concat(indexColumns.join(', '), ");");
|
|
3739
3844
|
console.log("Executing: ".concat(primaryKeySQL));
|
|
3740
|
-
_context.next =
|
|
3845
|
+
_context.next = 116;
|
|
3741
3846
|
return connection.query(primaryKeySQL);
|
|
3742
|
-
case
|
|
3743
|
-
_context.next =
|
|
3847
|
+
case 116:
|
|
3848
|
+
_context.next = 119;
|
|
3744
3849
|
break;
|
|
3745
|
-
case
|
|
3850
|
+
case 118:
|
|
3746
3851
|
logger("Cannot create PRIMARY index on ".concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3747
|
-
case
|
|
3748
|
-
_context.next =
|
|
3852
|
+
case 119:
|
|
3853
|
+
_context.next = 130;
|
|
3749
3854
|
break;
|
|
3750
|
-
case
|
|
3855
|
+
case 121:
|
|
3751
3856
|
// Create the new index with UNIQUE if applicable
|
|
3752
3857
|
uniqueSQL = diff.index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3753
3858
|
if (!(indexColumns.length > 0)) {
|
|
3754
|
-
_context.next =
|
|
3859
|
+
_context.next = 129;
|
|
3755
3860
|
break;
|
|
3756
3861
|
}
|
|
3757
3862
|
addIndexSQL = "ALTER TABLE `".concat(diff.tableName, "` ADD ").concat(uniqueSQL, "INDEX `").concat(diff.index.Name, "` (").concat(indexColumns.join(', '), ");");
|
|
3758
3863
|
console.log("Executing: ".concat(addIndexSQL));
|
|
3759
|
-
_context.next =
|
|
3864
|
+
_context.next = 127;
|
|
3760
3865
|
return connection.query(addIndexSQL);
|
|
3761
|
-
case
|
|
3762
|
-
_context.next =
|
|
3866
|
+
case 127:
|
|
3867
|
+
_context.next = 130;
|
|
3763
3868
|
break;
|
|
3764
|
-
case
|
|
3869
|
+
case 129:
|
|
3765
3870
|
logger("Cannot create index ".concat(diff.index.Name, " on ").concat(diff.tableName, ". ColumnName is undefined or empty."), diff.index);
|
|
3766
|
-
case
|
|
3767
|
-
_context.next =
|
|
3871
|
+
case 130:
|
|
3872
|
+
_context.next = 249;
|
|
3768
3873
|
break;
|
|
3769
|
-
case
|
|
3874
|
+
case 132:
|
|
3770
3875
|
if (!(diff.type === 'extra_index')) {
|
|
3771
|
-
_context.next =
|
|
3876
|
+
_context.next = 146;
|
|
3772
3877
|
break;
|
|
3773
3878
|
}
|
|
3774
3879
|
if (!(diff.index.Name === 'PRIMARY')) {
|
|
3775
|
-
_context.next =
|
|
3880
|
+
_context.next = 140;
|
|
3776
3881
|
break;
|
|
3777
3882
|
}
|
|
3778
3883
|
dropPrimaryKeySQL = "ALTER TABLE `".concat(diff.tableName, "` DROP PRIMARY KEY;");
|
|
3779
3884
|
console.log("Executing: ".concat(dropPrimaryKeySQL));
|
|
3780
|
-
_context.next =
|
|
3885
|
+
_context.next = 138;
|
|
3781
3886
|
return connection.query(dropPrimaryKeySQL);
|
|
3782
|
-
case
|
|
3783
|
-
_context.next =
|
|
3887
|
+
case 138:
|
|
3888
|
+
_context.next = 144;
|
|
3784
3889
|
break;
|
|
3785
|
-
case
|
|
3890
|
+
case 140:
|
|
3786
3891
|
dropIndexSQL = "DROP INDEX `".concat(diff.index.Name, "` ON `").concat(diff.tableName, "`;");
|
|
3787
3892
|
console.log("Executing: ".concat(dropIndexSQL));
|
|
3788
|
-
_context.next =
|
|
3893
|
+
_context.next = 144;
|
|
3789
3894
|
return connection.query(dropIndexSQL);
|
|
3790
|
-
case
|
|
3791
|
-
_context.next =
|
|
3895
|
+
case 144:
|
|
3896
|
+
_context.next = 249;
|
|
3792
3897
|
break;
|
|
3793
|
-
case
|
|
3898
|
+
case 146:
|
|
3794
3899
|
if (!(diff.type === 'mismatched_index')) {
|
|
3795
|
-
_context.next =
|
|
3900
|
+
_context.next = 174;
|
|
3796
3901
|
break;
|
|
3797
3902
|
}
|
|
3798
3903
|
_tableName3 = diff.tableName, index = diff.index; // Drop the existing index
|
|
3799
3904
|
if (!(index.Name === 'PRIMARY')) {
|
|
3800
|
-
_context.next =
|
|
3905
|
+
_context.next = 155;
|
|
3801
3906
|
break;
|
|
3802
3907
|
}
|
|
3803
3908
|
_dropPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` DROP PRIMARY KEY;");
|
|
3804
3909
|
console.log("Executing: ".concat(_dropPrimaryKeySQL));
|
|
3805
|
-
_context.next =
|
|
3910
|
+
_context.next = 153;
|
|
3806
3911
|
return connection.query(_dropPrimaryKeySQL);
|
|
3807
|
-
case
|
|
3808
|
-
_context.next =
|
|
3912
|
+
case 153:
|
|
3913
|
+
_context.next = 159;
|
|
3809
3914
|
break;
|
|
3810
|
-
case
|
|
3915
|
+
case 155:
|
|
3811
3916
|
_dropIndexSQL = "DROP INDEX `".concat(index.Name, "` ON `").concat(_tableName3, "`;");
|
|
3812
3917
|
console.log("Executing: ".concat(_dropIndexSQL));
|
|
3813
|
-
_context.next =
|
|
3918
|
+
_context.next = 159;
|
|
3814
3919
|
return connection.query(_dropIndexSQL);
|
|
3815
|
-
case
|
|
3920
|
+
case 159:
|
|
3816
3921
|
console.log('index', index);
|
|
3817
3922
|
|
|
3818
3923
|
// Create the new index
|
|
3819
3924
|
_uniqueSQL = index.Unique ? 'UNIQUE ' : ''; // Check if the index is unique
|
|
3820
3925
|
if (!(index.Name === 'PRIMARY')) {
|
|
3821
|
-
_context.next =
|
|
3926
|
+
_context.next = 168;
|
|
3822
3927
|
break;
|
|
3823
3928
|
}
|
|
3824
3929
|
addPrimaryKeySQL = "ALTER TABLE `".concat(_tableName3, "` ADD PRIMARY KEY (").concat(index.ColumnName.join(', '), ");");
|
|
3825
3930
|
console.log("Executing: ".concat(addPrimaryKeySQL));
|
|
3826
|
-
_context.next =
|
|
3931
|
+
_context.next = 166;
|
|
3827
3932
|
return connection.query(addPrimaryKeySQL);
|
|
3828
|
-
case
|
|
3829
|
-
_context.next =
|
|
3933
|
+
case 166:
|
|
3934
|
+
_context.next = 172;
|
|
3830
3935
|
break;
|
|
3831
|
-
case
|
|
3936
|
+
case 168:
|
|
3832
3937
|
_addIndexSQL = "ALTER TABLE `".concat(_tableName3, "` ADD ").concat(_uniqueSQL, "INDEX `").concat(index.Name, "` (").concat(index.ColumnName.join(', '), ");"); // Include UNIQUE if applicable
|
|
3833
3938
|
console.log("Executing: ".concat(_addIndexSQL));
|
|
3834
|
-
_context.next =
|
|
3939
|
+
_context.next = 172;
|
|
3835
3940
|
return connection.query(_addIndexSQL);
|
|
3836
|
-
case
|
|
3837
|
-
_context.next =
|
|
3941
|
+
case 172:
|
|
3942
|
+
_context.next = 249;
|
|
3838
3943
|
break;
|
|
3839
|
-
case
|
|
3944
|
+
case 174:
|
|
3840
3945
|
if (!(diff.type === 'missing_procedure' || diff.type === 'mismatched_procedure')) {
|
|
3841
|
-
_context.next =
|
|
3946
|
+
_context.next = 185;
|
|
3842
3947
|
break;
|
|
3843
3948
|
}
|
|
3844
3949
|
// Drop the procedure if it exists
|
|
3845
3950
|
dropCurrentProcSQL = "DROP PROCEDURE IF EXISTS `".concat(diff.Name, "`;");
|
|
3846
3951
|
console.log("Executing: ".concat(dropCurrentProcSQL));
|
|
3847
|
-
_context.next =
|
|
3952
|
+
_context.next = 179;
|
|
3848
3953
|
return connection.query(dropCurrentProcSQL);
|
|
3849
|
-
case
|
|
3954
|
+
case 179:
|
|
3850
3955
|
// Create the procedure
|
|
3851
3956
|
createProcSQL = diff.Definition;
|
|
3852
3957
|
console.log("Executing: ".concat(createProcSQL)); // Log the SQL statement
|
|
3853
|
-
_context.next =
|
|
3958
|
+
_context.next = 183;
|
|
3854
3959
|
return connection.query(createProcSQL);
|
|
3855
|
-
case
|
|
3856
|
-
_context.next =
|
|
3960
|
+
case 183:
|
|
3961
|
+
_context.next = 249;
|
|
3857
3962
|
break;
|
|
3858
|
-
case
|
|
3963
|
+
case 185:
|
|
3859
3964
|
if (!(diff.type === 'missing_view')) {
|
|
3860
|
-
_context.next =
|
|
3965
|
+
_context.next = 196;
|
|
3861
3966
|
break;
|
|
3862
3967
|
}
|
|
3863
3968
|
dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3864
3969
|
console.log("Executing: ".concat(dropViewSQL));
|
|
3865
|
-
_context.next =
|
|
3970
|
+
_context.next = 190;
|
|
3866
3971
|
return connection.query(dropViewSQL);
|
|
3867
|
-
case
|
|
3972
|
+
case 190:
|
|
3868
3973
|
createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3869
3974
|
console.log("Executing: ".concat(createViewSQL));
|
|
3870
|
-
_context.next =
|
|
3975
|
+
_context.next = 194;
|
|
3871
3976
|
return connection.query(createViewSQL);
|
|
3872
|
-
case
|
|
3873
|
-
_context.next =
|
|
3977
|
+
case 194:
|
|
3978
|
+
_context.next = 249;
|
|
3874
3979
|
break;
|
|
3875
|
-
case
|
|
3980
|
+
case 196:
|
|
3876
3981
|
if (!(diff.type === 'mismatched_view')) {
|
|
3877
|
-
_context.next =
|
|
3982
|
+
_context.next = 207;
|
|
3878
3983
|
break;
|
|
3879
3984
|
}
|
|
3880
3985
|
_dropViewSQL = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3881
3986
|
console.log("Executing: ".concat(_dropViewSQL));
|
|
3882
|
-
_context.next =
|
|
3987
|
+
_context.next = 201;
|
|
3883
3988
|
return connection.query(_dropViewSQL);
|
|
3884
|
-
case
|
|
3989
|
+
case 201:
|
|
3885
3990
|
_createViewSQL = diff.definition; // Use the expected definition to create the view
|
|
3886
3991
|
console.log("Executing: ".concat(_createViewSQL));
|
|
3887
|
-
_context.next =
|
|
3992
|
+
_context.next = 205;
|
|
3888
3993
|
return connection.query(_createViewSQL);
|
|
3889
|
-
case
|
|
3890
|
-
_context.next =
|
|
3994
|
+
case 205:
|
|
3995
|
+
_context.next = 249;
|
|
3891
3996
|
break;
|
|
3892
|
-
case
|
|
3997
|
+
case 207:
|
|
3893
3998
|
if (!(diff.type === 'extra_view')) {
|
|
3894
|
-
_context.next =
|
|
3999
|
+
_context.next = 214;
|
|
3895
4000
|
break;
|
|
3896
4001
|
}
|
|
3897
4002
|
_dropViewSQL2 = "DROP VIEW IF EXISTS `".concat(diff.viewName, "`;");
|
|
3898
4003
|
console.log("Executing: ".concat(_dropViewSQL2));
|
|
3899
|
-
_context.next =
|
|
4004
|
+
_context.next = 212;
|
|
3900
4005
|
return connection.query(_dropViewSQL2);
|
|
3901
|
-
case
|
|
3902
|
-
_context.next =
|
|
4006
|
+
case 212:
|
|
4007
|
+
_context.next = 249;
|
|
3903
4008
|
break;
|
|
3904
|
-
case
|
|
4009
|
+
case 214:
|
|
3905
4010
|
if (!(diff.type === 'missing_trigger')) {
|
|
3906
|
-
_context.next =
|
|
4011
|
+
_context.next = 222;
|
|
3907
4012
|
break;
|
|
3908
4013
|
}
|
|
3909
4014
|
createTriggerSQL = diff.trigger.Definition;
|
|
3910
4015
|
logger('fixing trigger', diff.trigger.Name);
|
|
3911
4016
|
console.log("Executing: ".concat(createTriggerSQL));
|
|
3912
|
-
_context.next =
|
|
4017
|
+
_context.next = 220;
|
|
3913
4018
|
return connection.query(createTriggerSQL);
|
|
3914
|
-
case
|
|
3915
|
-
_context.next =
|
|
4019
|
+
case 220:
|
|
4020
|
+
_context.next = 249;
|
|
3916
4021
|
break;
|
|
3917
|
-
case
|
|
4022
|
+
case 222:
|
|
3918
4023
|
if (!(diff.type === 'mismatched_trigger')) {
|
|
3919
|
-
_context.next =
|
|
4024
|
+
_context.next = 233;
|
|
3920
4025
|
break;
|
|
3921
4026
|
}
|
|
3922
4027
|
dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3923
4028
|
console.log("Executing: ".concat(dropTriggerSQL));
|
|
3924
|
-
_context.next =
|
|
4029
|
+
_context.next = 227;
|
|
3925
4030
|
return connection.query(dropTriggerSQL);
|
|
3926
|
-
case
|
|
4031
|
+
case 227:
|
|
3927
4032
|
_createTriggerSQL = diff.trigger.Definition;
|
|
3928
4033
|
console.log("Executing: ".concat(_createTriggerSQL));
|
|
3929
|
-
_context.next =
|
|
4034
|
+
_context.next = 231;
|
|
3930
4035
|
return connection.query(_createTriggerSQL);
|
|
3931
|
-
case
|
|
3932
|
-
_context.next =
|
|
4036
|
+
case 231:
|
|
4037
|
+
_context.next = 249;
|
|
3933
4038
|
break;
|
|
3934
|
-
case
|
|
4039
|
+
case 233:
|
|
3935
4040
|
if (!(diff.type === 'extra_trigger')) {
|
|
3936
|
-
_context.next =
|
|
4041
|
+
_context.next = 240;
|
|
3937
4042
|
break;
|
|
3938
4043
|
}
|
|
3939
4044
|
_dropTriggerSQL = "DROP TRIGGER IF EXISTS `".concat(diff.trigger.Name, "`;");
|
|
3940
4045
|
console.log("Executing: ".concat(_dropTriggerSQL));
|
|
3941
|
-
_context.next =
|
|
4046
|
+
_context.next = 238;
|
|
3942
4047
|
return connection.query(_dropTriggerSQL);
|
|
3943
|
-
case
|
|
3944
|
-
_context.next =
|
|
4048
|
+
case 238:
|
|
4049
|
+
_context.next = 249;
|
|
3945
4050
|
break;
|
|
3946
|
-
case
|
|
4051
|
+
case 240:
|
|
3947
4052
|
if (!(diff.type === 'missing_database')) {
|
|
3948
|
-
_context.next =
|
|
4053
|
+
_context.next = 248;
|
|
3949
4054
|
break;
|
|
3950
4055
|
}
|
|
3951
4056
|
logger('fixing missing database', diff.database);
|
|
3952
4057
|
_createDatabaseSQL = "CREATE DATABASE `".concat(diff.database, "`;");
|
|
3953
4058
|
console.log("Executing: ".concat(_createDatabaseSQL));
|
|
3954
|
-
_context.next =
|
|
4059
|
+
_context.next = 246;
|
|
3955
4060
|
return connection.query(_createDatabaseSQL);
|
|
3956
|
-
case
|
|
3957
|
-
_context.next =
|
|
4061
|
+
case 246:
|
|
4062
|
+
_context.next = 249;
|
|
3958
4063
|
break;
|
|
3959
|
-
case
|
|
4064
|
+
case 248:
|
|
3960
4065
|
logger("Error applying difference of type:".concat(diff.type), diff);
|
|
3961
|
-
case
|
|
3962
|
-
_context.next =
|
|
4066
|
+
case 249:
|
|
4067
|
+
_context.next = 254;
|
|
3963
4068
|
break;
|
|
3964
|
-
case
|
|
3965
|
-
_context.prev =
|
|
4069
|
+
case 251:
|
|
4070
|
+
_context.prev = 251;
|
|
3966
4071
|
_context.t0 = _context["catch"](1);
|
|
3967
4072
|
logger("Error applying difference of type:".concat(diff.type, ". Error: ").concat(_context.t0.message), diff);
|
|
3968
|
-
case
|
|
4073
|
+
case 254:
|
|
3969
4074
|
case "end":
|
|
3970
4075
|
return _context.stop();
|
|
3971
4076
|
}
|
|
3972
|
-
}, _loop, null, [[1,
|
|
4077
|
+
}, _loop, null, [[1, 251]]);
|
|
3973
4078
|
});
|
|
3974
4079
|
_iterator.s();
|
|
3975
4080
|
case 5:
|
package/package.json
CHANGED
package/src/apply.js
CHANGED
|
@@ -82,18 +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 defaultClause = field.Default === 'CURRENT_TIMESTAMP'
|
|
87
|
-
? 'DEFAULT CURRENT_TIMESTAMP'
|
|
88
|
-
: field.Default === 'NULL'
|
|
89
|
-
? 'DEFAULT NULL'
|
|
90
|
-
: field.Default !== undefined && field.Default !== null
|
|
91
|
-
? `DEFAULT '${field.Default}'`
|
|
92
|
-
: 'DEFAULT NULL';
|
|
85
|
+
const { tableName, field, currentField } = diff;
|
|
93
86
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
+
}
|
|
97
201
|
|
|
98
202
|
} else if (diff.type === 'missing_index') {
|
|
99
203
|
const existingColumns = await connection.query(`SHOW COLUMNS FROM \`${diff.tableName}\``);
|