diff --git a/.eslintrc b/.eslintrc
index b532eb41..c06c22b9 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -10,7 +10,7 @@
"plugin:prettier/recommended"
],
"parserOptions": {
- "ecmaVersion": 6
+ "ecmaVersion": 2020
},
"env": {
"node": true,
diff --git a/.travis.yml b/.travis.yml
index a925866f..c471a27a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -41,27 +41,25 @@ matrix:
allow_failures:
- node_js: "12"
env: DB=build SKIP_LEAK=1
- - node_js: "12"
- env: SKYSQL=true SKIP_LEAK=1
include:
- node_js: "12"
env: DB=build SKIP_LEAK=1
- node_js: "12"
env: SKYSQL=true SKIP_LEAK=1
- node_js: "10"
- env: DB=mariadb:10.4
+ env: DB=mariadb:10.5
- node_js: "12"
- env: DB=mariadb:10.4 SKIP_LEAK=1 ADDITIONAL_CONF=--version=10.4.199
+ env: DB=mariadb:10.5 SKIP_LEAK=1 ADDITIONAL_CONF=--version=10.5.199
- node_js: "14"
- env: DB=mariadb:10.4 SKIP_LEAK=1
+ env: DB=mariadb:10.5 SKIP_LEAK=1
- node_js: "12"
- env: DB=mariadb:10.4 SKIP_LEAK=1 TEST_COLLATION=cp1251_general_ci
+ env: DB=mariadb:10.5 SKIP_LEAK=1 TEST_COLLATION=cp1251_general_ci
- node_js: "12"
- env: DB=mariadb:10.4 LINT=1 SKIP_LEAK=1
+ env: DB=mariadb:10.5 LINT=1 SKIP_LEAK=1
- node_js: "12"
- env: DB=mariadb:10.4 BENCH=1 SKIP_LEAK=1
+ env: DB=mariadb:10.5 BENCH=1 SKIP_LEAK=1
- node_js: "12"
- env: DB=mariadb:10.4 MAXSCALE_VERSION=2.2.9 TEST_PORT=4007 TEST_USER=bob TEXT_DATABASE=test2 SKIP_LEAK=1
+ env: DB=mariadb:10.5 MAXSCALE_VERSION=2.5.4 MAXSCALE_TEST_DISABLE=true SKIP_LEAK=1
- node_js: "12"
env: DB=mariadb:10.1 SKIP_LEAK=1
- node_js: "12"
@@ -69,7 +67,7 @@ matrix:
- node_js: "12"
env: DB=mariadb:10.3 SKIP_LEAK=1
- node_js: "12"
- env: DB=mysql:5.6 SKIP_LEAK=1
+ env: DB=mariadb:10.4 SKIP_LEAK=1
- node_js: "12"
env: DB=mysql:5.7 SKIP_LEAK=1
- node_js: "12"
diff --git a/.travis/docker-compose.yml b/.travis/docker-compose.yml
index 69129be8..e9664e14 100644
--- a/.travis/docker-compose.yml
+++ b/.travis/docker-compose.yml
@@ -1,4 +1,4 @@
-version: '2'
+version: '2.1'
services:
db:
image: $DB
@@ -7,11 +7,14 @@ services:
- 3305:3306
volumes:
- $SSLCERT:/etc/sslcert
- - $ENTRYPOINT:/pam
+ - $ENTRYPOINT:/docker-entrypoint-initdb.d
environment:
MYSQL_DATABASE: testn
MYSQL_ALLOW_EMPTY_PASSWORD: 1
- MYSQL_ROOT_PASSWORD:
-
+ healthcheck:
+ test: ["CMD", "mysql", "--protocol=tcp", "-ubob", "-h127.0.0.1"]
+ timeout: 50s
+ retries: 10
+ interval: 5s
diff --git a/.travis/entrypoint/dbinit.sql b/.travis/entrypoint/dbinit.sql
deleted file mode 100644
index 665bca2a..00000000
--- a/.travis/entrypoint/dbinit.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-CREATE USER 'bob'@'%';
-GRANT ALL ON *.* TO 'bob'@'%' with grant option;
-
-CREATE USER 'boby'@'%' identified by 'heyPassw0@rd';
-GRANT ALL ON *.* TO 'boby'@'%' with grant option;
-
-INSTALL PLUGIN pam SONAME 'auth_pam';
-
-FLUSH PRIVILEGES;
-
-CREATE DATABASE test2;
\ No newline at end of file
diff --git a/.travis/maxscale-compose.yml b/.travis/maxscale-compose.yml
index 274e8acc..842f77da 100644
--- a/.travis/maxscale-compose.yml
+++ b/.travis/maxscale-compose.yml
@@ -1,20 +1,8 @@
version: '2.1'
services:
- maxscale:
- depends_on:
- - db
- ports:
- - 4006:4006
- - 4007:4007
- - 4008:4008
- build:
- context: .
- dockerfile: maxscale/Dockerfile
- args:
- MAXSCALE_VERSION: $MAXSCALE_VERSION
db:
image: $DB
- command: --max-connections=500 --max-allowed-packet=40m --innodb-log-file-size=400m --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --ssl-ca=/etc/sslcert/ca.crt --ssl-cert=/etc/sslcert/server.crt --ssl-key=/etc/sslcert/server.key --bind-address=0.0.0.0
+ command: --innodb-log-file-size=400m --max-allowed-packet=40m --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --ssl-ca=/etc/sslcert/ca.crt --ssl-cert=/etc/sslcert/server.crt --ssl-key=/etc/sslcert/server.key --bind-address=0.0.0.0 $ADDITIONAL_CONF
ports:
- 3305:3306
volumes:
@@ -23,3 +11,26 @@ services:
environment:
MYSQL_DATABASE: testn
MYSQL_ALLOW_EMPTY_PASSWORD: 1
+ healthcheck:
+ test: ["CMD", "mysql", "--protocol=tcp", "-ubob", "-h127.0.0.1"]
+ timeout: 50s
+ retries: 10
+ interval: 5s
+
+ maxscale:
+ depends_on:
+ db:
+ condition: service_healthy
+ links:
+ - "db:database"
+ ports:
+ - 4006:4006
+ - 4008:4008
+ - 4009:4009
+ volumes:
+ - $SSLCERT:/etc/sslcert
+ build:
+ context: .
+ dockerfile: maxscale/Dockerfile
+ args:
+ MAXSCALE_VERSION: $MAXSCALE_VERSION
diff --git a/.travis/maxscale/Dockerfile b/.travis/maxscale/Dockerfile
index 61e41817..4c6009a2 100644
--- a/.travis/maxscale/Dockerfile
+++ b/.travis/maxscale/Dockerfile
@@ -1,12 +1,11 @@
FROM centos:7
ARG MAXSCALE_VERSION
-ENV MAXSCALE_VERSION ${MAXSCALE_VERSION:-2.2.9}
+ENV MAXSCALE_VERSION ${MAXSCALE_VERSION:-2.5.4}
COPY maxscale/mariadb.repo /etc/yum.repos.d/
-
RUN rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB \
- && yum -y install https://downloads.mariadb.com/MaxScale/${MAXSCALE_VERSION}/centos/7/x86_64/maxscale-${MAXSCALE_VERSION}-1.centos.7.x86_64.rpm \
+ && yum -y install https://downloads.mariadb.com/MaxScale/${MAXSCALE_VERSION}/centos/7/x86_64/maxscale-${MAXSCALE_VERSION}-1.rhel.7.x86_64.rpm \
&& yum -y update
RUN yum -y install maxscale-${MAXSCALE_VERSION} MariaDB-client \
@@ -14,8 +13,8 @@ RUN yum -y install maxscale-${MAXSCALE_VERSION} MariaDB-client \
&& rm -rf /tmp/*
COPY maxscale/docker-entrypoint.sh /
-RUN chmod 777 /etc/maxscale.cnf
COPY maxscale/maxscale.cnf /etc/
+RUN chmod 777 /etc/maxscale.cnf
RUN chmod 777 /docker-entrypoint.sh
diff --git a/.travis/maxscale/maxscale.cnf b/.travis/maxscale/maxscale.cnf
index 59788bd1..46254ac8 100644
--- a/.travis/maxscale/maxscale.cnf
+++ b/.travis/maxscale/maxscale.cnf
@@ -1,45 +1,59 @@
-# MaxScale documentation on GitHub:
-# https://github.com/mariadb-corporation/MaxScale/blob/2.1/Documentation/Documentation-Contents.md
+# MaxScale documentation:
+# https://mariadb.com/kb/en/mariadb-maxscale-24/
# Global parameters
#
# Complete list of configuration options:
-# https://github.com/mariadb-corporation/MaxScale/blob/2.1/Documentation/Getting-Started/Configuration-Guide.md
-
+# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-maxscale-configuration-guide/
[maxscale]
-threads=2
-log_messages=1
-log_trace=1
-log_debug=1
+threads=auto
# Server definitions
#
# Set the address of the server to the network
-# address of a MySQL server.
+# address of a MariaDB server.
#
+[server2]
+type=server
+address=database
+port=3306
+protocol=MariaDBBackend
+ssl=true
+ssl_ca_cert=/etc/sslcert/server.crt
+ssl_cert=/etc/sslcert/client.crt
+ssl_key=/etc/sslcert/client.key
+
+
[server1]
type=server
address=db
port=3306
protocol=MariaDBBackend
-authenticator_options=skip_authentication=true
-router_options=master
+
# Monitor for the servers
#
# This will keep MaxScale aware of the state of the servers.
-# MySQL Monitor documentation:
-# https://github.com/mariadb-corporation/MaxScale/blob/2.1/Documentation/Monitors/MySQL-Monitor.md
+# MariaDB Monitor documentation:
+# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-monitor/
-[MySQLMonitor]
+[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=server1
user=boby
-passwd=heyPassw0@rd
-monitor_interval=10000
+password=heyPassw0@rd
+monitor_interval=2000
+
+[MariaDB-Monitor2]
+type=monitor
+module=mariadbmon
+servers=server2
+user=boby
+password=heyPassw0@rd
+monitor_interval=2000
# Service definitions
#
@@ -48,78 +62,61 @@ monitor_interval=10000
#
# ReadConnRoute documentation:
-# https://github.com/mariadb-corporation/MaxScale/blob/2.1/Documentation/Routers/ReadConnRoute.md
+# https://mariadb.com/kb/en/mariadb-maxscale-24-readconnroute/
-[Read-OnlyService]
-enable_root_user=1
-version_string=10.4.99-MariaDB-maxScale
+[Read-Only-Service]
type=service
-router=readconnroute
-servers=server1
+router=readwritesplit
+version_string=10.5.99-MariaDB-maxScale
+servers=server2
user=boby
-passwd=heyPassw0@rd
+password=heyPassw0@rd
router_options=slave
-localhost_match_wildcard_host=1
-[Read-WriteService]
-enable_root_user=1
-version_string=10.4.99-MariaDB-maxScale
+# ReadWriteSplit documentation:
+# https://mariadb.com/kb/en/mariadb-maxscale-24-readwritesplit/
+
+[Read-Write-Service]
type=service
router=readwritesplit
servers=server1
+version_string=10.5.99-MariaDB-maxScale
user=boby
-passwd=heyPassw0@rd
-localhost_match_wildcard_host=1
+password=heyPassw0@rd
-[WriteService]
+[Read-Write-Service2]
type=service
-router=readconnroute
-servers=server1
+router=readwritesplit
+version_string=10.5.99-MariaDB-maxScale
+servers=server2
user=boby
-passwd=heyPassw0@rd
-router_options=master
-localhost_match_wildcard_host=1
-version_string=10.4.99-MariaDB-maxScale
-
-
-# This service enables the use of the MaxAdmin interface
-# MaxScale administration guide:
-# https://github.com/mariadb-corporation/MaxScale/blob/2.1/Documentation/Reference/MaxAdmin.mda
-
-[MaxAdminService]
-enable_root_user=1
-version_string=10.4.99-MariaDB-maxScale
-type=service
-router=cli
+password=heyPassw0@rd
# Listener definitions for the services
#
# These listeners represent the ports the
# services will listen on.
#
-[WriteListener]
-type=listener
-service=WriteService
-protocol=MariaDBClient
-port=4007
-#socket=/var/lib/maxscale/writeconn.sock
-[Read-OnlyListener]
+[Read-Only-Listener]
type=listener
-service=Read-OnlyService
+service=Read-Only-Service
protocol=MariaDBClient
port=4008
-#socket=/var/lib/maxscale/readconn.sock
-[Read-WriteListener]
+[Read-Write-Listener]
type=listener
-service=Read-WriteService
+service=Read-Write-Service
protocol=MariaDBClient
port=4006
-#socket=/var/lib/maxscale/rwsplit.sock
-[MaxAdminListener]
+
+[Read-Write-Listener2]
type=listener
-service=MaxAdminService
-protocol=maxscaled
-socket=/tmp/maxadmin.sock
+service=Read-Write-Service2
+protocol=MariaDBClient
+port=4009
+ssl=true
+ssl_ca_cert=/etc/sslcert/ca.crt
+ssl_cert=/etc/sslcert/server.crt
+ssl_key=/etc/sslcert/server.key
diff --git a/.travis/script.sh b/.travis/script.sh
index 9e8083bb..e4082f28 100644
--- a/.travis/script.sh
+++ b/.travis/script.sh
@@ -9,52 +9,61 @@ set -e
if [ -n "$SKYSQL" ] ; then
- if [ -z "$SKYSQL_TEST_HOST" ] ; then
+ if [ -z "$SKYSQL_HOST" ] ; then
echo "No SkySQL configuration found !"
- exit 1
+ exit 0
+ else
+ export TEST_USER=$SKYSQL_USER
+ export TEST_HOST=$SKYSQL_HOST
+ export TEST_PASSWORD=$SKYSQL_PASSWORD
+ export TEST_PORT=$SKYSQL_PORT
+ export TEST_SSL_CA=$SKYSQL_SSL_CA
+ export TEST_BULK=false
fi
- export TEST_USER=$SKYSQL_TEST_USER
- export TEST_HOST=$SKYSQL_TEST_HOST
- export TEST_PASSWORD=$SKYSQL_TEST_PASSWORD
- export TEST_PORT=$SKYSQL_TEST_PORT
- export TEST_SSL_CA=$SKYSQL_TEST_SSL_CA
- export TEST_BULK=false
-
else
+ export TEST_USER=boby
+ export TEST_PASSWORD=heyPassw0@rd
+ export TEST_HOST=mariadb.example.com
+ export COMPOSE_FILE=.travis/docker-compose.yml
+ export ENTRYPOINT=$PROJ_PATH/.travis/sql
if [ "$DB" = "build" ] ; then
.travis/build/build.sh
docker build -t build:latest --label build .travis/build/
fi
- export ENTRYPOINT=$PROJ_PATH/.travis/entrypoint
if [ -n "$MAXSCALE_VERSION" ] ; then
###################################################################################################################
# launch Maxscale with one server
###################################################################################################################
export COMPOSE_FILE=.travis/maxscale-compose.yml
- export ENTRYPOINT=$PROJ_PATH/.travis/sql
+
docker-compose -f ${COMPOSE_FILE} build
- docker-compose -f ${COMPOSE_FILE} up -d
- else
- docker-compose -f .travis/docker-compose.yml up -d
+ export TEST_PORT=4006
+ export TEST_SSL_PORT=4009
fi
+ docker-compose -f ${COMPOSE_FILE} up -d
+
if [ -z "$SKIP_LEAK" ] ; then npm install node-memwatch; fi
node .travis/wait-for-docker-up.js
-
- if [ -z "$MAXSCALE_VERSION" ] ; then
- docker-compose -f .travis/docker-compose.yml exec -u root db bash /pam/pam.sh
- sleep 1
- docker-compose -f .travis/docker-compose.yml stop db
- sleep 1
- docker-compose -f .travis/docker-compose.yml up -d
- docker-compose -f .travis/docker-compose.yml logs db
- node --version
- node .travis/wait-for-docker-up.js
+ docker-compose -f ${COMPOSE_FILE} logs
+ if [ -n "$MAXSCALE_VERSION" ] ; then
+ docker-compose -f ${COMPOSE_FILE} exec maxscale tail -n 500 /var/log/maxscale/maxscale.log
fi
+
+# if [ -z "$MAXSCALE_VERSION" ] ; then
+# docker-compose -f .travis/docker-compose.yml exec -u root db bash /pam/pam.sh
+# sleep 1
+# docker-compose -f .travis/docker-compose.yml stop db
+# sleep 1
+# docker-compose -f .travis/docker-compose.yml up -d
+# docker-compose -f .travis/docker-compose.yml logs db
+# node --version
+# node .travis/wait-for-docker-up.js
+# fi
fi
if [ -n "$LINT" ] ; then npm run test:lint; fi
diff --git a/.travis/sql/dbinit.sql b/.travis/sql/dbinit.sql
index 81084176..9b671f60 100644
--- a/.travis/sql/dbinit.sql
+++ b/.travis/sql/dbinit.sql
@@ -1,9 +1,15 @@
+CREATE USER 'bob'@'localhost';
+GRANT ALL ON *.* TO 'bob'@'localhost' with grant option;
+
CREATE USER 'bob'@'%';
GRANT ALL ON *.* TO 'bob'@'%' with grant option;
CREATE USER 'boby'@'%' identified by 'heyPassw0@rd';
GRANT ALL ON *.* TO 'boby'@'%' with grant option;
+CREATE USER 'boby'@'localhost' identified by 'heyPassw0@rd';
+GRANT ALL ON *.* TO 'boby'@'localhost' with grant option;
+
FLUSH PRIVILEGES;
CREATE DATABASE test2;
\ No newline at end of file
diff --git a/.travis/entrypoint/pam.sh b/.travis/sql/pam.sh
similarity index 100%
rename from .travis/entrypoint/pam.sh
rename to .travis/sql/pam.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6fec257b..40522caf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,44 @@
# Change Log
+## [2.5.0](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.5.0) (15 Oct 2020)
+[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.4.2...2.5.0)
+
+* CONJS-148 - permit setting socket keep alive (option `keepAliveDelay`)
+* CONJS-145 - batch rewrite error when packet reach maxAllowedPacket
+* CONJS-146 - Using callback API, batch, avoid return error if connection not established
+* CONJS-144 - TypeScript type ssl wrong definitions
+* CONJS-143 - Array parameter escaping differ from mysql/mysql2
+* CONJS-133 - Support ES2020 BigInt object (option `supportBigInt`)
+* CONJS-77 - Support MySQL caching_sha256_password authentication
+* CONJS-76 - Support MySQL sha256_password authentication
+
+
+New Options
+
+|option|description|type|default|
+|---:|---|:---:|:---:|
+| **`arrayParenthesis`** | Indicate if array are included in parenthesis. This option permit compatibility with version < 2.5|*boolean* | false |
+| **`rsaPublicKey`** | Indicate path/content to MySQL server RSA public key. use requires Node.js v11.6+ |*string* | |
+| **`cachingRsaPublicKey`** | Indicate path/content to MySQL server caching RSA public key. use requires Node.js v11.6+ |*string* | |
+| **`allowPublicKeyRetrieval`** | Indicate that if `rsaPublicKey` or `cachingRsaPublicKey` public key are not provided, if client can ask server to send public key. |*boolean* | false |
+| **`supportBigInt`** | Whether resultset should return javascript ES2020 [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) for [BIGINT](https://mariadb.com/kb/en/bigint/) data type. This ensures having expected value even for value > 2^53 (see [safe](documentation/connection-options.md#support-for-big-integer) range). |*boolean* | false |
+| **`keepAliveDelay`** | permit to enable socket keep alive, setting delay. 0 means not enabled. Keep in mind that this don't reset server [@@wait_timeout](https://mariadb.com/kb/en/library/server-system-variables/#wait_timeout) (use pool option idleTimeout for that). in ms |*int* | |
+
+CONJS-143 is a breaking change. Queries that have a IN parameter with array parameters format change.
+previous format did not accept parenthesis :
+```
+conn.query('SELECT * FROM arrayParam WHERE id = ? AND val IN ?', [1, ['b', 'c']]);
+```
+
+now, format is
+```
+conn.query('SELECT * FROM arrayParam WHERE id = ? AND val IN (?)', [1, ['b', 'c']]);
+```
+same than mysql/mysql2 drivers.
+previous behaviour can be reverted setting option `arrayParenthesis` to true.
+
+
+
## [2.4.2](https://github.com/mariadb-corporation/mariadb-connector-nodejs/tree/2.4.2) (23 Jul 2020)
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-nodejs/compare/2.4.1...2.4.2)
diff --git a/appveyor-download.bat b/appveyor-download.bat
index fc12a609..5cc2dbbb 100644
--- a/appveyor-download.bat
+++ b/appveyor-download.bat
@@ -2,12 +2,11 @@
set archive=http://ftp.hosteurope.de/mirror/archive.mariadb.org//mariadb-%DB%/winx64-packages/mariadb-%DB%-winx64.msi
set last=http://mirror.i3d.net/pub/mariadb//mariadb-%DB%/winx64-packages/mariadb-%DB%-winx64.msi
-curl -fsS -o server.msi %archive%
+curl -fLsS -o server.msi %archive%
if %ERRORLEVEL% == 0 goto end
-
-curl -fsS -o server.msi %last%
+curl -fLsS -o server.msi %last%
if %ERRORLEVEL% == 0 goto end
echo Failure Reason Given is %errorlevel%
diff --git a/appveyor.yml b/appveyor.yml
index 7a9fb64c..874a27c0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,43 +12,43 @@ environment:
TEST_LOG_PACKETS: true
matrix:
- - DB: '10.4.13'
+ - DB: '10.5.6'
MEM: "21"
nodejs_version: "10"
- - DB: '10.4.13'
+ - DB: '10.5.6'
MEM: "21"
nodejs_version: "12"
SKIP_LEAK: "1"
- - DB: '10.4.13'
+ - DB: '10.5.6'
nodejs_version: "12"
MEM: "21"
TEST_ZIP: 1
SKIP_LEAK: "1"
- - DB: '10.4.13'
+ - DB: '10.5.6'
nodejs_version: "12"
MEM: "21"
BENCH: "1"
SKIP_LEAK: "1"
- - DB: '10.5.4'
+ - DB: '10.4.15'
MEM: "21"
nodejs_version: "12"
SKIP_LEAK: "1"
- - DB: '10.3.23'
+ - DB: '10.3.24'
MEM: "21"
nodejs_version: "12"
SKIP_LEAK: "1"
- - DB: '10.2.32'
+ - DB: '10.2.33'
MEM: "21"
nodejs_version: "12"
SKIP_LEAK: "1"
- - DB: '10.1.45'
+ - DB: '10.1.46'
MEM: "21"
nodejs_version: "12"
SKIP_LEAK: "1"
diff --git a/documentation/connection-options.md b/documentation/connection-options.md
index 44a14f4d..c7035446 100644
--- a/documentation/connection-options.md
+++ b/documentation/connection-options.md
@@ -355,7 +355,13 @@ mariadb.createConnection({
| **permitConnectionWhenExpired** | Permit a user with expired password to connect. Only possible operation in this case will be to change password ('SET PASSWORD=PASSWORD('XXX')')|*boolean* |false|
| **forceVersionCheck** | Force server version check by explicitly using SELECT VERSION(), not relying on server initial packet.
Since version 2.2.0 |*boolean* |false|
| **checkDuplicate** | Indicate to throw an exception if result-set will not contain some data due to having duplicate identifier.
JSON cannot have multiple identical key, so query like `SELECT 1 as i, 2 as i` cannot result in { i:1, i:2 }, 'i:1' would be skipped.
When `checkDuplicate` is enable (default) driver will throw an error if some data are skipped. Duplication error can be avoided by multiple ways, like using unique aliases or using options [`rowsAsArray`](https://github.com/mariadb-corporation/mariadb-connector-nodejs/blob/master/documentation/promise-api.md#rowsasarray) / [`nestTables`](https://github.com/mariadb-corporation/mariadb-connector-nodejs/blob/master/documentation/promise-api.md#nestTables) for example
Since version 2.3.0|*boolean* | true |
-
+| **arrayParenthesis** | Indicate if array are included in parenthesis. This option permit compatibility with version < 2.5|*boolean* | false |
+| **autoJsonMap** | indicate if JSON fields for MariaDB server 10.5.2+ results in JSON format (or String if disabled)|*boolean* | true |
+| **keepAliveDelay** | permit to enable socket keep alive, setting delay. 0 means not enabled. Keep in mind that this don't reset server [@@wait_timeout](https://mariadb.com/kb/en/library/server-system-variables/#wait_timeout) (use pool option idleTimeout for that). in ms |*int* | |
+| **rsaPublicKey** | Indicate path/content to MySQL server RSA public key. use requires Node.js v11.6+ |*string* | |
+| **cachingRsaPublicKey** | Indicate path/content to MySQL server caching RSA public key. use requires Node.js v11.6+ |*string* | |
+| **allowPublicKeyRetrieval** | Indicate that if `rsaPublicKey` or `cachingRsaPublicKey` public key are not provided, if client can ask server to send public key. |*boolean* | false |
+| **supportBigInt** | Whether resultset should return javascript ES2020 [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) for [BIGINT](https://mariadb.com/kb/en/bigint/) data type. This ensures having expected value even for value > 2^53 (see [safe](documentation/connection-options.md#support-for-big-integer) range). |*boolean* | false |
## F.A.Q.
diff --git a/documentation/promise-api.md b/documentation/promise-api.md
index a6a573f0..27dce51a 100644
--- a/documentation/promise-api.md
+++ b/documentation/promise-api.md
@@ -460,6 +460,7 @@ connection.query('select * from animals')
* [`nestTables`](#nestTables)
* [`dateStrings`](#dateStrings)
* [`supportBigNumbers`](#supportBigNumbers)
+* [`supportBigint`](#supportBigint)
* [`bigNumberStrings`](#bigNumberStrings)
Those options can be set on the query level, but are usually set at the connection level, and will then apply to all queries.
@@ -598,6 +599,16 @@ Whether you want the Connector to retrieve date values as strings, rather than `
Whether the query should return integers as [`Long`](https://www.npmjs.com/package/long) objects when they are not in the [safe](documentation/connection-options.md#support-for-big-integer) range.
+#### `supportBigInt`
+
+*boolean, default: false*
+
+Whether the query should return javascript ES2020 [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript
+/Reference/Global_Objects/BigInt)
+for [BIGINT](https://mariadb.com/kb/en/bigint/) data type.
+This ensures having expected value even for value > 2^53 (see [safe](documentation/connection-options.md#support-for-big-integer) range).
+
+
#### `bigNumberStrings`
*boolean, default: false*
diff --git a/lib/cmd/batch-bulk.js b/lib/cmd/batch-bulk.js
index a704b2cb..4e1a669e 100644
--- a/lib/cmd/batch-bulk.js
+++ b/lib/cmd/batch-bulk.js
@@ -12,7 +12,6 @@ const BulkPacket = require('../io/bulk-packet');
class BatchBulk extends CommonBinary {
constructor(resolve, reject, options, connOpts, sql, values) {
super(resolve, reject, options, connOpts, sql, values);
- this.sending = true;
this.onPacketReceive = this.readPrepareResultPacket;
}
@@ -24,6 +23,7 @@ class BatchBulk extends CommonBinary {
* @param info connection information
*/
start(out, opts, info) {
+ this.sending = true;
this.info = info;
this.values = this.initialValues;
@@ -65,9 +65,14 @@ class BatchBulk extends CommonBinary {
out.writeInt8(0x16);
out.writeString(questionMarkSql);
out.flushBuffer(true);
- out.startPacket(this);
- this.valueIdx = 0;
- this.sendQueries();
+
+ if (this.opts.pipelining) {
+ out.startPacket(this);
+ this.valueIdx = 0;
+ this.sendQueries();
+ } else {
+ this.out = out;
+ }
}
sendQueries() {
@@ -130,6 +135,16 @@ class BatchBulk extends CommonBinary {
success(val) {
this.packet.waitingResponseNo--;
+ if (!this.opts.pipelining && this.packet.statementId === -1) {
+ this.packet.statementId = this.statementId;
+ this.out.startPacket(this);
+ this.valueIdx = 0;
+ this.sendQueries();
+ this._responseIndex++;
+ this.onPacketReceive = this.readResponsePacket;
+ return;
+ }
+
if (!this.sending && this.packet.waitingResponseNo === 0) {
//send COM_STMT_CLOSE packet
if (!this.firstError || !this.firstError.fatal) {
diff --git a/lib/cmd/batch-rewrite.js b/lib/cmd/batch-rewrite.js
index 10cca146..51743824 100644
--- a/lib/cmd/batch-rewrite.js
+++ b/lib/cmd/batch-rewrite.js
@@ -13,7 +13,6 @@ const QUOTE = 0x27;
class BatchRewrite extends CommonText {
constructor(resolve, reject, options, connOpts, sql, values) {
super(resolve, reject, options, connOpts, sql, values);
- this.sending = true;
}
/**
@@ -24,6 +23,7 @@ class BatchRewrite extends CommonText {
* @param info connection information
*/
start(out, opts, info) {
+ this.sending = true;
this.info = info;
if (this.opts.timeout) {
const err = Errors.createError(
@@ -251,7 +251,7 @@ class BatchRewrite extends CommonText {
this.emit('send_end');
this.throwNewError(
'Parameter at position ' +
- (val.length + 1) +
+ val.length +
' is not set for values ' +
r +
'\n' +
diff --git a/lib/cmd/change-user.js b/lib/cmd/change-user.js
index bee90b77..da560214 100644
--- a/lib/cmd/change-user.js
+++ b/lib/cmd/change-user.js
@@ -24,7 +24,7 @@ class ChangeUser extends Handshake {
switch (info.defaultPluginName) {
case 'mysql_native_password':
case '':
- authToken = NativePasswordAuth.encryptPassword(pwd, info.seed);
+ authToken = NativePasswordAuth.encryptPassword(pwd, info.seed, 'sha1');
break;
case 'client_ed25519':
authToken = Ed25519PasswordAuth.encryptPassword(pwd, info.seed);
@@ -39,7 +39,7 @@ class ChangeUser extends Handshake {
out.writeString(this.opts.user || '');
out.writeInt8(0);
- if (info.serverCapabilities.low & Capabilities.SECURE_CONNECTION) {
+ if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
out.writeInt8(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
} else {
@@ -47,7 +47,7 @@ class ChangeUser extends Handshake {
out.writeInt8(0);
}
- if (info.clientCapabilities.low & Capabilities.CONNECT_WITH_DB) {
+ if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
out.writeString(this.opts.database);
out.writeInt8(0);
info.database = this.opts.database;
@@ -55,12 +55,12 @@ class ChangeUser extends Handshake {
out.writeInt16(this.opts.collation.index);
- if (info.clientCapabilities.low & Capabilities.PLUGIN_AUTH) {
+ if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
out.writeString(info.defaultPluginName);
out.writeInt8(0);
}
- if (this.opts.connectAttributes && info.serverCapabilities.low & Capabilities.CONNECT_ATTRS) {
+ if (this.opts.connectAttributes && info.serverCapabilities & Capabilities.CONNECT_ATTRS) {
out.writeInt8(0xfc);
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
out.writeInt16(0);
diff --git a/lib/cmd/column-definition.js b/lib/cmd/column-definition.js
index 1af14235..e208a678 100644
--- a/lib/cmd/column-definition.js
+++ b/lib/cmd/column-definition.js
@@ -11,7 +11,7 @@ const Capabilities = require('../const/capabilities');
class ColumnDef {
constructor(packet, info) {
this._parse = new StringParser(packet);
- if (info.serverCapabilities.high & Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO) {
+ if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO) {
const subPacket = packet.subPacketLengthEncoded();
while (subPacket.remaining()) {
switch (subPacket.readUInt8()) {
diff --git a/lib/cmd/command.js b/lib/cmd/command.js
index 78901ccb..bb86d249 100644
--- a/lib/cmd/command.js
+++ b/lib/cmd/command.js
@@ -114,7 +114,9 @@ class Command extends EventEmitter {
packet.skip(1); //skip header
const affectedRows = packet.readUnsignedLength();
- const insertId = packet.readSignedLength();
+ const insertId = opts.supportBigInt
+ ? packet.readSignedLengthBigInt()
+ : packet.readSignedLength();
info.status = packet.readUInt16();
diff --git a/lib/cmd/common-binary-cmd.js b/lib/cmd/common-binary-cmd.js
index 9b95683e..a7348576 100644
--- a/lib/cmd/common-binary-cmd.js
+++ b/lib/cmd/common-binary-cmd.js
@@ -25,6 +25,7 @@ class CommonBinary extends ResultSet {
flushed = out.writeInt8(0x00);
flushed = out.writeInt8(value ? 0x01 : 0x00) || flushed;
break;
+ case 'bigint':
case 'number':
flushed = out.writeInt8(0x00);
flushed = out.writeLengthStringAscii('' + value) || flushed;
diff --git a/lib/cmd/common-text-cmd.js b/lib/cmd/common-text-cmd.js
index ca49f6c6..e673c56d 100644
--- a/lib/cmd/common-text-cmd.js
+++ b/lib/cmd/common-text-cmd.js
@@ -28,6 +28,7 @@ class CommonText extends ResultSet {
case 'boolean':
out.writeStringAscii(value ? 'true' : 'false');
break;
+ case 'bigint':
case 'number':
out.writeStringAscii('' + value);
break;
@@ -45,12 +46,16 @@ class CommonText extends ResultSet {
} else if (Long.isLong(value)) {
out.writeStringAscii(value.toString());
} else if (Array.isArray(value)) {
- out.writeStringAscii('(');
+ if (opts.arrayParenthesis) {
+ out.writeStringAscii('(');
+ }
for (let i = 0; i < value.length; i++) {
if (i !== 0) out.writeStringAscii(',');
this.writeParam(out, value[i], opts, info);
}
- out.writeStringAscii(')');
+ if (opts.arrayParenthesis) {
+ out.writeStringAscii(')');
+ }
} else {
if (
value.type != null &&
@@ -267,12 +272,12 @@ class CommonText extends ResultSet {
column.int = () => packet.readIntLengthEncoded();
column.long = () =>
packet.readLongLengthEncoded(
+ opts.supportBigInt,
opts.supportBigNumbers,
opts.bigNumberStrings,
(column.flags & FieldDetail.UNSIGNED) > 0
);
- column.decimal = () =>
- packet.readDecimalLengthEncoded(opts.supportBigNumbers, opts.bigNumberStrings);
+ column.decimal = () => packet.readDecimalLengthEncoded(opts.bigNumberStrings);
column.date = () => packet.readDateTime(opts);
column.geometry = () => {
return column.readGeometry();
@@ -310,13 +315,14 @@ class CommonText extends ResultSet {
return packet.readFloatLengthCoded();
case FieldType.LONGLONG:
return packet.readLongLengthEncoded(
+ opts.supportBigInt,
opts.supportBigNumbers,
opts.bigNumberStrings,
(column.flags & FieldDetail.UNSIGNED) > 0
);
case FieldType.DECIMAL:
case FieldType.NEWDECIMAL:
- return packet.readDecimalLengthEncoded(opts.supportBigNumbers, opts.bigNumberStrings);
+ return packet.readDecimalLengthEncoded(opts.bigNumberStrings);
case FieldType.DATE:
if (opts.dateStrings) {
return packet.readAsciiStringLengthEncoded();
diff --git a/lib/cmd/handshake/auth/caching-sha2-password-auth.js b/lib/cmd/handshake/auth/caching-sha2-password-auth.js
new file mode 100644
index 00000000..598296d7
--- /dev/null
+++ b/lib/cmd/handshake/auth/caching-sha2-password-auth.js
@@ -0,0 +1,167 @@
+const PluginAuth = require('./plugin-auth');
+const fs = require('fs');
+const crypto = require('crypto');
+const Errors = require('../../../misc/errors');
+const NativePasswordAuth = require('./native-password-auth');
+const Sha256PasswordAuth = require('./sha256-password-auth');
+
+const State = {
+ INIT: 'INIT',
+ FAST_AUTH_RESULT: 'FAST_AUTH_RESULT',
+ REQUEST_SERVER_KEY: 'REQUEST_SERVER_KEY',
+ SEND_AUTH: 'SEND_AUTH'
+};
+
+/**
+ * Use caching Sha2 password authentication
+ */
+class CachingSha2PasswordAuth extends PluginAuth {
+ constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
+ super(resolve, reject, multiAuthResolver);
+ this.pluginData = pluginData;
+ this.sequenceNo = packSeq;
+ this.counter = 0;
+ this.state = State.INIT;
+ }
+
+ start(out, opts, info) {
+ this.exchange(this.pluginData, out, opts, info);
+ this.onPacketReceive = this.response;
+ }
+
+ exchange(buffer, out, opts, info) {
+ switch (this.state) {
+ case State.INIT:
+ const truncatedSeed = this.pluginData.slice(0, this.pluginData.length - 1);
+ const encPwd = NativePasswordAuth.encryptPassword(opts.password, truncatedSeed, 'sha256');
+ out.startPacket(this);
+ if (encPwd.length > 0) {
+ out.writeBuffer(encPwd, 0, encPwd.length);
+ out.flushBuffer(true);
+ } else {
+ out.writeEmptyPacket(true);
+ }
+ this.state = State.FAST_AUTH_RESULT;
+ return;
+
+ case State.FAST_AUTH_RESULT:
+ // length encoded numeric : 0x01 0x03/0x04
+ const fastAuthResult = buffer[1];
+ switch (fastAuthResult) {
+ case 0x03:
+ // success authentication
+ this.emit('send_end');
+ return this.successSend(packet, out, opts, info);
+
+ case 0x04:
+ if (opts.ssl) {
+ // using SSL, so sending password in clear
+ out.startPacket(this);
+ out.writeString(opts.password);
+ out.writeInt8(0);
+ out.flushBuffer(true);
+ return;
+ }
+
+ // retrieve public key from configuration or from server
+ if (opts.cachingRsaPublicKey) {
+ try {
+ let key = opts.cachingRsaPublicKey;
+ if (!key.includes('-----BEGIN')) {
+ // rsaPublicKey contain path
+ key = fs.readFileSync(key, 'utf8');
+ }
+ this.publicKey = Sha256PasswordAuth.retreivePublicKey(key);
+ } catch (err) {
+ return this.throwError(err, info);
+ }
+ // send Sha256Password Packet
+ Sha256PasswordAuth.sendSha256PwdPacket(
+ this,
+ this.pluginData,
+ this.publicKey,
+ opts.password,
+ out
+ );
+ } else {
+ if (!opts.allowPublicKeyRetrieval) {
+ return this.throwError(
+ Errors.createError(
+ 'RSA public key is not available client side. Either set option `cachingRsaPublicKey` to indicate' +
+ ' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
+ true,
+ info,
+ '08S01',
+ Errors.ER_CANNOT_RETRIEVE_RSA_KEY
+ ),
+ info
+ );
+ }
+ this.state = State.REQUEST_SERVER_KEY;
+ // ask caching public Key Retrieval
+ out.startPacket(this);
+ out.writeInt8(0x02);
+ out.flushBuffer(true);
+ }
+ return;
+ }
+
+ case State.REQUEST_SERVER_KEY:
+ this.publicKey = Sha256PasswordAuth.retreivePublicKey(buffer.toString('utf8', 1));
+ this.state = State.SEND_AUTH;
+ Sha256PasswordAuth.sendSha256PwdPacket(
+ this,
+ this.pluginData,
+ this.publicKey,
+ opts.password,
+ out
+ );
+ }
+ }
+
+ static retreivePublicKey(key) {
+ return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
+ }
+
+ static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
+ const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
+ out.startPacket(cmd);
+ const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
+ out.writeBuffer(enc, 0, enc.length);
+ out.flushBuffer(cmd);
+ }
+
+ // encrypt password with public key
+ static encrypt(seed, password, publicKey) {
+ const nullFinishedPwd = Buffer.from(password + '\0');
+ const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
+ const seedLength = seed.length;
+ for (let i = 0; i < xorBytes.length; i++) {
+ xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
+ }
+ return crypto.publicEncrypt(
+ { key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
+ xorBytes
+ );
+ }
+
+ response(packet, out, opts, info) {
+ const marker = packet.peek();
+ switch (marker) {
+ //*********************************************************************************************************
+ //* OK_Packet and Err_Packet ending packet
+ //*********************************************************************************************************
+ case 0x00:
+ case 0xff:
+ this.emit('send_end');
+ return this.successSend(packet, out, opts, info);
+
+ default:
+ let promptData = packet.readBufferRemaining();
+ this.exchange(promptData, out, opts, info);
+ this.onPacketReceive = this.response;
+ }
+ }
+}
+
+module.exports = CachingSha2PasswordAuth;
diff --git a/lib/cmd/handshake/auth/native-password-auth.js b/lib/cmd/handshake/auth/native-password-auth.js
index 8c8ec1df..464148ce 100644
--- a/lib/cmd/handshake/auth/native-password-auth.js
+++ b/lib/cmd/handshake/auth/native-password-auth.js
@@ -17,24 +17,28 @@ class NativePasswordAuth extends PluginAuth {
start(out, opts, info) {
//seed is ended with a null byte value.
const data = this.pluginData.slice(0, 20);
- let authToken = NativePasswordAuth.encryptPassword(opts.password, data);
+ let authToken = NativePasswordAuth.encryptPassword(opts.password, data, 'sha1');
out.startPacket(this);
- out.writeBuffer(authToken, 0, authToken.length);
- out.flushBuffer(true);
+ if (authToken.length > 0) {
+ out.writeBuffer(authToken, 0, authToken.length);
+ out.flushBuffer(true);
+ } else {
+ out.writeEmptyPacket(true);
+ }
this.emit('send_end');
this.onPacketReceive = this.successSend;
}
- static encryptPassword(password, seed) {
+ static encryptPassword(password, seed, algorithm) {
if (!password) return Buffer.alloc(0);
- let hash = Crypto.createHash('sha1');
+ let hash = Crypto.createHash(algorithm);
let stage1 = hash.update(password, 'utf8').digest();
- hash = Crypto.createHash('sha1');
+ hash = Crypto.createHash(algorithm);
let stage2 = hash.update(stage1).digest();
- hash = Crypto.createHash('sha1');
+ hash = Crypto.createHash(algorithm);
hash.update(seed);
hash.update(stage2);
diff --git a/lib/cmd/handshake/auth/sha256-password-auth.js b/lib/cmd/handshake/auth/sha256-password-auth.js
new file mode 100644
index 00000000..52291495
--- /dev/null
+++ b/lib/cmd/handshake/auth/sha256-password-auth.js
@@ -0,0 +1,142 @@
+const PluginAuth = require('./plugin-auth');
+const fs = require('fs');
+const crypto = require('crypto');
+const Errors = require('../../../misc/errors');
+
+/**
+ * Use Sha256 authentication
+ */
+class Sha256PasswordAuth extends PluginAuth {
+ constructor(packSeq, compressPackSeq, pluginData, resolve, reject, multiAuthResolver) {
+ super(resolve, reject, multiAuthResolver);
+ this.pluginData = pluginData;
+ this.sequenceNo = packSeq;
+ this.counter = 0;
+ this.initialState = true;
+ }
+
+ start(out, opts, info) {
+ this.exchange(this.pluginData, out, opts, info);
+ this.onPacketReceive = this.response;
+ }
+
+ exchange(buffer, out, opts, info) {
+ if (this.initialState) {
+ if (!opts.password) {
+ out.startPacket(this);
+ out.writeEmptyPacket(true);
+ return;
+ } else if (opts.ssl) {
+ // using SSL, so sending password in clear
+ out.startPacket(this);
+ if (opts.password) {
+ out.writeString(opts.password);
+ }
+ out.writeInt8(0);
+ out.flushBuffer(true);
+ return;
+ } else {
+ // retrieve public key from configuration or from server
+ if (opts.rsaPublicKey) {
+ try {
+ let key = opts.rsaPublicKey;
+ if (!key.includes('-----BEGIN')) {
+ // rsaPublicKey contain path
+ key = fs.readFileSync(key, 'utf8');
+ }
+ this.publicKey = Sha256PasswordAuth.retreivePublicKey(key);
+ } catch (err) {
+ return this.throwError(err, info);
+ }
+ } else {
+ if (!opts.allowPublicKeyRetrieval) {
+ return this.throwError(
+ Errors.createError(
+ 'RSA public key is not available client side. Either set option `rsaPublicKey` to indicate' +
+ ' public key path, or allow public key retrieval with option `allowPublicKeyRetrieval`',
+
+ true,
+ info,
+ '08S01',
+ Errors.ER_CANNOT_RETRIEVE_RSA_KEY
+ ),
+ info
+ );
+ }
+ this.initialState = false;
+
+ // ask public Key Retrieval
+ out.startPacket(this);
+ out.writeInt8(0x01);
+ out.flushBuffer(true);
+ return;
+ }
+ }
+
+ // send Sha256Password Packet
+ Sha256PasswordAuth.sendSha256PwdPacket(
+ this,
+ this.pluginData,
+ this.publicKey,
+ opts.password,
+ out
+ );
+ } else {
+ // has request public key
+ this.publicKey = Sha256PasswordAuth.retreivePublicKey(buffer.toString('utf8', 1));
+ Sha256PasswordAuth.sendSha256PwdPacket(
+ this,
+ this.pluginData,
+ this.publicKey,
+ opts.password,
+ out
+ );
+ }
+ }
+
+ static retreivePublicKey(key) {
+ return key.replace('(-+BEGIN PUBLIC KEY-+\\r?\\n|\\n?-+END PUBLIC KEY-+\\r?\\n?)', '');
+ }
+
+ static sendSha256PwdPacket(cmd, pluginData, publicKey, password, out) {
+ const truncatedSeed = pluginData.slice(0, pluginData.length - 1);
+ out.startPacket(cmd);
+ const enc = Sha256PasswordAuth.encrypt(truncatedSeed, password, publicKey);
+ out.writeBuffer(enc, 0, enc.length);
+ out.flushBuffer(cmd);
+ }
+
+ // encrypt password with public key
+ static encrypt(seed, password, publicKey) {
+ const nullFinishedPwd = Buffer.from(password + '\0');
+ const xorBytes = Buffer.allocUnsafe(nullFinishedPwd.length);
+ const seedLength = seed.length;
+ for (let i = 0; i < xorBytes.length; i++) {
+ xorBytes[i] = nullFinishedPwd[i] ^ seed[i % seedLength];
+ }
+ return crypto.publicEncrypt(
+ { key: publicKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
+ xorBytes
+ );
+ }
+
+ response(packet, out, opts, info) {
+ const marker = packet.peek();
+ switch (marker) {
+ //*********************************************************************************************************
+ //* OK_Packet and Err_Packet ending packet
+ //*********************************************************************************************************
+ case 0x00:
+ case 0xff:
+ this.emit('send_end');
+ return this.successSend(packet, out, opts, info);
+
+ default:
+ let promptData = packet.readBufferRemaining();
+ this.exchange(promptData, out, opts, info);
+ this.onPacketReceive = this.response;
+ }
+ }
+}
+
+module.exports = Sha256PasswordAuth;
diff --git a/lib/cmd/handshake/client-capabilities.js b/lib/cmd/handshake/client-capabilities.js
index 9c0692b9..336a13c7 100644
--- a/lib/cmd/handshake/client-capabilities.js
+++ b/lib/cmd/handshake/client-capabilities.js
@@ -1,7 +1,6 @@
'use strict';
const Capabilities = require('../../const/capabilities');
-const Long = require('long');
/**
* Initialize client capabilities according to options and server capabilities
@@ -10,7 +9,7 @@ const Long = require('long');
* @param info information
*/
module.exports.init = function (opts, info) {
- let capabilitiesLow =
+ let capabilities =
Capabilities.IGNORE_SPACE |
Capabilities.PROTOCOL_41 |
Capabilities.TRANSACTIONS |
@@ -21,53 +20,52 @@ module.exports.init = function (opts, info) {
Capabilities.PLUGIN_AUTH |
Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA;
- let capabilitiesHigh = 0;
- if ((info.serverCapabilities.low & Capabilities.MYSQL) === 0) {
- capabilitiesHigh |= Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO;
+ if ((info.serverCapabilities & Capabilities.MYSQL) === 0n) {
+ capabilities |= Capabilities.MARIADB_CLIENT_EXTENDED_TYPE_INFO;
}
if (opts.connectAttributes) {
- capabilitiesLow |= Capabilities.CONNECT_ATTRS;
+ capabilities |= Capabilities.CONNECT_ATTRS;
}
if (opts.foundRows) {
- capabilitiesLow |= Capabilities.FOUND_ROWS;
+ capabilities |= Capabilities.FOUND_ROWS;
}
if (opts.permitLocalInfile) {
- capabilitiesLow |= Capabilities.LOCAL_FILES;
+ capabilities |= Capabilities.LOCAL_FILES;
}
if (opts.multipleStatements) {
- capabilitiesLow |= Capabilities.MULTI_STATEMENTS;
+ capabilities |= Capabilities.MULTI_STATEMENTS;
}
- info.eofDeprecated = (info.serverCapabilities.low & Capabilities.DEPRECATE_EOF) > 0;
+ info.eofDeprecated = (info.serverCapabilities & Capabilities.DEPRECATE_EOF) > 0;
if (info.eofDeprecated) {
- capabilitiesLow |= Capabilities.DEPRECATE_EOF;
+ capabilities |= Capabilities.DEPRECATE_EOF;
}
if (opts.database) {
- capabilitiesLow |= Capabilities.CONNECT_WITH_DB;
+ capabilities |= Capabilities.CONNECT_WITH_DB;
}
// use compression only if requested by client and supported by server
if (opts.compress) {
- if (info.serverCapabilities.low & Capabilities.COMPRESS) {
- capabilitiesLow |= Capabilities.COMPRESS;
+ if (info.serverCapabilities & Capabilities.COMPRESS) {
+ capabilities |= Capabilities.COMPRESS;
} else {
opts.compress = false;
}
}
if (opts.bulk) {
- if (info.serverCapabilities.high & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) {
- capabilitiesHigh |= Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS;
+ if (info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) {
+ capabilities |= Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS;
}
}
if (opts.permitConnectionWhenExpired) {
- capabilitiesLow |= Capabilities.CAN_HANDLE_EXPIRED_PASSWORDS;
+ capabilities |= Capabilities.CAN_HANDLE_EXPIRED_PASSWORDS;
}
- info.clientCapabilities = new Long(capabilitiesLow, capabilitiesHigh, true);
+ info.clientCapabilities = capabilities;
};
diff --git a/lib/cmd/handshake/client-handshake-response.js b/lib/cmd/handshake/client-handshake-response.js
index 57c27df4..35571f1b 100644
--- a/lib/cmd/handshake/client-handshake-response.js
+++ b/lib/cmd/handshake/client-handshake-response.js
@@ -35,28 +35,27 @@ module.exports.send = function send(cmd, out, opts, pluginName, info) {
break;
default:
- authToken = NativePasswordAuth.encryptPassword(pwd, info.seed);
+ authToken = NativePasswordAuth.encryptPassword(pwd, info.seed, 'sha1');
authPlugin = 'mysql_native_password';
break;
}
-
- out.writeInt32(info.clientCapabilities.low);
+ out.writeInt32(Number(info.clientCapabilities & 0xffffffffn));
out.writeInt32(1024 * 1024 * 1024); // max packet size
out.writeInt8(opts.collation.index);
for (let i = 0; i < 19; i++) {
out.writeInt8(0);
}
- out.writeInt32(info.clientCapabilities.high);
+ out.writeInt32(Number(info.clientCapabilities >> 32n));
//null encoded user
out.writeString(opts.user || '');
out.writeInt8(0);
- if (info.serverCapabilities.low & Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) {
+ if (info.serverCapabilities & Capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA) {
out.writeLengthCoded(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
- } else if (info.serverCapabilities.low & Capabilities.SECURE_CONNECTION) {
+ } else if (info.serverCapabilities & Capabilities.SECURE_CONNECTION) {
out.writeInt8(authToken.length);
out.writeBuffer(authToken, 0, authToken.length);
} else {
@@ -64,18 +63,18 @@ module.exports.send = function send(cmd, out, opts, pluginName, info) {
out.writeInt8(0);
}
- if (info.clientCapabilities.low & Capabilities.CONNECT_WITH_DB) {
+ if (info.clientCapabilities & Capabilities.CONNECT_WITH_DB) {
out.writeString(opts.database);
out.writeInt8(0);
info.database = opts.database;
}
- if (info.clientCapabilities.low & Capabilities.PLUGIN_AUTH) {
- out.writeString(pluginName);
+ if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
+ out.writeString(authPlugin);
out.writeInt8(0);
}
- if (opts.connectAttributes && info.serverCapabilities.low & Capabilities.CONNECT_ATTRS) {
+ if (opts.connectAttributes && info.serverCapabilities & Capabilities.CONNECT_ATTRS) {
out.writeInt8(0xfc);
let initPos = out.pos; //save position, assuming connection attributes length will be less than 2 bytes length
out.writeInt16(0);
diff --git a/lib/cmd/handshake/handshake.js b/lib/cmd/handshake/handshake.js
index 07d5af62..29c7f325 100644
--- a/lib/cmd/handshake/handshake.js
+++ b/lib/cmd/handshake/handshake.js
@@ -7,6 +7,7 @@ const SslRequest = require('./ssl-request');
const ClientCapabilities = require('./client-capabilities');
const Errors = require('../../misc/errors');
const Capabilities = require('../../const/capabilities');
+const process = require('process');
/**
* Handle handshake.
@@ -25,7 +26,7 @@ class Handshake extends Command {
ensureOptionCompatibility(opts, info) {
if (
opts.multipleStatements &&
- (info.serverCapabilities.low & Capabilities.MULTI_STATEMENTS) === 0
+ (info.serverCapabilities & Capabilities.MULTI_STATEMENTS) === 0
) {
return this.throwNewError(
"Option `multipleStatements` enable, but server doesn'permits multi-statment",
@@ -36,7 +37,7 @@ class Handshake extends Command {
);
}
- if (opts.permitLocalInfile && (info.serverCapabilities.low & Capabilities.LOCAL_FILES) === 0) {
+ if (opts.permitLocalInfile && (info.serverCapabilities & Capabilities.LOCAL_FILES) === 0) {
return this.throwNewError(
"Option `permitLocalInfile` enable, but server doesn'permits using local file",
true,
@@ -60,8 +61,8 @@ class Handshake extends Command {
ClientCapabilities.init(opts, info);
if (opts.ssl) {
- if (info.serverCapabilities.low & Capabilities.SSL) {
- info.clientCapabilities.low |= Capabilities.SSL;
+ if (info.serverCapabilities & Capabilities.SSL) {
+ info.clientCapabilities |= Capabilities.SSL;
SslRequest.send(this, out, info, opts);
this._createSecureContext(
function () {
@@ -152,7 +153,7 @@ class Handshake extends Command {
*/
dispatchAuthSwitchRequest(packet, out, opts, info) {
let pluginName, pluginData;
- if (info.clientCapabilities.low & Capabilities.PLUGIN_AUTH) {
+ if (info.clientCapabilities & Capabilities.PLUGIN_AUTH) {
packet.skip(1); //header
if (packet.remaining()) {
//AuthSwitchRequest packet.
@@ -168,20 +169,25 @@ class Handshake extends Command {
pluginData = packet.readBufferRemaining();
}
- const plugin = Handshake.pluginHandler(
- pluginName,
- this.plugin.sequenceNo,
- this.plugin.compressSequenceNo,
- pluginData,
- info,
- opts,
- out,
- this.resolve,
- this.reject,
- this.handshakeResult.bind(this)
- );
+ try {
+ this.plugin = Handshake.pluginHandler(
+ pluginName,
+ this.plugin.sequenceNo,
+ this.plugin.compressSequenceNo,
+ pluginData,
+ info,
+ opts,
+ out,
+ this.resolve,
+ this.reject,
+ this.handshakeResult.bind(this)
+ );
+ } catch (err) {
+ this.reject(err);
+ return;
+ }
- if (!plugin) {
+ if (!this.plugin) {
this.reject(
Errors.createError(
"Client does not support authentication protocol '" +
@@ -194,7 +200,6 @@ class Handshake extends Command {
)
);
} else {
- this.plugin = plugin;
this._addCommand(this.plugin, false);
}
}
@@ -229,6 +234,32 @@ class Handshake extends Command {
pluginAuth = require('./auth/pam-password-auth.js');
break;
+ case 'sha256_password':
+ if (!Handshake.ensureNodeVersion(11, 6, 0)) {
+ throw Errors.createError(
+ 'sha256_password authentication plugin require node 11.6+',
+ true,
+ info,
+ '08004',
+ Errors.ER_MINIMUM_NODE_VERSION_REQUIRED
+ );
+ }
+ pluginAuth = require('./auth/sha256-password-auth.js');
+ break;
+
+ case 'caching_sha2_password':
+ if (!Handshake.ensureNodeVersion(11, 6, 0)) {
+ throw Errors.createError(
+ 'caching_sha2_password authentication plugin require node 11.6+',
+ true,
+ info,
+ '08004',
+ Errors.ER_MINIMUM_NODE_VERSION_REQUIRED
+ );
+ }
+ pluginAuth = require('./auth/caching-sha2-password-auth.js');
+ break;
+
//TODO "auth_gssapi_client"
default:
@@ -243,6 +274,15 @@ class Handshake extends Command {
multiAuthResolver
);
}
+
+ static ensureNodeVersion(major, minor, patch) {
+ const ver = process.versions.node.split('.');
+ return (
+ ver[0] > major ||
+ (ver[0] === major && ver[1] > minor) ||
+ (ver[0] === major && ver[1] === minor && ver[2] >= patch)
+ );
+ }
}
module.exports = Handshake;
diff --git a/lib/cmd/handshake/initial-handshake.js b/lib/cmd/handshake/initial-handshake.js
index aecd3081..f8edd0d9 100644
--- a/lib/cmd/handshake/initial-handshake.js
+++ b/lib/cmd/handshake/initial-handshake.js
@@ -2,7 +2,6 @@
const Capabilities = require('../../const/capabilities');
const ConnectionInformation = require('../../misc/connection-information');
-const Long = require('long');
/**
* Parser server initial handshake.
@@ -19,34 +18,33 @@ class InitialHandshake {
let seed1 = packet.readBuffer(8);
packet.skip(1); //reserved byte
- let serverCapabilitiesLow = packet.readUInt16();
+ let serverCapabilities = BigInt(packet.readUInt16());
//skip characterSet
packet.skip(1);
info.status = packet.readUInt16();
- serverCapabilitiesLow += packet.readUInt16() << 16;
+ serverCapabilities += BigInt(packet.readUInt16()) << 16n;
let saltLength = 0;
- if (serverCapabilitiesLow & Capabilities.PLUGIN_AUTH) {
+ if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
saltLength = Math.max(12, packet.readUInt8() - 9);
} else {
packet.skip(1);
}
- let serverCapabilitiesHigh = 0;
- if (serverCapabilitiesLow & Capabilities.MYSQL) {
+ if (serverCapabilities & Capabilities.MYSQL) {
packet.skip(10);
} else {
packet.skip(6);
- serverCapabilitiesHigh = packet.readUInt32();
+ serverCapabilities += BigInt(packet.readUInt32()) << 32n;
}
- if (serverCapabilitiesLow & Capabilities.SECURE_CONNECTION) {
+ if (serverCapabilities & Capabilities.SECURE_CONNECTION) {
let seed2 = packet.readBuffer(saltLength);
info.seed = Buffer.concat([seed1, seed2]);
} else {
info.seed = seed1;
}
packet.skip(1);
- info.serverCapabilities = new Long(serverCapabilitiesLow, serverCapabilitiesHigh, true);
+ info.serverCapabilities = serverCapabilities;
/**
* check for MariaDB 10.x replication hack , remove fake prefix if needed
@@ -61,10 +59,10 @@ class InitialHandshake {
//Support for MDEV-7780 faking server version
info.serverVersion.mariaDb =
info.serverVersion.raw.includes('MariaDB') ||
- (serverCapabilitiesLow & Capabilities.MYSQL) === 0;
+ (serverCapabilities & Capabilities.MYSQL) === 0n;
}
- if (serverCapabilitiesLow & Capabilities.PLUGIN_AUTH) {
+ if (serverCapabilities & Capabilities.PLUGIN_AUTH) {
this.pluginName = packet.readStringNullEnded();
} else {
this.pluginName = '';
diff --git a/lib/cmd/handshake/ssl-request.js b/lib/cmd/handshake/ssl-request.js
index a9756ee8..c6467d58 100644
--- a/lib/cmd/handshake/ssl-request.js
+++ b/lib/cmd/handshake/ssl-request.js
@@ -12,17 +12,17 @@ const Capabilities = require('../../const/capabilities');
*/
module.exports.send = function sendSSLRequest(cmd, out, info, opts) {
out.startPacket(cmd);
- out.writeInt32(info.clientCapabilities.low);
+ out.writeInt32(Number(info.clientCapabilities & 0xffffffffn));
out.writeInt32(1024 * 1024 * 1024); // max packet size
out.writeInt8(opts.collation.index);
for (let i = 0; i < 19; i++) {
out.writeInt8(0);
}
- if (info.serverCapabilities.low & Capabilities.MYSQL) {
+ if (info.serverCapabilities & Capabilities.MYSQL) {
out.writeInt32(0);
} else {
- out.writeInt32(info.clientCapabilities.high);
+ out.writeInt32(Number(info.clientCapabilities >> 32n));
}
out.flushBuffer(true);
diff --git a/lib/cmd/resultset.js b/lib/cmd/resultset.js
index e889d69c..a0ad8c6b 100644
--- a/lib/cmd/resultset.js
+++ b/lib/cmd/resultset.js
@@ -94,6 +94,9 @@ class ResultSet extends Command {
this.opts = {
timeout: cmdOpts.timeout,
autoJsonMap: connOpts.autoJsonMap,
+ arrayParenthesis: connOpts.arrayParenthesis,
+ supportBigInt:
+ cmdOpts.supportBigInt != undefined ? cmdOpts.supportBigInt : connOpts.supportBigInt,
checkDuplicate:
cmdOpts.checkDuplicate != undefined ? cmdOpts.checkDuplicate : connOpts.checkDuplicate,
typeCast: cmdOpts.typeCast != undefined ? cmdOpts.typeCast : connOpts.typeCast,
@@ -101,6 +104,7 @@ class ResultSet extends Command {
nestTables: cmdOpts.nestTables != undefined ? cmdOpts.nestTables : connOpts.nestTables,
dateStrings: cmdOpts.dateStrings != undefined ? cmdOpts.dateStrings : connOpts.dateStrings,
tz: cmdOpts.tz != undefined ? cmdOpts.tz : connOpts.tz,
+ pipelining: connOpts.pipelining,
localTz: cmdOpts.localTz != undefined ? cmdOpts.localTz : connOpts.localTz,
namedPlaceholders:
cmdOpts.namedPlaceholders != undefined
@@ -474,13 +478,20 @@ class ResultSet extends Command {
sqlMsg += '}';
} else {
sqlMsg += '[';
- for (let i = 0; i < values.length; i++) {
- if (i !== 0) sqlMsg += ',';
- let param = values[i];
- sqlMsg = ResultSet.logParam(sqlMsg, param);
+ if (Array.isArray(values)) {
+ for (let i = 0; i < values.length; i++) {
+ if (i !== 0) sqlMsg += ',';
+ let param = values[i];
+ sqlMsg = ResultSet.logParam(sqlMsg, param);
+ if (sqlMsg.length > this.opts.debugLen) {
+ sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
+ break;
+ }
+ }
+ } else {
+ sqlMsg = ResultSet.logParam(sqlMsg, values);
if (sqlMsg.length > this.opts.debugLen) {
sqlMsg = sqlMsg.substr(0, this.opts.debugLen) + '...';
- break;
}
}
sqlMsg += ']';
diff --git a/lib/config/connection-options.js b/lib/config/connection-options.js
index 1a7fb4ee..ec0067e4 100644
--- a/lib/config/connection-options.js
+++ b/lib/config/connection-options.js
@@ -62,6 +62,9 @@ class ConnectionOptions {
this.debugLen = opts.debugLen || 256;
this.foundRows = opts.foundRows === undefined || opts.foundRows;
this.host = opts.host || 'localhost';
+ this.rsaPublicKey = opts.rsaPublicKey;
+ this.cachingRsaPublicKey = opts.cachingRsaPublicKey;
+ this.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval || false;
this.initSql = opts.initSql;
this.forceVersionCheck = opts.forceVersionCheck || false;
this.maxAllowedPacket = opts.maxAllowedPacket;
@@ -71,6 +74,8 @@ class ConnectionOptions {
this.nestTables = opts.nestTables;
this.password = opts.password;
this.autoJsonMap = opts.autoJsonMap === undefined ? true : opts.autoJsonMap;
+ this.arrayParenthesis = opts.arrayParenthesis || false;
+ this.keepAliveDelay = opts.keepAliveDelay === undefined ? 0 : opts.keepAliveDelay;
this.permitSetMultiParamEntries = opts.permitSetMultiParamEntries || false;
this.permitConnectionWhenExpired = opts.permitConnectionWhenExpired || false;
this.pipelining = opts.pipelining;
@@ -98,6 +103,7 @@ class ConnectionOptions {
}
}
this.supportBigNumbers = opts.supportBigNumbers || false;
+ this.supportBigInt = opts.supportBigInt || false;
this.timezone = opts.timezone || 'local';
if (this.timezone && this.timezone !== 'local' && this.timezone !== 'auto') {
let tzName = this.timezone;
@@ -163,17 +169,24 @@ class ConnectionOptions {
static parseOptionDataType(opts) {
if (opts.bigNumberStrings) opts.bigNumberStrings = opts.bigNumberStrings == 'true';
if (opts.bulk) opts.bulk = opts.bulk == 'true';
+ if (opts.rsaPublicKey) opts.rsaPublicKey = opts.rsaPublicKey;
+ if (opts.cachingRsaPublicKey) opts.cachingRsaPublicKey = opts.cachingRsaPublicKey;
if (opts.logPackets) opts.logPackets = opts.logPackets == 'true';
+ if (opts.allowPublicKeyRetrieval)
+ opts.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval == 'true';
+
if (opts.charsetNumber && !isNaN(Number.parseInt(opts.charsetNumber))) {
opts.charsetNumber = Number.parseInt(opts.charsetNumber);
}
if (opts.compress) opts.compress = opts.compress == 'true';
if (opts.connectAttributes) opts.connectAttributes = JSON.parse(opts.connectAttributes);
if (opts.connectTimeout) opts.connectTimeout = parseInt(opts.connectTimeout);
+ if (opts.keepAliveDelay) opts.keepAliveDelay = parseInt(opts.keepAliveDelay);
if (opts.socketTimeout) opts.socketTimeout = parseInt(opts.socketTimeout);
if (opts.dateStrings) opts.dateStrings = opts.dateStrings == 'true';
if (opts.debug) opts.debug = opts.debug == 'true';
if (opts.autoJsonMap) opts.autoJsonMap = opts.autoJsonMap == 'true';
+ if (opts.arrayParenthesis) opts.arrayParenthesis = opts.arrayParenthesis == 'true';
if (opts.checkDuplicate) opts.checkDuplicate = opts.checkDuplicate == 'true';
if (opts.debugCompress) opts.debugCompress = opts.debugCompress == 'true';
@@ -192,6 +205,7 @@ class ConnectionOptions {
if (opts.forceVersionCheck) opts.forceVersionCheck = opts.forceVersionCheck == 'true';
if (opts.rowsAsArray) opts.rowsAsArray = opts.rowsAsArray == 'true';
if (opts.supportBigNumbers) opts.supportBigNumbers = opts.supportBigNumbers == 'true';
+ if (opts.supportBigInt) opts.supportBigInt = opts.supportBigInt == 'true';
if (opts.trace) opts.trace = opts.trace == 'true';
if (opts.ssl && (opts.ssl == 'true' || opts.ssl == 'false')) opts.ssl = opts.ssl == 'true';
return opts;
diff --git a/lib/connection.js b/lib/connection.js
index 6b455ddb..63856a10 100644
--- a/lib/connection.js
+++ b/lib/connection.js
@@ -659,11 +659,14 @@ function Connection(options) {
* @return {boolean} indicating if must use rewrite or bulk
*/
const canUseBulk = (values) => {
+ // not using info.isMariaDB() directly in case of callback use,
+ // without connection beeing completly finished.
let useBulk =
- info.isMariaDB() &&
+ info.serverVersion &&
+ info.serverVersion.mariaDb &&
info.hasMinVersion(10, 2, 7) &&
opts.bulk &&
- (info.serverCapabilities.high & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) > 0;
+ (info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) > 0n;
if (useBulk) {
//ensure that there is no stream object
@@ -726,7 +729,7 @@ function Connection(options) {
_authSucceed,
_authFail,
_createSecureContext.bind(this, _authFail),
- _addCommand.bind(this),
+ _addCommandEnable.bind(this),
_getSocket
);
Error.captureStackTrace(handshake);
@@ -934,6 +937,11 @@ function Connection(options) {
_socketConnected = true;
_socket.setTimeout(opts.socketTimeout, _socketTimeoutReached.bind(this, authFailHandler));
_socket.setNoDelay(true);
+
+ // keep alive for socket. This won't reset server wait_timeout use pool option idleTimeout for that
+ if (opts.keepAliveDelay) {
+ _socket.setKeepAlive(true, opts.keepAliveDelay);
+ }
}
}.bind(this)
);
@@ -952,7 +960,7 @@ function Connection(options) {
//enable packet compression according to option
if (opts.logPackets) info.enableLogPacket();
if (opts.compress) {
- if (info.serverCapabilities.low & Capabilities.COMPRESS) {
+ if (info.serverCapabilities & Capabilities.COMPRESS) {
_out.setStream(new CompressionOutputStream(_socket, opts, info));
_in = new CompressionInputStream(_in, _receiveQueue, opts, info);
_socket.removeAllListeners('data');
@@ -964,17 +972,12 @@ function Connection(options) {
}
}
- if (opts.pipelining) {
- _addCommand = _addCommandEnablePipeline;
- const commands = _receiveQueue.toArray();
- commands.forEach((cmd) => {
- const listeners = cmd.listeners('end');
- cmd.removeListener('end', listeners[0]);
- cmd.once('send_end', () => {
- setImmediate(_nextSendCmd);
- });
- });
- }
+ _addCommand = opts.pipelining ? _addCommandEnablePipeline : _addCommandEnable;
+
+ const commands = _waitingAuthenticationQueue.toArray();
+ commands.forEach((cmd) => {
+ _addCommand(cmd);
+ });
const errorInitialQueries = (err) => {
if (!err.fatal) this.end().catch((err) => {});
@@ -1154,6 +1157,18 @@ function Connection(options) {
_fatalError(err, true);
};
+ /**
+ * Add command to waiting queue until authentication.
+ *
+ * @param cmd command
+ * @returns {*} current command
+ * @private
+ */
+ const _addCommandQueue = (cmd) => {
+ _waitingAuthenticationQueue.push(cmd);
+ return cmd;
+ };
+
/**
* Add command to command sending and receiving queue.
*
@@ -1235,9 +1250,10 @@ function Connection(options) {
*/
const _socketErrorHandler = function (authFailHandler, err) {
if (_status === Status.CLOSING || _status === Status.CLOSED) return;
-
- _socket.writeBuf = () => {};
- _socket.flush = () => {};
+ if (_socket) {
+ _socket.writeBuf = () => {};
+ _socket.flush = () => {};
+ }
//socket has been ended without error
if (!err) {
@@ -1381,11 +1397,12 @@ function Connection(options) {
const info = new ConnectionInformation();
const _sendQueue = new Queue();
const _receiveQueue = new Queue();
+ const _waitingAuthenticationQueue = new Queue();
let _status = Status.NOT_CONNECTED;
let _socketConnected = false;
let _socket = null;
let _timeout = null;
- let _addCommand = _addCommandEnable;
+ let _addCommand = _addCommandQueue;
const _fatalError = _fatalErrorHandler(this);
let _out = new PacketOutputStream(opts, info);
let _in = new PacketInputStream(_unexpectedPacket.bind(this), _receiveQueue, _out, opts, info);
diff --git a/lib/const/capabilities.js b/lib/const/capabilities.js
index 17c9f8f2..aedd8568 100644
--- a/lib/const/capabilities.js
+++ b/lib/const/capabilities.js
@@ -3,62 +3,62 @@
* see : https://mariadb.com/kb/en/library/1-connecting-connecting/#capabilities
*/
/* mysql/old mariadb server/client */
-module.exports.MYSQL = 1;
+module.exports.MYSQL = 1n;
/* Found instead of affected rows */
-module.exports.FOUND_ROWS = 2;
+module.exports.FOUND_ROWS = 2n;
/* get all column flags */
-module.exports.LONG_FLAG = 4;
+module.exports.LONG_FLAG = 4n;
/* one can specify db on connect */
-module.exports.CONNECT_WITH_DB = 8;
+module.exports.CONNECT_WITH_DB = 8n;
/* don't allow database.table.column */
-module.exports.NO_SCHEMA = 1 << 4;
+module.exports.NO_SCHEMA = 1n << 4n;
/* can use compression protocol */
-module.exports.COMPRESS = 1 << 5;
+module.exports.COMPRESS = 1n << 5n;
/* odbc client */
-module.exports.ODBC = 1 << 6;
+module.exports.ODBC = 1n << 6n;
/* can use LOAD DATA LOCAL */
-module.exports.LOCAL_FILES = 1 << 7;
+module.exports.LOCAL_FILES = 1n << 7n;
/* ignore spaces before '' */
-module.exports.IGNORE_SPACE = 1 << 8;
+module.exports.IGNORE_SPACE = 1n << 8n;
/* new 4.1 protocol */
-module.exports.PROTOCOL_41 = 1 << 9;
+module.exports.PROTOCOL_41 = 1n << 9n;
/* this is an interactive client */
-module.exports.INTERACTIVE = 1 << 10;
+module.exports.INTERACTIVE = 1n << 10n;
/* switch to ssl after handshake */
-module.exports.SSL = 1 << 11;
+module.exports.SSL = 1n << 11n;
/* IGNORE sigpipes */
-module.exports.IGNORE_SIGPIPE = 1 << 12;
+module.exports.IGNORE_SIGPIPE = 1n << 12n;
/* client knows about transactions */
-module.exports.TRANSACTIONS = 1 << 13;
+module.exports.TRANSACTIONS = 1n << 13n;
/* old flag for 4.1 protocol */
-module.exports.RESERVED = 1 << 14;
+module.exports.RESERVED = 1n << 14n;
/* new 4.1 authentication */
-module.exports.SECURE_CONNECTION = 1 << 15;
+module.exports.SECURE_CONNECTION = 1n << 15n;
/* enable/disable multi-stmt support */
-module.exports.MULTI_STATEMENTS = 1 << 16;
+module.exports.MULTI_STATEMENTS = 1n << 16n;
/* enable/disable multi-results */
-module.exports.MULTI_RESULTS = 1 << 17;
+module.exports.MULTI_RESULTS = 1n << 17n;
/* multi-results in ps-protocol */
-module.exports.PS_MULTI_RESULTS = 1 << 18;
+module.exports.PS_MULTI_RESULTS = 1n << 18n;
/* client supports plugin authentication */
-module.exports.PLUGIN_AUTH = 1 << 19;
+module.exports.PLUGIN_AUTH = 1n << 19n;
/* permits connection attributes */
-module.exports.CONNECT_ATTRS = 1 << 20;
+module.exports.CONNECT_ATTRS = 1n << 20n;
/* Enable authentication response packet to be larger than 255 bytes. */
-module.exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = 1 << 21;
+module.exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = 1n << 21n;
/* Don't close the connection for a connection with expired password. */
-module.exports.CAN_HANDLE_EXPIRED_PASSWORDS = 1 << 22;
+module.exports.CAN_HANDLE_EXPIRED_PASSWORDS = 1n << 22n;
/* Capable of handling server state change information. Its a hint to the
server to include the state change information in Ok packet. */
-module.exports.SESSION_TRACK = 1 << 23;
+module.exports.SESSION_TRACK = 1n << 23n;
/* Client no longer needs EOF packet */
-module.exports.DEPRECATE_EOF = 1 << 24;
-module.exports.SSL_VERIFY_SERVER_CERT = 1 << 30;
+module.exports.DEPRECATE_EOF = 1n << 24n;
+module.exports.SSL_VERIFY_SERVER_CERT = 1n << 30n;
/* MariaDB extended capabilities */
/* Permit bulk insert*/
-module.exports.MARIADB_CLIENT_STMT_BULK_OPERATIONS = 1 << (34 - 32);
+module.exports.MARIADB_CLIENT_STMT_BULK_OPERATIONS = 1n << 34n;
/* Clients supporting extended metadata */
-module.exports.MARIADB_CLIENT_EXTENDED_TYPE_INFO = 1 << (35 - 32);
+module.exports.MARIADB_CLIENT_EXTENDED_TYPE_INFO = 1n << 35n;
diff --git a/lib/io/bulk-packet.js b/lib/io/bulk-packet.js
index 34b8b1c4..a15f749e 100644
--- a/lib/io/bulk-packet.js
+++ b/lib/io/bulk-packet.js
@@ -23,6 +23,7 @@ class BulkPacket {
this.pos = 4;
this.datatypes = [];
this.encoding = out.encoding;
+ this.statementId = -1;
this.waitingResponseNo = 1;
this.singleQuery = false;
this.haveErrorResponse = false;
@@ -50,6 +51,7 @@ class BulkPacket {
if (this.datatypes[r] !== 0x01) return true;
break;
case 'number':
+ case 'bigint':
if (this.datatypes[r] !== 0x0f) return true;
break;
case 'object':
@@ -86,11 +88,10 @@ class BulkPacket {
this.buf[this.pos++] = 0xfa;
//use last prepare command
- this.buf[this.pos++] = 0xff;
- this.buf[this.pos++] = 0xff;
- this.buf[this.pos++] = 0xff;
- this.buf[this.pos++] = 0xff;
-
+ this.buf[this.pos++] = this.statementId;
+ this.buf[this.pos++] = this.statementId >> 8;
+ this.buf[this.pos++] = this.statementId >> 16;
+ this.buf[this.pos++] = this.statementId >> 24;
//set bulk flags to Send types to server
this.buf[this.pos++] = 0x80;
this.buf[this.pos++] = 0x00;
@@ -106,6 +107,7 @@ class BulkPacket {
case 'boolean':
this.buf[this.pos++] = 0x01;
break;
+ case 'bigint':
case 'number':
this.buf[this.pos++] = 0x0f;
break;
diff --git a/lib/io/packet.js b/lib/io/packet.js
index 6cab9a5a..62ce9a16 100644
--- a/lib/io/packet.js
+++ b/lib/io/packet.js
@@ -183,27 +183,9 @@ class Packet {
}
readInt64() {
- const first = this.readInt32();
- const second = this.readInt32();
-
- const long = new Long(first, second, false);
- if (long.isNegative()) {
- if (long.lessThan(-9007199254740991)) return long;
- } else if (long.greaterThan(9007199254740991)) return long;
-
- return long.toNumber();
- }
-
- readUInt64() {
- const first = this.readInt32();
- const second = this.readInt32();
-
- const long = new Long(first, second, true);
- if (long.isNegative()) {
- if (long.lessThan(-9007199254740991)) return long;
- } else if (long.greaterThan(9007199254740991)) return long;
-
- return long.toNumber();
+ const val = this.buf.readBigInt64LE(this.pos);
+ this.pos += 8;
+ return val;
}
readUnsignedLength() {
@@ -216,7 +198,8 @@ class Packet {
case 0xfd:
return this.readUInt24();
case 0xfe:
- return this.readUInt64();
+ // limitation to BigInt signed value
+ return Number(this.readInt64());
default:
return type;
}
@@ -259,12 +242,28 @@ class Packet {
case 0xfd:
return this.readUInt24();
case 0xfe:
- return this.readInt64();
+ return Number(this.readInt64());
default:
return type;
}
}
+ readSignedLengthBigInt() {
+ const type = this.buf[this.pos++];
+ switch (type) {
+ case 0xfb:
+ return null;
+ case 0xfc:
+ return BigInt(this.readUInt16());
+ case 0xfd:
+ return BigInt(this.readUInt24());
+ case 0xfe:
+ return this.readInt64();
+ default:
+ return BigInt(type);
+ }
+ }
+
readAsciiStringLengthEncoded() {
const len = this.readUnsignedLength();
if (len === null) return null;
@@ -283,10 +282,16 @@ class Packet {
return Iconv.decode(this.buf.slice(this.pos - len, this.pos), encoding);
}
- readLongLengthEncoded(supportBigNumbers, bigNumberStrings, unsigned) {
+ readLongLengthEncoded(supportBigInt, supportBigNumbers, bigNumberStrings, unsigned) {
const len = this.readUnsignedLength();
if (len === null) return null;
+ if (supportBigInt) {
+ const str = this.buf.toString('ascii', this.pos, this.pos + len);
+ this.pos += len;
+ return BigInt(str);
+ }
+
let result = 0;
let negate = false;
let begin = this.pos;
@@ -313,7 +318,7 @@ class Packet {
return val;
}
- readDecimalLengthEncoded(supportBigNumbers, bigNumberStrings) {
+ readDecimalLengthEncoded(bigNumberStrings) {
const len = this.readUnsignedLength();
if (len === null) return null;
diff --git a/lib/io/rewrite-packet.js b/lib/io/rewrite-packet.js
index eec918d5..dfbec26d 100644
--- a/lib/io/rewrite-packet.js
+++ b/lib/io/rewrite-packet.js
@@ -378,13 +378,12 @@ class ReWritePacket {
//not enough room for current query, flush mark.
this.flushMark();
flushed = true;
- } else {
- //just mark ending query
- this.markPos = this.pos;
- if (isLast) {
- this.flushMark();
- flushed = true;
- }
+ }
+ //just mark ending query
+ this.markPos = this.pos;
+ if (isLast) {
+ this.flushMark();
+ flushed = true;
}
if (!isLast) flushed = this.writeStringAscii(',') || flushed;
}
@@ -443,13 +442,13 @@ class ReWritePacket {
this.pos = 4;
this.buf[this.pos++] = 0x03;
this.writeString(this.initStr);
+ this.markPos = undefined;
if (afterMark) {
if (this.buf.length - this.pos < afterMark.length)
this.growBuffer(afterMark.length - (this.buf.length - this.pos));
afterMark.copy(this.buf, this.pos, 0, afterMark.length);
this.pos += afterMark.length;
}
- this.markPos = undefined;
this.singleQuery = false;
this.singleQuerySequenceNo = undefined;
this.singleQueryCompressSequenceNo = undefined;
diff --git a/lib/misc/errors.js b/lib/misc/errors.js
index 48e99fc7..e0dafe01 100644
--- a/lib/misc/errors.js
+++ b/lib/misc/errors.js
@@ -101,6 +101,8 @@ module.exports.ER_DUPLICATE_FIELD = 45040;
module.exports.ER_CLIENT_OPTION_INCOMPATIBILITY = 45041;
module.exports.ER_PING_TIMEOUT = 45042;
module.exports.ER_BAD_PARAMETER_VALUE = 45043;
+module.exports.ER_CANNOT_RETRIEVE_RSA_KEY = 45044;
+module.exports.ER_MINIMUM_NODE_VERSION_REQUIRED = 45045;
const keys = Object.keys(module.exports);
const errByNo = {};
diff --git a/lib/misc/utils.js b/lib/misc/utils.js
index ab6ab297..2b6e1640 100644
--- a/lib/misc/utils.js
+++ b/lib/misc/utils.js
@@ -122,6 +122,7 @@ module.exports.escape = (opts, info, value) => {
switch (typeof value) {
case 'boolean':
return value ? 'true' : 'false';
+ case 'bigint':
case 'number':
return '' + value;
case 'object':
@@ -142,12 +143,12 @@ module.exports.escape = (opts, info, value) => {
} else if (Long.isLong(value)) {
return value.toString();
} else if (Array.isArray(value)) {
- let out = '(';
+ let out = opts.arrayParenthesis ? '(' : '';
for (let i = 0; i < value.length; i++) {
if (i !== 0) out += ',';
out += this.escape(opts, info, value[i]);
}
- out += ')';
+ if (opts.arrayParenthesis) out += ')';
return out;
} else {
if (
diff --git a/package.json b/package.json
index f8010e93..96387e8e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mariadb",
- "version": "2.4.2",
+ "version": "2.5.0",
"description": "fast mariadb/mysql connector.",
"main": "promise.js",
"types": "types/index.d.ts",
@@ -46,31 +46,31 @@
"license": "LGPL-2.1-or-later",
"dependencies": {
"@types/geojson": "^7946.0.7",
- "@types/node": "^13.9.8",
+ "@types/node": "^14.11.2",
"denque": "^1.4.1",
- "iconv-lite": "^0.5.1",
+ "iconv-lite": "^0.6.2",
"long": "^4.0.0",
"moment-timezone": "^0.5.31",
"please-upgrade-node": "^3.2.0"
},
"devDependencies": {
- "@typescript-eslint/eslint-plugin": "^2.26.0",
- "@typescript-eslint/parser": "^2.26.0",
+ "@typescript-eslint/eslint-plugin": "^4.3.0",
+ "@typescript-eslint/parser": "^4.3.0",
"benchmark": "^2.1.4",
"chai": "^4.2.0",
- "codecov": "^3.6.4",
+ "codecov": "^3.8.0",
"colors": "^1.4.0",
"dom-parser": "^0.1.6",
"error-stack-parser": "^2.0.6",
- "eslint": "^6.6.0",
- "eslint-config-prettier": "^6.10.1",
+ "eslint": "^7.11.0",
+ "eslint-config-prettier": "^6.12.0",
"eslint-plugin-markdown": "^1.0.1",
"eslint-plugin-prettier": "^3.1.0",
- "mocha": "^7.1.1",
+ "mocha": "^8.1.3",
"mocha-lcov-reporter": "^1.3.0",
"nyc": "^15.0.0",
- "prettier": "^2.0.2",
- "typescript": "^3.7.5"
+ "prettier": "^2.1.2",
+ "typescript": "^4.0.3"
},
"bugs": {
"url": "https://jira.mariadb.org/projects/CONJS/"
diff --git a/test/integration/datatype/test-buffer.js b/test/integration/datatype/test-buffer.js
index 6987f35f..e578e222 100644
--- a/test/integration/datatype/test-buffer.js
+++ b/test/integration/datatype/test-buffer.js
@@ -27,9 +27,14 @@ describe('buffer', () => {
? "_binary'let\\'s rocks\\n😊 🤘'"
: "_binary'let\\'s rocks\\nmore simple'"
);
- shareConn.query('CREATE TEMPORARY TABLE BufEscape(b blob)');
shareConn
- .query(' SELECT ' + shareConn.escape(buf) + ' t')
+ .query('DROP TABLE IF EXISTS BufEscape')
+ .then(() => {
+ return shareConn.query('CREATE TABLE BufEscape(b blob)');
+ })
+ .then(() => {
+ return shareConn.query(' SELECT ' + shareConn.escape(buf) + ' t');
+ })
.then((rows) => {
assert.deepEqual(rows, [{ t: buf }]);
return shareConn.query('INSERT INTO BufEscape VALUE (' + shareConn.escape(buf) + ')');
@@ -49,15 +54,26 @@ describe('buffer', () => {
it('text multi bytes characters', function (done) {
if (!base.utf8Collation()) this.skip();
- shareConn.query(
- 'CREATE TEMPORARY TABLE BlobTeststreamtest2 (id int primary key not null, st varchar(20), strm text) CHARSET utf8'
- );
const toInsert1 = '\u00D8bbcdefgh\njklmn"';
const toInsert2 = '\u00D8abcdefgh\njklmn"';
- shareConn.query('insert into BlobTeststreamtest2 values(?, ?, ?)', [2, toInsert1, toInsert2]);
shareConn
- .query('select * from BlobTeststreamtest2')
+ .query('DROP TABLE IF EXISTS BlobTeststreamtest2')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE BlobTeststreamtest2 (id int primary key not null, st varchar(20), strm text) CHARSET utf8'
+ );
+ })
+ .then(() => {
+ return shareConn.query('insert into BlobTeststreamtest2 values(?, ?, ?)', [
+ 2,
+ toInsert1,
+ toInsert2
+ ]);
+ })
+ .then(() => {
+ return shareConn.query('select * from BlobTeststreamtest2');
+ })
.then((rows) => {
assert.deepEqual(rows, [{ id: 2, st: toInsert1, strm: toInsert2 }]);
done();
@@ -76,12 +92,19 @@ describe('buffer', () => {
});
it('blobs to buffer type', function (done) {
- shareConn.query(
- 'CREATE TEMPORARY TABLE blobToBuff (id int not null primary key auto_increment, test longblob, test2 blob, test3 text)'
- );
- shareConn.query("insert into blobToBuff values(null, 'a','b','c')");
shareConn
- .query('SELECT * FROM blobToBuff', [buf])
+ .query('DROP TABLE IF EXISTS blobToBuff')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE blobToBuff (id int not null primary key auto_increment, test longblob, test2 blob, test3 text)'
+ );
+ })
+ .then(() => {
+ return shareConn.query("insert into blobToBuff values(null, 'a','b','c')");
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM blobToBuff', [buf]);
+ })
.then((rows) => {
assert.strictEqual(rows.length, 1);
assert.strictEqual(rows[0].id, 1);
@@ -94,13 +117,23 @@ describe('buffer', () => {
});
it('blob empty and null', function (done) {
- shareConn.query('CREATE TEMPORARY TABLE blobEmpty (val LONGBLOB)');
- shareConn.query('insert into blobEmpty values (?)', ['']);
- shareConn.query('insert into blobEmpty values (?)', ['hello']);
- shareConn.query('insert into blobEmpty values (?)', [null]);
-
shareConn
- .query('select * from blobEmpty')
+ .query('DROP TABLE IF EXISTS blobEmpty')
+ .then(() => {
+ return shareConn.query('CREATE TABLE blobEmpty (val LONGBLOB)');
+ })
+ .then(() => {
+ return shareConn.query('insert into blobEmpty values (?)', ['']);
+ })
+ .then(() => {
+ return shareConn.query('insert into blobEmpty values (?)', ['hello']);
+ })
+ .then(() => {
+ return shareConn.query('insert into blobEmpty values (?)', [null]);
+ })
+ .then(() => {
+ return shareConn.query('select * from blobEmpty');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ val: Buffer.from('') },
diff --git a/test/integration/datatype/test-datetime.js b/test/integration/datatype/test-datetime.js
index 685447b9..4527f8e0 100644
--- a/test/integration/datatype/test-datetime.js
+++ b/test/integration/datatype/test-datetime.js
@@ -57,7 +57,10 @@ describe('datetime', () => {
it('standard date', function (done) {
//using distant server, time might be different
- if (Conf.baseConfig.host !== 'localhost' && Conf.baseConfig.host !== 'mariadb.example.com')
+ if (
+ (Conf.baseConfig.host !== 'localhost' && Conf.baseConfig.host !== 'mariadb.example.com') ||
+ process.env.MAXSCALE_TEST_DISABLE
+ )
this.skip();
shareConn
diff --git a/test/integration/datatype/test-enum.js b/test/integration/datatype/test-enum.js
index c1255113..f39122ba 100644
--- a/test/integration/datatype/test-enum.js
+++ b/test/integration/datatype/test-enum.js
@@ -5,18 +5,31 @@ const { assert } = require('chai');
describe('enum', () => {
it('enum type verification', (done) => {
- shareConn.query(
- 'CREATE TEMPORARY TABLE fruits (\n' +
- ' id INT NOT NULL auto_increment PRIMARY KEY,\n' +
- " fruit ENUM('apple','orange','pear'),\n" +
- ' bushels INT)'
- );
- shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', ['pear', 20]);
- shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', ['apple', 100]);
- shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', [2, 110]);
- shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', [null, 120]);
shareConn
- .query('SELECT * FROM fruits')
+ .query('DROP TABLE IF EXISTS fruits')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE fruits (\n' +
+ ' id INT NOT NULL auto_increment PRIMARY KEY,\n' +
+ " fruit ENUM('apple','orange','pear'),\n" +
+ ' bushels INT)'
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', ['pear', 20]);
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', ['apple', 100]);
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', [2, 110]);
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO fruits (fruit,bushels) VALUES (?, ?)', [null, 120]);
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM fruits');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ id: 1, fruit: 'pear', bushels: 20 },
diff --git a/test/integration/datatype/test-float.js b/test/integration/datatype/test-float.js
index ad92c9e1..7e2f82b7 100644
--- a/test/integration/datatype/test-float.js
+++ b/test/integration/datatype/test-float.js
@@ -7,7 +7,10 @@ const Long = require('long');
describe('float', () => {
before((done) => {
shareConn
- .query('CREATE TEMPORARY TABLE testBigfloat (a FLOAT, b DOUBLE)')
+ .query('DROP TABLE IF EXISTS testBigfloat')
+ .then(() => {
+ return shareConn.query('CREATE TABLE testBigfloat (a FLOAT, b DOUBLE)');
+ })
.then(() => {
done();
})
@@ -29,9 +32,12 @@ describe('float', () => {
it('bigint format', (done) => {
shareConn
- .query(
- 'INSERT INTO testBigfloat values (-127.1, -128.2), (19925.0991, 900719925.4740991), (null, null)'
- )
+ .query('TRUNCATE testBigfloat')
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO testBigfloat values (-127.1, -128.2), (19925.0991, 900719925.4740991), (null, null)'
+ );
+ })
.then((rows) => {
return shareConn.query('SELECT * FROM testBigfloat');
})
diff --git a/test/integration/datatype/test-geometry.js b/test/integration/datatype/test-geometry.js
index 605948e8..7e8eda4d 100644
--- a/test/integration/datatype/test-geometry.js
+++ b/test/integration/datatype/test-geometry.js
@@ -7,15 +7,20 @@ describe('geometry data type', () => {
it('Point format', function (done) {
//MySQL 5.5 doesn't have ST_PointFromText function
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_point (g POINT)');
shareConn
- .query(
- 'INSERT INTO gis_point VALUES\n' +
- " (ST_PointFromText('POINT(10 10)')),\n" +
- " (ST_PointFromText('POINT(20 10)')),\n" +
- " (ST_PointFromText('POINT(20 20)')),\n" +
- " (ST_PointFromText('POINT(10 20)'))"
- )
+ .query('DROP TABLE IF EXISTS gis_point')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_point (g POINT)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_point VALUES\n' +
+ " (ST_PointFromText('POINT(10 10)')),\n" +
+ " (ST_PointFromText('POINT(20 10)')),\n" +
+ " (ST_PointFromText('POINT(20 20)')),\n" +
+ " (ST_PointFromText('POINT(10 20)'))"
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_point');
})
@@ -176,10 +181,16 @@ describe('geometry data type', () => {
it('Point Insert', function (done) {
//mysql < 8 doesn't permit sending empty data
if (!shareConn.info.isMariaDB()) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_point_insert (g POINT)');
shareConn
- .query('INSERT INTO gis_point_insert VALUES (?)', [{ type: 'Point', coordinates: [10, 10] }])
+ .query('DROP TABLE IF EXISTS gis_point_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_point_insert (g POINT)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_point_insert VALUES (?)', [
+ { type: 'Point', coordinates: [10, 10] }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_point_insert VALUES (?)', [
{ type: 'Point', coordinates: [20, 10] }
@@ -212,13 +223,17 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Point' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Point' }
: null
}
@@ -231,15 +246,19 @@ describe('geometry data type', () => {
it('LineString format', function (done) {
//MySQL 5.5 doesn't have ST_LineFromText function
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_line (g LINESTRING)');
shareConn
- .query(
- 'INSERT INTO gis_line VALUES\n' +
- " (ST_LineFromText('LINESTRING(0 0,0 10,10 0)')),\n" +
- " (ST_LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),\n" +
- ' (ST_LineStringFromWKB(ST_AsWKB(LineString(Point(10, 10), Point(40, 10)))))'
- )
+ .query('DROP TABLE IF EXISTS gis_line')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_line (g LINESTRING)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_line VALUES\n' +
+ " (ST_LineFromText('LINESTRING(0 0,0 10,10 0)')),\n" +
+ " (ST_LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),\n" +
+ ' (ST_LineStringFromWKB(ST_AsWKB(LineString(Point(10, 10), Point(40, 10)))))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_line');
})
@@ -284,19 +303,23 @@ describe('geometry data type', () => {
it('LineString insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_line_insert (g LINESTRING)');
shareConn
- .query('INSERT INTO gis_line_insert VALUES (?)', [
- {
- type: 'LineString',
- coordinates: [
- [0, 0],
- [0, 10],
- [10, 0]
- ]
- }
- ])
+ .query('DROP TABLE IF EXISTS gis_line_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_line_insert (g LINESTRING)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_line_insert VALUES (?)', [
+ {
+ type: 'LineString',
+ coordinates: [
+ [0, 0],
+ [0, 10],
+ [10, 0]
+ ]
+ }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_line_insert VALUES (?)', [
{
@@ -339,13 +362,17 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'LineString' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'LineString' }
: null
}
@@ -358,15 +385,19 @@ describe('geometry data type', () => {
it('Polygon format', function (done) {
//MySQL 5.5 doesn't have ST_PolygonFromText function
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_polygon (g POLYGON)');
shareConn
- .query(
- 'INSERT INTO gis_polygon VALUES\n' +
- " (ST_PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),\n" +
- " (ST_PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),\n" +
- ' (ST_PolyFromWKB(ST_AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))))'
- )
+ .query('DROP TABLE IF EXISTS gis_polygon')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_polygon (g POLYGON)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_polygon VALUES\n' +
+ " (ST_PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),\n" +
+ " (ST_PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),\n" +
+ ' (ST_PolyFromWKB(ST_AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_polygon');
})
@@ -429,23 +460,27 @@ describe('geometry data type', () => {
it('Polygon insert', function (done) {
//mysql < 8 doesn't permit sending empty data
if (!shareConn.info.isMariaDB()) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_polygon_insert (g POLYGON)');
shareConn
- .query('INSERT INTO gis_polygon_insert VALUES (?)', [
- {
- type: 'Polygon',
- coordinates: [
- [
- [10, 10],
- [20, 10],
- [20, 20],
- [10, 20],
- [10, 10]
+ .query('DROP TABLE IF EXISTS gis_polygon_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_polygon_insert (g POLYGON)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_polygon_insert VALUES (?)', [
+ {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [10, 10],
+ [20, 10],
+ [20, 20],
+ [10, 20],
+ [10, 10]
+ ]
]
- ]
- }
- ])
+ }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_polygon_insert VALUES (?)', [
{
@@ -522,13 +557,17 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Polygon' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Polygon' }
: null
}
@@ -543,14 +582,19 @@ describe('geometry data type', () => {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 6)) this.skip();
if (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 1, 4)) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_point (g MULTIPOINT)');
shareConn
- .query(
- 'INSERT INTO gis_multi_point VALUES\n' +
- " (ST_MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),\n" +
- " (ST_MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),\n" +
- ' (ST_MPointFromWKB(ST_AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))))'
- )
+ .query('DROP TABLE IF EXISTS gis_multi_point')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_point (g MULTIPOINT)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_multi_point VALUES\n' +
+ " (ST_MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),\n" +
+ " (ST_MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),\n" +
+ ' (ST_MPointFromWKB(ST_AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_point');
})
@@ -597,19 +641,24 @@ describe('geometry data type', () => {
//mysql < 8 doesn't permit sending empty data
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_point_insert (g MULTIPOINT)');
shareConn
- .query('INSERT INTO gis_multi_point_insert VALUES (?)', [
- {
- type: 'MultiPoint',
- coordinates: [
- [0, 0],
- [10, 10],
- [10, 20],
- [20, 20]
- ]
- }
- ])
+ .query('DROP TABLE IF EXISTS gis_multi_point_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_point_insert (g MULTIPOINT)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_multi_point_insert VALUES (?)', [
+ {
+ type: 'MultiPoint',
+ coordinates: [
+ [0, 0],
+ [10, 10],
+ [10, 20],
+ [20, 20]
+ ]
+ }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_multi_point_insert VALUES (?)', [
{ type: 'MultiPoint', coordinates: [[10, 0]] }
@@ -649,13 +698,17 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPoint' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPoint' }
: null
}
@@ -670,14 +723,19 @@ describe('geometry data type', () => {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 6)) this.skip();
if (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 1, 4)) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_line (g MULTILINESTRING)');
shareConn
- .query(
- 'INSERT INTO gis_multi_line VALUES\n' +
- " (ST_MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),\n" +
- " (ST_MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),\n" +
- ' (ST_MLineFromWKB(ST_AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))))'
- )
+ .query('DROP TABLE IF EXISTS gis_multi_line')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_line (g MULTILINESTRING)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_multi_line VALUES\n' +
+ " (ST_MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),\n" +
+ " (ST_MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),\n" +
+ ' (ST_MLineFromWKB(ST_AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_line');
})
@@ -738,25 +796,30 @@ describe('geometry data type', () => {
//mysql < 8 doesn't permit sending empty data
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_line_insert (g MULTILINESTRING)');
shareConn
- .query('INSERT INTO gis_multi_line_insert VALUES (?)', [
- {
- type: 'MultiLineString',
- coordinates: [
- [
- [10, 48],
- [10, 21],
- [10, 0]
- ],
- [
- [16, 0],
- [16, 23],
- [16, 48]
+ .query('DROP TABLE IF EXISTS gis_multi_line_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_line_insert (g MULTILINESTRING)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_multi_line_insert VALUES (?)', [
+ {
+ type: 'MultiLineString',
+ coordinates: [
+ [
+ [10, 48],
+ [10, 21],
+ [10, 0]
+ ],
+ [
+ [16, 0],
+ [16, 23],
+ [16, 48]
+ ]
]
- ]
- }
- ])
+ }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_multi_line_insert VALUES (?)', [
{
@@ -822,19 +885,25 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
}
@@ -849,14 +918,19 @@ describe('geometry data type', () => {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 6)) this.skip();
if (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 1, 4)) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_polygon (g MULTIPOLYGON)');
shareConn
- .query(
- 'INSERT INTO gis_multi_polygon VALUES\n' +
- " (ST_MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),\n" +
- " (ST_MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),\n" +
- ' (ST_MPolyFromWKB(ST_AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))))'
- )
+ .query('DROP TABLE IF EXISTS gis_multi_polygon')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_polygon (g MULTIPOLYGON)');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO gis_multi_polygon VALUES\n' +
+ " (ST_MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),\n" +
+ " (ST_MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),\n" +
+ ' (ST_MPolyFromWKB(ST_AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_polygon');
})
@@ -951,40 +1025,45 @@ describe('geometry data type', () => {
//mysql < 8 doesn't permit sending empty data
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_polygon_insert (g MULTIPOLYGON)');
shareConn
- .query('INSERT INTO gis_multi_polygon_insert VALUES (?)', [
- {
- type: 'MultiPolygon',
- coordinates: [
- [
+ .query('DROP TABLE IF EXISTS gis_multi_polygon_insert')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_polygon_insert (g MULTIPOLYGON)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO gis_multi_polygon_insert VALUES (?)', [
+ {
+ type: 'MultiPolygon',
+ coordinates: [
[
- [28, 26],
- [28, 0],
- [84, 0],
- [84, 42],
- [28, 26]
+ [
+ [28, 26],
+ [28, 0],
+ [84, 0],
+ [84, 42],
+ [28, 26]
+ ],
+ [
+ [52, 18],
+ [66, 23],
+ [73, 9],
+ [48, 6],
+ [52, 18]
+ ]
],
[
- [52, 18],
- [66, 23],
- [73, 9],
- [48, 6],
- [52, 18]
- ]
- ],
- [
- [
- [59, 18],
- [67, 18],
- [67, 13],
- [59, 13],
- [59, 18]
+ [
+ [59, 18],
+ [67, 18],
+ [67, 13],
+ [59, 13],
+ [59, 18]
+ ]
]
]
- ]
- }
- ])
+ }
+ ]);
+ })
.then(() => {
return shareConn.query('INSERT INTO gis_multi_polygon_insert VALUES (?)', [
{
@@ -1101,25 +1180,33 @@ describe('geometry data type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
}
@@ -1137,17 +1224,22 @@ describe('geometry data type', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE gis_geometrycollection (g GEOMETRYCOLLECTION)');
conn
- .query(
- 'INSERT INTO gis_geometrycollection VALUES\n' +
- " (ST_GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),\n" +
- ' (ST_GeometryFromWKB(ST_AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))))' +
- (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(8, 0, 0)
- ? ''
- : ",(ST_GeomFromText('GeometryCollection()')),\n" +
- " (ST_GeomFromText('GeometryCollection EMPTY'))")
- )
+ .query('DROP TABLE IF EXISTS gis_geometrycollection')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_geometrycollection (g GEOMETRYCOLLECTION)');
+ })
+ .then(() => {
+ return conn.query(
+ 'INSERT INTO gis_geometrycollection VALUES\n' +
+ " (ST_GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),\n" +
+ ' (ST_GeometryFromWKB(ST_AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))))' +
+ (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(8, 0, 0)
+ ? ''
+ : ",(ST_GeomFromText('GeometryCollection()')),\n" +
+ " (ST_GeomFromText('GeometryCollection EMPTY'))")
+ );
+ })
.then(() => {
return conn.query('SELECT * FROM gis_geometrycollection');
})
@@ -1261,81 +1353,88 @@ describe('geometry data type', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE gis_geometrycollection_ins (g GEOMETRYCOLLECTION)');
conn
- .query('INSERT INTO gis_geometrycollection_ins VALUES (?)', [
- {
- type: 'GeometryCollection',
- geometries: [
- {
- type: 'Point',
- coordinates: [10, 10]
- },
- {
- type: 'LineString',
- coordinates: [
- [0, 0],
- [0, 10],
- [10, 0]
- ]
- },
- {
- type: 'MultiPoint',
- coordinates: [
- [0, 0],
- [10, 10],
- [10, 20],
- [20, 20]
- ]
- },
- {
- type: 'MultiLineString',
- coordinates: [
- [
- [10, 48],
- [10, 21],
+ .query('DROP TABLE IF EXISTS gis_geometrycollection_ins')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE gis_geometrycollection_ins (g GEOMETRYCOLLECTION)'
+ );
+ })
+ .then(() => {
+ return conn.query('INSERT INTO gis_geometrycollection_ins VALUES (?)', [
+ {
+ type: 'GeometryCollection',
+ geometries: [
+ {
+ type: 'Point',
+ coordinates: [10, 10]
+ },
+ {
+ type: 'LineString',
+ coordinates: [
+ [0, 0],
+ [0, 10],
[10, 0]
- ],
- [
- [16, 0],
- [16, 23],
- [16, 48]
]
- ]
- },
- {
- type: 'MultiPolygon',
- coordinates: [
- [
+ },
+ {
+ type: 'MultiPoint',
+ coordinates: [
+ [0, 0],
+ [10, 10],
+ [10, 20],
+ [20, 20]
+ ]
+ },
+ {
+ type: 'MultiLineString',
+ coordinates: [
[
- [28, 26],
- [28, 0],
- [84, 0],
- [84, 42],
- [28, 26]
+ [10, 48],
+ [10, 21],
+ [10, 0]
],
[
- [52, 18],
- [66, 23],
- [73, 9],
- [48, 6],
- [52, 18]
+ [16, 0],
+ [16, 23],
+ [16, 48]
]
- ],
- [
+ ]
+ },
+ {
+ type: 'MultiPolygon',
+ coordinates: [
+ [
+ [
+ [28, 26],
+ [28, 0],
+ [84, 0],
+ [84, 42],
+ [28, 26]
+ ],
+ [
+ [52, 18],
+ [66, 23],
+ [73, 9],
+ [48, 6],
+ [52, 18]
+ ]
+ ],
[
- [59, 18],
- [67, 18],
- [67, 13],
- [59, 13],
- [59, 18]
+ [
+ [59, 18],
+ [67, 18],
+ [67, 13],
+ [59, 13],
+ [59, 18]
+ ]
]
]
- ]
- }
- ]
- }
- ])
+ }
+ ]
+ }
+ ]);
+ })
.then(() => {
return conn.query('INSERT INTO gis_geometrycollection_ins VALUES (?)', [
{
diff --git a/test/integration/datatype/test-integer.js b/test/integration/datatype/test-integer.js
index f73a16ad..432e9fb2 100644
--- a/test/integration/datatype/test-integer.js
+++ b/test/integration/datatype/test-integer.js
@@ -7,7 +7,12 @@ const Long = require('long');
describe('integer with big value', () => {
before((done) => {
shareConn
- .query('CREATE TEMPORARY TABLE testBigint (v BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY)')
+ .query('DROP TABLE IF EXISTS testBigint')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE testBigint (v BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY)'
+ );
+ })
.then(() => {
done();
})
@@ -31,7 +36,10 @@ describe('integer with big value', () => {
it('decimal value without truncation', function (done) {
shareConn
- .query('CREATE TEMPORARY TABLE floatTest (t DOUBLE, t2 DECIMAL(32,16))')
+ .query('DROP TABLE IF EXISTS floatTest')
+ .then(() => {
+ return shareConn.query('CREATE TABLE floatTest (t DOUBLE, t2 DECIMAL(32,16))');
+ })
.then(() => {
return shareConn.query(
'INSERT INTO floatTest VALUES (-0.9999237060546875, 9999237060546875.9999237060546875)'
@@ -62,16 +70,21 @@ describe('integer with big value', () => {
return shareConn.query('INSERT INTO testBigint values ()');
})
.then((rows) => {
- assert.strictEqual(rows.insertId.toNumber(), 9007199254740992);
+ assert.strictEqual(rows.insertId, 9007199254740992);
+ return shareConn.query('INSERT INTO testBigint values ()');
+ })
+ .then((rows) => {
+ assert.strictEqual(rows.insertId, 9007199254740993);
return shareConn.query('SELECT * FROM testBigint');
})
.then((rows) => {
- assert.strictEqual(rows.length, 5);
+ assert.strictEqual(rows.length, 6);
assert.strictEqual(rows[0].v, -9007199254740991);
assert.strictEqual(rows[1].v, 127);
assert.strictEqual(rows[2].v, 128);
assert.strictEqual(rows[3].v, 9007199254740991);
assert.strictEqual(rows[4].v, 9007199254740992);
+ assert.strictEqual(rows[4].v, 9007199254740993);
assert.strictEqual(typeof rows[3].v, 'number');
return shareConn.query({
supportBigNumbers: true,
@@ -79,67 +92,121 @@ describe('integer with big value', () => {
});
})
.then((rows) => {
- assert.strictEqual(rows.length, 5);
+ assert.strictEqual(rows.length, 6);
assert.strictEqual(rows[0].v, -9007199254740991);
assert.strictEqual(rows[1].v, 127);
assert.strictEqual(rows[2].v, 128);
assert.strictEqual(rows[3].v, 9007199254740991);
assert.strictEqual(typeof rows[4].v, 'object');
assert.strictEqual(rows[4].v.toString(), '9007199254740992');
+ assert.strictEqual(rows[5].v.toString(), '9007199254740993');
return shareConn.query({
bigNumberStrings: true,
sql: 'SELECT * FROM testBigint'
});
})
.then((rows) => {
- assert.strictEqual(rows.length, 5);
+ assert.strictEqual(rows.length, 6);
assert.strictEqual(rows[0].v, -9007199254740991);
assert.strictEqual(rows[1].v, 127);
assert.strictEqual(rows[2].v, 128);
assert.strictEqual(rows[3].v, 9007199254740991);
assert.strictEqual(rows[4].v, '9007199254740992');
+ assert.strictEqual(rows[5].v, '9007199254740993');
assert.strictEqual(typeof rows[4].v, 'string');
- done();
+ return shareConn.query({
+ supportBigInt: true,
+ sql: 'SELECT * FROM testBigint'
+ });
+ })
+ .then((rows) => {
+ assert.strictEqual(rows.length, 6);
+ assert.strictEqual(rows[0].v, -9007199254740991n);
+ assert.strictEqual(rows[1].v, 127n);
+ assert.strictEqual(rows[2].v, 128n);
+ assert.strictEqual(rows[3].v, 9007199254740991n);
+ assert.strictEqual(rows[4].v, 9007199254740992n);
+ assert.strictEqual(rows[5].v, 9007199254740993n);
+ assert.strictEqual(typeof rows[4].v, 'bigint');
+ return base.createConnection({ supportBigInt: true });
+ })
+ .then((conn2) => {
+ conn2
+ .query('INSERT INTO testBigint values ()')
+ .then((rows) => {
+ assert.strictEqual(rows.insertId, 9007199254740994n);
+ conn2.end();
+ done();
+ })
+ .catch(done);
})
.catch(done);
});
it('bigint format null ', (done) => {
- shareConn.query('CREATE TEMPORARY TABLE testBigintNull (v BIGINT)');
- shareConn.query('INSERT INTO testBigintNull values (127), (null)');
-
- const checkResult = (rows) => {
- assert.strictEqual(rows.length, 2);
- assert.strictEqual(rows[0].v, 127);
- assert.strictEqual(rows[1].v, null);
- };
-
- shareConn.query('SELECT * FROM testBigintNull').then(checkResult);
- shareConn
- .query({ supportBigNumbers: true, sql: 'SELECT * FROM testBigintNull' })
- .then(checkResult);
shareConn
- .query({ bigNumberStrings: true, sql: 'SELECT * FROM testBigintNull' })
+ .query('DROP TABLE IF EXISTS testBigintNull')
+ .then(() => {
+ return shareConn.query('CREATE TABLE testBigintNull (v BIGINT)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO testBigintNull values (127), (null)');
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM testBigintNull');
+ })
.then((rows) => {
- checkResult(rows);
+ assert.strictEqual(rows.length, 2);
+ assert.strictEqual(rows[0].v, 127);
+ assert.strictEqual(rows[1].v, null);
+ return shareConn.query({ supportBigNumbers: true, sql: 'SELECT * FROM testBigintNull' });
+ })
+ .then((rows) => {
+ assert.strictEqual(rows.length, 2);
+ assert.strictEqual(rows[0].v, 127);
+ assert.strictEqual(rows[1].v, null);
+ return shareConn.query({ bigNumberStrings: true, sql: 'SELECT * FROM testBigintNull' });
+ })
+ .then((rows) => {
+ assert.strictEqual(rows.length, 2);
+ assert.strictEqual(rows[0].v, 127);
+ assert.strictEqual(rows[1].v, null);
+ return shareConn.query({ supportBigInt: true, sql: 'SELECT * FROM testBigintNull' });
+ })
+ .then((rows) => {
+ assert.strictEqual(rows.length, 2);
+ assert.strictEqual(rows[0].v, 127n);
+ assert.strictEqual(rows[1].v, null);
done();
});
});
it('numeric fields conversion to int', (done) => {
- shareConn.query(
- 'CREATE TEMPORARY TABLE intAllField (' +
- 't1 TINYINT(1), t2 SMALLINT(1), t3 MEDIUMINT(1), t4 INT(1), t5 BIGINT(1), t6 DECIMAL(1), t7 FLOAT, t8 DOUBLE)'
- );
- shareConn.query(
- 'INSERT INTO intAllField VALUES (null, null, null, null, null, null, null, null)'
- );
- shareConn.query('INSERT INTO intAllField VALUES (0, 0, 0, 0, 0, 0, 0, 0)');
- shareConn.query('INSERT INTO intAllField VALUES (1, 1, 1, 1, 1, 1, 1, 1)');
- shareConn.query('INSERT INTO intAllField VALUES (2, 2, 2, 2, 2, 2, 2, 2)');
-
shareConn
- .query('SELECT * FROM intAllField')
+ .query('DROP TABLE IF EXISTS intAllField')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE intAllField (' +
+ 't1 TINYINT(1), t2 SMALLINT(1), t3 MEDIUMINT(1), t4 INT(1), t5 BIGINT(1), t6 DECIMAL(1), t7 FLOAT, t8 DOUBLE)'
+ );
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO intAllField VALUES (null, null, null, null, null, null, null, null)'
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO intAllField VALUES (0, 0, 0, 0, 0, 0, 0, 0)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO intAllField VALUES (1, 1, 1, 1, 1, 1, 1, 1)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO intAllField VALUES (2, 2, 2, 2, 2, 2, 2, 2)');
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM intAllField');
+ })
.then((res) => {
assert.deepEqual(res, [
{
@@ -164,9 +231,14 @@ describe('integer with big value', () => {
it('using very big number', function (done) {
const maxValue = Long.fromString('18446744073709551615', true);
base.createConnection({ supportBigNumbers: true }).then((conn) => {
- conn.query('CREATE TEMPORARY TABLE BIG_NUMBER (val BIGINT unsigned)');
conn
- .query('INSERT INTO BIG_NUMBER values (?), (?)', [10, maxValue])
+ .query('DROP TABLE IF EXISTS BIG_NUMBER')
+ .then(() => {
+ return conn.query('CREATE TABLE BIG_NUMBER (val BIGINT unsigned)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO BIG_NUMBER values (?), (?)', [10, maxValue]);
+ })
.then(() => {
return conn.query('SELECT * FROM BIG_NUMBER LIMIT ?', [maxValue]);
})
@@ -178,4 +250,27 @@ describe('integer with big value', () => {
.catch(done);
});
});
+
+ it('using very big number bigint', function (done) {
+ const maxValue = 18446744073709551615n;
+ base.createConnection({ supportBigInt: true }).then((conn) => {
+ conn
+ .query('DROP TABLE IF EXISTS BIG_NUMBER')
+ .then(() => {
+ return conn.query('CREATE TABLE BIG_NUMBER (val BIGINT unsigned)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO BIG_NUMBER values (?), (?)', [10, maxValue]);
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM BIG_NUMBER LIMIT ?', [maxValue]);
+ })
+ .then((res) => {
+ assert.deepEqual(res, [{ val: 10n }, { val: maxValue }]);
+ conn.end();
+ done();
+ })
+ .catch(done);
+ });
+ });
});
diff --git a/test/integration/datatype/test-json.js b/test/integration/datatype/test-json.js
index da5d579d..5336e2d1 100644
--- a/test/integration/datatype/test-json.js
+++ b/test/integration/datatype/test-json.js
@@ -26,24 +26,40 @@ describe('json', () => {
this.skip();
}
- shareConn.query('CREATE TEMPORARY TABLE `test-json-insert-type` (val1 JSON)');
const obj = { id: 2, val: 'test' };
- shareConn.query(
- {
- stringifyObjects: true,
- sql: 'INSERT INTO `test-json-insert-type` values (?)'
- },
- [obj]
- );
- shareConn.query('INSERT INTO `test-json-insert-type` values (?)', [JSON.stringify(obj)]);
- validateJSON('test-json-insert-type', done);
+ shareConn
+ .query('DROP TABLE IF EXISTS `test-json-insert-type`')
+ .then(() => {
+ return shareConn.query('CREATE TABLE `test-json-insert-type` (val1 JSON)');
+ })
+ .then(() => {
+ return shareConn.query(
+ {
+ stringifyObjects: true,
+ sql: 'INSERT INTO `test-json-insert-type` values (?)'
+ },
+ [obj]
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO `test-json-insert-type` values (?)', [
+ JSON.stringify(obj)
+ ]);
+ })
+ .then(() => {
+ validateJSON('test-json-insert-type', done);
+ })
+ .catch(done);
});
function validateJSON(tableName, done) {
shareConn
.query('SELECT * FROM `' + tableName + '`')
.then((rows) => {
- if (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 5, 2)) {
+ if (
+ (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 5, 2)) ||
+ process.env.MAXSCALE_TEST_DISABLE
+ ) {
const val1 = JSON.parse(rows[0].val1);
const val2 = JSON.parse(rows[1].val1);
assert.equal(val1.id, 2);
@@ -70,26 +86,37 @@ describe('json', () => {
this.skip();
}
- shareConn.query(
- 'CREATE TEMPORARY TABLE `test-json-return-type` (val1 JSON, val2 LONGTEXT, val3 LONGBLOB)'
- );
const obj = { id: 2, val: 'test' };
const jsonString = JSON.stringify(obj);
- shareConn.query(
- "INSERT INTO `test-json-return-type` values ('" +
- jsonString +
- "','" +
- jsonString +
- "','" +
- jsonString +
- "')"
- );
shareConn
- .query('SELECT * FROM `test-json-return-type`')
+ .query('DROP TABLE IF EXISTS `test-json-return-type`')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE `test-json-return-type` (val1 JSON, val2 LONGTEXT, val3 LONGBLOB)'
+ );
+ })
+ .then(() => {
+ return shareConn.query(
+ "INSERT INTO `test-json-return-type` values ('" +
+ jsonString +
+ "','" +
+ jsonString +
+ "','" +
+ jsonString +
+ "')"
+ );
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM `test-json-return-type`');
+ })
.then((rows) => {
if (shareConn.info.isMariaDB()) {
- if (shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)) {
+ if (
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
+ ) {
assert.deepEqual(rows[0].val1, obj);
} else {
assert.equal(rows[0].val1, jsonString);
@@ -108,29 +135,36 @@ describe('json', () => {
it('disable json format', function (done) {
//server permit JSON format
if (
- (shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 5, 2)) ||
+ (shareConn.info.isMariaDB() &&
+ (!shareConn.info.hasMinVersion(10, 5, 2) || process.env.MAXSCALE_TEST_DISABLE)) ||
!shareConn.info.isMariaDB()
) {
this.skip();
}
base.createConnection({ autoJsonMap: false }).then((conn) => {
- conn.query(
- 'CREATE TEMPORARY TABLE `test-json-return-type` (val1 JSON, val2 LONGTEXT, val3 LONGBLOB)'
- );
const obj = { id: 2, val: 'test' };
const jsonString = JSON.stringify(obj);
- conn.query(
- "INSERT INTO `test-json-return-type` values ('" +
- jsonString +
- "','" +
- jsonString +
- "','" +
- jsonString +
- "')"
- );
-
conn
- .query('SELECT * FROM `test-json-return-type`')
+ .query('DROP TABLE IF EXISTS `test-json-return-type`')
+ .then(() => {
+ return conn.query(
+ 'CREATE TABLE `test-json-return-type` (val1 JSON, val2 LONGTEXT, val3 LONGBLOB)'
+ );
+ })
+ .then(() => {
+ return conn.query(
+ "INSERT INTO `test-json-return-type` values ('" +
+ jsonString +
+ "','" +
+ jsonString +
+ "','" +
+ jsonString +
+ "')"
+ );
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM `test-json-return-type`');
+ })
.then((rows) => {
assert.equal(rows[0].val1, jsonString);
assert.equal(rows[0].val2, jsonString);
diff --git a/test/integration/datatype/test-mapping.js b/test/integration/datatype/test-mapping.js
index c62e06ad..2f8e0524 100644
--- a/test/integration/datatype/test-mapping.js
+++ b/test/integration/datatype/test-mapping.js
@@ -79,98 +79,109 @@ describe('mapping', () => {
];
before((done) => {
- shareConn.query(
- 'CREATE TEMPORARY TABLE nullMappingTable(' +
- 't1 BIT(1) NULL,' +
- 't2 BIT(2) NULL,' +
- 't3 TINYINT NULL,' +
- 't4 TINYINT UNSIGNED NULL,' +
- 't5 BOOL NULL,' +
- 't6 SMALLINT NULL,' +
- 't7 SMALLINT UNSIGNED NULL,' +
- 't8 MEDIUMINT NULL,' +
- 't9 MEDIUMINT UNSIGNED NULL,' +
- 't10 INT NULL,' +
- 't11 INT UNSIGNED NULL,' +
- 't12 BIGINT NULL,' +
- 't13 BIGINT UNSIGNED NULL,' +
- 't14 FLOAT NULL,' +
- 't15 DOUBLE NULL,' +
- 't16 DECIMAL NULL,' +
- 't17 DATE NULL,' +
- 't18 DATETIME NULL,' +
- 't19 TIMESTAMP NULL,' +
- 't20 TIME NULL,' +
- 't21 YEAR NULL,' +
- 't22 CHAR(1) NULL,' +
- 't23 CHAR(1) binary NULL,' +
- 't24 VARCHAR(1) NULL,' +
- 't25 VARCHAR(10) BINARY NULL,' +
- 't26 BINARY(10) NULL,' +
- 't27 VARBINARY(10) NULL)'
- );
- shareConn.query('INSERT INTO nullMappingTable values ()');
- if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) {
- //MySQL 5.5 doesn't permit DATETIME/TIMESTAMP with microseconds
- done();
- } else {
- //MySQL 5.6 delete YEAR(2) type
- if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 6)) {
- initValue[23] = 2018;
- nullValue[23] = 1999;
- }
- shareConn
- .query(
- 'CREATE TEMPORARY TABLE mappingTable(' +
- 't1 BIT(1),' +
- 't2 BIT(2),' +
- 't3 TINYINT,' +
- 't4 TINYINT UNSIGNED,' +
- 't5 BOOL default 1,' +
- 't6 SMALLINT default 1,' +
- 't7 SMALLINT UNSIGNED default 0,' +
- 't8 MEDIUMINT default 1,' +
- 't9 MEDIUMINT UNSIGNED default 0,' +
- 't10 INT default 1,' +
- 't11 INT UNSIGNED default 0,' +
- 't12 BIGINT default 1,' +
- 't13 BIGINT UNSIGNED default 0,' +
- 't14 FLOAT default 0,' +
- 't15 DOUBLE default 1,' +
- 't16 DECIMAL default 0,' +
- 't17 DECIMAL(15,4) default 0,' +
- "t18 DATE default '2001-01-01'," +
- "t19 DATETIME(6) default '2001-01-01 00:00:00'," +
- "t20 TIMESTAMP(6) default '2001-01-01 00:00:00'," +
- "t21 TIMESTAMP(0) null default '2001-01-01 00:00:00'," +
- 't22 TIMESTAMP null, ' +
- "t23 TIME(6) default '22:11:00.560001'," +
- (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 6)
- ? 't24 YEAR(4) default 99,'
- : 't24 YEAR(2) default 99,') +
- 't25 YEAR(4) default 2011,' +
- "t26 CHAR(1) default '0'," +
- "t27 CHAR(1) binary default '0'," +
- "t28 VARCHAR(1) default '1'," +
- 't29 VARCHAR(10) BINARY default 0x5a,' +
- 't30 BINARY(10) default 0x1,' +
- 't31 VARBINARY(10) default 0x1' +
- ')'
- )
- .then(() => {
- return shareConn.query(
- 'INSERT INTO mappingTable VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
- initValue
- );
- })
- .then(() => {
- return shareConn.query('INSERT INTO mappingTable VALUES ()');
- })
- .then(() => {
+ shareConn
+ .query('DROP TABLE IF EXISTS nullMappingTable')
+ .then(() => {
+ return shareConn.query('DROP TABLE IF EXISTS mappingTable');
+ })
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE nullMappingTable(' +
+ 't1 BIT(1) NULL,' +
+ 't2 BIT(2) NULL,' +
+ 't3 TINYINT NULL,' +
+ 't4 TINYINT UNSIGNED NULL,' +
+ 't5 BOOL NULL,' +
+ 't6 SMALLINT NULL,' +
+ 't7 SMALLINT UNSIGNED NULL,' +
+ 't8 MEDIUMINT NULL,' +
+ 't9 MEDIUMINT UNSIGNED NULL,' +
+ 't10 INT NULL,' +
+ 't11 INT UNSIGNED NULL,' +
+ 't12 BIGINT NULL,' +
+ 't13 BIGINT UNSIGNED NULL,' +
+ 't14 FLOAT NULL,' +
+ 't15 DOUBLE NULL,' +
+ 't16 DECIMAL NULL,' +
+ 't17 DATE NULL,' +
+ 't18 DATETIME NULL,' +
+ 't19 TIMESTAMP NULL,' +
+ 't20 TIME NULL,' +
+ 't21 YEAR NULL,' +
+ 't22 CHAR(1) NULL,' +
+ 't23 CHAR(1) binary NULL,' +
+ 't24 VARCHAR(1) NULL,' +
+ 't25 VARCHAR(10) BINARY NULL,' +
+ 't26 BINARY(10) NULL,' +
+ 't27 VARBINARY(10) NULL)'
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO nullMappingTable values ()');
+ })
+ .then(() => {
+ if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6)) {
+ //MySQL 5.5 doesn't permit DATETIME/TIMESTAMP with microseconds
done();
- })
- .catch(done);
- }
+ } else {
+ //MySQL 5.6 delete YEAR(2) type
+ if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 6)) {
+ initValue[23] = 2018;
+ nullValue[23] = 1999;
+ }
+ shareConn
+ .query(
+ 'CREATE TABLE mappingTable(' +
+ 't1 BIT(1),' +
+ 't2 BIT(2),' +
+ 't3 TINYINT,' +
+ 't4 TINYINT UNSIGNED,' +
+ 't5 BOOL default 1,' +
+ 't6 SMALLINT default 1,' +
+ 't7 SMALLINT UNSIGNED default 0,' +
+ 't8 MEDIUMINT default 1,' +
+ 't9 MEDIUMINT UNSIGNED default 0,' +
+ 't10 INT default 1,' +
+ 't11 INT UNSIGNED default 0,' +
+ 't12 BIGINT default 1,' +
+ 't13 BIGINT UNSIGNED default 0,' +
+ 't14 FLOAT default 0,' +
+ 't15 DOUBLE default 1,' +
+ 't16 DECIMAL default 0,' +
+ 't17 DECIMAL(15,4) default 0,' +
+ "t18 DATE default '2001-01-01'," +
+ "t19 DATETIME(6) default '2001-01-01 00:00:00'," +
+ "t20 TIMESTAMP(6) default '2001-01-01 00:00:00'," +
+ "t21 TIMESTAMP(0) null default '2001-01-01 00:00:00'," +
+ 't22 TIMESTAMP null, ' +
+ "t23 TIME(6) default '22:11:00.560001'," +
+ (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 6)
+ ? 't24 YEAR(4) default 99,'
+ : 't24 YEAR(2) default 99,') +
+ 't25 YEAR(4) default 2011,' +
+ "t26 CHAR(1) default '0'," +
+ "t27 CHAR(1) binary default '0'," +
+ "t28 VARCHAR(1) default '1'," +
+ 't29 VARCHAR(10) BINARY default 0x5a,' +
+ 't30 BINARY(10) default 0x1,' +
+ 't31 VARBINARY(10) default 0x1' +
+ ')'
+ )
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO mappingTable VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)',
+ initValue
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO mappingTable VALUES ()');
+ })
+ .then(() => {
+ done();
+ })
+ .catch(done);
+ }
+ });
});
it('query mapping field', function (done) {
@@ -206,12 +217,19 @@ describe('mapping', () => {
});
it('dataType with null', (done) => {
- shareConn.query(
- 'CREATE TEMPORARY TABLE dataTypeWithNull (id int not null primary key auto_increment, test longblob, test2 blob, test3 text)'
- );
- shareConn.query("insert into dataTypeWithNull values(null, 'a','b','c')");
shareConn
- .query('SELECT * FROM dataTypeWithNull')
+ .query('DROP TABLE IF EXISTS dataTypeWithNull')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE dataTypeWithNull (id int not null primary key auto_increment, test longblob, test2 blob, test3 text)'
+ );
+ })
+ .then(() => {
+ return shareConn.query("insert into dataTypeWithNull values(null, 'a','b','c')");
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM dataTypeWithNull');
+ })
.then((rows) => {
assert.ok(Buffer.isBuffer(rows[0].test));
assert.ok(Buffer.isBuffer(rows[0].test2));
diff --git a/test/integration/datatype/test-set.js b/test/integration/datatype/test-set.js
index ee5f45b6..11a1beee 100644
--- a/test/integration/datatype/test-set.js
+++ b/test/integration/datatype/test-set.js
@@ -5,21 +5,26 @@ const { assert } = require('chai');
describe('set', () => {
it('set array', (done) => {
- shareConn.query("CREATE TEMPORARY TABLE set_array(tt SET('v1','v2', 'v3'))");
-
- shareConn.query(
- 'INSERT INTO set_array values ' +
- "('v1'), " +
- "('v2'), " +
- "('v1,v2'), " +
- "('v3'), " +
- "('v3,v2'), " +
- "('')," +
- '(null)'
- );
-
shareConn
- .query('SELECT * from set_array')
+ .query('DROP TABLE IF EXISTS set_array')
+ .then(() => {
+ return shareConn.query("CREATE TABLE set_array(tt SET('v1','v2', 'v3'))");
+ })
+ .then(() => {
+ return shareConn.query(
+ 'INSERT INTO set_array values ' +
+ "('v1'), " +
+ "('v2'), " +
+ "('v1,v2'), " +
+ "('v3'), " +
+ "('v3,v2'), " +
+ "('')," +
+ '(null)'
+ );
+ })
+ .then(() => {
+ return shareConn.query('SELECT * from set_array');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ tt: ['v1'] },
diff --git a/test/integration/datatype/test-string.js b/test/integration/datatype/test-string.js
index 5d765360..0d2dda74 100644
--- a/test/integration/datatype/test-string.js
+++ b/test/integration/datatype/test-string.js
@@ -27,13 +27,20 @@ describe('string', () => {
it('utf8 buffer verification', function (done) {
if (!base.utf8Collation()) this.skip();
- shareConn.query(
- 'CREATE TEMPORARY TABLE buf_utf8_chars(tt text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)'
- );
const buf = Buffer.from([0xf0, 0x9f, 0xa4, 0x98, 0xf0, 0x9f, 0x92, 0xaa]); // 🤘💪
- shareConn.query('INSERT INTO buf_utf8_chars VALUES (?)', buf);
shareConn
- .query("SELECT _binary'🤘💪' t1, '🤘💪' t2, tt FROM buf_utf8_chars")
+ .query('DROP TABLE IF EXISTS buf_utf8_chars')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE buf_utf8_chars(tt text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)'
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO buf_utf8_chars VALUES (?)', buf);
+ })
+ .then(() => {
+ return shareConn.query("SELECT _binary'🤘💪' t1, '🤘💪' t2, tt FROM buf_utf8_chars");
+ })
.then((results) => {
assert.equal(results[0].t1, '🤘💪');
assert.equal(results[0].t2, '🤘💪');
@@ -55,27 +62,31 @@ describe('string', () => {
it('utf8 strings', function (done) {
if (!base.utf8Collation()) this.skip();
-
- shareConn.query(
- 'CREATE TEMPORARY TABLE buf_utf8_string(tt text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)'
- );
-
- //F0 9F 98 8E 😎 unicode 6 smiling face with sunglasses
- //F0 9F 8C B6 🌶 unicode 7 hot pepper
- //F0 9F 8E A4 🎤 unicode 8 no microphones
- //F0 9F A5 82 🥂 unicode 9 champagne glass
-
- shareConn.query(
- 'INSERT INTO buf_utf8_string values ' +
- "('hel\\'lo'), " +
- "('您好 (chinese)'), " +
- "('नमस्ते (Hindi)'), " +
- "('привет (Russian)'), " +
- "('😎🌶🎤🥂')"
- );
-
shareConn
- .query('SELECT * from buf_utf8_string')
+ .query('DROP TABLE IF EXISTS buf_utf8_string')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE buf_utf8_string(tt text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci)'
+ );
+ })
+ .then(() => {
+ //F0 9F 98 8E 😎 unicode 6 smiling face with sunglasses
+ //F0 9F 8C B6 🌶 unicode 7 hot pepper
+ //F0 9F 8E A4 🎤 unicode 8 no microphones
+ //F0 9F A5 82 🥂 unicode 9 champagne glass
+
+ return shareConn.query(
+ 'INSERT INTO buf_utf8_string values ' +
+ "('hel\\'lo'), " +
+ "('您好 (chinese)'), " +
+ "('नमस्ते (Hindi)'), " +
+ "('привет (Russian)'), " +
+ "('😎🌶🎤🥂')"
+ );
+ })
+ .then(() => {
+ return shareConn.query('SELECT * from buf_utf8_string');
+ })
.then((rows) => {
checkUtf8String(rows);
done();
@@ -114,12 +125,26 @@ describe('string', () => {
it('table encoding not affecting query', function (done) {
if (!base.utf8Collation()) this.skip();
const str = '財團法人資訊工業策進會';
- shareConn.query('CREATE TEMPORARY TABLE utf8_encoding_table(t1 text) CHARSET utf8');
- shareConn.query('CREATE TEMPORARY TABLE big5_encoding_table(t2 text) CHARSET big5');
- shareConn.query('INSERT INTO utf8_encoding_table values (?)', [str]);
- shareConn.query('INSERT INTO big5_encoding_table values (?)', [str]);
shareConn
- .query('SELECT * from utf8_encoding_table, big5_encoding_table')
+ .query('DROP TABLE IF EXISTS utf8_encoding_table')
+ .then(() => {
+ return shareConn.query('DROP TABLE IF EXISTS big5_encoding_table');
+ })
+ .then(() => {
+ return shareConn.query('CREATE TABLE utf8_encoding_table(t1 text) CHARSET utf8');
+ })
+ .then(() => {
+ return shareConn.query('CREATE TABLE big5_encoding_table(t2 text) CHARSET big5');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO utf8_encoding_table values (?)', [str]);
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO big5_encoding_table values (?)', [str]);
+ })
+ .then(() => {
+ return shareConn.query('SELECT * from utf8_encoding_table, big5_encoding_table');
+ })
.then((res) => {
assert.deepEqual(res, [{ t1: str, t2: str }]);
done();
@@ -128,10 +153,17 @@ describe('string', () => {
});
it('string escape', (done) => {
- shareConn.query('CREATE TEMPORARY TABLE escape_utf8_string(tt text) CHARSET utf8');
- shareConn.query('INSERT INTO escape_utf8_string values (?)', ['a \'b\\"c']);
shareConn
- .query('SELECT * from escape_utf8_string')
+ .query('DROP TABLE IF EXISTS escape_utf8_string')
+ .then(() => {
+ return shareConn.query('CREATE TABLE escape_utf8_string(tt text) CHARSET utf8');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO escape_utf8_string values (?)', ['a \'b\\"c']);
+ })
+ .then(() => {
+ return shareConn.query('SELECT * from escape_utf8_string');
+ })
.then((res) => {
assert.deepEqual(res, [{ tt: 'a \'b\\"c' }]);
done();
@@ -144,10 +176,17 @@ describe('string', () => {
const wrongString = 'a\ue800\ud800b\udc01c\ud800';
base.createConnection().then((conn) => {
- conn.query('CREATE TEMPORARY TABLE wrong_utf8_string(tt text) CHARSET utf8mb4');
- conn.query('INSERT INTO wrong_utf8_string values (?)', [wrongString]);
conn
- .query('SELECT * from wrong_utf8_string')
+ .query('DROP TABLE IF EXISTS wrong_utf8_string')
+ .then(() => {
+ return conn.query('CREATE TABLE wrong_utf8_string(tt text) CHARSET utf8mb4');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO wrong_utf8_string values (?)', [wrongString]);
+ })
+ .then(() => {
+ return conn.query('SELECT * from wrong_utf8_string');
+ })
.then((res) => {
assert.deepEqual(res, [{ tt: 'a?b?c?' }]);
conn.end();
diff --git a/test/integration/test-additional-server-info.js b/test/integration/test-additional-server-info.js
index cb0a159c..ce76adbd 100644
--- a/test/integration/test-additional-server-info.js
+++ b/test/integration/test-additional-server-info.js
@@ -9,8 +9,8 @@ describe('server additional information API', () => {
.query('SELECT VERSION() a')
.then((res) => {
if (process.env.MAXSCALE_VERSION) {
- //maxscale version is set to 10.4.99-MariaDB-maxScale
- assert.deepEqual(shareConn.serverVersion(), '10.4.99-MariaDB-maxScale');
+ //maxscale version is set to 10.5.99-MariaDB-maxScale
+ assert.deepEqual(shareConn.serverVersion(), '10.5.99-MariaDB-maxScale');
} else {
assert.deepEqual(res, [{ a: shareConn.serverVersion() }]);
}
diff --git a/test/integration/test-auth-plugin.js b/test/integration/test-auth-plugin.js
index e6726d24..8d77f9f7 100644
--- a/test/integration/test-auth-plugin.js
+++ b/test/integration/test-auth-plugin.js
@@ -5,8 +5,66 @@ const { assert } = require('chai');
const Conf = require('../conf');
describe('authentication plugin', () => {
+ let rsaPublicKey = process.env.TEST_RSA_PUBLIC_KEY;
+ let cachingRsaPublicKey = process.env.TEST_CACHING_RSA_PUBLIC_KEY;
+
+ before(async function () {
+ if (!rsaPublicKey) {
+ if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7, 0)) {
+ const res = await shareConn.query({
+ sql: "SHOW STATUS LIKE 'Rsa_public_key'",
+ rowsAsArray: true
+ });
+ rsaPublicKey = res[0][1];
+ }
+ }
+
+ if (!cachingRsaPublicKey) {
+ if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(8, 0, 0)) {
+ const res = await shareConn.query({
+ sql: "SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'",
+ rowsAsArray: true
+ });
+ cachingRsaPublicKey = res[0][1];
+ }
+ }
+
+ await shareConn.query("DROP USER IF EXISTS 'sha256User'@'%'");
+ await shareConn.query("DROP USER IF EXISTS 'cachingSha256User'@'%'");
+ await shareConn.query("DROP USER IF EXISTS 'cachingSha256User2'@'%'");
+ await shareConn.query("DROP USER IF EXISTS 'cachingSha256User3'@'%'");
+
+ if (!shareConn.info.isMariaDB()) {
+ if (shareConn.info.hasMinVersion(8, 0, 0)) {
+ await shareConn.query(
+ "CREATE USER 'sha256User'@'%' IDENTIFIED WITH sha256_password BY 'password'"
+ );
+ await shareConn.query("GRANT ALL PRIVILEGES ON *.* TO 'sha256User'@'%'");
+
+ await shareConn.query(
+ "CREATE USER 'cachingSha256User'@'%' IDENTIFIED WITH caching_sha2_password BY 'password'"
+ );
+ await shareConn.query("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User'@'%'");
+ await shareConn.query(
+ "CREATE USER 'cachingSha256User2'@'%' IDENTIFIED WITH caching_sha2_password BY 'password'"
+ );
+ await shareConn.query("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User2'@'%'");
+ await shareConn.query(
+ "CREATE USER 'cachingSha256User3'@'%' IDENTIFIED WITH caching_sha2_password BY 'password'"
+ );
+ await shareConn.query("GRANT ALL PRIVILEGES ON *.* TO 'cachingSha256User3'@'%'");
+ } else {
+ await shareConn.query("CREATE USER 'sha256User'@'%'");
+ await shareConn.query(
+ "GRANT ALL PRIVILEGES ON *.* TO 'sha256User'@'%' IDENTIFIED WITH " +
+ "sha256_password BY 'password'"
+ );
+ }
+ }
+ });
+
it('ed25519 authentication plugin', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
const self = this;
if (!shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(10, 1, 22)) this.skip();
@@ -72,6 +130,7 @@ describe('authentication plugin', () => {
it('name pipe authentication plugin', function (done) {
if (process.platform !== 'win32') this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(10, 1, 11)) this.skip();
if (Conf.baseConfig.host !== 'localhost' && Conf.baseConfig.host !== 'mariadb.example.com')
this.skip();
@@ -161,8 +220,8 @@ describe('authentication plugin', () => {
});
it('dialog authentication plugin', function (done) {
- //pam is set using .travis/entrypoint/pam.sh
- if (!process.env.TRAVIS || process.env.MAXSCALE_VERSION) this.skip();
+ //pam is set using .travis/sql/pam.sh
+ if (!process.env.TRAVIS || process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
this.timeout(10000);
@@ -191,8 +250,8 @@ describe('authentication plugin', () => {
});
it('dialog authentication plugin multiple password', function (done) {
- //pam is set using .travis/entrypoint/pam.sh
- if (!process.env.TRAVIS || process.env.MAXSCALE_VERSION) this.skip();
+ //pam is set using .travis/sql/pam.sh
+ if (!process.env.TRAVIS || process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
this.timeout(10000);
@@ -221,7 +280,7 @@ describe('authentication plugin', () => {
});
it('multi authentication plugin', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
if (!shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(10, 4, 3)) this.skip();
shareConn.query("drop user IF EXISTS mysqltest1@'%'").catch((err) => {});
shareConn
@@ -275,4 +334,233 @@ describe('authentication plugin', () => {
})
.catch(done);
});
+
+ it('sha256 authentication plugin', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (process.platform === 'win32') this.skip();
+ if (!rsaPublicKey || shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7, 0))
+ this.skip();
+
+ const self = this;
+ base
+ .createConnection({
+ user: 'sha256User',
+ password: 'password',
+ rsaPublicKey: rsaPublicKey
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ if (err.message.includes('sha256_password authentication plugin require node 11.6+'))
+ self.skip();
+ done(err);
+ });
+ });
+
+ it('sha256 authentication plugin with public key retrieval', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (process.platform === 'win32') this.skip();
+ if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7, 0)) this.skip();
+
+ const self = this;
+ base
+ .createConnection({
+ user: 'sha256User',
+ password: 'password',
+ allowPublicKeyRetrieval: true
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ if (err.message.includes('sha256_password authentication plugin require node 11.6+'))
+ self.skip();
+ done(err);
+ });
+ });
+
+ it('sha256 authentication plugin without public key retrieval', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(5, 7, 0)) this.skip();
+
+ base
+ .createConnection({
+ user: 'sha256User',
+ password: 'password'
+ })
+ .then((conn) => {
+ conn.end();
+ done(new Error('must have thrown error'));
+ })
+ .catch((err) => {
+ assert.isTrue(
+ err.message.includes('RSA public key is not available client side.') ||
+ err.message.includes('sha256_password authentication plugin require node 11.6+')
+ );
+ done();
+ });
+ });
+
+ it('sha256 authentication plugin with ssl', function (done) {
+ if (
+ process.env.MAXSCALE_TEST_DISABLE ||
+ shareConn.info.isMariaDB() ||
+ !shareConn.info.hasMinVersion(5, 7, 0)
+ )
+ this.skip();
+
+ const self = this;
+ shareConn
+ .query("SHOW VARIABLES LIKE 'have_ssl'")
+ .then((rows) => {
+ // console.log("ssl is not enable on database, skipping test :");
+ if (rows[0].Value === 'YES') {
+ base
+ .createConnection({
+ user: 'sha256User',
+ password: 'password',
+ ssl: {
+ rejectUnauthorized: false
+ }
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ if (err.message.includes('sha256_password authentication plugin require node 11.6+'))
+ self.skip();
+ done(err);
+ });
+ } else {
+ this.skip();
+ }
+ })
+ .catch(done);
+ });
+
+ it('cachingsha256 authentication plugin', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (process.platform === 'win32') this.skip();
+ if (!rsaPublicKey || shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(8, 0, 0))
+ this.skip();
+
+ const self = this;
+ base
+ .createConnection({
+ user: 'cachingSha256User',
+ password: 'password',
+ cachingRsaPublicKey: rsaPublicKey
+ })
+ .then((conn) => {
+ conn.end();
+ //using fast auth
+ base
+ .createConnection({
+ user: 'cachingSha256User',
+ password: 'password',
+ cachingRsaPublicKey: rsaPublicKey
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch(done);
+ })
+ .catch((err) => {
+ if (err.message.includes('caching_sha2_password authentication plugin require node 11.6+'))
+ self.skip();
+ done(err);
+ });
+ });
+
+ it('cachingsha256 authentication plugin with public key retrieval', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (process.platform === 'win32') this.skip();
+ if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(8, 0, 0)) this.skip();
+
+ const self = this;
+ base
+ .createConnection({
+ user: 'cachingSha256User2',
+ password: 'password',
+ allowPublicKeyRetrieval: true
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ if (err.message.includes('caching_sha2_password authentication plugin require node 11.6+'))
+ self.skip();
+ done(err);
+ });
+ });
+
+ it('cachingsha256 authentication plugin without public key retrieval', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
+ if (shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(8, 0, 0)) this.skip();
+
+ base
+ .createConnection({
+ user: 'cachingSha256User3',
+ password: 'password'
+ })
+ .then((conn) => {
+ conn.end();
+ done(new Error('must have thrown error'));
+ })
+ .catch((err) => {
+ assert.isTrue(
+ err.message.includes('RSA public key is not available client side.') ||
+ err.message.includes('caching_sha2_password authentication plugin require node 11.6+')
+ );
+ done();
+ });
+ });
+
+ it('cachingsha256 authentication plugin with ssl', function (done) {
+ if (
+ process.env.MAXSCALE_TEST_DISABLE ||
+ shareConn.info.isMariaDB() ||
+ !shareConn.info.hasMinVersion(8, 0, 0)
+ )
+ this.skip();
+
+ const self = this;
+ shareConn
+ .query("SHOW VARIABLES LIKE 'have_ssl'")
+ .then((rows) => {
+ // console.log("ssl is not enable on database, skipping test :");
+ if (rows[0].Value === 'YES') {
+ base
+ .createConnection({
+ user: 'cachingSha256User3',
+ password: 'password',
+ ssl: {
+ rejectUnauthorized: false
+ }
+ })
+ .then((conn) => {
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ if (
+ err.message.includes(
+ 'caching_sha2_password authentication plugin require node 11.6+'
+ )
+ )
+ self.skip();
+ done();
+ });
+ } else {
+ self.skip();
+ }
+ })
+ .catch(done);
+ });
});
diff --git a/test/integration/test-batch-callback.js b/test/integration/test-batch-callback.js
index 0d66ab02..a2698d27 100644
--- a/test/integration/test-batch-callback.js
+++ b/test/integration/test-batch-callback.js
@@ -15,9 +15,7 @@ describe('batch callback', () => {
let supportBulk;
before(function (done) {
supportBulk = (Conf.baseConfig.bulk === undefined ? true : Conf.baseConfig.bulk)
- ? (shareConn.info.serverCapabilities.high &
- Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) >
- 0
+ ? (shareConn.info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) > 0
: false;
const hourOffset = Math.round((-1 * new Date().getTimezoneOffset()) / 60);
@@ -207,7 +205,7 @@ describe('batch callback', () => {
);
conn.query('select 1', (err, rows) => {
if (err) return done(err);
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
});
});
};
@@ -274,7 +272,7 @@ describe('batch callback', () => {
done(err);
});
}
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
});
});
};
@@ -327,7 +325,7 @@ describe('batch callback', () => {
done(err);
});
}
- assert.deepEqual(rows, [{ '2': 2 }]);
+ assert.deepEqual(rows, [{ 2: 2 }]);
});
});
};
@@ -453,7 +451,7 @@ describe('batch callback', () => {
done(err);
});
}
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
});
});
};
@@ -543,7 +541,7 @@ describe('batch callback', () => {
done(err);
});
}
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
clearTimeout(timeout);
return conn.end(() => {
done();
@@ -1098,6 +1096,24 @@ describe('batch callback', () => {
describe('standard question mark using rewrite', () => {
const useCompression = false;
+ it('immediate batch after callback', function (done) {
+ let conn = base.createCallbackConnection();
+ conn.batch(
+ 'INSERT INTO contacts(first_name, last_name, email) VALUES(?, ?, ?)',
+ ['John', 'Smith', 'js@example.com'],
+ (err, res, meta) => {
+ conn.end();
+ if (err) {
+ if (err.message.includes('Parameter at position 1 is not set for values 0')) {
+ done();
+ } else done(err);
+ } else {
+ done(new Error('Must have throw error'));
+ }
+ }
+ );
+ });
+
it('simple batch, local date', function (done) {
if (!base.utf8Collation()) this.skip();
this.timeout(30000);
@@ -1133,7 +1149,7 @@ describe('batch callback', () => {
})
.catch((err) => {
assert.isTrue(
- err.message.includes('Parameter at position 2 is not set for values 1'),
+ err.message.includes('Parameter at position 1 is not set for values 1'),
err.message
);
conn.end();
diff --git a/test/integration/test-batch-geometry-type.js b/test/integration/test-batch-geometry-type.js
index cffe68b3..7b76dc73 100644
--- a/test/integration/test-batch-geometry-type.js
+++ b/test/integration/test-batch-geometry-type.js
@@ -9,54 +9,56 @@ describe('batch geometry type', () => {
let supportBulk;
before(function () {
supportBulk = (Conf.baseConfig.bulk === undefined ? true : Conf.baseConfig.bulk)
- ? (shareConn.info.serverCapabilities.high &
- Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) >
- 0
+ ? (shareConn.info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) > 0
: false;
});
it('Point format', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_point_batch (g POINT)');
shareConn
- .batch('INSERT INTO gis_point_batch VALUES (?)', [
- [
- {
- type: 'Point',
- coordinates: [10, 10]
- }
- ],
- [
- {
- type: 'Point',
- coordinates: [20, 10]
- }
- ],
- [
- {
- type: 'Point',
- coordinates: [20, 20]
- }
- ],
- [
- {
- type: 'Point',
- coordinates: [10, 20]
- }
- ],
- [
- {
- type: 'Point',
- coordinates: []
- }
- ],
- [
- {
- type: 'Point'
- }
- ]
- ])
+ .query('DROP TABLE IF EXISTS gis_point_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_point_batch (g POINT)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_point_batch VALUES (?)', [
+ [
+ {
+ type: 'Point',
+ coordinates: [10, 10]
+ }
+ ],
+ [
+ {
+ type: 'Point',
+ coordinates: [20, 10]
+ }
+ ],
+ [
+ {
+ type: 'Point',
+ coordinates: [20, 20]
+ }
+ ],
+ [
+ {
+ type: 'Point',
+ coordinates: [10, 20]
+ }
+ ],
+ [
+ {
+ type: 'Point',
+ coordinates: []
+ }
+ ],
+ [
+ {
+ type: 'Point'
+ }
+ ]
+ ]);
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_point_batch');
})
@@ -88,13 +90,17 @@ describe('batch geometry type', () => {
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Point' }
: null
},
{
g:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Point' }
: null
}
@@ -106,37 +112,42 @@ describe('batch geometry type', () => {
it('LineString insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_line_batch (g LINESTRING)');
shareConn
- .batch('INSERT INTO gis_line_batch VALUES (?)', [
- [
- {
- type: 'LineString',
- coordinates: [
- [0, 0],
- [0, 10],
- [10, 0]
- ]
- }
- ],
- [
- {
- type: 'LineString',
- coordinates: [[0, 10]]
- }
- ],
- [
- {
- type: 'LineString',
- coordinates: []
- }
- ],
- [
- {
- type: 'LineString'
- }
- ]
- ])
+ .query('DROP TABLE IF EXISTS gis_line_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_line_batch (g LINESTRING)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_line_batch VALUES (?)', [
+ [
+ {
+ type: 'LineString',
+ coordinates: [
+ [0, 0],
+ [0, 10],
+ [10, 0]
+ ]
+ }
+ ],
+ [
+ {
+ type: 'LineString',
+ coordinates: [[0, 10]]
+ }
+ ],
+ [
+ {
+ type: 'LineString',
+ coordinates: []
+ }
+ ],
+ [
+ {
+ type: 'LineString'
+ }
+ ]
+ ]);
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_line_batch');
})
@@ -165,12 +176,15 @@ describe('batch geometry type', () => {
coordinates: [],
type: 'LineString'
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'LineString' }
: null
},
{
- g: shareConn.info.hasMinVersion(10, 5, 2) ? { type: 'LineString' } : null
+ g:
+ shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
+ ? { type: 'LineString' }
+ : null
}
]);
} else {
@@ -206,68 +220,73 @@ describe('batch geometry type', () => {
it('Polygon insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_polygon_batch (g POLYGON)');
shareConn
- .batch('INSERT INTO gis_polygon_batch VALUES (?)', [
- [
- {
- type: 'Polygon',
- coordinates: [
- [
- [10, 10],
- [20, 10],
- [20, 20],
- [10, 20],
- [10, 10]
+ .query('DROP TABLE IF EXISTS gis_polygon_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_polygon_batch (g POLYGON)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_polygon_batch VALUES (?)', [
+ [
+ {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [10, 10],
+ [20, 10],
+ [20, 20],
+ [10, 20],
+ [10, 10]
+ ]
]
- ]
- }
- ],
- [
- {
- type: 'Polygon',
- coordinates: [
- [
- [0, 0],
- [50, 0],
- [50, 50],
- [0, 50],
- [0, 0]
- ],
- [
- [10, 10],
- [20, 10],
- [20, 20],
- [10, 20],
- [10, 10]
+ }
+ ],
+ [
+ {
+ type: 'Polygon',
+ coordinates: [
+ [
+ [0, 0],
+ [50, 0],
+ [50, 50],
+ [0, 50],
+ [0, 0]
+ ],
+ [
+ [10, 10],
+ [20, 10],
+ [20, 20],
+ [10, 20],
+ [10, 10]
+ ]
]
- ]
- }
- ],
- [
- {
- type: 'Polygon',
- coordinates: [
- [[0, 0], [50]],
- [
- [10, 10],
- [20, 10]
+ }
+ ],
+ [
+ {
+ type: 'Polygon',
+ coordinates: [
+ [[0, 0], [50]],
+ [
+ [10, 10],
+ [20, 10]
+ ]
]
- ]
- }
- ],
- [
- {
- type: 'Polygon',
- coordinates: []
- }
- ],
- [
- {
- type: 'Polygon'
- }
- ]
- ])
+ }
+ ],
+ [
+ {
+ type: 'Polygon',
+ coordinates: []
+ }
+ ],
+ [
+ {
+ type: 'Polygon'
+ }
+ ]
+ ]);
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_polygon_batch');
})
@@ -310,7 +329,10 @@ describe('batch geometry type', () => {
}
},
{
- g: shareConn.info.hasMinVersion(10, 5, 2) ? { type: 'Polygon' } : null
+ g:
+ shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
+ ? { type: 'Polygon' }
+ : null
},
{
g: supportBulk
@@ -318,12 +340,15 @@ describe('batch geometry type', () => {
type: 'Polygon',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Polygon' }
: null
},
{
- g: shareConn.info.hasMinVersion(10, 5, 2) ? { type: 'Polygon' } : null
+ g:
+ shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
+ ? { type: 'Polygon' }
+ : null
}
]);
} else {
@@ -381,24 +406,29 @@ describe('batch geometry type', () => {
it('MultiPoint insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_point_batch (g MULTIPOINT)');
shareConn
- .batch('INSERT INTO gis_multi_point_batch VALUES (?)', [
- [
- {
- type: 'MultiPoint',
- coordinates: [
- [30, 30],
- [10, 10],
- [10, 20],
- [20, 20]
- ]
- }
- ],
- [{ type: 'MultiPoint', coordinates: [[10, 0]] }],
- [{ type: 'MultiPoint', coordinates: [] }],
- [{ type: 'MultiPoint' }]
- ])
+ .query('DROP TABLE IF EXISTS gis_multi_point_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_point_batch (g MULTIPOINT)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_multi_point_batch VALUES (?)', [
+ [
+ {
+ type: 'MultiPoint',
+ coordinates: [
+ [30, 30],
+ [10, 10],
+ [10, 20],
+ [20, 20]
+ ]
+ }
+ ],
+ [{ type: 'MultiPoint', coordinates: [[10, 0]] }],
+ [{ type: 'MultiPoint', coordinates: [] }],
+ [{ type: 'MultiPoint' }]
+ ]);
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_point_batch');
})
@@ -428,7 +458,7 @@ describe('batch geometry type', () => {
type: 'MultiPoint',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPoint' }
: null
},
@@ -438,7 +468,7 @@ describe('batch geometry type', () => {
type: 'MultiPoint',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPoint' }
: null
}
@@ -477,42 +507,48 @@ describe('batch geometry type', () => {
it('Multi-line insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_line_batch (g MULTILINESTRING)');
shareConn
- .batch('INSERT INTO gis_multi_line_batch VALUES (?)', [
- [
- {
- type: 'MultiLineString',
- coordinates: [
- [
- [10, 48],
- [10, 21],
- [10, 0]
- ],
- [
- [16, 0],
- [16, 23],
- [16, 48]
+ .query('DROP TABLE IF EXISTS gis_multi_line_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_line_batch (g MULTILINESTRING)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_multi_line_batch VALUES (?)', [
+ [
+ {
+ type: 'MultiLineString',
+ coordinates: [
+ [
+ [10, 48],
+ [10, 21],
+ [10, 0]
+ ],
+ [
+ [16, 0],
+ [16, 23],
+ [16, 48]
+ ]
]
- ]
- }
- ],
- [
- {
- type: 'MultiLineString',
- coordinates: [
- [
- [10, 48],
- [10, 21],
- [10, 0]
+ }
+ ],
+ [
+ {
+ type: 'MultiLineString',
+ coordinates: [
+ [
+ [10, 48],
+ [10, 21],
+ [10, 0]
+ ]
]
- ]
- }
- ],
- [{ type: 'MultiLineString', coordinates: [[]] }],
- [{ type: 'MultiLineString', coordinates: [] }],
- [{ type: 'MultiLineString' }]
- ])
+ }
+ ],
+ [{ type: 'MultiLineString', coordinates: [[]] }],
+ [{ type: 'MultiLineString', coordinates: [] }],
+ [{ type: 'MultiLineString' }]
+ ]);
+ })
+
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_line_batch');
})
@@ -554,7 +590,7 @@ describe('batch geometry type', () => {
type: 'MultiLineString',
coordinates: [[]]
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
},
@@ -564,7 +600,7 @@ describe('batch geometry type', () => {
type: 'MultiLineString',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
},
@@ -574,7 +610,7 @@ describe('batch geometry type', () => {
type: 'MultiLineString',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiLineString' }
: null
}
@@ -628,89 +664,93 @@ describe('batch geometry type', () => {
it('Multi-polygon insert', function (done) {
if (!shareConn.info.isMariaDB()) this.skip();
-
- shareConn.query('CREATE TEMPORARY TABLE gis_multi_polygon_batch (g MULTIPOLYGON)');
shareConn
- .batch('INSERT INTO gis_multi_polygon_batch VALUES (?)', [
- [
- {
- type: 'MultiPolygon',
- coordinates: [
- [
+ .query('DROP TABLE IF EXISTS gis_multi_polygon_batch')
+ .then(() => {
+ return shareConn.query('CREATE TABLE gis_multi_polygon_batch (g MULTIPOLYGON)');
+ })
+ .then(() => {
+ return shareConn.batch('INSERT INTO gis_multi_polygon_batch VALUES (?)', [
+ [
+ {
+ type: 'MultiPolygon',
+ coordinates: [
[
- [28, 26],
- [28, 0],
- [84, 0],
- [84, 42],
- [28, 26]
+ [
+ [28, 26],
+ [28, 0],
+ [84, 0],
+ [84, 42],
+ [28, 26]
+ ],
+ [
+ [52, 18],
+ [66, 23],
+ [73, 9],
+ [48, 6],
+ [52, 18]
+ ]
],
[
- [52, 18],
- [66, 23],
- [73, 9],
- [48, 6],
- [52, 18]
- ]
- ],
- [
- [
- [59, 18],
- [67, 18],
- [67, 13],
- [59, 13],
- [59, 18]
+ [
+ [59, 18],
+ [67, 18],
+ [67, 13],
+ [59, 13],
+ [59, 18]
+ ]
]
]
- ]
- }
- ],
- [
- {
- type: 'MultiPolygon',
- coordinates: [
- [
- [
- [28, 26],
- [28, 0],
- [84, 0],
- [84, 42],
- [28, 26]
- ],
+ }
+ ],
+ [
+ {
+ type: 'MultiPolygon',
+ coordinates: [
[
- [52, 18],
- [66, 23],
- [73, 9],
- [48, 6],
- [52, 18]
+ [
+ [28, 26],
+ [28, 0],
+ [84, 0],
+ [84, 42],
+ [28, 26]
+ ],
+ [
+ [52, 18],
+ [66, 23],
+ [73, 9],
+ [48, 6],
+ [52, 18]
+ ]
]
]
- ]
- }
- ],
- [
- {
- type: 'MultiPolygon',
- coordinates: [[[]]]
- }
- ],
- [
- {
- type: 'MultiPolygon',
- coordinates: [[]]
- }
- ],
- [
- {
- type: 'MultiPolygon',
- coordinates: []
- }
- ],
- [
- {
- type: 'MultiPolygon'
- }
- ]
- ])
+ }
+ ],
+ [
+ {
+ type: 'MultiPolygon',
+ coordinates: [[[]]]
+ }
+ ],
+ [
+ {
+ type: 'MultiPolygon',
+ coordinates: [[]]
+ }
+ ],
+ [
+ {
+ type: 'MultiPolygon',
+ coordinates: []
+ }
+ ],
+ [
+ {
+ type: 'MultiPolygon'
+ }
+ ]
+ ]);
+ })
.then(() => {
return shareConn.query('SELECT * FROM gis_multi_polygon_batch');
})
@@ -778,7 +818,7 @@ describe('batch geometry type', () => {
type: 'MultiPolygon',
coordinates: [[[]]]
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
@@ -788,7 +828,7 @@ describe('batch geometry type', () => {
type: 'MultiPolygon',
coordinates: [[]]
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
@@ -798,7 +838,7 @@ describe('batch geometry type', () => {
type: 'MultiPolygon',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
},
@@ -808,7 +848,7 @@ describe('batch geometry type', () => {
type: 'MultiPolygon',
coordinates: []
}
- : shareConn.info.hasMinVersion(10, 5, 2)
+ : shareConn.info.hasMinVersion(10, 5, 2) && !process.env.MAXSCALE_TEST_DISABLE
? { type: 'MultiPolygon' }
: null
}
@@ -895,111 +935,116 @@ describe('batch geometry type', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE gis_geometrycollection_batch (g GEOMETRYCOLLECTION)');
conn
- .batch('INSERT INTO gis_geometrycollection_batch VALUES (?)', [
- [
- {
- type: 'GeometryCollection',
- geometries: [
- {
- type: 'Point',
- coordinates: [10, 10]
- },
- {
- type: 'LineString',
- coordinates: [
- [0, 0],
- [0, 10],
- [10, 0]
- ]
- },
- {
- type: 'MultiPoint',
- coordinates: [
- [0, 0],
- [10, 10],
- [10, 20],
- [20, 20]
- ]
- },
- {
- type: 'MultiLineString',
- coordinates: [
- [
- [10, 48],
- [10, 21],
+ .query('DROP TABLE IF EXISTS gis_geometrycollection_batch')
+ .then(() => {
+ return conn.query('CREATE TABLE gis_geometrycollection_batch (g GEOMETRYCOLLECTION)');
+ })
+ .then(() => {
+ return conn.batch('INSERT INTO gis_geometrycollection_batch VALUES (?)', [
+ [
+ {
+ type: 'GeometryCollection',
+ geometries: [
+ {
+ type: 'Point',
+ coordinates: [10, 10]
+ },
+ {
+ type: 'LineString',
+ coordinates: [
+ [0, 0],
+ [0, 10],
[10, 0]
- ],
- [
- [16, 0],
- [16, 23],
- [16, 48]
]
- ]
- },
- {
- type: 'MultiPolygon',
- coordinates: [
- [
+ },
+ {
+ type: 'MultiPoint',
+ coordinates: [
+ [0, 0],
+ [10, 10],
+ [10, 20],
+ [20, 20]
+ ]
+ },
+ {
+ type: 'MultiLineString',
+ coordinates: [
[
- [28, 26],
- [28, 0],
- [84, 0],
- [84, 42],
- [28, 26]
+ [10, 48],
+ [10, 21],
+ [10, 0]
],
[
- [52, 18],
- [66, 23],
- [73, 9],
- [48, 6],
- [52, 18]
+ [16, 0],
+ [16, 23],
+ [16, 48]
]
- ],
- [
+ ]
+ },
+ {
+ type: 'MultiPolygon',
+ coordinates: [
[
- [59, 18],
- [67, 18],
- [67, 13],
- [59, 13],
- [59, 18]
+ [
+ [28, 26],
+ [28, 0],
+ [84, 0],
+ [84, 42],
+ [28, 26]
+ ],
+ [
+ [52, 18],
+ [66, 23],
+ [73, 9],
+ [48, 6],
+ [52, 18]
+ ]
+ ],
+ [
+ [
+ [59, 18],
+ [67, 18],
+ [67, 13],
+ [59, 13],
+ [59, 18]
+ ]
]
]
- ]
- }
- ]
- }
- ],
- [
- {
- type: 'GeometryCollection',
- geometries: [
- {
- type: 'Point',
- coordinates: [10, 20]
- }
- ]
- }
- ],
- [
- {
- type: 'GeometryCollection',
- geometries: [{}]
- }
- ],
- [
- {
- type: 'GeometryCollection',
- geometries: []
- }
- ],
- [
- {
- type: 'GeometryCollection'
- }
- ]
- ])
+ }
+ ]
+ }
+ ],
+ [
+ {
+ type: 'GeometryCollection',
+ geometries: [
+ {
+ type: 'Point',
+ coordinates: [10, 20]
+ }
+ ]
+ }
+ ],
+ [
+ {
+ type: 'GeometryCollection',
+ geometries: [{}]
+ }
+ ],
+ [
+ {
+ type: 'GeometryCollection',
+ geometries: []
+ }
+ ],
+ [
+ {
+ type: 'GeometryCollection'
+ }
+ ]
+ ]);
+ })
.then(() => {
return conn.query('SELECT * FROM gis_geometrycollection_batch');
})
diff --git a/test/integration/test-batch.js b/test/integration/test-batch.js
index f3429062..19d4b999 100644
--- a/test/integration/test-batch.js
+++ b/test/integration/test-batch.js
@@ -20,9 +20,7 @@ describe('batch', () => {
before(function (done) {
timezoneParam = 'America/New_York';
supportBulk = (Conf.baseConfig.bulk === undefined ? true : Conf.baseConfig.bulk)
- ? (shareConn.info.serverCapabilities.high &
- Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) >
- 0
+ ? (shareConn.info.serverCapabilities & Capabilities.MARIADB_CLIENT_STMT_BULK_OPERATIONS) > 0
: false;
shareConn
.query('SELECT @@max_allowed_packet as t')
@@ -74,133 +72,133 @@ describe('batch', () => {
console.log(conn.info.getLastPackets());
}, 25000);
- conn.query('DROP TABLE IF EXISTS simpleBatch');
- conn.query(
- 'CREATE TABLE simpleBatch(id int, id2 boolean, id3 int, t varchar(128), d datetime, d2 datetime(6), g POINT, id4 int) CHARSET utf8mb4'
- );
- const f = {};
- f.toSqlString = () => {
- return 'blabla';
- };
conn
- .batch('INSERT INTO `simpleBatch` values (1, ?, 2, ?, ?, ?, ?, 3)', [
- [
- true,
- 'Ʉjo"h\u000An😎🌶\\\\',
- new Date('2001-12-31 23:59:58+3'),
- new Date('2018-01-01 12:30:20.456789+3'),
+ .query('DROP TABLE IF EXISTS simpleBatch')
+ .then(() => {
+ return conn.query(
+ 'CREATE TABLE simpleBatch(id int, id2 boolean, id3 int, t varchar(128), d datetime, d2 datetime(6), g POINT, id4 int) CHARSET utf8mb4'
+ );
+ })
+ .then(() => {
+ const f = {};
+ f.toSqlString = () => {
+ return 'blabla';
+ };
+ return conn.batch('INSERT INTO `simpleBatch` values (1, ?, 2, ?, ?, ?, ?, 3)', [
+ [
+ true,
+ 'Ʉjo"h\u000An😎🌶\\\\',
+ new Date('2001-12-31 23:59:58+3'),
+ new Date('2018-01-01 12:30:20.456789+3'),
+ {
+ type: 'Point',
+ coordinates: [10, 10]
+ }
+ ],
+ [
+ true,
+ f,
+ new Date('2001-12-31 23:59:58+3'),
+ new Date('2018-01-01 12:30:20.456789+3'),
+ {
+ type: 'Point',
+ coordinates: [10, 10]
+ }
+ ],
+ [
+ false,
+ { name: 'jack\u000Aमस्', val: 'tt' },
+ null,
+ new Date('2018-01-21 11:30:20.123456+3'),
+ {
+ type: 'Point',
+ coordinates: [10, 20]
+ }
+ ],
+ [
+ 0,
+ null,
+ new Date('2020-12-31 23:59:59+3'),
+ new Date('2018-01-21 11:30:20.123456+3'),
+ {
+ type: 'Point',
+ coordinates: [20, 20]
+ }
+ ]
+ ]);
+ })
+ .then((res) => {
+ assert.equal(res.affectedRows, 4);
+ return conn.query('select * from `simpleBatch`');
+ })
+ .then((res) => {
+ assert.deepEqual(res, [
{
- type: 'Point',
- coordinates: [10, 10]
- }
- ],
- [
- true,
- f,
- new Date('2001-12-31 23:59:58+3'),
- new Date('2018-01-01 12:30:20.456789+3'),
+ id: 1,
+ id2: 1,
+ id3: 2,
+ t: 'Ʉjo"h\u000An😎🌶\\\\',
+ d: new Date('2001-12-31 23:59:58+3'),
+ d2: new Date('2018-01-01 12:30:20.456789+3'),
+ g: {
+ type: 'Point',
+ coordinates: [10, 10]
+ },
+ id4: 3
+ },
{
- type: 'Point',
- coordinates: [10, 10]
- }
- ],
- [
- false,
- { name: 'jack\u000Aमस्', val: 'tt' },
- null,
- new Date('2018-01-21 11:30:20.123456+3'),
+ id: 1,
+ id2: 1,
+ id3: 2,
+ t: 'blabla',
+ d: new Date('2001-12-31 23:59:58+3'),
+ d2: new Date('2018-01-01 12:30:20.456789+3'),
+ g: {
+ type: 'Point',
+ coordinates: [10, 10]
+ },
+ id4: 3
+ },
{
- type: 'Point',
- coordinates: [10, 20]
- }
- ],
- [
- 0,
- null,
- new Date('2020-12-31 23:59:59+3'),
- new Date('2018-01-21 11:30:20.123456+3'),
+ id: 1,
+ id2: 0,
+ id3: 2,
+ t: '{"name":"jack\\nमस्","val":"tt"}',
+ d: null,
+ d2: new Date('2018-01-21 11:30:20.123456+3'),
+ g: {
+ type: 'Point',
+ coordinates: [10, 20]
+ },
+ id4: 3
+ },
{
- type: 'Point',
- coordinates: [20, 20]
+ id: 1,
+ id2: 0,
+ id3: 2,
+ t: null,
+ d: new Date('2020-12-31 23:59:59+3'),
+ d2: new Date('2018-01-21 11:30:20.123456+3'),
+ g: {
+ type: 'Point',
+ coordinates: [20, 20]
+ },
+ id4: 3
}
- ]
- ])
+ ]);
+ return conn.query('DROP TABLE simpleBatch');
+ })
.then((res) => {
- assert.equal(res.affectedRows, 4);
- conn
- .query('select * from `simpleBatch`')
- .then((res) => {
- assert.deepEqual(res, [
- {
- id: 1,
- id2: 1,
- id3: 2,
- t: 'Ʉjo"h\u000An😎🌶\\\\',
- d: new Date('2001-12-31 23:59:58+3'),
- d2: new Date('2018-01-01 12:30:20.456789+3'),
- g: {
- type: 'Point',
- coordinates: [10, 10]
- },
- id4: 3
- },
- {
- id: 1,
- id2: 1,
- id3: 2,
- t: 'blabla',
- d: new Date('2001-12-31 23:59:58+3'),
- d2: new Date('2018-01-01 12:30:20.456789+3'),
- g: {
- type: 'Point',
- coordinates: [10, 10]
- },
- id4: 3
- },
- {
- id: 1,
- id2: 0,
- id3: 2,
- t: '{"name":"jack\\nमस्","val":"tt"}',
- d: null,
- d2: new Date('2018-01-21 11:30:20.123456+3'),
- g: {
- type: 'Point',
- coordinates: [10, 20]
- },
- id4: 3
- },
- {
- id: 1,
- id2: 0,
- id3: 2,
- t: null,
- d: new Date('2020-12-31 23:59:59+3'),
- d2: new Date('2018-01-21 11:30:20.123456+3'),
- g: {
- type: 'Point',
- coordinates: [20, 20]
- },
- id4: 3
- }
- ]);
- conn
- .query('DROP TABLE simpleBatch')
- .then((res) => {
- clearTimeout(timeout);
- conn.end();
- done();
- })
- .catch(done);
- })
- .catch((err) => {
- done(err);
- });
- });
- conn
+ clearTimeout(timeout);
+ conn.end();
+ done();
+ })
+ .catch(done);
+
+ return conn
.query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
})
.catch(done);
})
@@ -215,55 +213,55 @@ describe('batch', () => {
console.log(conn.info.getLastPackets());
}, 25000);
- conn.query('DROP TABLE IF EXISTS simpleBatchWithOptions');
- conn.query('CREATE TABLE simpleBatchWithOptions(id int, d datetime)');
- const f = {};
- f.toSqlString = () => {
- return 'blabla';
- };
conn
- .batch(
- {
- sql: 'INSERT INTO `simpleBatchWithOptions` values (?, ?)',
- maxAllowedPacket: 1048576
- },
- [
- [1, new Date('2001-12-31 23:59:58')],
- [2, new Date('2001-12-31 23:59:58')]
- ]
- )
+ .query('DROP TABLE IF EXISTS simpleBatchWithOptions')
+ .then(() => {
+ return conn.query('CREATE TABLE simpleBatchWithOptions(id int, d datetime)');
+ })
+ .then(() => {
+ const f = {};
+ f.toSqlString = () => {
+ return 'blabla';
+ };
+ return conn.batch(
+ {
+ sql: 'INSERT INTO `simpleBatchWithOptions` values (?, ?)',
+ maxAllowedPacket: 1048576
+ },
+ [
+ [1, new Date('2001-12-31 23:59:58')],
+ [2, new Date('2001-12-31 23:59:58')]
+ ]
+ );
+ })
.then((res) => {
assert.equal(res.affectedRows, 2);
- conn
- .query('select * from `simpleBatchWithOptions`')
- .then((res) => {
- assert.deepEqual(res, [
- {
- id: 1,
- d: new Date('2001-12-31 23:59:58')
- },
- {
- id: 2,
- d: new Date('2001-12-31 23:59:58')
- }
- ]);
- conn
- .query('DROP TABLE simpleBatchWithOptions')
- .then((res) => {
- clearTimeout(timeout);
- conn.end();
- done();
- })
- .catch(done);
- })
- .catch((err) => {
- done(err);
- });
- });
- conn
+ return conn.query('select * from `simpleBatchWithOptions`');
+ })
+ .then((res) => {
+ assert.deepEqual(res, [
+ {
+ id: 1,
+ d: new Date('2001-12-31 23:59:58')
+ },
+ {
+ id: 2,
+ d: new Date('2001-12-31 23:59:58')
+ }
+ ]);
+ return conn.query('DROP TABLE simpleBatchWithOptions');
+ })
+ .then((res) => {
+ clearTimeout(timeout);
+ conn.end();
+ done();
+ })
+ .catch(done);
+
+ return conn
.query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
})
.catch(done);
})
@@ -282,39 +280,41 @@ describe('batch', () => {
console.log(conn.info.getLastPackets());
}, 25000);
- conn.query('DROP TABLE IF EXISTS simpleBatchCP1251');
- conn.query('CREATE TABLE simpleBatchCP1251(t varchar(128), id int) CHARSET utf8mb4');
conn
- .batch('INSERT INTO `simpleBatchCP1251` values (?, ?)', [
- ['john', 2],
- ['©°', 3]
- ])
+ .query('DROP TABLE IF EXISTS simpleBatchCP1251')
+ .then(() => {
+ return conn.query(
+ 'CREATE TABLE simpleBatchCP1251(t varchar(128), id int) CHARSET utf8mb4'
+ );
+ })
+ .then(() => {
+ return conn.batch('INSERT INTO `simpleBatchCP1251` values (?, ?)', [
+ ['john', 2],
+ ['©°', 3]
+ ]);
+ })
.then((res) => {
assert.equal(res.affectedRows, 2);
- conn
- .query('select * from `simpleBatchCP1251`')
- .then((res) => {
- assert.deepEqual(res, [
- { id: 2, t: 'john' },
- { id: 3, t: '©°' }
- ]);
- conn
- .query('DROP TABLE simpleBatchCP1251')
- .then((res) => {
- clearTimeout(timeout);
- conn.end();
- done();
- })
- .catch(done);
- })
- .catch((err) => {
- done(err);
- });
- });
- conn
- .query('select 2')
+ return conn.query('select * from `simpleBatchCP1251`');
+ })
+ .then((res) => {
+ assert.deepEqual(res, [
+ { id: 2, t: 'john' },
+ { id: 3, t: '©°' }
+ ]);
+ return conn.query('DROP TABLE simpleBatchCP1251');
+ })
+ .then((res) => {
+ clearTimeout(timeout);
+ conn.end();
+ done();
+ })
+ .catch(done);
+
+ return conn
+ .query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '2': 2 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
})
.catch(done);
})
@@ -461,7 +461,7 @@ describe('batch', () => {
conn
.query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
})
.catch(done);
})
@@ -655,7 +655,7 @@ describe('batch', () => {
conn
.query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
clearTimeout(timeout);
conn.end();
done();
@@ -885,7 +885,7 @@ describe('batch', () => {
conn
.query('select 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
clearTimeout(timeout);
done();
@@ -1614,6 +1614,38 @@ describe('batch', () => {
});
});
+ it('rewrite split for maxAllowedPacket', function (done) {
+ const t = makeid(100);
+ base
+ .createConnection({ bulk: false, maxAllowedPacket: 150 })
+ .then((conn) => {
+ conn
+ .query('DROP TABLE IF EXISTS my_table')
+ .then(() => {
+ return conn.query('CREATE TABLE my_table(id int, val LONGTEXT)');
+ })
+ .then(() => {
+ return conn.batch('INSERT INTO my_table(id,val) VALUES( ?, ?) ', [
+ [1, t],
+ [2, t]
+ ]);
+ })
+ .then((res) => {
+ return conn.query('SELECT * FROM my_table');
+ })
+ .then((res) => {
+ assert.deepEqual(res, [
+ { id: 1, val: t },
+ { id: 2, val: t }
+ ]);
+ conn.end();
+ done();
+ })
+ .catch(done);
+ })
+ .catch(done);
+ });
+
it('batch with erroneous parameter', function (done) {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
base.createConnection({ compress: useCompression, bulk: false }).then((conn) => {
@@ -1625,7 +1657,7 @@ describe('batch', () => {
})
.catch((err) => {
assert.isTrue(
- err.message.includes('Parameter at position 2 is not set for values 1'),
+ err.message.includes('Parameter at position 1 is not set for values 1'),
err.message
);
conn.end();
@@ -2034,3 +2066,13 @@ describe('batch', () => {
});
});
});
+
+function makeid(length) {
+ var result = '';
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ var charactersLength = characters.length;
+ for (var i = 0; i < length; i++) {
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
+ }
+ return result;
+}
diff --git a/test/integration/test-big-query.js b/test/integration/test-big-query.js
index 9c5fca4c..493a85ee 100644
--- a/test/integration/test-big-query.js
+++ b/test/integration/test-big-query.js
@@ -26,9 +26,14 @@ describe('Big query', function () {
it('parameter bigger than 16M packet size', function (done) {
if (maxAllowedSize <= testSize) this.skip();
this.timeout(20000); //can take some time
- shareConn.query('CREATE TEMPORARY TABLE bigParameterBigParam (b longblob)');
shareConn
- .query('insert into bigParameterBigParam(b) values(?)', [buf])
+ .query('DROP TABLE IF EXISTS bigParameterBigParam')
+ .then(() => {
+ return shareConn.query('CREATE TABLE bigParameterBigParam (b longblob)');
+ })
+ .then(() => {
+ return shareConn.query('insert into bigParameterBigParam(b) values(?)', [buf]);
+ })
.then(() => {
return shareConn.query('SELECT * from bigParameterBigParam');
})
@@ -40,11 +45,16 @@ describe('Big query', function () {
});
it('int8 buffer overflow', function (done) {
+ const buf = Buffer.alloc(979, '0');
base.createConnection({ collation: 'latin1_swedish_ci' }).then((conn) => {
- conn.query('CREATE TEMPORARY TABLE bigParameterInt8 (a varchar(1024), b varchar(10))');
- const buf = Buffer.alloc(979, '0');
conn
- .query('insert into bigParameterInt8 values(?, ?)', [buf.toString(), 'test'])
+ .query('DROP TABLE IF EXISTS bigParameterInt8')
+ .then(() => {
+ return conn.query('CREATE TABLE bigParameterInt8 (a varchar(1024), b varchar(10))');
+ })
+ .then(() => {
+ return conn.query('insert into bigParameterInt8 values(?, ?)', [buf.toString(), 'test']);
+ })
.then(() => {
return conn.query('SELECT * from bigParameterInt8');
})
@@ -84,7 +94,7 @@ describe('Big query', function () {
const st = Buffer.alloc(65536, '0').toString();
const st2 = Buffer.alloc(1048576, '0').toString();
const params = [st];
- let sql = 'CREATE TEMPORARY TABLE bigParameter (a0 MEDIUMTEXT ';
+ let sql = 'CREATE TABLE bigParameter (a0 MEDIUMTEXT ';
let sqlInsert = 'insert into bigParameter values (?';
for (let i = 1; i < 10; i++) {
sql += ',a' + i + ' MEDIUMTEXT ';
@@ -93,9 +103,14 @@ describe('Big query', function () {
}
sql += ')';
sqlInsert += ')';
- conn.query(sql);
conn
- .query(sqlInsert, params)
+ .query('DROP TABLE IF EXISTS bigParameter')
+ .then(() => {
+ return conn.query(sql);
+ })
+ .then(() => {
+ return conn.query(sqlInsert, params);
+ })
.then(() => {
return conn.query('SELECT * from bigParameter');
})
@@ -106,6 +121,9 @@ describe('Big query', function () {
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
}
});
diff --git a/test/integration/test-change-user.js b/test/integration/test-change-user.js
index 89e818f9..f5ad0d19 100644
--- a/test/integration/test-change-user.js
+++ b/test/integration/test-change-user.js
@@ -7,35 +7,55 @@ const Conf = require('../conf');
describe('change user', () => {
before((done) => {
- shareConn.query("DROP USER ChangeUser@'%'").catch((err) => {});
- shareConn.query("DROP USER ChangeUser2@'%'").catch((err) => {});
- shareConn.query('CREATE DATABASE IF NOT EXISTS test');
- shareConn.query("CREATE USER ChangeUser@'%' IDENTIFIED BY 'm1P4ssw0@rd'");
- shareConn.query(
- 'GRANT SELECT,EXECUTE ON `' + Conf.baseConfig.database + "`.* TO ChangeUser@'%'"
- );
- shareConn.query("CREATE USER ChangeUser2@'%' IDENTIFIED BY 'm1SecondP@rd'");
- shareConn.query(
- 'GRANT SELECT,EXECUTE ON `' +
- Conf.baseConfig.database +
- "`.* TO ChangeUser2@'%' with grant option"
- );
- shareConn
- .query('FLUSH PRIVILEGES')
+ Promise.all([
+ shareConn.query("DROP USER IF EXISTS ChangeUser@'%'"),
+ shareConn.query("DROP USER IF EXISTS ChangeUser2@'%'")
+ ])
+ .then(() => {
+ return shareConn.query('CREATE DATABASE IF NOT EXISTS test');
+ })
+ .then(() => {
+ return shareConn.query("CREATE USER ChangeUser@'%' IDENTIFIED BY 'm1P4ssw0@rd'");
+ })
+ .then(() => {
+ return shareConn.query(
+ 'GRANT SELECT,EXECUTE ON `' + Conf.baseConfig.database + "`.* TO ChangeUser@'%'"
+ );
+ })
+ .then(() => {
+ return shareConn.query("CREATE USER ChangeUser2@'%' IDENTIFIED BY 'm1SecondP@rd'");
+ })
+ .then(() => {
+ return shareConn.query(
+ 'GRANT SELECT,EXECUTE ON `' +
+ Conf.baseConfig.database +
+ "`.* TO ChangeUser2@'%' with grant option"
+ );
+ })
+ .then(() => {
+ return shareConn.query('FLUSH PRIVILEGES');
+ })
.then(() => done())
.catch((err) => done());
});
after((done) => {
- shareConn.query("DROP USER ChangeUser@'%'");
- shareConn.query("DROP USER ChangeUser2@'%'");
shareConn
- .query('FLUSH PRIVILEGES')
- .then(() => done())
+ .query("DROP USER IF EXISTS ChangeUser@'%'")
+ .then(() => {
+ return shareConn.query("DROP USER IF EXISTS ChangeUser2@'%'");
+ })
+ .then(() => {
+ return shareConn.query('FLUSH PRIVILEGES');
+ })
+ .then(() => {
+ done();
+ })
.catch((err) => done());
});
it('basic change user using callback', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
const conn = base.createCallbackConnection();
conn.connect((err) => {
@@ -61,6 +81,7 @@ describe('change user', () => {
});
it('wrong charset', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base.createConnection().then((conn) => {
conn
@@ -81,6 +102,7 @@ describe('change user', () => {
});
it('wrong collation in charset', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base.createConnection().then((conn) => {
conn
@@ -96,7 +118,9 @@ describe('change user', () => {
.catch(done);
});
});
+
it('wrong collation', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base.createConnection().then((conn) => {
conn
@@ -117,7 +141,7 @@ describe('change user', () => {
});
it('basic change user using callback no function', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
const conn = base.createCallbackConnection();
conn.connect((err) => {
@@ -137,7 +161,7 @@ describe('change user', () => {
});
it('callback change user without option', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
const conn = base.createCallbackConnection();
conn.connect((err) => {
@@ -157,7 +181,7 @@ describe('change user', () => {
});
it('basic change user using promise', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base
@@ -196,7 +220,7 @@ describe('change user', () => {
});
it('basic change user using promise non node.js encoding', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base
@@ -236,6 +260,7 @@ describe('change user', () => {
});
it('change user with collation', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base
.createConnection()
@@ -275,6 +300,7 @@ describe('change user', () => {
});
it('autocommit state after changing user', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
base
.createConnection()
@@ -296,7 +322,7 @@ describe('change user', () => {
if (
shareConn.info.isMariaDB() &&
shareConn.info.hasMinVersion(10, 2, 2) &&
- !process.env.MAXSCALE_VERSION &&
+ !process.env.MAXSCALE_TEST_DISABLE &&
!process.env.SKYSQL
) {
assert.equal(conn.info.database, 'test');
diff --git a/test/integration/test-cluster.js b/test/integration/test-cluster.js
index e3747071..9ba54488 100644
--- a/test/integration/test-cluster.js
+++ b/test/integration/test-cluster.js
@@ -486,7 +486,7 @@ describe('cluster', function () {
it('server close connection during query', function (done) {
if (process.env.SKYSQL) this.skip();
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(10000);
const poolCluster = basePromise.createPoolCluster({});
@@ -525,7 +525,7 @@ describe('cluster', function () {
});
it('socket close connection during query', function (done) {
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB() || !shareConn.info.hasMinVersion(10, 1, 2)) this.skip();
this.timeout(10000);
const poolCluster = basePromise.createPoolCluster({});
diff --git a/test/integration/test-compression.js b/test/integration/test-compression.js
index 765adb22..a778fe2e 100644
--- a/test/integration/test-compression.js
+++ b/test/integration/test-compression.js
@@ -42,7 +42,7 @@ describe('Compression', function () {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
@@ -56,13 +56,13 @@ describe('Compression', function () {
.query('select 1; DO 1;select 2')
.then((rows) => {
assert.equal(rows.length, 3);
- assert.deepEqual(rows[0], [{ '1': 1 }]);
+ assert.deepEqual(rows[0], [{ 1: 1 }]);
assert.deepEqual(rows[1], {
affectedRows: 0,
insertId: 0,
warningStatus: 0
});
- assert.deepEqual(rows[2], [{ '2': 2 }]);
+ assert.deepEqual(rows[2], [{ 2: 2 }]);
done();
})
.catch(done);
@@ -71,9 +71,14 @@ describe('Compression', function () {
it('parameter bigger than 16M packet size', function (done) {
if (maxAllowedSize <= testSize) this.skip();
this.timeout(20000); //can take some time
- conn.query('CREATE TEMPORARY TABLE bigParameter (b longblob)');
conn
- .query('insert into bigParameter(b) values(?)', [buf])
+ .query('DROP TABLE IF EXISTS bigParameter')
+ .then(() => {
+ return conn.query('CREATE TABLE bigParameter (b longblob)');
+ })
+ .then(() => {
+ return conn.query('insert into bigParameter(b) values(?)', [buf]);
+ })
.then(() => {
return conn.query('SELECT * from bigParameter');
})
@@ -87,9 +92,14 @@ describe('Compression', function () {
it('multi compression packet size', function (done) {
if (maxAllowedSize <= testSize) this.skip();
this.timeout(20000); //can take some time
- conn.query('CREATE TEMPORARY TABLE bigParameter2 (b longblob)');
conn
- .query('insert into bigParameter2(b) values(?)', [randomBuf])
+ .query('DROP TABLE IF EXISTS bigParameter2')
+ .then(() => {
+ return conn.query('CREATE TABLE bigParameter2 (b longblob)');
+ })
+ .then(() => {
+ return conn.query('insert into bigParameter2(b) values(?)', [randomBuf]);
+ })
.then(() => {
return conn.query('SELECT * from bigParameter2');
})
diff --git a/test/integration/test-connection-meta.js b/test/integration/test-connection-meta.js
index 141fd481..2c3cdd8d 100644
--- a/test/integration/test-connection-meta.js
+++ b/test/integration/test-connection-meta.js
@@ -12,10 +12,10 @@ describe('Connection meta', function () {
assert(serverVersion.startsWith('10.5'));
} else {
const version =
- process.platform === 'win32'
- ? process.env.DB
- : process.env.DB.substr(process.env.DB.indexOf(':') + 1);
- assert(serverVersion.startsWith(version));
+ process.env.DB.indexOf(':') != -1
+ ? process.env.DB.substr(process.env.DB.indexOf(':') + 1)
+ : process.env.DB;
+ assert(serverVersion.startsWith(version), serverVersion + '/' + version);
}
}
});
diff --git a/test/integration/test-connection-opts.js b/test/integration/test-connection-opts.js
index 6425fe0e..b53dca5d 100644
--- a/test/integration/test-connection-opts.js
+++ b/test/integration/test-connection-opts.js
@@ -219,6 +219,7 @@ describe('connection option', () => {
});
it('Server with different tz', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
//MySQL 5.5 doesn't have milliseconds
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
@@ -226,15 +227,27 @@ describe('connection option', () => {
.createConnection({ timezone: 'Etc/GMT+5' })
.then((conn) => {
const now = new Date();
- conn.query("SET SESSION time_zone = '-05:00'");
- conn.query('CREATE TEMPORARY TABLE t1 (a timestamp(6))');
- conn.query('INSERT INTO t1 values (?)', now);
- conn.query('SELECT NOW() as b, t1.a FROM t1').then((res) => {
- assert.deepEqual(res[0].a, now);
- assert.isOk(Math.abs(res[0].b.getTime() - now.getTime()) < 5000);
- conn.end();
- done();
- });
+ conn
+ .query("SET SESSION time_zone = '-05:00'")
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t1');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a timestamp(6))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO t1 values (?)', now);
+ })
+ .then(() => {
+ return conn.query('SELECT NOW() as b, t1.a FROM t1');
+ })
+ .then((res) => {
+ assert.deepEqual(res[0].a, now);
+ assert.isOk(Math.abs(res[0].b.getTime() - now.getTime()) < 5000);
+ conn.end();
+ done();
+ })
+ .catch(done);
})
.catch(done);
});
@@ -243,23 +256,38 @@ describe('connection option', () => {
base
.createConnection({ nestTables: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query('SELECT * FROM t1, t2')
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM t1, t2');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ t1: { a: 'bla' }, t2: { b: 'bou' } },
{ t1: { a: 'bla2' }, t2: { b: 'bou' } }
]);
- return conn.end();
- })
- .then(() => {
+ conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -268,23 +296,38 @@ describe('connection option', () => {
base
.createConnection({ nestTables: '_' })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query('SELECT * FROM t1, t2')
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM t1, t2');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ t1_a: 'bla', t2_b: 'bou' },
{ t1_a: 'bla2', t2_b: 'bou' }
]);
- return conn.end();
- })
- .then(() => {
+ conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -293,12 +336,26 @@ describe('connection option', () => {
base
.createConnection({ rowsAsArray: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query('SELECT * FROM t1, t2')
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM t1, t2');
+ })
.then((rows) => {
assert.deepEqual(rows, [
['bla', 'bou'],
@@ -318,12 +375,26 @@ describe('connection option', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query({ rowsAsArray: true, sql: 'SELECT * FROM t1, t2' })
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query({ rowsAsArray: true, sql: 'SELECT * FROM t1, t2' });
+ })
.then((rows) => {
assert.deepEqual(rows, [
['bla', 'bou'],
@@ -343,12 +414,26 @@ describe('connection option', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query({ nestTables: true, sql: 'SELECT * FROM t1, t2' })
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query({ nestTables: true, sql: 'SELECT * FROM t1, t2' });
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ t1: { a: 'bla' }, t2: { b: 'bou' } },
@@ -368,12 +453,26 @@ describe('connection option', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t1 (a varchar(20))');
- conn.query('CREATE TEMPORARY TABLE t2 (b varchar(20))');
- conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
- conn.query("INSERT INTO t2 VALUES ('bou')");
conn
- .query({ nestTables: '_', sql: 'SELECT * FROM t1, t2' })
+ .query('DROP TABLE IF EXISTS t1')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS t2');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t1 (a varchar(20))');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE t2 (b varchar(20))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t1 VALUES ('bla'), ('bla2')");
+ })
+ .then(() => {
+ return conn.query("INSERT INTO t2 VALUES ('bou')");
+ })
+ .then(() => {
+ return conn.query({ nestTables: '_', sql: 'SELECT * FROM t1, t2' });
+ })
.then((rows) => {
assert.deepEqual(rows, [
{ t1_a: 'bla', t2_b: 'bou' },
@@ -396,7 +495,7 @@ describe('connection option', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
diff --git a/test/integration/test-connection.js b/test/integration/test-connection.js
index d791699e..45271da2 100644
--- a/test/integration/test-connection.js
+++ b/test/integration/test-connection.js
@@ -25,7 +25,7 @@ describe('connection', () => {
});
it('with medium connection attributes', function (done) {
- const mediumAttribute = Buffer.alloc(20000, 'a').toString();
+ const mediumAttribute = Buffer.alloc(512, 'a').toString();
connectWithAttributes({ par1: 'bouh', par2: mediumAttribute }, done);
});
@@ -36,7 +36,7 @@ describe('connection', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
@@ -46,7 +46,7 @@ describe('connection', () => {
}
it('connection attributes with encoding not supported by node.js', function (done) {
- const mediumAttribute = Buffer.alloc(20000, 'a').toString();
+ const mediumAttribute = Buffer.alloc(500, 'a').toString();
base
.createConnection({
connectAttributes: { par1: 'bouh', par2: mediumAttribute },
@@ -56,7 +56,7 @@ describe('connection', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
@@ -91,7 +91,7 @@ describe('connection', () => {
if (err) {
done(err);
} else {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
}
@@ -182,7 +182,7 @@ describe('connection', () => {
});
it('connection error event', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 6, 0)) this.skip();
base
.createConnection()
@@ -254,7 +254,7 @@ describe('connection', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
@@ -425,7 +425,7 @@ describe('connection', () => {
});
it('connection.destroy() during query execution', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
this.timeout(10000);
base.createConnection().then((conn) => {
@@ -591,7 +591,7 @@ describe('connection', () => {
if (
(shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 2, 2)) ||
(!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 4)) ||
- process.env.MAXSCALE_VERSION ||
+ process.env.MAXSCALE_TEST_DISABLE ||
process.env.SKYSQL
) {
//session tracking not implemented
@@ -642,7 +642,8 @@ describe('connection', () => {
it('connection.connect() error code validation callback', function (done) {
const conn = base.createCallbackConnection({
user: 'fooUser',
- password: 'myPwd'
+ password: 'myPwd',
+ allowPublicKeyRetrieval: true
});
conn.connect((err) => {
if (!err) done(new Error('must have thrown error'));
@@ -685,7 +686,7 @@ describe('connection', () => {
it('connection.connect() error code validation promise', function (done) {
base
- .createConnection({ user: 'fooUser', password: 'myPwd' })
+ .createConnection({ user: 'fooUser', password: 'myPwd', allowPublicKeyRetrieval: true })
.then(() => {
done(new Error('must have thrown error'));
})
@@ -773,7 +774,7 @@ describe('connection', () => {
if (
((shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 2)) ||
(!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7))) &&
- !process.env.MAXSCALE_VERSION &&
+ !process.env.MAXSCALE_TEST_DISABLE &&
!process.env.SKYSQL
) {
//ok packet contain meta change
@@ -796,7 +797,7 @@ describe('connection', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
const diff = process.hrtime(startTime);
//query has take more than 500ms
assert.isTrue(
@@ -848,7 +849,7 @@ describe('connection', () => {
if (
!shareConn.info.isMariaDB() ||
!shareConn.info.hasMinVersion(10, 4, 3) ||
- process.env.MAXSCALE_VERSION ||
+ process.env.MAXSCALE_TEST_DISABLE ||
process.env.SKYSQL
) {
//session tracking not implemented
@@ -889,7 +890,7 @@ describe('connection', () => {
if (
!shareConn.info.isMariaDB() ||
!shareConn.info.hasMinVersion(10, 4, 3) ||
- process.env.MAXSCALE_VERSION ||
+ process.env.MAXSCALE_TEST_DISABLE ||
process.env.SKYSQL
) {
//session tracking not implemented
diff --git a/test/integration/test-debug.js b/test/integration/test-debug.js
index 3848ab29..994f9040 100644
--- a/test/integration/test-debug.js
+++ b/test/integration/test-debug.js
@@ -66,7 +66,7 @@ describe('debug', () => {
.then(() => {
if (
compress &&
- process.env.MAXSCALE_VERSION == undefined &&
+ process.env.MAXSCALE_TEST_DISABLE == undefined &&
process.env.SKYSQL == undefined
) {
conn.debugCompress(true);
@@ -78,7 +78,7 @@ describe('debug', () => {
.then(() => {
if (
compress &&
- process.env.MAXSCALE_VERSION == undefined &&
+ process.env.MAXSCALE_TEST_DISABLE == undefined &&
process.env.SKYSQL == undefined
) {
conn.debugCompress(false);
@@ -96,13 +96,13 @@ describe('debug', () => {
console.log = initialStdOut;
const serverVersion = conn.serverVersion();
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) compress = false;
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) compress = false;
const rangeWithEOF = compress ? [900, 1200] : [1800, 2400];
const rangeWithoutEOF = compress ? [900, 1200] : [1750, 2000];
if (
((conn.info.isMariaDB() && conn.info.hasMinVersion(10, 2, 2)) ||
(!conn.info.isMariaDB() && conn.info.hasMinVersion(5, 7, 5))) &&
- !process.env.MAXSCALE_VERSION &&
+ !process.env.MAXSCALE_TEST_DISABLE &&
!process.env.SKYSQL
) {
assert(
@@ -145,7 +145,7 @@ describe('debug', () => {
}
it('select big request (compressed data) debug', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
initialStdOut = console.log;
let data = '';
console.log = function () {
@@ -216,23 +216,26 @@ describe('debug', () => {
compress: compress
})
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE smallLocalInfile(id int, test varchar(100))');
conn
- .query(
- "LOAD DATA LOCAL INFILE '" +
- smallFileName.replace(/\\/g, '/') +
- "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
- )
+ .query('DROP TABLE IF EXISTS smallLocalInfile')
.then(() => {
- return conn.end();
+ return conn.query('CREATE TABLE smallLocalInfile(id int, test varchar(100))');
+ })
+ .then(() => {
+ return conn.query(
+ "LOAD DATA LOCAL INFILE '" +
+ smallFileName.replace(/\\/g, '/') +
+ "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
+ );
})
.then(() => {
+ conn.end();
//wait 100ms to ensure stream has been written
setTimeout(() => {
console.log = initialStdOut;
const serverVersion = conn.serverVersion();
- const range = [5500, 6800];
+ const range = [5500, 7000];
assert(
data.length > range[0] && data.length < range[1],
'wrong data length : ' +
diff --git a/test/integration/test-error.js b/test/integration/test-error.js
index 30e2463d..9e6ef9a0 100644
--- a/test/integration/test-error.js
+++ b/test/integration/test-error.js
@@ -334,7 +334,7 @@ describe('Error', () => {
it('server close connection without warning', function (done) {
//removed for maxscale, since wait_timeout will be set to other connections
- if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(20000);
let connectionErr = false;
base
@@ -374,7 +374,7 @@ describe('Error', () => {
it('server close connection - no connection error event', function (done) {
this.timeout(20000);
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
// Remove Mocha's error listener
const originalException = process.listeners('uncaughtException').pop();
process.removeListener('uncaughtException', originalException);
@@ -415,7 +415,7 @@ describe('Error', () => {
});
it('server close connection during query', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(20000);
base
.createConnection()
@@ -427,7 +427,7 @@ describe('Error', () => {
done(new Error('must have thrown error !'));
})
.catch((err) => {
- if (process.env.MAXSCALE_VERSION) {
+ if (process.env.MAXSCALE_TEST_DISABLE) {
assert.isTrue(err.message.includes('Lost connection to backend server'), err.message);
assert.equal(err.sqlState, 'HY000');
} else {
@@ -448,7 +448,7 @@ describe('Error', () => {
});
it('end connection query error', function (done) {
- // if (process.env.MAXSCALE_VERSION) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
base
.createConnection()
.then((conn) => {
@@ -502,7 +502,7 @@ describe('Error', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
@@ -521,10 +521,18 @@ describe('Error', () => {
)
);
};
-
- shareConn.query('CREATE TEMPORARY TABLE undefinedParameter (id int, id2 int, id3 int)');
shareConn
- .query('INSERT INTO undefinedParameter values (?, ?, ?)', [1, undefined, 3])
+ .query('DROP TABLE IF EXISTS undefinedParameter')
+ .then(() => {
+ return shareConn.query('CREATE TABLE undefinedParameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO undefinedParameter values (?, ?, ?)', [
+ 1,
+ undefined,
+ 3
+ ]);
+ })
.then(() => {
done(new Error('must have thrown error !'));
})
@@ -533,7 +541,7 @@ describe('Error', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
@@ -552,9 +560,14 @@ describe('Error', () => {
)
);
};
- shareConn.query('CREATE TEMPORARY TABLE execute_missing_parameter (id int, id2 int, id3 int)');
shareConn
- .query('INSERT INTO execute_missing_parameter values (?, ?, ?)', [1, 3])
+ .query('DROP TABLE IF EXISTS execute_missing_parameter')
+ .then(() => {
+ return shareConn.query('CREATE TABLE execute_missing_parameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO execute_missing_parameter values (?, ?, ?)', [1, 3]);
+ })
.then(() => {
done(new Error('must have thrown error !'));
})
@@ -562,51 +575,60 @@ describe('Error', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
});
it('query missing parameter with compression', function (done) {
- const handleResult = function (err) {
- assert.equal(err.errno, 45016);
- assert.equal(err.sqlState, 'HY000');
- assert.equal(err.code, 'ER_MISSING_PARAMETER');
- assert.isTrue(!err.fatal);
- assert.ok(
- err.message.includes(
- 'Parameter at position 3 is not set\n' +
- 'sql: INSERT INTO execute_missing_parameter values (?, ?, ?) - parameters:[1,3]'
- )
- );
- };
base
.createConnection({ compress: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE execute_missing_parameter (id int, id2 int, id3 int)');
conn
- .query('INSERT INTO execute_missing_parameter values (?, ?, ?)', [1, 3])
+ .query('DROP TABLE IF EXISTS execute_missing_parameter')
.then(() => {
- done(new Error('must have thrown error !'));
+ return conn.query('CREATE TABLE execute_missing_parameter (id int, id2 int, id3 int)');
})
- .catch(handleResult);
- conn
- .query('SELECT 1')
- .then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
- conn.end();
- done();
+ .then(() => {
+ return conn.query('INSERT INTO execute_missing_parameter values (?, ?, ?)', [1, 3]);
+ })
+ .then(() => {
+ done(new Error('must have thrown error !'));
})
- .catch(done);
+ .catch((err) => {
+ assert.equal(err.errno, 45016);
+ assert.equal(err.sqlState, 'HY000');
+ assert.equal(err.code, 'ER_MISSING_PARAMETER');
+ assert.isTrue(!err.fatal);
+ assert.ok(
+ err.message.includes(
+ 'Parameter at position 3 is not set\n' +
+ 'sql: INSERT INTO execute_missing_parameter values (?, ?, ?) - parameters:[1,3]'
+ )
+ );
+ return conn
+ .query('SELECT 1')
+ .then((rows) => {
+ assert.deepEqual(rows, [{ 1: 1 }]);
+ conn.end();
+ done();
+ })
+ .catch(done);
+ });
})
.catch(done);
});
it('query no parameter', function (done) {
- shareConn.query('CREATE TEMPORARY TABLE execute_no_parameter (id int, id2 int, id3 int)');
shareConn
- .query('INSERT INTO execute_no_parameter values (?, ?, ?)', [])
+ .query('DROP TABLE IF EXISTS execute_no_parameter')
+ .then(() => {
+ return shareConn.query('CREATE TABLE execute_no_parameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO execute_no_parameter values (?, ?, ?)', []);
+ })
.then(() => {
done(new Error('must have thrown error !'));
})
@@ -625,16 +647,22 @@ describe('Error', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
});
it('query to much parameter', function (done) {
- shareConn.query('CREATE TEMPORARY TABLE to_much_parameters (id int, id2 int, id3 int)');
shareConn
- .query('INSERT INTO to_much_parameters values (?, ?, ?) ', [1, 2, 3, 4])
+ .query('DROP TABLE IF EXISTS to_much_parameters')
+ .then(() => {
+ return shareConn.query('CREATE TABLE to_much_parameters (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO to_much_parameters values (?, ?, ?) ', [1, 2, 3, 4]);
+ })
+
.then(() => done())
.catch(done);
});
diff --git a/test/integration/test-initial-commands.js b/test/integration/test-initial-commands.js
index 82da9f40..9748d785 100644
--- a/test/integration/test-initial-commands.js
+++ b/test/integration/test-initial-commands.js
@@ -12,7 +12,7 @@ describe('initial connection commands', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
@@ -77,7 +77,7 @@ describe('initial connection commands', () => {
conn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
diff --git a/test/integration/test-local-infile.js b/test/integration/test-local-infile.js
index 3c6414a6..ccee8a4f 100644
--- a/test/integration/test-local-infile.js
+++ b/test/integration/test-local-infile.js
@@ -82,6 +82,7 @@ describe('local-infile', () => {
conn
.query("LOAD DATA LOCAL INFILE 'dummy.tsv' INTO TABLE t (id, test)")
.then(() => {
+ conn.end();
done(new Error('must have thrown error !'));
})
.catch((err) => {
@@ -112,8 +113,11 @@ describe('local-infile', () => {
base
.createConnection({ permitLocalInfile: true })
.then((conn) => {
- conn
- .query('CREATE TEMPORARY TABLE smallLocalInfile(id int, test varchar(100))')
+ shareConn
+ .query('DROP TABLE IF EXISTS smallLocalInfile')
+ .then(() => {
+ return conn.query('CREATE TABLE smallLocalInfile(id int, test varchar(100))');
+ })
.then(() => {
return conn.query(
"LOAD DATA LOCAL INFILE '" +
@@ -160,13 +164,18 @@ describe('local-infile', () => {
base
.createConnection({ permitLocalInfile: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE smallLocalInfile(id int, test varchar(100))');
- conn
- .query(
- "LOAD DATA LOCAL INFILE '" +
- smallFileName.replace(/\\/g, '/') +
- "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
- )
+ shareConn
+ .query('DROP TABLE IF EXISTS smallLocalInfile')
+ .then(() => {
+ return conn.query('CREATE TABLE smallLocalInfile(id int, test varchar(100))');
+ })
+ .then(() => {
+ return conn.query(
+ "LOAD DATA LOCAL INFILE '" +
+ smallFileName.replace(/\\/g, '/') +
+ "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
+ );
+ })
.then(() => {
return conn.query('SELECT * FROM smallLocalInfile');
})
@@ -204,13 +213,18 @@ describe('local-infile', () => {
base
.createConnection({ permitLocalInfile: true, charset: 'big5' })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE smallLocalInfile(id int, test varchar(100))');
- conn
- .query(
- "LOAD DATA LOCAL INFILE '" +
- smallFileName.replace(/\\/g, '/') +
- "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
- )
+ shareConn
+ .query('DROP TABLE IF EXISTS smallLocalInfile')
+ .then(() => {
+ return conn.query('CREATE TABLE smallLocalInfile(id int, test varchar(100))');
+ })
+ .then(() => {
+ return conn.query(
+ "LOAD DATA LOCAL INFILE '" +
+ smallFileName.replace(/\\/g, '/') +
+ "' INTO TABLE smallLocalInfile FIELDS TERMINATED BY ',' (id, test)"
+ );
+ })
.then(() => {
return conn.query('SELECT * FROM smallLocalInfile');
})
@@ -252,13 +266,18 @@ describe('local-infile', () => {
base
.createConnection({ permitLocalInfile: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE nonReadableFile(id int, test varchar(100))');
- conn
- .query(
- "LOAD DATA LOCAL INFILE '" +
- nonReadableFile.replace(/\\/g, '/') +
- "' INTO TABLE nonReadableFile FIELDS TERMINATED BY ',' (id, test)"
- )
+ shareConn
+ .query('DROP TABLE IF EXISTS nonReadableFile')
+ .then(() => {
+ return conn.query('CREATE TABLE nonReadableFile(id int, test varchar(100))');
+ })
+ .then(() => {
+ return conn.query(
+ "LOAD DATA LOCAL INFILE '" +
+ nonReadableFile.replace(/\\/g, '/') +
+ "' INTO TABLE nonReadableFile FIELDS TERMINATED BY ',' (id, test)"
+ );
+ })
.then(() => {
conn.end();
done('must have thrown error');
@@ -308,16 +327,21 @@ describe('local-infile', () => {
base
.createConnection({ permitLocalInfile: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE bigLocalInfile(t1 varchar(10), t2 varchar(2))');
- conn
- .query(
- "LOAD DATA LOCAL INFILE '" +
- bigFileName.replace(/\\/g, '/') +
- "' INTO TABLE bigLocalInfile " +
- "COLUMNS TERMINATED BY ',' ENCLOSED BY '\\\"' ESCAPED BY '\\\\' " +
- "LINES TERMINATED BY '\\n' IGNORE 1 LINES " +
- '(t1, t2)'
- )
+ shareConn
+ .query('DROP TABLE IF EXISTS bigLocalInfile')
+ .then(() => {
+ return conn.query('CREATE TABLE bigLocalInfile(t1 varchar(10), t2 varchar(2))');
+ })
+ .then(() => {
+ return conn.query(
+ "LOAD DATA LOCAL INFILE '" +
+ bigFileName.replace(/\\/g, '/') +
+ "' INTO TABLE bigLocalInfile " +
+ "COLUMNS TERMINATED BY ',' ENCLOSED BY '\\\"' ESCAPED BY '\\\\' " +
+ "LINES TERMINATED BY '\\n' IGNORE 1 LINES " +
+ '(t1, t2)'
+ );
+ })
.then(() => {
return conn.query('SELECT * FROM bigLocalInfile');
})
diff --git a/test/integration/test-metadata.js b/test/integration/test-metadata.js
index bdeacd7a..d942ca9e 100644
--- a/test/integration/test-metadata.js
+++ b/test/integration/test-metadata.js
@@ -8,15 +8,18 @@ const FieldType = require('../../lib/const/field-type');
describe('metadata', () => {
it('result metadata values', function (done) {
shareConn
- .query(
- 'CREATE TEMPORARY TABLE metadatatable (id BIGINT not null primary key auto_increment, ' +
- 't varchar(32) UNIQUE, ' +
- 'd DECIMAL(10,4) UNSIGNED ZEROFILL, ' +
- 'ds DECIMAL(10,4) SIGNED, ' +
- 'd2 DECIMAL(10,0) UNSIGNED, ' +
- 'ds2 DECIMAL(10,0) SIGNED ' +
- ") COLLATE='utf8mb4_unicode_ci'"
- )
+ .query('DROP TABLE IF EXISTS metadatatable')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE metadatatable (id BIGINT not null primary key auto_increment, ' +
+ 't varchar(32) UNIQUE, ' +
+ 'd DECIMAL(10,4) UNSIGNED ZEROFILL, ' +
+ 'ds DECIMAL(10,4) SIGNED, ' +
+ 'd2 DECIMAL(10,0) UNSIGNED, ' +
+ 'ds2 DECIMAL(10,0) SIGNED ' +
+ ") COLLATE='utf8mb4_unicode_ci'"
+ );
+ })
.then(() => {
return shareConn.query(
'SELECT id as id1, t as t1, d as d1, ds as d2, d2 as d3, ds2 as d4 FROM metadatatable as tm'
diff --git a/test/integration/test-multi-results.js b/test/integration/test-multi-results.js
index 1b5af4e0..ec66e25e 100644
--- a/test/integration/test-multi-results.js
+++ b/test/integration/test-multi-results.js
@@ -42,10 +42,17 @@ describe('multi-results', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t (i int)');
- conn.query('INSERT INTO t(i) VALUES (1)');
- conn
- .query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' })
+ shareConn
+ .query('DROP TABLE IF EXISTS t')
+ .then(() => {
+ return conn.query('CREATE TABLE t (i int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO t(i) VALUES (1)');
+ })
+ .then(() => {
+ return conn.query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' });
+ })
.then((res) => {
conn
.query('SELECT i, i FROM t')
@@ -82,10 +89,17 @@ describe('multi-results', () => {
base
.createConnection({ checkDuplicate: false })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t (i int)');
- conn.query('INSERT INTO t(i) VALUES (1)');
- conn
- .query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' })
+ shareConn
+ .query('DROP TABLE IF EXISTS t')
+ .then(() => {
+ return conn.query('CREATE TABLE t (i int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO t(i) VALUES (1)');
+ })
+ .then(() => {
+ return conn.query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' });
+ })
.then((res) => {
conn
.query('SELECT i, i FROM t')
@@ -112,10 +126,17 @@ describe('multi-results', () => {
base
.createConnection({ nestTables: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t (i int)');
- conn.query('INSERT INTO t(i) VALUES (1)');
- conn
- .query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' })
+ shareConn
+ .query('DROP TABLE IF EXISTS t')
+ .then(() => {
+ return conn.query('CREATE TABLE t (i int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO t(i) VALUES (1)');
+ })
+ .then(() => {
+ return conn.query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' });
+ })
.then((res) => {
conn
.query('SELECT i, i FROM t')
@@ -146,10 +167,18 @@ describe('multi-results', () => {
base
.createConnection({ checkDuplicate: false, nestTables: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE t (i int)');
- conn.query('INSERT INTO t(i) VALUES (1)');
- conn
- .query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' })
+ shareConn
+ .query('DROP TABLE IF EXISTS t')
+ .then(() => {
+ return conn.query('CREATE TABLE t (i int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO t(i) VALUES (1)');
+ })
+ .then(() => {
+ return conn.query({ rowsAsArray: true, sql: 'SELECT i, i FROM t' });
+ })
+
.then((res) => {
conn
.query('SELECT i, i FROM t')
@@ -234,7 +263,7 @@ describe('multi-results', () => {
shareConn
.query('SELECT 1')
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
@@ -244,7 +273,7 @@ describe('multi-results', () => {
shareConn
.query('select 1', (err, rows) => {})
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
done();
})
.catch(done);
@@ -256,7 +285,7 @@ describe('multi-results', () => {
.query('select 1')
.then((obj) => {
assert.equal(obj.length, 2);
- assert.deepEqual(obj[0], [{ '1': 1 }]);
+ assert.deepEqual(obj[0], [{ 1: 1 }]);
conn.end();
done();
})
@@ -272,7 +301,7 @@ describe('multi-results', () => {
.then((obj) => {
assert.equal(obj[0].length, 2);
assert.equal(obj[1].length, 2);
- assert.deepEqual(obj[0], [[{ '1': 1 }], [{ '2': 2 }]]);
+ assert.deepEqual(obj[0], [[{ 1: 1 }], [{ 2: 2 }]]);
conn.end();
done();
})
@@ -290,7 +319,7 @@ describe('multi-results', () => {
if (err) {
done(err);
} else {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
callbackConn.end();
done();
}
@@ -410,8 +439,8 @@ describe('multi-results', () => {
.query('call myProc()')
.then((rows) => {
assert.equal(rows.length, 3);
- assert.deepEqual(rows[0], [{ '1': 1 }]);
- assert.deepEqual(rows[1], [{ '2': 2 }]);
+ assert.deepEqual(rows[0], [{ 1: 1 }]);
+ assert.deepEqual(rows[1], [{ 2: 2 }]);
assert.deepEqual(rows[2], {
affectedRows: 0,
insertId: 0,
diff --git a/test/integration/test-ok-packet.js b/test/integration/test-ok-packet.js
index f56331ee..1f0b5c09 100644
--- a/test/integration/test-ok-packet.js
+++ b/test/integration/test-ok-packet.js
@@ -6,7 +6,12 @@ const { assert } = require('chai');
describe('ok packet', () => {
it('insertId', function (done) {
shareConn
- .query('CREATE TEMPORARY TABLE autoInc (id BIGINT not null primary key auto_increment)')
+ .query('DROP TABLE IF EXISTS autoInc')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE autoInc (id BIGINT not null primary key auto_increment)'
+ );
+ })
.then(() => {
return shareConn.query('INSERT INTO autoInc values ()');
})
@@ -59,7 +64,12 @@ describe('ok packet', () => {
it('negative insertId', function (done) {
shareConn
- .query('CREATE TEMPORARY TABLE negAutoInc (id BIGINT not null primary key auto_increment)')
+ .query('DROP TABLE IF EXISTS negAutoInc')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE negAutoInc (id BIGINT not null primary key auto_increment)'
+ );
+ })
.then(() => {
return shareConn.query('INSERT INTO negAutoInc values (-9007199254740990)');
})
@@ -103,15 +113,19 @@ describe('ok packet', () => {
});
it('basic insert result', function (done) {
- shareConn.query(
- 'CREATE TEMPORARY TABLE insertResultSet1(' +
- 'id int(11) unsigned NOT NULL AUTO_INCREMENT,' +
- 'val varchar(256),' +
- 'PRIMARY KEY (id))'
- );
-
shareConn
- .query('INSERT INTO insertResultSet1(val) values (?)', ['t'])
+ .query('DROP TABLE IF EXISTS insertResultSet1')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE insertResultSet1(' +
+ 'id int(11) unsigned NOT NULL AUTO_INCREMENT,' +
+ 'val varchar(256),' +
+ 'PRIMARY KEY (id))'
+ );
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO insertResultSet1(val) values (?)', ['t']);
+ })
.then((rows) => {
assert.ok(!Array.isArray(rows));
assert.strictEqual(typeof rows, 'object');
@@ -129,11 +143,14 @@ describe('ok packet', () => {
.createConnection({ multipleStatements: true })
.then((conn) => {
conn
- .query(
- 'CREATE TEMPORARY TABLE multiple_insert_result(' +
- 'id int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,' +
- 'val varchar(256))'
- )
+ .query('DROP TABLE IF EXISTS multiple_insert_result')
+ .then(() => {
+ return conn.query(
+ 'CREATE TABLE multiple_insert_result(' +
+ 'id int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,' +
+ 'val varchar(256))'
+ );
+ })
.then(() => {
return conn.query(
'INSERT INTO multiple_insert_result(val) values (?); ' +
@@ -164,7 +181,10 @@ describe('ok packet', () => {
it('update result text', function (done) {
shareConn
- .query('CREATE TEMPORARY TABLE updateResultSet1(id int(11))')
+ .query('DROP TABLE IF EXISTS updateResultSet1')
+ .then(() => {
+ return shareConn.query('CREATE TABLE updateResultSet1(id int(11))');
+ })
.then(() => {
return shareConn.query('INSERT INTO updateResultSet1 values (1), (1), (2), (3)');
})
@@ -195,7 +215,10 @@ describe('ok packet', () => {
.createConnection({ foundRows: false })
.then((conn) => {
conn
- .query('CREATE TEMPORARY TABLE updateResultSet1(id int(11))')
+ .query('DROP TABLE IF EXISTS updateResultSet1')
+ .then(() => {
+ return conn.query('CREATE TABLE updateResultSet1(id int(11))');
+ })
.then(() => {
return conn.query('INSERT INTO updateResultSet1 values (1), (1), (2), (3)');
})
diff --git a/test/integration/test-pipelining.js b/test/integration/test-pipelining.js
index 39238c5d..059c54cc 100644
--- a/test/integration/test-pipelining.js
+++ b/test/integration/test-pipelining.js
@@ -59,7 +59,7 @@ describe('pipelining', () => {
conn.connect((err) => {});
conn.query('DO 1');
conn.query('SELECT 1', (err, rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
});
@@ -69,9 +69,15 @@ describe('pipelining', () => {
this.timeout(60000);
let diff, pipelineDiff;
conn1
- .query('CREATE TEMPORARY TABLE pipeline1 (test int)')
+ .query('DROP TABLE IF EXISTS pipeline1')
.then(() => {
- return conn2.query('CREATE TEMPORARY TABLE pipeline2 (test int)');
+ return conn2.query('DROP TABLE IF EXISTS pipeline2');
+ })
+ .then(() => {
+ return conn1.query('CREATE TABLE pipeline1 (test int)');
+ })
+ .then(() => {
+ return conn2.query('CREATE TABLE pipeline2 (test int)');
})
.then(() => {
return insertBulk(conn1, 'pipeline1');
diff --git a/test/integration/test-placholders.js b/test/integration/test-placholders.js
index 115cd895..ed026e20 100644
--- a/test/integration/test-placholders.js
+++ b/test/integration/test-placholders.js
@@ -50,7 +50,7 @@ describe('Placeholder', () => {
{ 'param-3': 30, 'param-1': 10, 'param-2': 20 }
)
.then((rows) => {
- assert.deepEqual(rows, [{ val1: 10, val3: 30, '20': 20 }]);
+ assert.deepEqual(rows, [{ val1: 10, val3: 30, 20: 20 }]);
done();
})
.catch(done);
@@ -108,12 +108,17 @@ describe('Placeholder', () => {
base
.createConnection({ namedPlaceholders: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE undefinedParameter (id int, id2 int, id3 int)');
conn
- .query('INSERT INTO undefinedParameter values (:param3, :param1, :param2)', {
- param1: 1,
- param3: 3,
- param4: 4
+ .query('DROP TABLE IF EXISTS undefinedParameter')
+ .then(() => {
+ return conn.query('CREATE TABLE undefinedParameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO undefinedParameter values (:param3, :param1, :param2)', {
+ param1: 1,
+ param3: 3,
+ param4: 4
+ });
})
.then(() => {
done(new Error('must have thrown error!'));
@@ -143,11 +148,16 @@ describe('Placeholder', () => {
base
.createConnection({ namedPlaceholders: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE execute_missing_parameter (id int, id2 int, id3 int)');
conn
- .query('INSERT INTO execute_missing_parameter values (:t1, :t2, :t3)', {
- t1: 1,
- t3: 3
+ .query('DROP TABLE IF EXISTS execute_missing_parameter')
+ .then(() => {
+ return conn.query('CREATE TABLE execute_missing_parameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO execute_missing_parameter values (:t1, :t2, :t3)', {
+ t1: 1,
+ t3: 3
+ });
})
.then(() => {
done(new Error('must have thrown error!'));
@@ -176,9 +186,14 @@ describe('Placeholder', () => {
base
.createConnection({ namedPlaceholders: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE execute_no_parameter (id int, id2 int, id3 int)');
conn
- .query('INSERT INTO execute_no_parameter values (:t1, :t2, :t3)', [])
+ .query('DROP TABLE IF EXISTS execute_no_parameter')
+ .then(() => {
+ return conn.query('CREATE TABLE execute_no_parameter (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO execute_no_parameter values (:t1, :t2, :t3)', []);
+ })
.then(() => {
done(new Error('must have thrown error!'));
})
@@ -195,13 +210,18 @@ describe('Placeholder', () => {
base
.createConnection({ namedPlaceholders: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE to_much_parameters (id int, id2 int, id3 int)');
conn
- .query('INSERT INTO to_much_parameters values (:t2, :t0, :t1)', {
- t0: 0,
- t1: 1,
- t2: 2,
- t3: 3
+ .query('DROP TABLE IF EXISTS to_much_parameters')
+ .then(() => {
+ return conn.query('CREATE TABLE to_much_parameters (id int, id2 int, id3 int)');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO to_much_parameters values (:t2, :t0, :t1)', {
+ t0: 0,
+ t1: 1,
+ t2: 2,
+ t3: 3
+ });
})
.then(() => {
conn.end();
@@ -217,10 +237,17 @@ describe('Placeholder', () => {
base
.createConnection({ namedPlaceholders: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.query('INSERT INTO `parse` value (:val)', { val: value });
conn
- .query('select * from `parse` where t = :val', { val: value })
+ .query('DROP TABLE IF EXISTS parse')
+ .then(() => {
+ return conn.query('CREATE TABLE parse(t varchar(128))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO `parse` value (:val)', { val: value });
+ })
+ .then(() => {
+ return conn.query('select * from `parse` where t = :val', { val: value });
+ })
.then((res) => {
assert.strictEqual(res[0].t, value);
conn.end();
@@ -238,7 +265,7 @@ describe('Placeholder', () => {
conn
.query('select 1', [2])
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
diff --git a/test/integration/test-pool-callback-event.js b/test/integration/test-pool-callback-event.js
index 44770866..d771d831 100644
--- a/test/integration/test-pool-callback-event.js
+++ b/test/integration/test-pool-callback-event.js
@@ -72,8 +72,8 @@ describe('Pool callback event', () => {
assert.equal(releaseNumber, 500, releaseNumber);
pool.end();
done();
- }, 1000);
+ }, 5000);
});
- }, 500);
+ }, 1000);
});
});
diff --git a/test/integration/test-pool-callback.js b/test/integration/test-pool-callback.js
index f0ed94f1..7adacd16 100644
--- a/test/integration/test-pool-callback.js
+++ b/test/integration/test-pool-callback.js
@@ -6,10 +6,11 @@ const Conf = require('../conf');
describe('Pool callback', () => {
before(function () {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
});
it('pool with wrong authentication', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip(); //to avoid host beeing blocked
this.timeout(10000);
const pool = base.createPoolCallback({
acquireTimeout: 4000,
@@ -29,7 +30,8 @@ describe('Pool callback', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.message
);
pool.end();
@@ -67,7 +69,8 @@ describe('Pool callback', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.errno + ' - ' + err.message
);
done();
@@ -256,10 +259,14 @@ describe('Pool callback', () => {
assert.equal(pool.idleConnections(), 10);
assert.equal(pool.taskQueueSize(), 0);
let closed = false;
+ let doneSend = false;
for (let i = 0; i < 10000; i++) {
pool.query('SELECT ? as a', [i], (err, rows) => {
if (err) {
- if (!closed) done(err);
+ if (!doneSend) {
+ doneSend = true;
+ done(err);
+ }
} else {
assert.deepEqual(rows, [{ a: i }]);
}
@@ -290,7 +297,7 @@ describe('Pool callback', () => {
assert.equal(pool.idleConnections(), 0);
assert.equal(pool.taskQueueSize(), 0);
}
- done();
+ if (!doneSend) done();
});
}, 5000);
});
@@ -298,7 +305,7 @@ describe('Pool callback', () => {
});
it('connection fail handling', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPoolCallback({
connectionLimit: 2,
minDelayValidation: 200
@@ -339,7 +346,7 @@ describe('Pool callback', () => {
});
it('query fail handling', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPoolCallback({
connectionLimit: 2,
minDelayValidation: 200
@@ -438,6 +445,7 @@ describe('Pool callback', () => {
});
it('connection destroy', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
const pool = base.createPoolCallback({ connectionLimit: 2 });
setTimeout(() => {
//check available connections in pool
@@ -504,44 +512,49 @@ describe('Pool callback', () => {
connectionLimit: 1,
resetAfterUse: false
});
- pool.query('DROP TABLE IF EXISTS parse');
- pool.query('CREATE TABLE parse(id int, id2 int, id3 int, t varchar(128), id4 int)');
- pool.batch(
- 'INSERT INTO `parse` values (1, ?, 2, ?, 3)',
- [
- [1, 'john'],
- [2, 'jack']
- ],
- (err, res) => {
- if (err) {
- done(err);
- } else {
- assert.equal(res.affectedRows, 2);
- pool.query('select * from `parse`', (err2, res2) => {
- assert.deepEqual(res2, [
- {
- id: 1,
- id2: 1,
- id3: 2,
- t: 'john',
- id4: 3
- },
- {
- id: 1,
- id2: 2,
- id3: 2,
- t: 'jack',
- id4: 3
+ pool.query('DROP TABLE IF EXISTS parse', (err, res) => {
+ pool.query(
+ 'CREATE TABLE parse(id int, id2 int, id3 int, t varchar(128), id4 int)',
+ (err, res) => {
+ pool.batch(
+ 'INSERT INTO `parse` values (1, ?, 2, ?, 3)',
+ [
+ [1, 'john'],
+ [2, 'jack']
+ ],
+ (err, res) => {
+ if (err) {
+ done(err);
+ } else {
+ assert.equal(res.affectedRows, 2);
+ pool.query('select * from `parse`', (err2, res2) => {
+ assert.deepEqual(res2, [
+ {
+ id: 1,
+ id2: 1,
+ id3: 2,
+ t: 'john',
+ id4: 3
+ },
+ {
+ id: 1,
+ id2: 2,
+ id3: 2,
+ t: 'jack',
+ id4: 3
+ }
+ ]);
+ pool.query('DROP TABLE parse');
+ pool.end(() => {
+ done();
+ });
+ });
}
- ]);
- pool.query('DROP TABLE parse');
- pool.end(() => {
- done();
- });
- });
+ }
+ );
}
- }
- );
+ );
+ });
});
it('pool batch without parameters', function (done) {
@@ -565,25 +578,43 @@ describe('Pool callback', () => {
connectionLimit: 1,
resetAfterUse: false
});
- pool.query('CREATE TEMPORARY TABLE singleBatchArrayCallback(id int)');
- pool.batch('INSERT INTO `singleBatchArrayCallback` values (?)', [1, 2, 3], (err, res) => {
+ pool.query('DROP TABLE IF EXISTS singleBatchArrayCallback', (err, res) => {
if (err) {
+ pool.end();
done(err);
} else {
- pool.query('select * from `singleBatchArrayCallback`', (err, res) => {
- assert.deepEqual(res, [
- {
- id: 1
- },
- {
- id: 2
- },
- {
- id: 3
- }
- ]);
- pool.end();
- done();
+ pool.query('CREATE TABLE singleBatchArrayCallback(id int)', (err, res) => {
+ if (err) {
+ pool.end();
+ done(err);
+ } else {
+ pool.batch(
+ 'INSERT INTO `singleBatchArrayCallback` values (?)',
+ [1, 2, 3],
+ (err, res) => {
+ if (err) {
+ pool.end();
+ done(err);
+ } else {
+ pool.query('select * from `singleBatchArrayCallback`', (err, res) => {
+ assert.deepEqual(res, [
+ {
+ id: 1
+ },
+ {
+ id: 2
+ },
+ {
+ id: 3
+ }
+ ]);
+ pool.end();
+ done();
+ });
+ }
+ }
+ );
+ }
});
}
});
@@ -595,32 +626,34 @@ describe('Pool callback', () => {
const pool = base.createPoolCallback({
connectionLimit: 10,
minimumIdle: 4,
- idleTimeout: 2
+ idleTimeout: 2,
+ acquireTimeout: 20000
});
-
- for (let i = 0; i < 15000; i++) {
- pool.query('SELECT ' + i);
- }
- pool.query('SELECT 15000', [], (err) => {
- if (err) {
- pool.end();
- done(err);
- } else {
- setTimeout(() => {
- assert.equal(pool.totalConnections(), 10);
- assert.equal(pool.idleConnections(), 10);
- }, 5);
-
- setTimeout(() => {
- //minimumIdle-1 is possible after reaching idleTimeout and connection
- // is still not recreated
- assert.isTrue(pool.totalConnections() === 4 || pool.totalConnections() === 3);
- assert.isTrue(pool.idleConnections() === 4 || pool.idleConnections() === 3);
- pool.end();
- done();
- }, 7000);
+ setTimeout(() => {
+ for (let i = 0; i < 5000; i++) {
+ pool.query('SELECT ' + i);
}
- });
+ pool.query('SELECT 5000', [], (err) => {
+ if (err) {
+ pool.end();
+ done(err);
+ } else {
+ setTimeout(() => {
+ assert.equal(pool.totalConnections(), 10);
+ assert.equal(pool.idleConnections(), 10);
+ }, 5);
+
+ setTimeout(() => {
+ //minimumIdle-1 is possible after reaching idleTimeout and connection
+ // is still not recreated
+ assert.isTrue(pool.totalConnections() === 4 || pool.totalConnections() === 3);
+ assert.isTrue(pool.idleConnections() === 4 || pool.idleConnections() === 3);
+ pool.end();
+ done();
+ }, 7000);
+ }
+ });
+ }, 4000);
});
it('test minimum idle', function (done) {
@@ -628,7 +661,8 @@ describe('Pool callback', () => {
const pool = base.createPoolCallback({
connectionLimit: 10,
minimumIdle: 4,
- idleTimeout: 2
+ idleTimeout: 2,
+ acquireTimeout: 20000
});
setTimeout(() => {
diff --git a/test/integration/test-pool.js b/test/integration/test-pool.js
index d6b469b7..830d8cf8 100644
--- a/test/integration/test-pool.js
+++ b/test/integration/test-pool.js
@@ -50,9 +50,11 @@ describe('Pool', () => {
});
});
- it('pool escape', function () {
+ it('pool escape', function (done) {
if (!base.utf8Collation()) this.skip();
const pool = base.createPool({ connectionLimit: 1 });
+ const pool2 = base.createPool({ connectionLimit: 1, arrayParenthesis: true });
+
pool.on('connection', (conn) => {
assert.equal(pool.escape(new Date('1999-01-31 12:13:14.000')), "'1999-01-31 12:13:14.000'");
assert.equal(
@@ -82,15 +84,17 @@ describe('Pool', () => {
assert.equal(pool.escape("let'g'o😊"), "'let\\'g\\'o😊'");
assert.equal(pool.escape("a'\nb\tc\rd\\e%_\u001a"), "'a\\'\\nb\\tc\\rd\\\\e%_\\Z'");
const arr = ["let'g'o😊", false, null, fctStr];
- assert.equal(pool.escape(arr), "('let\\'g\\'o😊',false,NULL,'bla\\'bla')");
+ assert.equal(pool.escape(arr), "'let\\'g\\'o😊',false,NULL,'bla\\'bla'");
+ assert.equal(pool2.escape(arr), "('let\\'g\\'o😊',false,NULL,'bla\\'bla')");
assert.equal(pool.escapeId('good_$one'), '`good_$one`');
assert.equal(pool.escape(''), "''");
assert.equal(pool.escapeId('f:a'), '`f:a`');
assert.equal(pool.escapeId('`f:a`'), '`f:a`');
assert.equal(pool.escapeId('good_`è`one'), '`good_``è``one`');
-
pool.end();
+ pool2.end();
+ done();
});
});
@@ -105,6 +109,7 @@ describe('Pool', () => {
});
it('pool with wrong authentication', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip(); //to avoid host beeing blocked
this.timeout(10000);
const pool = base.createPool({
acquireTimeout: 4000,
@@ -123,7 +128,8 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45025 ||
- err.errno === 45028,
+ err.errno === 45028 ||
+ err.errno === 45044,
err.message
);
pool
@@ -139,7 +145,8 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.message
);
done();
@@ -157,13 +164,15 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45025 ||
- err.errno === 45028,
+ err.errno === 45028 ||
+ err.errno === 45044,
err.message
);
});
});
it('pool with wrong authentication connection', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(10000);
const pool = base.createPool({
acquireTimeout: 4000,
@@ -182,7 +191,8 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.message
);
pool
@@ -198,7 +208,8 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.message
);
done();
@@ -216,13 +227,15 @@ describe('Pool', () => {
err.errno === 1045 ||
err.errno === 1698 ||
err.errno === 45028 ||
- err.errno === 45025,
+ err.errno === 45025 ||
+ err.errno === 45044,
err.message
);
});
});
it('create pool', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(5000);
const pool = base.createPool({ connectionLimit: 1 });
const initTime = Date.now();
@@ -249,7 +262,7 @@ describe('Pool', () => {
});
it('create pool with multipleStatement', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(5000);
const pool = base.createPool({
connectionLimit: 5,
@@ -259,7 +272,7 @@ describe('Pool', () => {
.query('select 1; select 2')
.then((results) => {
//select 1 results
- assert.deepEqual(results, [[{ '1': 1 }], [{ '2': 2 }]]);
+ assert.deepEqual(results, [[{ 1: 1 }], [{ 2: 2 }]]);
pool.end();
done();
})
@@ -270,10 +283,14 @@ describe('Pool', () => {
});
it('ensure commit', function (done) {
- shareConn.query('DROP TABLE IF EXISTS ensureCommit');
- shareConn.query('CREATE TABLE ensureCommit(firstName varchar(32))');
shareConn
- .query("INSERT INTO ensureCommit values ('john')")
+ .query('DROP TABLE IF EXISTS ensureCommit')
+ .then(() => {
+ return shareConn.query('CREATE TABLE ensureCommit(firstName varchar(32))');
+ })
+ .then(() => {
+ return shareConn.query("INSERT INTO ensureCommit values ('john')");
+ })
.then((res) => {
const pool = base.createPool({ connectionLimit: 1 });
pool.getConnection().then((conn) => {
@@ -306,10 +323,14 @@ describe('Pool', () => {
});
it('pool without control after use', function (done) {
- shareConn.query('DROP TABLE IF EXISTS ensureCommit');
- shareConn.query('CREATE TABLE ensureCommit(firstName varchar(32))');
shareConn
- .query("INSERT INTO ensureCommit values ('john')")
+ .query('DROP TABLE IF EXISTS ensureCommit')
+ .then(() => {
+ return shareConn.query('CREATE TABLE ensureCommit(firstName varchar(32))');
+ })
+ .then(() => {
+ return shareConn.query("INSERT INTO ensureCommit values ('john')");
+ })
.then((res) => {
const pool = base.createPool({
connectionLimit: 1,
@@ -363,6 +384,7 @@ describe('Pool', () => {
});
it('pool ending during requests', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(20000);
const initial = new Date();
const pool = base.createPool({ connectionLimit: 1 });
@@ -471,7 +493,7 @@ describe('Pool', () => {
});
it('pool getConnection timeout', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({ connectionLimit: 1, acquireTimeout: 200 });
let errorThrown = false;
pool
@@ -495,7 +517,7 @@ describe('Pool', () => {
});
it('pool leakDetectionTimeout timeout', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({
connectionLimit: 1,
acquireTimeout: 200,
@@ -518,7 +540,7 @@ describe('Pool', () => {
});
it('pool getConnection timeout recovery', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
this.timeout(5000);
const pool = base.createPool({
connectionLimit: 10,
@@ -530,7 +552,6 @@ describe('Pool', () => {
for (let i = 0; i < 10; i++) {
pool.query('SELECT SLEEP(1)').catch((err) => {
console.log('SLEEP ERROR');
- console.log(err);
done(err);
});
}
@@ -571,6 +592,7 @@ describe('Pool', () => {
});
it('pool query timeout', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
this.timeout(5000);
const pool = base.createPool({ connectionLimit: 1, acquireTimeout: 500 });
const initTime = Date.now();
@@ -677,7 +699,7 @@ describe('Pool', () => {
});
it('connection fail handling', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({
connectionLimit: 2,
minDelayValidation: 200
@@ -721,7 +743,7 @@ describe('Pool', () => {
});
it('query fail handling', function (done) {
- if (process.env.MAXSCALE_VERSION || process.env.SKYSQL) this.skip();
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({
connectionLimit: 2,
minDelayValidation: 200
@@ -763,6 +785,7 @@ describe('Pool', () => {
});
it('connection end', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({ connectionLimit: 2 });
setTimeout(() => {
//check available connections in pool
@@ -796,6 +819,7 @@ describe('Pool', () => {
});
it('connection release alias', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({ connectionLimit: 2 });
setTimeout(() => {
//check available connections in pool
@@ -829,6 +853,7 @@ describe('Pool', () => {
});
it('connection destroy', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE || process.env.SKYSQL) this.skip();
const pool = base.createPool({ connectionLimit: 2 });
setTimeout(() => {
//check available connections in pool
@@ -901,12 +926,17 @@ describe('Pool', () => {
it('pool batch', function (done) {
const pool = base.createPool({ connectionLimit: 1, resetAfterUse: false });
- pool.query('CREATE TEMPORARY TABLE parse(id int, id2 int, id3 int, t varchar(128), id4 int)');
pool
- .batch('INSERT INTO `parse` values (1, ?, 2, ?, 3)', [
- [1, 'john'],
- [2, 'jack']
- ])
+ .query('DROP TABLE IF EXISTS parse')
+ .then(() => {
+ return pool.query('CREATE TABLE parse(id int, id2 int, id3 int, t varchar(128), id4 int)');
+ })
+ .then(() => {
+ return pool.batch('INSERT INTO `parse` values (1, ?, 2, ?, 3)', [
+ [1, 'john'],
+ [2, 'jack']
+ ]);
+ })
.then((res) => {
assert.equal(res.affectedRows, 2);
return pool.query('select * from `parse`');
@@ -938,9 +968,15 @@ describe('Pool', () => {
it('pool batch single array', function (done) {
const pool = base.createPool({ connectionLimit: 1, resetAfterUse: false });
- pool.query('CREATE TEMPORARY TABLE singleBatchArray(id int)');
+
pool
- .batch('INSERT INTO `singleBatchArray` values (?)', [1, 2, 3])
+ .query('DROP TABLE IF EXISTS singleBatchArray')
+ .then(() => {
+ return pool.query('CREATE TABLE singleBatchArray(id int)');
+ })
+ .then(() => {
+ return pool.batch('INSERT INTO `singleBatchArray` values (?)', [1, 2, 3]);
+ })
.then((res) => {
assert.equal(res.affectedRows, 3);
return pool.query('select * from `singleBatchArray`');
@@ -966,6 +1002,7 @@ describe('Pool', () => {
});
it("ensure pipe ending doesn't stall connection", function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
//sequence engine only exist in MariaDB
if (!shareConn.info.isMariaDB()) this.skip();
const ver = process.version.substring(1).split('.');
@@ -1008,48 +1045,59 @@ describe('Pool', () => {
});
it('test minimum idle decrease', function (done) {
- if (process.env.SKYSQL) this.skip();
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(30000);
const pool = base.createPool({
connectionLimit: 10,
- minimumIdle: 4,
+ minimumIdle: 8,
idleTimeout: 2,
acquireTimeout: 20000
});
const requests = [];
- for (let i = 0; i < 15000; i++) {
+ for (let i = 0; i < 5000; i++) {
requests.push(pool.query('SELECT ' + i));
}
- Promise.all(requests)
- .then(() => {
- setTimeout(() => {
- assert.equal(pool.totalConnections(), 10);
- assert.equal(pool.idleConnections(), 10);
- }, 5);
+ setTimeout(() => {
+ Promise.all(requests)
+ .then(() => {
+ setTimeout(() => {
+ assert.isTrue(
+ pool.totalConnections() === 8 ||
+ pool.totalConnections() === 9 ||
+ pool.totalConnections() === 10
+ );
+ assert.isTrue(
+ pool.idleConnections() === 8 ||
+ pool.idleConnections() === 9 ||
+ pool.idleConnections() === 10
+ );
+ }, 5);
- setTimeout(() => {
- //wait for 1 second
- assert.equal(pool.totalConnections(), 10);
- assert.equal(pool.idleConnections(), 10);
- }, 1000);
+ setTimeout(() => {
+ //wait for 1 second
+ assert.equal(pool.totalConnections(), 8);
+ assert.equal(pool.idleConnections(), 8);
+ }, 1000);
- setTimeout(() => {
- //minimumIdle-1 is possible after reaching idleTimeout and connection
- // is still not recreated
- assert.isTrue(pool.totalConnections() === 4 || pool.totalConnections() === 3);
- assert.isTrue(pool.idleConnections() === 4 || pool.idleConnections() === 3);
+ setTimeout(() => {
+ //minimumIdle-1 is possible after reaching idleTimeout and connection
+ // is still not recreated
+ assert.isTrue(pool.totalConnections() === 8 || pool.totalConnections() === 7);
+ assert.isTrue(pool.idleConnections() === 8 || pool.idleConnections() === 7);
+ pool.end();
+ done();
+ }, 3000);
+ })
+ .catch((err) => {
pool.end();
- done();
- }, 3000);
- })
- .catch((err) => {
- pool.end();
- done(err);
- });
+ done(err);
+ });
+ }, 4000);
});
it('test minimum idle', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(5000);
const pool = base.createPool({
connectionLimit: 10,
@@ -1070,6 +1118,7 @@ describe('Pool', () => {
});
it('pool immediate error', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
const pool = base.createPool({});
pool
.getConnection()
@@ -1086,6 +1135,7 @@ describe('Pool', () => {
});
it('pool server defect timeout', function (done) {
+ if (process.env.SKYSQL || process.env.MAXSCALE_TEST_DISABLE) this.skip();
this.timeout(5000);
const proxy = new Proxy({
port: Conf.baseConfig.port,
diff --git a/test/integration/test-query-values-in-sql.js b/test/integration/test-query-values-in-sql.js
index 6aed5445..eb3f3536 100644
--- a/test/integration/test-query-values-in-sql.js
+++ b/test/integration/test-query-values-in-sql.js
@@ -5,14 +5,28 @@ const { assert } = require('chai');
describe('sql template strings', () => {
const value = "'`\\";
+
it('query with parameters', (done) => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.query({ sql: 'INSERT INTO parse value (?)', values: [value] });
conn
- .query({ sql: 'select * from parse where t = ?', values: [value] })
+ .query('DROP TABLE IF EXISTS query_with_parameter')
+ .then(() => {
+ return conn.query('CREATE TABLE query_with_parameter(t varchar(128))');
+ })
+ .then(() => {
+ return conn.query({
+ sql: 'INSERT INTO query_with_parameter value (?)',
+ values: [value]
+ });
+ })
+ .then(() => {
+ return conn.query({
+ sql: 'select * from query_with_parameter where t = ?',
+ values: [value]
+ });
+ })
.then((res) => {
assert.strictEqual(res[0].t, value);
conn.end();
@@ -27,16 +41,32 @@ describe('sql template strings', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.batch({ sql: 'INSERT INTO parse value (?)', values: [value] });
conn
- .query({ sql: 'select * from parse where t = ?', values: [value] })
+ .query('DROP TABLE IF EXISTS batch_with_parameters')
+ .then(() => {
+ return conn.query('CREATE TABLE batch_with_parameters(t varchar(128))');
+ })
+ .then(() => {
+ return conn.batch({
+ sql: 'INSERT INTO batch_with_parameters value (?)',
+ values: [value]
+ });
+ })
+ .then(() => {
+ return conn.query({
+ sql: 'select * from batch_with_parameters where t = ?',
+ values: [value]
+ });
+ })
.then((res) => {
assert.strictEqual(res[0].t, value);
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -47,15 +77,44 @@ describe('sql template strings', () => {
if (err) {
done(err);
} else {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.query({ sql: 'INSERT INTO parse value (?)', values: [value] });
- conn.query({ sql: 'select * from parse where t = ?', values: [value] }, (err, res) => {
+ conn.query('DROP TABLE IF EXISTS callback_with_parameters', (err) => {
if (err) {
+ conn.end();
done(err);
} else {
- assert.strictEqual(res[0].t, value);
- conn.end();
- done();
+ conn.query('CREATE TABLE callback_with_parameters(t varchar(128))', (err) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ conn.query(
+ { sql: 'INSERT INTO callback_with_parameters value (?)', values: [value] },
+ (err) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ conn.query(
+ {
+ sql: 'select * from callback_with_parameters where t = ?',
+ values: [value]
+ },
+ (err, res) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ assert.strictEqual(res[0].t, value);
+ conn.end();
+ done();
+ }
+ }
+ );
+ }
+ }
+ );
+ }
+ });
}
});
}
@@ -68,15 +127,44 @@ describe('sql template strings', () => {
if (err) {
done(err);
} else {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.batch({ sql: 'INSERT INTO parse value (?)', values: [value] });
- conn.query({ sql: 'select * from parse where t = ?', values: [value] }, (err, res) => {
+ conn.query('DROP TABLE IF EXISTS callback_batch_with_parameters', (err) => {
if (err) {
+ conn.end();
done(err);
} else {
- assert.strictEqual(res[0].t, value);
- conn.end();
- done();
+ conn.query('CREATE TABLE callback_batch_with_parameters(t varchar(128))', (err) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ conn.batch(
+ { sql: 'INSERT INTO callback_batch_with_parameters value (?)', values: [value] },
+ (err) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ conn.query(
+ {
+ sql: 'select * from callback_batch_with_parameters where t = ?',
+ values: [value]
+ },
+ (err, res) => {
+ if (err) {
+ conn.end();
+ done(err);
+ } else {
+ assert.strictEqual(res[0].t, value);
+ conn.end();
+ done();
+ }
+ }
+ );
+ }
+ }
+ );
+ }
+ });
}
});
}
@@ -86,20 +174,20 @@ describe('sql template strings', () => {
it('pool query with parameters', (done) => {
const pool = base.createPool();
pool
- .query('drop table IF EXISTS pool_parse')
+ .query('drop table IF EXISTS pool_query_param')
.catch((err) => {})
.then(() => {
- return pool.query('CREATE TABLE pool_parse(t varchar(128))');
+ return pool.query('CREATE TABLE pool_query_param(t varchar(128))');
})
.then(() => {
- return pool.query({ sql: 'INSERT INTO pool_parse value (?)', values: [value] });
+ return pool.query({ sql: 'INSERT INTO pool_query_param value (?)', values: [value] });
})
.then(() => {
- return pool.query({ sql: 'select * from pool_parse where t = ?', values: [value] });
+ return pool.query({ sql: 'select * from pool_query_param where t = ?', values: [value] });
})
.then((res) => {
assert.strictEqual(res[0].t, value);
- return pool.query('drop table pool_parse');
+ return pool.query('drop table pool_query_param');
})
.then(() => {
pool.end();
@@ -143,6 +231,7 @@ describe('sql template strings', () => {
{ sql: 'select * from pool_parse_call where t = ?', values: [value] },
(err, res) => {
if (err) {
+ pool.end();
done(err);
} else {
assert.strictEqual(res[0].t, value);
diff --git a/test/integration/test-query.js b/test/integration/test-query.js
index 9ed0787c..af8d89bb 100644
--- a/test/integration/test-query.js
+++ b/test/integration/test-query.js
@@ -11,7 +11,7 @@ describe('basic query', () => {
conn
.query('select 1', [2])
.then((rows) => {
- assert.deepEqual(rows, [{ '1': 1 }]);
+ assert.deepEqual(rows, [{ 1: 1 }]);
conn.end();
done();
})
@@ -25,16 +25,26 @@ describe('basic query', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE parse(t varchar(128))');
- conn.query('INSERT INTO `parse` value (?)', value);
conn
- .query('select * from `parse` where t = ?', value)
+ .query('DROP TABLE IF EXISTS parse')
+ .then(() => {
+ return conn.query('CREATE TABLE parse(t varchar(128))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO `parse` value (?)', value);
+ })
+ .then(() => {
+ return conn.query('select * from `parse` where t = ?', value);
+ })
.then((res) => {
assert.strictEqual(res[0].t, value);
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -43,10 +53,19 @@ describe('basic query', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE arrayParam (id int, val varchar(10))');
- conn.query("INSERT INTO arrayParam VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')");
conn
- .query('SELECT * FROM arrayParam WHERE val IN ?', [['b', 'c', 1]])
+ .query('DROP TABLE IF EXISTS arrayParam')
+ .then(() => {
+ return conn.query('CREATE TABLE arrayParam (id int, val varchar(10))');
+ })
+ .then(() => {
+ return conn.query(
+ "INSERT INTO arrayParam VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')"
+ );
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM arrayParam WHERE val IN (?)', [['b', 'c', 1]]);
+ })
.then((rows) => {
assert.deepEqual(rows, [
{
@@ -61,7 +80,10 @@ describe('basic query', () => {
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -70,11 +92,20 @@ describe('basic query', () => {
base
.createConnection()
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE arrayParam (id int, val varchar(10))');
- conn.query('INSERT INTO arrayParam VALUES ?', [[1, null]]);
- conn.query('INSERT INTO arrayParam VALUES ?', [[2, 'a']]);
conn
- .query('SELECT * FROM arrayParam')
+ .query('DROP TABLE IF EXISTS arrayParamNull')
+ .then(() => {
+ return conn.query('CREATE TABLE arrayParamNull (id int, val varchar(10))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO arrayParamNull VALUES (?)', [[1, null]]);
+ })
+ .then(() => {
+ return conn.query('INSERT INTO arrayParamNull VALUES (?)', [[2, 'a']]);
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM arrayParamNull');
+ })
.then((rows) => {
assert.deepEqual(rows, [
{
@@ -89,7 +120,50 @@ describe('basic query', () => {
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
+ })
+ .catch(done);
+ });
+
+ it('array parameter with null value with parenthesis', function (done) {
+ base
+ .createConnection({ arrayParenthesis: true })
+ .then((conn) => {
+ conn
+ .query('DROP TABLE IF EXISTS arrayParamNullParen')
+ .then(() => {
+ return conn.query('CREATE TABLE arrayParamNullParen (id int, val varchar(10))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO arrayParamNullParen VALUES ?', [[1, null]]);
+ })
+ .then(() => {
+ return conn.query('INSERT INTO arrayParamNullParen VALUES ?', [[2, 'a']]);
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM arrayParamNullParen');
+ })
+ .then((rows) => {
+ assert.deepEqual(rows, [
+ {
+ id: 1,
+ val: null
+ },
+ {
+ id: 2,
+ val: 'a'
+ }
+ ]);
+ conn.end();
+ done();
+ })
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -99,16 +173,26 @@ describe('basic query', () => {
base
.createConnection({ permitSetMultiParamEntries: true })
.then((conn) => {
- conn.query('CREATE TEMPORARY TABLE setTable(id int, val varchar(128))');
- conn.query('INSERT INTO setTable SET ?', jsonValue);
conn
- .query('select * from setTable')
+ .query('DROP TABLE IF EXISTS setTable')
+ .then(() => {
+ return conn.query('CREATE TABLE setTable(id int, val varchar(128))');
+ })
+ .then(() => {
+ return conn.query('INSERT INTO setTable SET ?', jsonValue);
+ })
+ .then(() => {
+ return conn.query('select * from setTable');
+ })
.then((res) => {
assert.deepEqual(res[0], jsonValue);
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
@@ -191,24 +275,34 @@ describe('basic query', () => {
base
.createConnection()
.then((conn) => {
- conn.query(
- "set @@SQL_MODE = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'"
- );
- conn.query('create TEMPORARY table h (c1 varchar(5))');
conn
- .query("insert into h values ('123456')")
+ .query(
+ "set @@SQL_MODE = 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'"
+ )
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS h');
+ })
+ .then(() => {
+ return conn.query('create table h (c1 varchar(5))');
+ })
+ .then(() => {
+ return conn.query("insert into h values ('123456')");
+ })
.then((res) => {
assert.equal(res.warningStatus, 1);
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
it('255 columns', (done) => {
- let table = 'CREATE TEMPORARY TABLE myTable(';
+ let table = 'CREATE TABLE myTable(';
let insert = 'INSERT INTO myTable VALUES (';
let expRes = {};
for (let i = 0; i < 255; i++) {
@@ -226,26 +320,43 @@ describe('basic query', () => {
base
.createConnection()
.then((conn) => {
- conn.query(table);
- conn.query(insert);
conn
- .query('SELECT * FROM myTable')
+ .query('DROP TABLE IF EXISTS myTable')
+ .then(() => {
+ return conn.query(table);
+ })
+ .then(() => {
+ return conn.query(insert);
+ })
+ .then(() => {
+ return conn.query('SELECT * FROM myTable');
+ })
.then((res) => {
assert.deepEqual(res[0], expRes);
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ conn.end();
+ done(err);
+ });
})
.catch(done);
});
it('escape validation', function (done) {
if (!base.utf8Collation()) this.skip();
- shareConn.query('CREATE TEMPORARY TABLE tt1 (id int, tt varchar(256)) CHARSET utf8mb4');
- shareConn.query('INSERT INTO tt1 VALUES (?,?)', [1, 'jack\nkमस्']);
shareConn
- .query('SELECT * FROM tt1')
+ .query('DROP TABLE IF EXISTS tt1')
+ .then(() => {
+ return shareConn.query('CREATE TABLE tt1 (id int, tt varchar(256)) CHARSET utf8mb4');
+ })
+ .then(() => {
+ return shareConn.query('INSERT INTO tt1 VALUES (?,?)', [1, 'jack\nkमस्']);
+ })
+ .then(() => {
+ return shareConn.query('SELECT * FROM tt1');
+ })
.then((res) => {
assert.equal(res[0].tt, 'jack\nkमस्');
done();
diff --git a/test/integration/test-socket.js b/test/integration/test-socket.js
index ec602382..f89c17ab 100644
--- a/test/integration/test-socket.js
+++ b/test/integration/test-socket.js
@@ -7,7 +7,7 @@ const Conf = require('../conf');
describe('test socket', () => {
it('named pipe', function (done) {
if (process.platform !== 'win32') this.skip();
- if (process.env.MUST_USE_TCPIP) this.skip();
+ if (process.env.MUST_USE_TCPIP || process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (Conf.baseConfig.host !== 'localhost' && Conf.baseConfig.host !== 'mariadb.example.com')
this.skip();
const test = this;
diff --git a/test/integration/test-ssl.js b/test/integration/test-ssl.js
index b0734d25..ab4ecbc3 100644
--- a/test/integration/test-ssl.js
+++ b/test/integration/test-ssl.js
@@ -12,149 +12,137 @@ describe('ssl', function () {
let clientCert = null;
let clientKeystore = null;
let sslEnable = false;
+ let sslPort = Conf.baseConfig.port;
before(function (done) {
- if (process.env.MAXSCALE_VERSION) {
- done();
- } else {
- if (
- tls.DEFAULT_MIN_VERSION === 'TLSv1.2' &&
- ((process.platform === 'win32' &&
- shareConn.info.isMariaDB() &&
- !shareConn.info.hasMinVersion(10, 4, 0)) ||
- (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(8, 0, 0)))
- ) {
- //TLSv1.2 is supported on windows only since MariaDB 10.4
- //TLSv1.2 is supported in MySQL only since 8.0 (unix/windows)
- //so if testing with Node.js 12, force possible TLS1.1
- if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0)) {
- //MySQL 5.5 and MySQL 5.6 needs TLSv1
- tls.DEFAULT_MIN_VERSION = 'TLSv1';
- } else {
- tls.DEFAULT_MIN_VERSION = 'TLSv1.1';
- }
+ if (process.env.TEST_SSL_PORT) sslPort = parseInt(process.env.TEST_SSL_PORT);
+ if (
+ tls.DEFAULT_MIN_VERSION === 'TLSv1.2' &&
+ ((process.platform === 'win32' &&
+ shareConn.info.isMariaDB() &&
+ !shareConn.info.hasMinVersion(10, 4, 0)) ||
+ (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(8, 0, 0)))
+ ) {
+ //TLSv1.2 is supported on windows only since MariaDB 10.4
+ //TLSv1.2 is supported in MySQL only since 8.0 (unix/windows)
+ //so if testing with Node.js 12, force possible TLS1.1
+ if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0)) {
+ //MySQL 5.5 and MySQL 5.6 needs TLSv1
+ tls.DEFAULT_MIN_VERSION = 'TLSv1';
+ } else {
+ tls.DEFAULT_MIN_VERSION = 'TLSv1.1';
}
+ }
- let serverCaFile =
- Conf.baseConfig.ssl && Conf.baseConfig.ssl.ca ? null : process.env.TEST_SSL_CA_FILE;
- let clientKeyFileName = process.env.TEST_SSL_CLIENT_KEY_FILE;
- let clientCertFileName = process.env.TEST_SSL_CLIENT_CERT_FILE;
- let clientKeystoreFileName = process.env.TEST_SSL_CLIENT_KEYSTORE_FILE;
-
- if (
- !serverCaFile &&
- (Conf.baseConfig.host === 'localhost' || Conf.baseConfig.host === 'mariadb.example.com')
- ) {
- try {
- if (fs.existsSync('../ssl')) {
- serverCaFile = '../ssl/server.crt';
- clientKeyFileName = '../ssl/client.key';
- clientCertFileName = '../ssl/client.crt';
- clientKeystoreFileName = '../ssl/fullclient-keystore.p12';
- }
- } catch (err) {
- console.error(err);
+ let serverCaFile =
+ Conf.baseConfig.ssl && Conf.baseConfig.ssl.ca ? null : process.env.TEST_SSL_CA_FILE;
+ let clientKeyFileName = process.env.TEST_SSL_CLIENT_KEY_FILE;
+ let clientCertFileName = process.env.TEST_SSL_CLIENT_CERT_FILE;
+ let clientKeystoreFileName = process.env.TEST_SSL_CLIENT_KEYSTORE_FILE;
+
+ if (
+ !serverCaFile &&
+ (Conf.baseConfig.host === 'localhost' || Conf.baseConfig.host === 'mariadb.example.com')
+ ) {
+ try {
+ if (fs.existsSync('../../ssl')) {
+ serverCaFile = '../../ssl/server.crt';
+ clientKeyFileName = '../../ssl/client.key';
+ clientCertFileName = '../../ssl/client.crt';
+ clientKeystoreFileName = '../../ssl/fullclient-keystore.p12';
}
+ } catch (err) {
+ console.error(err);
}
+ }
- if (serverCaFile) ca = [fs.readFileSync(serverCaFile, 'utf8')];
- if (clientKeyFileName) clientKey = [fs.readFileSync(clientKeyFileName, 'utf8')];
- if (clientCertFileName) clientCert = [fs.readFileSync(clientCertFileName, 'utf8')];
- if (clientKeystoreFileName) clientKeystore = [fs.readFileSync(clientKeystoreFileName)];
-
- shareConn.query("DROP USER 'sslTestUser'@'%'").catch((err) => {});
- shareConn.query("DROP USER 'X509testUser'@'%'").catch((err) => {});
+ if (serverCaFile) ca = [fs.readFileSync(serverCaFile, 'utf8')];
+ if (clientKeyFileName) clientKey = [fs.readFileSync(clientKeyFileName, 'utf8')];
+ if (clientCertFileName) clientCert = [fs.readFileSync(clientCertFileName, 'utf8')];
+ if (clientKeystoreFileName) clientKeystore = [fs.readFileSync(clientKeystoreFileName)];
- shareConn
- .query(
+ shareConn
+ .query("DROP USER IF EXISTS 'sslTestUser'@'%'")
+ .then(() => {
+ return shareConn.query("DROP USER IF EXISTS 'X509testUser'@'%'");
+ })
+ .then(() => {
+ return shareConn.query(
"CREATE USER 'sslTestUser'@'%' IDENTIFIED BY 'ytoKS@ç%ùed5' " +
((shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 2, 0)) ||
(!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7, 0))
? ' REQUIRE SSL'
: '')
- )
- .then(() => {
- return shareConn.query(
- "GRANT SELECT ON *.* TO 'sslTestUser'@'%' " +
- ((shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 2, 0)) ||
- (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0))
- ? ' REQUIRE SSL'
- : '')
- );
- })
- .then(() => {
+ );
+ })
+ .then(() => {
+ return shareConn.query(
+ "GRANT SELECT ON *.* TO 'sslTestUser'@'%' " +
+ ((shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 2, 0)) ||
+ (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0))
+ ? ' REQUIRE SSL'
+ : '')
+ );
+ })
+ .then(() => {
+ return shareConn.query(
+ "CREATE USER 'X509testUser'@'%' IDENTIFIED BY 'éà@d684SQpl¨^' " +
+ ((shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 2, 0)) ||
+ (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7, 0))
+ ? ' REQUIRE X509'
+ : '')
+ );
+ })
+ .then(() => {
+ return shareConn.query(
+ "GRANT SELECT ON *.* TO 'X509testUser'@'%' " +
+ ((shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 2, 0)) ||
+ (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0))
+ ? ' REQUIRE X509'
+ : '')
+ );
+ })
+ .then(() => {
+ if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(8)) {
return shareConn.query(
- "CREATE USER 'X509testUser'@'%' IDENTIFIED BY 'éà@d684SQpl¨^' " +
- ((shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 2, 0)) ||
- (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(5, 7, 0))
- ? ' REQUIRE X509'
- : '')
+ "ALTER USER 'sslTestUser'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'ytoKS@ç%ùed5'"
);
- })
- .then(() => {
+ }
+ return shareConn.query("SET PASSWORD FOR 'sslTestUser'@'%' = PASSWORD('ytoKS@ç%ùed5')");
+ })
+ .then(() => {
+ if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(8)) {
return shareConn.query(
- "GRANT SELECT ON *.* TO 'X509testUser'@'%' " +
- ((shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(10, 2, 0)) ||
- (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 0))
- ? ' REQUIRE X509'
- : '')
+ "ALTER USER 'X509testUser'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'éà@d684SQpl¨^'"
);
- })
- .then(() => {
- if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(8)) {
- return shareConn.query(
- "ALTER USER 'sslTestUser'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'ytoKS@ç%ùed5'"
- );
- }
- return shareConn.query("SET PASSWORD FOR 'sslTestUser'@'%' = PASSWORD('ytoKS@ç%ùed5')");
- })
- .then(() => {
- if (!shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(8)) {
- return shareConn.query(
- "ALTER USER 'X509testUser'@'%' IDENTIFIED WITH 'mysql_native_password' BY 'éà@d684SQpl¨^'"
- );
- }
- return shareConn.query("SET PASSWORD FOR 'X509testUser'@'%' = PASSWORD('éà@d684SQpl¨^')");
- })
- .then(() => {
- return shareConn.query("SHOW VARIABLES LIKE 'have_ssl'");
- })
- .then((rows) => {
- if (rows[0].Value === 'YES') {
- sslEnable = true;
- done();
- } else {
- //ssl is not enable on database, skipping test.
- shareConn
- .query("SHOW VARIABLES LIKE '%ssl%'")
- .then((rows) => {
- // console.log("ssl is not enable on database, skipping test :");
- // for (let i = 0; i < rows.length; i++) {
- // console.log(rows[0]["Variable_name"] + " = " + rows[0]["Value"]);
- // }
- done();
- })
- .catch(done);
- }
- })
- .catch(done);
- }
- });
-
- after(function (done) {
- if (process.env.MAXSCALE_VERSION) {
- done();
- } else {
- shareConn
- .query("DROP USER 'sslTestUser'@'%'")
- .then(() => {
- return shareConn.query("DROP USER 'X509testUser'@'%'");
- })
- .then(() => {
+ }
+ return shareConn.query("SET PASSWORD FOR 'X509testUser'@'%' = PASSWORD('éà@d684SQpl¨^')");
+ })
+ .then(() => {
+ return shareConn.query('FLUSH PRIVILEGES');
+ })
+ .then(() => {
+ return shareConn.query("SHOW VARIABLES LIKE 'have_ssl'");
+ })
+ .then((rows) => {
+ if (rows[0].Value === 'YES') {
+ sslEnable = true;
done();
- })
- .catch(done);
- }
+ } else {
+ //ssl is not enable on database, skipping test.
+ shareConn
+ .query("SHOW VARIABLES LIKE '%ssl%'")
+ .then((rows) => {
+ // console.log("ssl is not enable on database, skipping test :");
+ // for (let i = 0; i < rows.length; i++) {
+ // console.log(rows[0]["Variable_name"] + " = " + rows[0]["Value"]);
+ // }
+ done();
+ })
+ .catch(done);
+ }
+ })
+ .catch(done);
});
it('signed certificate error ', function (done) {
@@ -163,9 +151,11 @@ describe('ssl', function () {
.createConnection({
user: 'sslTestUser',
password: 'ytoKS@ç%ùed5',
- ssl: true
+ ssl: true,
+ port: sslPort
})
- .then(() => {
+ .then((conn) => {
+ conn.end();
done(new Error('Must have thrown an exception !'));
})
.catch((err) => {
@@ -177,7 +167,7 @@ describe('ssl', function () {
it('signed certificate forcing', function (done) {
if (!sslEnable) this.skip();
base
- .createConnection({ ssl: { rejectUnauthorized: false } })
+ .createConnection({ ssl: { rejectUnauthorized: false }, port: sslPort })
.then((conn) => {
conn.end();
done();
@@ -192,13 +182,17 @@ describe('ssl', function () {
.createConnection({
user: 'sslTestUser',
password: 'ytoKS@ç%ùed5',
- ssl: { rejectUnauthorized: false }
+ ssl: { rejectUnauthorized: false },
+ port: sslPort
})
.then((conn) => {
conn.end();
done();
})
- .catch(done);
+ .catch((err) => {
+ console.log(err);
+ done(err);
+ });
});
it('SSLv3 disable', function (done) {
@@ -208,9 +202,11 @@ describe('ssl', function () {
ssl: {
rejectUnauthorized: false,
secureProtocol: 'SSLv3_client_method'
- }
+ },
+ port: sslPort
})
- .then(() => {
+ .then((conn) => {
+ conn.end();
done(new Error('Must have thrown an exception !'));
})
.catch((err) => {
@@ -223,9 +219,11 @@ describe('ssl', function () {
if (!sslEnable) this.skip();
base
.createConnection({
- ssl: { rejectUnauthorized: false, secureProtocol: 'SSLv2_method' }
+ ssl: { rejectUnauthorized: false, secureProtocol: 'SSLv2_method' },
+ port: sslPort
})
- .then(() => {
+ .then((conn) => {
+ conn.end();
done(new Error('Must have thrown an exception !'));
})
.catch((err) => {
@@ -246,7 +244,8 @@ describe('ssl', function () {
}
base
.createConnection({
- ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_method' }
+ ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_method' },
+ port: sslPort
})
.then((conn) => {
checkProtocol(conn, 'TLSv1');
@@ -268,7 +267,8 @@ describe('ssl', function () {
}
base
.createConnection({
- ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_1_method' }
+ ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_1_method' },
+ port: sslPort
})
.then((conn) => {
checkProtocol(conn, 'TLSv1.1');
@@ -296,7 +296,8 @@ describe('ssl', function () {
secureProtocol: 'TLSv1_1_method',
ciphers:
'DHE-RSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256'
- }
+ },
+ port: sslPort
})
.then((conn) => {
checkProtocol(conn, 'TLSv1.1');
@@ -324,9 +325,11 @@ describe('ssl', function () {
rejectUnauthorized: false,
secureProtocol: 'TLSv1_1_method',
ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256'
- }
+ },
+ port: sslPort
})
- .then(() => {
+ .then((conn) => {
+ conn.end();
done(new Error('Must have thrown an exception !'));
})
.catch((err) => {
@@ -351,9 +354,11 @@ describe('ssl', function () {
rejectUnauthorized: false,
secureProtocol: 'TLSv1_1_method',
ciphers: 'ECDHE-ECDSA-AES256-STRANGE'
- }
+ },
+ port: sslPort
})
- .then(() => {
+ .then((conn) => {
+ conn.end();
done(new Error('Must have thrown an exception !'));
})
.catch((err) => {
@@ -373,7 +378,8 @@ describe('ssl', function () {
base
.createConnection({
- ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_2_method' }
+ ssl: { rejectUnauthorized: false, secureProtocol: 'TLSv1_2_method' },
+ port: sslPort
})
.then((conn) => {
checkProtocol(conn, 'TLSv1.2');
@@ -384,6 +390,7 @@ describe('ssl', function () {
});
it('TLSv1.2 with cipher working', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!sslEnable) this.skip();
//MariaDB server doesn't permit TLSv1.2 on windows
//MySQL community version doesn't support TLSv1.2
@@ -399,7 +406,8 @@ describe('ssl', function () {
secureProtocol: 'TLSv1_2_method',
ciphers:
'DHE-RSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256'
- }
+ },
+ port: sslPort
})
.then((conn) => {
checkProtocol(conn, 'TLSv1.2');
@@ -422,7 +430,8 @@ describe('ssl', function () {
checkServerIdentity: (servername, cert) => {
return;
}
- }
+ },
+ port: sslPort
})
.then((conn) => {
conn.end();
@@ -465,7 +474,7 @@ describe('ssl', function () {
if (!shareConn.info.isMariaDB() && !shareConn.info.hasMinVersion(5, 7, 10)) this.skip();
base
- .createConnection({ host: 'mariadb.example.com', ssl: { ca: ca } })
+ .createConnection({ host: 'mariadb.example.com', ssl: { ca: ca }, port: sslPort })
.then((conn) => {
const isWin = process.platform === 'win32';
let expectedProtocol = ['TLSv1.2', 'TLSv1.3'];
@@ -492,10 +501,16 @@ describe('ssl', function () {
user: 'X509testUser',
password: 'éà@d684SQpl¨^',
host: 'mariadb.example.com',
- ssl: { ca: ca }
+ ssl: { ca: ca },
+ port: sslPort
})
- .then(() => {
- done(new Error('Must have thrown an exception !'));
+ .then((conn) => {
+ conn.end();
+ if (!process.env.MAXSCALE_TEST_DISABLE) {
+ done(new Error('Must have thrown an exception !'));
+ } else {
+ done();
+ }
})
.catch((err) => {
done();
@@ -517,7 +532,8 @@ describe('ssl', function () {
ca: ca,
cert: clientCert,
key: clientKey
- }
+ },
+ port: sslPort
})
.then((conn) => {
conn.end();
@@ -541,7 +557,8 @@ describe('ssl', function () {
ca: ca,
pfx: clientKeystore,
passphrase: 'kspass'
- }
+ },
+ port: sslPort
})
.then((conn) => {
conn.end();
@@ -551,12 +568,16 @@ describe('ssl', function () {
});
it('ssl change user', function (done) {
+ if (process.env.MAXSCALE_TEST_DISABLE) this.skip();
if (!shareConn.info.isMariaDB()) this.skip();
if (!sslEnable) this.skip();
let currUser;
let conn;
base
- .createConnection({ ssl: { rejectUnauthorized: false } })
+ .createConnection({
+ ssl: { rejectUnauthorized: false },
+ port: sslPort
+ })
.then((con) => {
conn = con;
conn.query("DROP USER IF EXISTS ChangeUser@'%'").catch((err) => {});
diff --git a/test/integration/test-streaming.js b/test/integration/test-streaming.js
index 0c2695a0..9f718224 100644
--- a/test/integration/test-streaming.js
+++ b/test/integration/test-streaming.js
@@ -17,9 +17,12 @@ describe('streaming', () => {
before(function (done) {
this.timeout(20000);
shareConn
- .query(
- 'CREATE TEMPORARY TABLE Streaming (id int NOT NULL AUTO_INCREMENT, b longblob, c varchar(10), d longblob, e varchar(10), PRIMARY KEY (id))'
- )
+ .query('DROP TABLE IF EXISTS Streaming')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE Streaming (id int NOT NULL AUTO_INCREMENT, b longblob, c varchar(10), d longblob, e varchar(10), PRIMARY KEY (id))'
+ );
+ })
.then(() => {
return shareConn.query('SELECT @@max_allowed_packet as t');
})
@@ -39,10 +42,13 @@ describe('streaming', () => {
it('Streaming url content', function (done) {
this.timeout(30000);
shareConn
- .query(
- 'CREATE TEMPORARY TABLE StreamingContent (id int NOT NULL AUTO_INCREMENT, b longblob, c' +
- ' varchar(10), PRIMARY KEY (id))'
- )
+ .query('DROP TABLE IF EXISTS StreamingContent')
+ .then(() => {
+ return shareConn.query(
+ 'CREATE TABLE StreamingContent (id int NOT NULL AUTO_INCREMENT, b longblob, c' +
+ ' varchar(10), PRIMARY KEY (id))'
+ );
+ })
.then(() => {
const https = require('https');
https.get(
@@ -139,7 +145,7 @@ describe('streaming', () => {
this.timeout(20000);
const r = fs.createReadStream(halfFileName);
- let createTable = 'CREATE TEMPORARY TABLE Streaming2 (b longblob';
+ let createTable = 'CREATE TABLE Streaming2 (b longblob';
let insertSql = 'insert into Streaming2 values(?';
const params = [r];
const max = 200;
@@ -152,7 +158,10 @@ describe('streaming', () => {
insertSql += ')';
shareConn
- .query(createTable)
+ .query('DROP TABLE IF EXISTS Streaming2')
+ .then(() => {
+ return shareConn.query(createTable);
+ })
.then(() => {
return shareConn.query(insertSql, params);
})
diff --git a/test/integration/test-transaction.js b/test/integration/test-transaction.js
index 0179a986..7b6f69b5 100644
--- a/test/integration/test-transaction.js
+++ b/test/integration/test-transaction.js
@@ -7,7 +7,10 @@ const { assert } = require('chai');
describe('transaction', () => {
before((done) => {
shareConn
- .query('CREATE TEMPORARY TABLE testTransaction (v varchar(10))')
+ .query('DROP TABLE IF EXISTS testTransaction')
+ .then(() => {
+ return shareConn.query('CREATE TABLE testTransaction (v varchar(10))');
+ })
.then(() => {
done();
})
@@ -48,35 +51,44 @@ describe('transaction', () => {
it('transaction rollback with callback', (done) => {
const conn = base.createCallbackConnection();
conn.connect(function (err) {
- if (err) return done(err);
- conn.query('CREATE TEMPORARY TABLE testTransaction2 (v varchar(10))', (err) => {
- if (err) return done(err);
- conn.rollback((err) => {
- if (err) return done(err);
- conn.query('SET autocommit=0', (err) => {
- if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
- assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
- conn.beginTransaction((err) => {
+ if (err) {
+ return done(err);
+ } else {
+ conn.query('DROP TABLE IF EXISTS testTransaction2', (err) => {
+ if (err) {
+ return done(err);
+ } else {
+ conn.query('CREATE TABLE testTransaction2 (v varchar(10))', (err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- conn.query("INSERT INTO testTransaction2 values ('test')");
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
conn.rollback((err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
- conn.query('SELECT count(*) as nb FROM testTransaction2', (err, rows) => {
+ conn.query('SET autocommit=0', (err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- assert.equal(rows[0].nb, 0);
- conn.end();
- done();
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
+ assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
+ conn.beginTransaction((err) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ conn.query("INSERT INTO testTransaction2 values ('test')");
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ conn.rollback((err) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
+ conn.query('SELECT count(*) as nb FROM testTransaction2', (err, rows) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ assert.equal(rows[0].nb, 0);
+ conn.end();
+ done();
+ });
+ });
+ });
});
});
});
- });
+ }
});
- });
+ }
});
});
@@ -84,24 +96,30 @@ describe('transaction', () => {
const conn = base.createCallbackConnection();
conn.connect(function (err) {
if (err) return done(err);
- conn.query('CREATE TEMPORARY TABLE testTransaction2 (v varchar(10))', (err) => {
- if (err) return done(err);
- conn.rollback();
- conn.query('SET autocommit=0', (err) => {
- if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
- assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
- conn.beginTransaction();
- conn.query("INSERT INTO testTransaction2 values ('test')");
- conn.rollback();
- conn.query('SELECT count(*) as nb FROM testTransaction2', (err, rows) => {
+ conn.query('DROP TABLE IF EXISTS testTransaction2', (err) => {
+ if (err) {
+ return done(err);
+ } else {
+ conn.query('CREATE TABLE testTransaction2 (v varchar(10))', (err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- assert.equal(rows[0].nb, 0);
- conn.end();
- done();
+ conn.rollback();
+ conn.query('SET autocommit=0', (err) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
+ assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
+ conn.beginTransaction();
+ conn.query("INSERT INTO testTransaction2 values ('test')");
+ conn.rollback();
+ conn.query('SELECT count(*) as nb FROM testTransaction2', (err, rows) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ assert.equal(rows[0].nb, 0);
+ conn.end();
+ done();
+ });
+ });
});
- });
+ }
});
});
});
@@ -140,43 +158,69 @@ describe('transaction', () => {
it('transaction commit error handling', function (done) {
let conn;
- base
- .createConnection()
- .then((con) => {
- conn = con;
- conn.query('SET autocommit=0');
- conn.query('CREATE TEMPORARY TABLE testTransaction (v varchar(10))');
- return conn.query("INSERT INTO testTransaction values ('test')");
- })
- .then(() => {
- process.nextTick(
- conn.__tests.getSocket().destroy.bind(conn.__tests.getSocket(), new Error('close forced'))
- );
- conn
- .commit()
- .then(() => {
- done('must have thrown error !');
- conn.end();
- })
- .catch((err) => {
- conn.end();
- done();
- });
- })
- .catch(done);
+ base.createConnection().then((con) => {
+ conn = con;
+ return conn
+ .query('SET autocommit=0')
+ .then(() => {
+ return conn.query('DROP TABLE IF EXISTS testTransaction1');
+ })
+ .then(() => {
+ return conn.query('CREATE TABLE testTransaction1 (v varchar(10))');
+ })
+ .then(() => {
+ return conn.query("INSERT INTO testTransaction1 values ('test')");
+ })
+ .then(() => {
+ process.nextTick(
+ conn.__tests
+ .getSocket()
+ .destroy.bind(conn.__tests.getSocket(), new Error('close forced'))
+ );
+ conn
+ .commit()
+ .then(() => {
+ done('must have thrown error !');
+ conn.end();
+ })
+ .catch((err) => {
+ conn.end();
+ done();
+ });
+ })
+ .catch(done);
+ });
});
it('transaction commit no callback with error', function (done) {
const conn = base.createCallbackConnection();
conn.connect((err) => {
- conn.query('SET autocommit=0');
- conn.query('CREATE TEMPORARY TABLE testTransaction (v varchar(10))');
- conn.query("INSERT INTO testTransaction values ('test')", (err) => {
- process.nextTick(
- conn.__tests.getSocket().destroy.bind(conn.__tests.getSocket(), new Error('close forced'))
- );
- conn.commit();
- done();
+ conn.query('SET autocommit=0', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query('DROP TABLE IF EXISTS testTransaction2', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query('CREATE TABLE testTransaction2 (v varchar(10))', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query("INSERT INTO testTransaction2 values ('test')", (err) => {
+ process.nextTick(
+ conn.__tests
+ .getSocket()
+ .destroy.bind(conn.__tests.getSocket(), new Error('close forced'))
+ );
+ conn.commit();
+ done();
+ });
+ }
+ });
+ }
+ });
+ }
});
});
});
@@ -184,14 +228,30 @@ describe('transaction', () => {
it('transaction commit no callback success', function (done) {
const conn = base.createCallbackConnection();
conn.connect((err) => {
- conn.query('SET autocommit=0');
- conn.query('CREATE TEMPORARY TABLE testTransaction (v varchar(10))');
- conn.query("INSERT INTO testTransaction values ('test')", (err) => {
- conn.commit();
- setTimeout(() => {
- conn.end();
- done();
- }, 100);
+ conn.query('SET autocommit=0', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query('DROP TABLE IF EXISTS testTransaction3', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query('CREATE TABLE testTransaction3 (v varchar(10))', (err) => {
+ if (err) {
+ done(err);
+ } else {
+ conn.query("INSERT INTO testTransaction3 values ('test')", (err) => {
+ conn.commit();
+ setTimeout(() => {
+ conn.end();
+ done();
+ }, 100);
+ });
+ }
+ });
+ }
+ });
+ }
});
});
});
@@ -225,34 +285,40 @@ describe('transaction', () => {
const conn = base.createCallbackConnection();
conn.connect((err) => {
if (err) return done(err);
- conn.query('CREATE TEMPORARY TABLE testTransaction (v varchar(10))', (err) => {
- if (err) return done(err);
- conn.commit((err) => {
- if (err) return done(err);
- conn.query('SET autocommit=0', (err) => {
+ conn.query('DROP TABLE IF EXISTS testTransaction4', (err) => {
+ if (err) {
+ return done(err);
+ } else {
+ conn.query('CREATE TABLE testTransaction4 (v varchar(10))', (err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
- assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
- conn.beginTransaction((err) => {
+ conn.commit((err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- conn.query("INSERT INTO testTransaction values ('test')", (err) => {
+ conn.query('SET autocommit=0', (err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- conn.commit((err) => {
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
+ assert.equal(conn.info.status & ServerStatus.STATUS_AUTOCOMMIT, 0);
+ conn.beginTransaction((err) => {
if (err) return done(err);
- assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
- conn.query('SELECT count(*) as nb FROM testTransaction', (err, rows) => {
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ conn.query("INSERT INTO testTransaction4 values ('test')", (err) => {
if (err) return done(err);
assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
- assert.equal(rows[0].nb, 1);
- conn.end(done);
+ conn.commit((err) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 0);
+ conn.query('SELECT count(*) as nb FROM testTransaction4', (err, rows) => {
+ if (err) return done(err);
+ assert.equal(conn.info.status & ServerStatus.STATUS_IN_TRANS, 1);
+ assert.equal(rows[0].nb, 1);
+ conn.end(done);
+ });
+ });
});
});
});
});
});
- });
+ }
});
});
});
diff --git a/test/integration/test-typecast.js b/test/integration/test-typecast.js
index bd005802..086f8819 100644
--- a/test/integration/test-typecast.js
+++ b/test/integration/test-typecast.js
@@ -105,7 +105,10 @@ describe('TypeCast', () => {
.createConnection({ typeCast: tinyToBoolean })
.then((conn) => {
conn
- .query('CREATE TEMPORARY TABLE tinyToBool(b1 TINYINT(1), b2 TINYINT(2))')
+ .query('DROP TABLE IF EXISTS tinyToBool')
+ .then(() => {
+ return conn.query('CREATE TABLE tinyToBool(b1 TINYINT(1), b2 TINYINT(2))');
+ })
.then(() => {
return conn.query('INSERT INTO tinyToBool VALUES (0,0), (1,1), (2,2), (null,null)');
})
@@ -141,7 +144,10 @@ describe('TypeCast', () => {
.createConnection({ typeCast: longCast })
.then((conn) => {
conn
- .query('CREATE TEMPORARY TABLE stupidCast(b1 TINYINT(1), b2 varchar(3))')
+ .query('DROP TABLE IF EXISTS stupidCast')
+ .then(() => {
+ return conn.query('CREATE TABLE stupidCast(b1 TINYINT(1), b2 varchar(3))');
+ })
.then(() => {
return conn.query(
"INSERT INTO stupidCast VALUES (0,'0.1'), (1,'1.1')," + " (2,'2.2'), (null,null)"
@@ -177,7 +183,10 @@ describe('TypeCast', () => {
.createConnection({ typeCast: longCast })
.then((conn) => {
conn
- .query('CREATE TEMPORARY TABLE stupidCast(b1 varchar(100))')
+ .query('DROP TABLE IF EXISTS stupidCast')
+ .then(() => {
+ return conn.query('CREATE TABLE stupidCast(b1 varchar(100))');
+ })
.then(() => {
return conn.query(
"INSERT INTO stupidCast VALUES ('1999-01-31" +
@@ -208,7 +217,10 @@ describe('TypeCast', () => {
.createConnection({ typeCast: longCast })
.then((conn) => {
conn
- .query('CREATE TEMPORARY TABLE stupidCast(b1 POINT)')
+ .query('DROP TABLE IF EXISTS stupidCast')
+ .then(() => {
+ return conn.query('CREATE TABLE stupidCast(b1 POINT)');
+ })
.then(() => {
return conn.query('INSERT INTO stupidCast VALUES (?), (?),(null)', [
{
@@ -240,7 +252,9 @@ describe('TypeCast', () => {
},
{
b1:
- shareConn.info.isMariaDB() && shareConn.info.hasMinVersion(10, 5, 2)
+ shareConn.info.isMariaDB() &&
+ shareConn.info.hasMinVersion(10, 5, 2) &&
+ !process.env.MAXSCALE_TEST_DISABLE
? { type: 'Point' }
: null
}
diff --git a/test/unit/config/test-connection-options.js b/test/unit/config/test-connection-options.js
index 8d9c5660..e1fac305 100644
--- a/test/unit/config/test-connection-options.js
+++ b/test/unit/config/test-connection-options.js
@@ -107,6 +107,7 @@ describe('test connection options', () => {
assert.equal(result.database, 'шdb');
assert.equal(result.host, 'example.com');
assert.equal(result.password, 'p@ssword');
+ assert.equal(result.keepAliveDelay, 0);
assert.equal(result.port, 3307);
assert.equal(result.user, 'rootå');
assert.deepEqual(result.connectAttributes, { par1: 'bouh', par2: 'bla' });
@@ -226,13 +227,14 @@ describe('test connection options', () => {
it('with options', () => {
const result = ConnOptions.parse(
- 'mariadb://root:pass@localhost:3307/db?metaAsArray=false&ssl=true&dateStrings=true&collation=latin1_swedish_ci&maxAllowedPacket=1048576&permitSetMultiParamEntries=true'
+ 'mariadb://root:pass@localhost:3307/db?metaAsArray=false&ssl=true&dateStrings=true&collation=latin1_swedish_ci&maxAllowedPacket=1048576&permitSetMultiParamEntries=true&keepAliveDelay=1000'
);
assert.deepEqual(result, {
database: 'db',
dateStrings: true,
host: 'localhost',
metaAsArray: false,
+ keepAliveDelay: 1000,
password: 'pass',
port: 3307,
ssl: true,
diff --git a/types/index.d.ts b/types/index.d.ts
index 042a40a5..ca366bcd 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
-// Type definitions for mariadb 2.0
+// Type definitions for mariadb 2.5
// Project: https://github.com/mariadb-corporation/mariadb-connector-nodejs
// Definitions by: Diego Dupin
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
@@ -228,9 +228,12 @@ export interface ConnectionConfig extends UserConnectionConfig, QueryConfig {
multipleStatements?: boolean;
/**
- * object with ssl parameters or a string containing name of ssl profile
+ * object with ssl parameters or a boolean to enable ssl without setting any other ssl option.
+ * see
+ * https://github.com/mariadb-corporation/mariadb-connector-nodejs/blob/master/documentation/connection-options.md#ssl
+ * for more information
*/
- ssl?: string | (tls.SecureContextOptions & { rejectUnauthorized?: boolean });
+ ssl?: boolean | (tls.SecureContextOptions & { rejectUnauthorized?: boolean });
/**
* Compress exchanges with database using gzip.
@@ -275,6 +278,51 @@ export interface ConnectionConfig extends UserConnectionConfig, QueryConfig {
* Example: sessionVariables:{'idle_transaction_timeout':10000}
*/
sessionVariables?: any;
+
+ /**
+ * Indicate if array are included in parenthesis. This option permit compatibility with version < 2.5
+ */
+ arrayParenthesis?: boolean;
+
+ /**
+ * indicate if JSON fields for MariaDB server 10.5.2+ results in JSON format (or String if disabled)
+ */
+ autoJsonMap?: boolean;
+
+ /**
+ * permit to enable socket keep alive, setting delay. 0 means not enabled. Keep in mind that this don't reset server [@@wait_timeout](https://mariadb.com/kb/en/library/server-system-variables/#wait_timeout) (use pool option idleTimeout for that).
+ * in ms
+ * (Default: 0)
+ */
+ keepAliveDelay?: number;
+
+ /**
+ * Indicate path/content to MySQL server RSA public key.
+ * use requires Node.js v11.6+
+ */
+ rsaPublicKey?: string;
+
+ /**
+ * Indicate path/content to MySQL server caching RSA public key.
+ * use requires Node.js v11.6+
+ */
+ cachingRsaPublicKey?: string;
+
+ /**
+ * Indicate that if `rsaPublicKey` or `cachingRsaPublicKey` public key are not provided, if client can ask server to send public key.
+ * default: false
+ */
+ allowPublicKeyRetrieval?: boolean;
+
+ /**
+ * Whether resultset should return javascript ES2020 [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
+ * for [BIGINT](https://mariadb.com/kb/en/bigint/) data type.
+ * This ensures having expected value even for value > 2^53
+ * (see [safe](documentation/connection-options.md#support-for-big-integer) range).
+ *
+ * default false
+ */
+ supportBigInt?: boolean;
}
export interface PoolConfig extends ConnectionConfig {
diff --git a/types/mariadb-tests.ts b/types/mariadb-tests.ts
index 9494e417..32f2d0ee 100644
--- a/types/mariadb-tests.ts
+++ b/types/mariadb-tests.ts
@@ -24,8 +24,30 @@ function createPoolConfig(options?: PoolConfig): mariadb.PoolConfig {
);
}
+function createPoolConfigWithSSl(options?: PoolConfig): mariadb.PoolConfig {
+ Object.assign(
+ {
+ host: baseConfig.host,
+ user: baseConfig.user,
+ password: baseConfig.password,
+ ssl: true
+ },
+ options
+ );
+ return Object.assign(
+ {
+ host: baseConfig.host,
+ user: baseConfig.user,
+ password: baseConfig.password,
+ ssl: { ca: 'fff' }
+ },
+ options
+ );
+}
+
function createPool(options?: unknown): mariadb.Pool {
- return mariadb.createPool(createPoolConfig(options));
+ mariadb.createPool(createPoolConfig(options));
+ return mariadb.createPool(createPoolConfigWithSSl(options));
}
async function testMisc(): Promise {