@mysql/xdevapi
Version:
MySQL Connector/Node.js - A Node.js driver for MySQL using the X Protocol and X DevAPI.
859 lines (731 loc) • 35 kB
JavaScript
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is also distributed with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms,
* as designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an
* additional permission to link the program and your derivative works
* with the separately licensed software that they have included with
* MySQL.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of MySQL Connector/Node.js, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* http://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
;
/* eslint-env node, mocha */
const config = require('../../../config');
const expect = require('chai').expect;
const fixtures = require('../../../fixtures');
const mysqlx = require('../../../../');
// TODO(Rui): extract tests into proper self-contained suites.
describe('relational miscellaneous tests', () => {
const baseConfig = { schema: config.schema || 'mysql-connector-nodejs_test' };
let schema, session;
beforeEach('create default schema', () => {
return fixtures.createSchema(baseConfig.schema);
});
beforeEach('create session using default schema', () => {
const defaultConfig = Object.assign({}, config, baseConfig);
return mysqlx.getSession(defaultConfig)
.then(s => {
session = s;
});
});
beforeEach('load default schema', () => {
schema = session.getDefaultSchema();
});
afterEach('drop default schema', () => {
return session.dropSchema(schema.getName());
});
afterEach('close session', () => {
return session.close();
});
context('raw SQL query', () => {
it('handles the results with a callback provided as an argument', () => {
const expected = [1];
let actual;
return session.sql('SELECT 1')
.execute(row => { actual = row; })
.then(() => expect(actual).to.deep.equal(expected));
});
it('handles the column metadata with a callback provided as an argument', () => {
const actual = {};
return session.sql('SELECT 1')
.execute(row => { actual.row = row; }, meta => { actual.meta = meta; })
.then(() => {
expect(actual).to.have.all.keys('meta', 'row');
expect(actual.meta).to.have.lengthOf(1);
expect(actual.meta[0]).to.contain.keys('getType', 'getColumnLabel', 'getColumnName', 'getTableLabel', 'getTableName', 'getSchemaName', 'getLength');
expect(actual.meta[0].getType()).to.equal('TINYINT');
expect(actual.meta[0].getColumnLabel()).to.equal('1');
expect(actual.meta[0].getColumnName()).to.equal('');
expect(actual.meta[0].getTableLabel()).to.equal('');
expect(actual.meta[0].getTableName()).to.equal('');
expect(actual.meta[0].getSchemaName()).to.equal('');
expect(actual.meta[0].getLength()).to.be.a('number');
});
});
it('handles the results using both callbacks provided in an object', () => {
const actual = {};
return session.sql('SELECT 1')
.execute({
row (row) {
actual.row = row;
},
meta (meta) {
actual.meta = meta;
}
})
.then(() => {
expect(actual).to.have.all.keys('meta', 'row');
expect(actual.meta).to.have.lengthOf(1);
expect(actual.meta[0]).to.contain.keys('getType', 'getColumnLabel', 'getColumnName', 'getTableLabel', 'getTableName', 'getSchemaName', 'getLength');
expect(actual.meta[0].getType()).to.equal('TINYINT');
expect(actual.meta[0].getColumnLabel()).to.equal('1');
expect(actual.meta[0].getColumnName()).to.equal('');
expect(actual.meta[0].getTableLabel()).to.equal('');
expect(actual.meta[0].getTableName()).to.equal('');
expect(actual.meta[0].getSchemaName()).to.equal('');
expect(actual.meta[0].getLength()).to.be.a('number');
});
});
context('placeholder binding', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
name VARCHAR(5),
age TINYINT)`)
.execute();
});
it('binds values to query placeholders', () => {
const rows = [];
const expected = [['foo'], ['baz']];
return session.sql('INSERT INTO test VALUES (?, ?), (?, ?), (?, ?)')
.bind('foo', 23, 'bar')
.bind([42, 'baz', 23])
.execute()
.then(() => {
return session
.sql('SELECT name FROM test WHERE age < ?')
.bind(40)
.execute(row => rows.push(row))
.then(() => expect(rows).to.deep.equal(expected));
});
});
});
});
context('column type decoding', () => {
context('values encoded as SINT', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
tiny_signed_int_1 TINYINT,
tiny_signed_int_2 TINYINT,
small_signed_int_1 SMALLINT,
small_signed_int_2 SMALLINT,
medium_signed_int_1 MEDIUMINT,
medium_signed_int_2 MEDIUMINT,
signed_int_1 INT,
signed_int_2 INT,
big_signed_int_1 BIGINT,
big_signed_int_2 BIGINT)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql(`INSERT INTO test VALUES (
-128, 127, -32768, 32767, -8388608, 8388607, -2147483648, 2147483647, -9223372036854775808, 9223372036854775807)`)
.execute();
});
it('decodes values correctly', () => {
const expected = [[-128, 127, -32768, 32767, -8388608, 8388607, -2147483648, 2147483647, '-9223372036854775808', '9223372036854775807']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('BUG# non BIGINT values store in BIGINT columns', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (not_big_int BIGINT)')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (4294967295)')
.execute();
});
it('decodes values correctly', () => {
const expected = [4294967295];
return schema.getTable('test').select()
.execute()
.then(res => expect(res.fetchOne()).to.deep.equal(expected));
});
});
context('values encoded as UINT', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
tiny_unsigned_int_1 TINYINT UNSIGNED,
tiny_unsigned_int_2 TINYINT UNSIGNED,
small_unsigned_int_1 SMALLINT UNSIGNED,
small_unsigned_int_2 SMALLINT UNSIGNED,
medium_unsigned_int_1 MEDIUMINT UNSIGNED,
medium_unsigned_int_2 MEDIUMINT UNSIGNED,
signed_int_1 INT UNSIGNED,
signed_int_2 INT UNSIGNED,
big_unsigned_int_1 BIGINT UNSIGNED,
big_unsigned_int_2 BIGINT UNSIGNED)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql(`INSERT INTO test VALUES (
0, 255, 0, 65535, 0, 16777215, 0, 16777215, 0, 18446744073709551615)`)
.execute();
});
it('decodes values correctly', () => {
const expected = [[0, 255, 0, 65535, 0, 16777215, 0, 16777215, 0, '18446744073709551615']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('values encoded as BIT', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (bit_1 BIT, bit_2 BIT(3))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (b\'1\', b\'111\')')
.execute();
});
it('decodes values correctly', () => {
const expected = [['1', '7']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('values encoded as DOUBLE and FLOAT', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
double_1 DOUBLE,
double_2 DOUBLE PRECISION (5, 4),
float_1 FLOAT(3, 2))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql(`INSERT INTO test VALUES (
1.2345678910111213141516171819202, 1.23456789, 1.23456789)`)
.execute();
});
it('decodes values correctly', () => {
// eslint-disable-next-line no-loss-of-precision
const expected = [[1.2345678910111213141516171819202, 1.2346, 1.23]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
it('decodes the column metadata correctly', () => {
return schema.getTable('test').select()
.execute()
.then(res => {
const columns = res.getColumns();
expect(columns[0].getFractionalDigits()).to.equal(31);
expect(columns[1].getFractionalDigits()).to.equal(4);
expect(columns[2].getFractionalDigits()).to.equal(2);
});
});
});
context('values encoded as BYTES', () => {
context('BLOB columns', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_tiny_blob TINYBLOB,
a_blob BLOB(5),
a_medium_blob MEDIUMBLOB,
a_long_blob LONGBLOB)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("foo", "bar", "baz", "qux")')
.execute();
});
it('decodes values correctly', () => {
const expected = [[Buffer.from('foo'), Buffer.from('bar'), Buffer.from('baz'), Buffer.from('qux')]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('TEXT columns', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_tiny_text TINYTEXT,
a_text TEXT(5),
a_medium_text MEDIUMTEXT,
a_long_text LONGTEXT)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("foo", "bar", "baz", "qux")')
.execute();
});
it('decodes values correctly', () => {
const expected = [['foo', 'bar', 'baz', 'qux']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('variable and fixed size BINARY columns', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_varbinary VARBINARY(5),
a_binary BINARY(5))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("foo", "bar")')
.execute();
});
it('decodes values correctly', () => {
// BINARY length = byte size
const expected = [[Buffer.from('foo'), Buffer.from('bar\0\0')]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('variable and fixed size CHAR columns', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_varchar VARCHAR(5),
a_char CHAR(5))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("foo", "bar")')
.execute();
});
it('decodes values correctly', () => {
// CHAR length = byte size * 4 (to accommodate UTF8)
const expected = [['foo', 'bar ']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('BUG#30030159', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_char CHAR(4),
a_binary BINARY(4))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("0", "0")')
.execute();
});
it('decodes numeric values for columns of fixed-length datatypes that require padding', () => {
// BINARY length = byte size
// CHAR length = byte size * 4 (to accommodate UTF8)
const expected = [['0 ', Buffer.from('0\0\0\0')]];
const actual = [];
return schema.getTable('test').select()
.execute(row => actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('ENUM columns', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (a_enum ENUM(\'foo\', \'bar\', \'baz\'))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES ("foo")')
.execute();
});
it('decodes values correctly', () => {
const expected = [['foo']];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('GEOMETRY columns', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (a_geo GEOMETRY)')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (ST_GeomFromText(\'POINT(1 1)\'))')
.execute();
});
it('decodes values correctly', () => {
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => actual.forEach(row => expect(row[0]).to.be.an.instanceof(Buffer)));
});
});
});
context('values encoded as TIME', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (a_time TIME(6))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql(`INSERT INTO test VALUES ('11 12:13:14'), ('-12:13:14'), ('12:13:14.123456'),
('21 22:03'), ('-22:03'), ('22:03'), ('1 02'), ('-02'), ('02'), ('101112'), ('-101112'), (101112), (-101112), (8), (-8)`)
.execute();
});
it('decodes values correctly', () => {
const expected = [
['+276:13:14.000000'],
['-12:13:14.000000'],
['+12:13:14.123456'],
['+526:03:00.000000'],
['-22:03:00.000000'],
['+22:03:00.000000'],
['+26:00:00.000000'],
['-00:00:02.000000'],
['+00:00:02.000000'],
['+10:11:12.000000'],
['-10:11:12.000000'],
['+10:11:12.000000'],
['-10:11:12.000000'],
['+00:00:08.000000'],
['-00:00:08.000000']
];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('values encoded as DATE, DATETIME or TIMESTAMP', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
a_date DATE,
a_datetime DATETIME,
a_timestamp TIMESTAMP)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (\'2018-02-18\', \'2018-02-18 12:33:17\', \'2018-02-18 12:33:17.123456\')')
.execute();
});
it('decodes values correctly', () => {
const expected = [[new Date('2018-02-18Z'), new Date('2018-02-18T12:33:17Z'), 1518957197000]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('values encoded as DECIMAL', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
decimal_1 DECIMAL,
decimal_2 DECIMAL(3),
decimal_3 DECIMAL(3,2))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (-999.99, 999, 9.99)')
.execute();
});
it('decodes values correctly', () => {
const expected = [[-1000, 999, 9.99]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
it('decodes the column metadata correctly', () => {
return schema.getTable('test').select()
.execute()
.then(res => {
const columns = res.getColumns();
expect(columns[0].getFractionalDigits()).to.equal(0);
expect(columns[1].getFractionalDigits()).to.equal(0);
expect(columns[2].getFractionalDigits()).to.equal(2);
});
});
});
context('BUG#34016587 values encoded as DECIMAL with precision loss', () => {
beforeEach('create table', () => {
// A JavaScript number does not have enough precision to safely
// represent a decimal value with more than 16 decimal scale
// digits (sometimes even less depending on which digits).
return session.sql(`CREATE TABLE test (
decimal_1 DECIMAL(17, 1),
decimal_2 DECIMAL(17, 16),
decimal_3 DECIMAL(17, 16),
decimal_4 DECIMAL(17, 1))`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (-9999999999999999.9, -9.9999999999999999, 9.9999999999999999, 9999999999999999.9)')
.execute();
});
it('decodes values using a string to avoid precision loss', () => {
const expected = [['-9999999999999999.9', '-9.9999999999999999', '9.9999999999999999', '9999999999999999.9']];
return schema.getTable('test').select()
.execute()
.then(res => {
return expect(res.fetchAll()).to.deep.equal(expected);
});
});
});
context('values encoded as SET', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (a_set SET(\'foo\', \'bar\'))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (\'foo,bar\'), (\'foo\'), (\'\'), (NULL)')
.execute();
});
it('decodes values correctly', () => {
const expected = [[['foo', 'bar']], [['foo']], [[]], [null]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('BUG#31654667 single-character SET values', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (a_set SET(\'S\', \'M\', \'L\'))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (\'S,M,L\'), (\'S,L\'), (\'L\')')
.execute();
});
it('decodes values correctly', () => {
const expected = [[['S', 'M', 'L']], [['S', 'L']], [['L']]];
const actual = [];
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
context('NULL values', () => {
beforeEach('create table', () => {
return session.sql(`CREATE TABLE test (
null_01 TINYINT,
null_02 TINYINT UNSIGNED,
null_03 SMALLINT,
null_04 SMALLINT UNSIGNED,
null_05 MEDIUMINT,
null_06 MEDIUMINT UNSIGNED,
null_07 INT,
null_08 INT UNSIGNED,
null_09 BIGINT,
null_10 BIGINT UNSIGNED,
null_11 DOUBLE,
null_12 FLOAT,
null_13 DECIMAL,
null_14 VARCHAR(5),
null_15 CHAR(5),
null_16 VARBINARY(5),
null_17 BINARY(5),
null_18 ENUM('foo', 'bar'),
null_19 TIME,
null_20 DATE,
null_21 DATETIME,
null_22 TIMESTAMP,
null_23 SET('foo', 'bar'),
null_24 BIT
)`)
.execute();
});
beforeEach('add fixtures', () => {
return session.sql(`INSERT INTO test VALUES (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)`)
.execute();
});
it('decodes values correctly', () => {
const expected = [[]];
const actual = [];
for (let i = 0; i < 24; ++i) {
expected[0].push(null);
}
return schema.getTable('test').select()
.execute(row => row && row.length && actual.push(row))
.then(() => expect(actual).to.deep.equal(expected));
});
});
});
context('column metadata', () => {
context('signed and unsigned values', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (sint INT, uint INT UNSIGNED)')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (1, 1)')
.execute();
});
it('allows to determine if a field is signed or not', () => {
let metadata = [];
return session.sql('SELECT * FROM test')
.execute(() => {}, meta => {
metadata = metadata.concat(meta);
})
.then(() => {
/* eslint-disable no-unused-expressions */
expect(metadata[0].isNumberSigned()).to.be.true;
expect(metadata[1].isNumberSigned()).to.be.false;
/* eslint-enable no-unused-expressions */
});
});
});
context('padded values', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (rchar CHAR(5), vchar VARCHAR(5))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql('INSERT INTO test VALUES (\'foo\', \'bar\')')
.execute();
});
it('allows to determine if a field is padded or not', () => {
let metadata = [];
return session.sql('SELECT * FROM test')
.execute(() => {}, meta => {
metadata = metadata.concat(meta);
})
.then(() => {
/* eslint-disable no-unused-expressions */
expect(metadata[0].isPadded()).to.be.true;
expect(metadata[1].isPadded()).to.be.false;
/* eslint-enable no-unused-expressions */
});
});
});
context('table metadata', () => {
beforeEach('create table', () => {
return session.sql('CREATE TABLE test (vchar VARCHAR(3))')
.execute();
});
beforeEach('add fixtures', () => {
return session.sql("INSERT INTO test VALUES ('foo')")
.execute();
});
it('decodes the table name in the column metadata', () => {
return session.sql('SELECT * FROM test')
.execute()
.then(res => {
return expect(res.getColumns()[0].getTableName()).to.equal('test');
});
});
it('decodes the schema name in the column metadata', () => {
return session.sql('SELECT * FROM test')
.execute()
.then(res => {
return expect(res.getColumns()[0].getSchemaName()).to.equal(schema.getName());
});
});
});
});
context('tables in the schema', () => {
let schema;
beforeEach('set schema', () => {
schema = session.getDefaultSchema();
});
it('checks if a table exists in the database', () => {
return session.sql('CREATE TABLE foo (name VARCHAR(3))')
.execute()
.then(() => schema.getTable('foo').existsInDatabase())
.then(exists => expect(exists).to.be.true);
});
it('distinguishes tables from collections', () => {
return session.sql('CREATE TABLE foo (name VARCHAR(3))')
.execute()
.then(() => schema.getCollection('foo').existsInDatabase())
.then(exists => expect(exists).to.be.false);
});
});
context('table views', () => {
const tableName = 'test';
const viewName = 'v_test';
beforeEach('create a table', () => {
return session.sql(`CREATE TABLE ${tableName} (quantity INT, price INT)`)
.execute();
});
beforeEach('create a view on the table', () => {
return session.sql(`CREATE VIEW ${viewName} AS SELECT quantity, price, quantity*price AS VALUE FROM ${tableName}`)
.execute();
});
it('checks if a table is not a view', () => {
return session.getSchema(schema.getName()).getTable(tableName)
.isView()
.then(res => {
return expect(res).to.be.false;
});
});
it('checks if a table is a view', () => {
return session.getSchema(schema.getName()).getTable(viewName)
.isView()
.then(res => {
return expect(res).to.be.true;
});
});
});
context('date and time manipulation', () => {
context('BUG#35690736 date unit encoding', () => {
beforeEach('create table', async () => {
await session.sql(`CREATE TABLE test (
name VARCHAR(3),
createdAt DATE)`)
.execute();
});
beforeEach('add fixtures', async () => {
await session.sql("INSERT INTO test (name, createdAt) values ('foo', CURDATE())")
.execute();
await session.sql("INSERT INTO test (name, createdAt) values ('bar', DATE_ADD(CURDATE(), INTERVAL 3 DAY))")
.execute();
});
it('retrieves the appropriate data within a given temporal range', async () => {
const diff = 3;
const now = new Date();
const then = new Date();
then.setUTCDate(now.getUTCDate() + diff);
then.setUTCHours(0);
then.setUTCMinutes(0);
then.setUTCSeconds(0);
then.setUTCMilliseconds(0);
const want = [['bar', then]];
const res = await schema.getTable('test')
.select()
.where(`createdAt > CURDATE() + INTERVAL ${diff - 1} DAY`)
.execute();
const got = res.fetchAll();
expect(got).to.deep.equal(want);
});
});
});
});