Skip to content

Commit 07173b6

Browse files
committed
feat: add mysql8 support, update to mysql2 client and drop nodejs v14 and mysql5.7 support
BREAKING CHANGE drop mysql5.7 support Signed-off-by: Samarpan Bhattacharya <[email protected]>
1 parent ab28f74 commit 07173b6

12 files changed

+268
-169
lines changed

.github/workflows/ci.yml

+12-12
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ env:
1111

1212
jobs:
1313
build:
14-
# ubuntu support dropped due to https://github.com/ankane/setup-mysql/commit/70636bf8d2c54521a1b871af766b58d76b468d94
15-
runs-on: macos-12
14+
runs-on: ubuntu-20.04
1615
strategy:
1716
matrix:
1817
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
19-
node-version: [14, 16]
18+
node-version: [16, 18, 20]
2019
steps:
2120
- uses: actions/checkout@v3
2221
- name: Use Node.js ${{ matrix.node-version }}
@@ -25,7 +24,7 @@ jobs:
2524
node-version: ${{ matrix.node-version }}
2625
- uses: ankane/setup-mysql@v1
2726
with:
28-
mysql-version: 5.7
27+
mysql-version: 8.0
2928
- run: |
3029
sudo mysql -e "CREATE USER '${{ secrets.MYSQL_USER }}'@'localhost' IDENTIFIED BY '${{ secrets.MYSQL_PASSWORD }}'"
3130
sudo mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO '${{ secrets.MYSQL_USER }}'@'localhost'"
@@ -34,6 +33,7 @@ jobs:
3433
- run: npm install
3534
- run: npm test
3635
env:
36+
MYSQL_HOST: '127.0.0.1'
3737
MYSQL_USER: ${{ secrets.MYSQL_USER }}
3838
MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
3939
CI: true
@@ -42,11 +42,11 @@ jobs:
4242
runs-on: ubuntu-latest
4343
timeout-minutes: 60
4444
steps:
45-
- uses: actions/checkout@v2
46-
- name: Use Node.js 14
47-
uses: actions/setup-node@v2
45+
- uses: actions/checkout@v3
46+
- name: Use Node.js 18
47+
uses: actions/setup-node@v3
4848
with:
49-
node-version: 14
49+
node-version: 18
5050
- name: Bootstrap project
5151
run: |
5252
npm ci --ignore-scripts
@@ -58,13 +58,13 @@ jobs:
5858
runs-on: ubuntu-latest
5959
timeout-minutes: 60
6060
steps:
61-
- uses: actions/checkout@v2
61+
- uses: actions/checkout@v3
6262
with:
6363
fetch-depth: 0
64-
- name: Use Node.js 14
65-
uses: actions/setup-node@v2
64+
- name: Use Node.js 18
65+
uses: actions/setup-node@v3
6666
with:
67-
node-version: 14
67+
node-version: 18
6868
- name: Bootstrap project
6969
run: |
7070
npm ci --ignore-scripts

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ In your application root directory, enter this command to install the connector:
1212
npm install loopback-connector-mysql --save
1313
```
1414

15-
**Note**: The MySQL connector requires MySQL 5.0+.
15+
**Note**: Since `loopback-connector-mysql` v7.x.x, this MySQL connector has dropped support for MySQL 5.7 and requires MySQL 8.0+.
1616

1717
This installs the module from npm and adds it as a dependency to the
1818
application's `package.json` file.

lib/migration.js

+5-51
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,11 @@ function mixinMigration(MySQL, mysql) {
893893
case 'int':
894894
case 'integer':
895895
case 'bigint':
896-
columnType = integerOptions(p, columnType);
896+
// As of MySQL 8.0.17, the display width attribute is deprecated for integer data types;
897+
// you should expect support for it to be removed in a future version of MySQL.
898+
// As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE, and DECIMAL (and any synonyms);
899+
// you should expect support for it to be removed in a future version of MySQL.
900+
columnType = unsigned(p, columnType);
897901
break;
898902

899903
case 'decimal':
@@ -906,7 +910,6 @@ function mixinMigration(MySQL, mysql) {
906910
columnType = floatingPointOptions(p, columnType);
907911
break;
908912
}
909-
columnType = unsigned(p, columnType);
910913
return columnType;
911914
}
912915

@@ -944,55 +947,6 @@ function mixinMigration(MySQL, mysql) {
944947
return columnType;
945948
}
946949

947-
function integerOptions(p, columnType) {
948-
let tmp = 0;
949-
if (p.display || p.limit) {
950-
tmp = Number(p.display || p.limit);
951-
}
952-
if (tmp > 0) {
953-
columnType += '(' + tmp + ')';
954-
} else if (p.unsigned) {
955-
switch (columnType.toLowerCase()) {
956-
default:
957-
case 'int':
958-
columnType += '(10)';
959-
break;
960-
case 'mediumint':
961-
columnType += '(8)';
962-
break;
963-
case 'smallint':
964-
columnType += '(5)';
965-
break;
966-
case 'tinyint':
967-
columnType += '(3)';
968-
break;
969-
case 'bigint':
970-
columnType += '(20)';
971-
break;
972-
}
973-
} else {
974-
switch (columnType.toLowerCase()) {
975-
default:
976-
case 'int':
977-
columnType += '(11)';
978-
break;
979-
case 'mediumint':
980-
columnType += '(9)';
981-
break;
982-
case 'smallint':
983-
columnType += '(6)';
984-
break;
985-
case 'tinyint':
986-
columnType += '(4)';
987-
break;
988-
case 'bigint':
989-
columnType += '(20)';
990-
break;
991-
}
992-
}
993-
return columnType;
994-
}
995-
996950
function dateOptionsByType(p, columnType) {
997951
switch (columnType.toLowerCase()) {
998952
default:

lib/mysql.js

+24-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const g = require('strong-globalize')();
99
/*!
1010
* Module dependencies
1111
*/
12-
const mysql = require('mysql');
12+
const mysql = require('mysql2');
1313

1414
const SqlConnector = require('loopback-connector').SqlConnector;
1515
const ParameterizedSQL = SqlConnector.ParameterizedSQL;
@@ -353,6 +353,11 @@ MySQL.prototype.toColumnValue = function(prop, val) {
353353
if (val === null) {
354354
if (this.isNullable(prop)) {
355355
return val;
356+
} else if (prop.type === Date) {
357+
// MySQL has disallowed comparison of date types with strings.
358+
// https://bugs.mysql.com/bug.php?id=95466
359+
// https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html
360+
return new Date();
356361
} else {
357362
try {
358363
const castNull = prop.type(val);
@@ -569,19 +574,28 @@ MySQL.prototype.buildExpression = function(columnName, operator, operatorValue,
569574
let clause;
570575
switch (operator) {
571576
case 'regexp':
572-
clause = columnName + ' REGEXP ?';
573-
// By default, MySQL regexp is not case sensitive. (https://dev.mysql.com/doc/refman/5.7/en/regexp.html)
574-
// To allow case sensitive regexp query, it has to be binded to a `BINARY` type.
575-
// If ignore case is not specified, search it as case sensitive.
576-
if (!operatorValue.ignoreCase) {
577-
clause = columnName + ' REGEXP BINARY ?';
577+
// https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-like
578+
// REGEXP_LIKE(expr, pat[, match_type]) - match_type parameter now support c,i and m flags of RegExp
579+
let matchType = '';
580+
if (operatorValue.ignoreCase === false) {
581+
matchType += 'c';
582+
} else if (operatorValue.ignoreCase === true) {
583+
matchType += 'i';
578584
}
579585

580-
if (operatorValue.global)
586+
if (operatorValue.multiline) {
587+
matchType += 'm';
588+
}
589+
590+
if (operatorValue.global) {
581591
g.warn('{{MySQL}} {{regex}} syntax does not respect the {{`g`}} flag');
592+
}
582593

583-
if (operatorValue.multiline)
584-
g.warn('{{MySQL}} {{regex}} syntax does not respect the {{`m`}} flag');
594+
if (!!matchType) {
595+
clause = `REGEXP_LIKE(${columnName}, ?, '${matchType}')`;
596+
} else {
597+
clause = `REGEXP_LIKE(${columnName}, ?)`;
598+
}
585599

586600
return new ParameterizedSQL(clause,
587601
[operatorValue.source]);

0 commit comments

Comments
 (0)