Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mysql8 support, update to mysql2 client, drop nodejs v14 and mysql5.7 support [BREAKING CHANGE] #484

Merged
merged 1 commit into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 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-20.04
strategy:
matrix:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
node-version: [14, 16]
node-version: [16, 18, 20]
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 @@ -34,6 +33,7 @@ jobs:
- run: npm install
- run: npm test
env:
MYSQL_HOST: '127.0.0.1'
MYSQL_USER: ${{ secrets.MYSQL_USER }}
MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
CI: true
Expand All @@ -42,11 +42,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 +58,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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In your application root directory, enter this command to install the connector:
npm install loopback-connector-mysql --save
```

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

This installs the module from npm and adds it as a dependency to the
application's `package.json` file.
Expand Down
56 changes: 5 additions & 51 deletions lib/migration.js
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,11 @@ function mixinMigration(MySQL, mysql) {
case 'int':
case 'integer':
case 'bigint':
columnType = integerOptions(p, 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.
// 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 +910,6 @@ function mixinMigration(MySQL, mysql) {
columnType = floatingPointOptions(p, columnType);
break;
}
columnType = unsigned(p, columnType);
return columnType;
}

Expand Down Expand Up @@ -944,55 +947,6 @@ 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;
}

function dateOptionsByType(p, columnType) {
switch (columnType.toLowerCase()) {
default:
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