Skip to content

Commit 5ff776d

Browse files
committed
feat!: Update to support MySQL 8.0
BREAKING CHANGE: The code that handles foreign keys now follows MySQL 8.0's semantics for the `NO ACTION` foreign key constraint (it's treated the same as omitting the constraint).
1 parent 60f2fa8 commit 5ff776d

File tree

9 files changed

+140
-109
lines changed

9 files changed

+140
-109
lines changed

lib/KeyDefinitions/ForeignKeyDefinition.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ const {escapeId} = require('mysql/lib/protocol/SqlString');
55

66
const referenceOptions = ['RESTRICT', 'CASCADE', 'SET NULL', 'NO ACTION'];
77

8+
function sanitizeReferenceOption(option) {
9+
const refOption = option.toUpperCase();
10+
if (referenceOptions.indexOf(refOption) === -1) {
11+
throw new Error('Invalid foreign key reference option: ' + option);
12+
}
13+
14+
// NO ACTION is the same as RESTRICT in MySQL 8
15+
// https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-key-referential-actions
16+
if (refOption === 'NO ACTION') {
17+
return 'RESTRICT';
18+
}
19+
20+
return refOption;
21+
}
22+
823
class ForeignKeyDefinition {
924
constructor(columns) {
1025
this.$columns = columns;
@@ -24,20 +39,12 @@ class ForeignKeyDefinition {
2439
}
2540

2641
onDelete(option) {
27-
const refOption = option.toUpperCase();
28-
if (referenceOptions.indexOf(refOption) === -1) {
29-
throw new Error('Invalid foreign key reference option: ' + option);
30-
}
31-
this._onDelete = refOption;
42+
this._onDelete = sanitizeReferenceOption(option);
3243
return this;
3344
}
3445

3546
onUpdate(option) {
36-
const refOption = option.toUpperCase();
37-
if (referenceOptions.indexOf(refOption) === -1) {
38-
throw new Error('Invalid foreign key reference option: ' + option);
39-
}
40-
this._onUpdate = refOption;
47+
this._onUpdate = sanitizeReferenceOption(option);
4148
return this;
4249
}
4350

@@ -77,6 +84,9 @@ class ForeignKeyDefinition {
7784
`CONSTRAINT ${escapeId(this.$name)}\n FOREIGN KEY (${escapeId(this.$columns)}) ` +
7885
`REFERENCES ${escapeId(this._referenceTable)} (${escapeId(this._referenceColumns)})`;
7986

87+
// RESTRICT and NO ACTION are equivalent to omitting the clause:
88+
// https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html#foreign-key-referential-actions
89+
// (NO ACTION is transformed into RESTRICT above because it's basically an alias in MySQL 8)
8090
if (this._onDelete !== 'RESTRICT') {
8191
sql += ' ON DELETE ' + this._onDelete;
8292
}

tasks/createTestDB.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = function(grunt) {
1919
throw err;
2020
}
2121

22-
db.query('CREATE DATABASE ?? CHARACTER SET utf8 COLLATE utf8_general_ci', [database], (err) => {
22+
db.query('CREATE DATABASE ?? CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci', [database], (err) => {
2323
if (err) {
2424
throw err;
2525
}

0 commit comments

Comments
 (0)