Skip to content

Commit

Permalink
feat: add mysql8 support, update to mysql2 client and drop nodejs v14…
Browse files Browse the repository at this point in the history
… support and drop mysql5.7 support

BREAKING CHANGE
drop mysql5.7 support

Signed-off-by: Samarpan Bhattacharya <[email protected]>
  • Loading branch information
samarpanB committed Jun 25, 2023
1 parent edf176b commit 620581e
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 161 deletions.
23 changes: 11 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ env:

jobs:
build:
# ubuntu support dropped due to https://github.com/ankane/setup-mysql/commit/70636bf8d2c54521a1b871af766b58d76b468d94
runs-on: macos-12
runs-on: ubuntu-22.04
strategy:
matrix:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
node-version: [14, 16]
node-version: [16, 18]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
Expand All @@ -25,7 +24,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- uses: ankane/setup-mysql@v1
with:
mysql-version: 5.7
mysql-version: 8.0
- run: |
sudo mysql -e "CREATE USER '${{ secrets.MYSQL_USER }}'@'localhost' IDENTIFIED BY '${{ secrets.MYSQL_PASSWORD }}'"
sudo mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO '${{ secrets.MYSQL_USER }}'@'localhost'"
Expand All @@ -42,11 +41,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v2
- name: Use Node.js 14
uses: actions/setup-node@v2
- uses: actions/checkout@v3
- name: Use Node.js 18
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 18
- name: Bootstrap project
run: |
npm ci --ignore-scripts
Expand All @@ -58,13 +57,13 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use Node.js 14
uses: actions/setup-node@v2
- name: Use Node.js 18
uses: actions/setup-node@v3
with:
node-version: 14
node-version: 18
- name: Bootstrap project
run: |
npm ci --ignore-scripts
Expand Down
103 changes: 53 additions & 50 deletions lib/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,9 @@ function mixinMigration(MySQL, mysql) {
case 'int':
case 'integer':
case 'bigint':
columnType = integerOptions(p, columnType);
// As of MySQL 8.0.17, the UNSIGNED attribute is deprecated for columns of type FLOAT, DOUBLE, and DECIMAL (and any synonyms);
// you should expect support for it to be removed in a future version of MySQL.
columnType = unsigned(p, columnType);
break;

case 'decimal':
Expand All @@ -906,7 +908,6 @@ function mixinMigration(MySQL, mysql) {
columnType = floatingPointOptions(p, columnType);
break;
}
columnType = unsigned(p, columnType);
return columnType;
}

Expand Down Expand Up @@ -944,54 +945,56 @@ function mixinMigration(MySQL, mysql) {
return columnType;
}

function integerOptions(p, columnType) {
let tmp = 0;
if (p.display || p.limit) {
tmp = Number(p.display || p.limit);
}
if (tmp > 0) {
columnType += '(' + tmp + ')';
} else if (p.unsigned) {
switch (columnType.toLowerCase()) {
default:
case 'int':
columnType += '(10)';
break;
case 'mediumint':
columnType += '(8)';
break;
case 'smallint':
columnType += '(5)';
break;
case 'tinyint':
columnType += '(3)';
break;
case 'bigint':
columnType += '(20)';
break;
}
} else {
switch (columnType.toLowerCase()) {
default:
case 'int':
columnType += '(11)';
break;
case 'mediumint':
columnType += '(9)';
break;
case 'smallint':
columnType += '(6)';
break;
case 'tinyint':
columnType += '(4)';
break;
case 'bigint':
columnType += '(20)';
break;
}
}
return columnType;
}
// As of MySQL 8.0.17, the display width attribute is deprecated for integer data types;
// you should expect support for it to be removed in a future version of MySQL.
// function integerOptions(p, columnType) {
// let tmp = 0;
// if (p.display || p.limit) {
// tmp = Number(p.display || p.limit);
// }
// if (tmp > 0) {
// columnType += '(' + tmp + ')';
// } else if (p.unsigned) {
// switch (columnType.toLowerCase()) {
// default:
// case 'int':
// columnType += '(10)';
// break;
// case 'mediumint':
// columnType += '(8)';
// break;
// case 'smallint':
// columnType += '(5)';
// break;
// case 'tinyint':
// columnType += '(3)';
// break;
// case 'bigint':
// columnType += '(20)';
// break;
// }
// } else {
// switch (columnType.toLowerCase()) {
// default:
// case 'int':
// columnType += '(11)';
// break;
// case 'mediumint':
// columnType += '(9)';
// break;
// case 'smallint':
// columnType += '(6)';
// break;
// case 'tinyint':
// columnType += '(4)';
// break;
// case 'bigint':
// columnType += '(20)';
// break;
// }
// }
// return columnType;
// }

function dateOptionsByType(p, columnType) {
switch (columnType.toLowerCase()) {
Expand Down
34 changes: 24 additions & 10 deletions lib/mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const g = require('strong-globalize')();
/*!
* Module dependencies
*/
const mysql = require('mysql');
const mysql = require('mysql2');

const SqlConnector = require('loopback-connector').SqlConnector;
const ParameterizedSQL = SqlConnector.ParameterizedSQL;
Expand Down Expand Up @@ -353,6 +353,11 @@ MySQL.prototype.toColumnValue = function(prop, val) {
if (val === null) {
if (this.isNullable(prop)) {
return val;
} else if (prop.type === Date) {
// MySQL has disallowed comparison of date types with strings.
// https://bugs.mysql.com/bug.php?id=95466
// https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html
return new Date();
} else {
try {
const castNull = prop.type(val);
Expand Down Expand Up @@ -569,19 +574,28 @@ MySQL.prototype.buildExpression = function(columnName, operator, operatorValue,
let clause;
switch (operator) {
case 'regexp':
clause = columnName + ' REGEXP ?';
// By default, MySQL regexp is not case sensitive. (https://dev.mysql.com/doc/refman/5.7/en/regexp.html)
// To allow case sensitive regexp query, it has to be binded to a `BINARY` type.
// If ignore case is not specified, search it as case sensitive.
if (!operatorValue.ignoreCase) {
clause = columnName + ' REGEXP BINARY ?';
// https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-like
// REGEXP_LIKE(expr, pat[, match_type]) - match_type parameter now support c,i and m flags of RegExp
let matchType = '';
if (operatorValue.ignoreCase === false) {
matchType += 'c';
} else if (operatorValue.ignoreCase === true) {
matchType += 'i';
}

if (operatorValue.global)
if (operatorValue.multiline) {
matchType += 'm';
}

if (operatorValue.global) {
g.warn('{{MySQL}} {{regex}} syntax does not respect the {{`g`}} flag');
}

if (operatorValue.multiline)
g.warn('{{MySQL}} {{regex}} syntax does not respect the {{`m`}} flag');
if (!!matchType) {
clause = `REGEXP_LIKE(${columnName}, ?, '${matchType}')`;
} else {
clause = `REGEXP_LIKE(${columnName}, ?)`;
}

return new ParameterizedSQL(clause,
[operatorValue.source]);
Expand Down
Loading

0 comments on commit 620581e

Please sign in to comment.