Skip to content
This repository was archived by the owner on Dec 13, 2019. It is now read-only.

Sugo db2 support #1

Open
wants to merge 52 commits into
base: db2_support
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
fa57155
docs: explain defaults/where behavior for find/create (#11069)
levibostian Jun 26, 2019
89802e0
docs: improve datatype docs
sushantdhiman Jun 26, 2019
d7c3c7d
refactor(query-generation): remove lodash string templates (#11122)
Jun 28, 2019
92cb903
refactor: remove unused _templateSettings
sushantdhiman Jun 28, 2019
7a6cc32
feat(hooks): beforeDisconnect / afterDisconnect (#11117)
UziTech Jun 28, 2019
3a914f0
fix: update sequelize-pool (#11134)
sushantdhiman Jul 2, 2019
7ac8f02
fix(types): silent option for update (#11115)
negezor Jul 2, 2019
695c87b
docs(models-definition): correct spelling mistakes (#11147)
CoreyBuckley Jul 4, 2019
ff3c225
fix(types): add string to Includeable (#11003)
zjr Jul 5, 2019
75b95dc
fix(types): relax order typing (#10802)
Chocobozzz Jul 6, 2019
f2b0aec
fix(model): don't alter original scopes when combining them (#10722)
jorgelf Jul 6, 2019
b6d6787
fix(types): add literal to possible where options (#10990)
Jul 6, 2019
f95d26f
test: remove redundant test (#11156)
SimonSchick Jul 6, 2019
d93b01b
fix(types): support json,text type
xjandwqz Jul 9, 2019
2178740
fix(test): add test
HeGanjie Jul 9, 2019
d6bc560
fix(types): fix json default value
xjandwqz Jul 9, 2019
c60fcbd
fix(test): more test
HeGanjie Jul 9, 2019
9b34f6f
fix: travis linting issues
bimalkjha Jul 9, 2019
715330a
Merge branch 'master' into db2_support
bimalkjha Jul 9, 2019
4e0ce38
docs(migrations): use timestamps with seed (#11160)
neverstew Jul 9, 2019
2d5f0a6
fix(types): fix json、boolean cast
xjandwqz Jul 10, 2019
52fd707
fix(types): fix json、jsonb to clob
xjandwqz Jul 10, 2019
307442d
fix(test): partial implement client side filter
HeGanjie Jul 10, 2019
1639bf5
Merge branch 'master' into db2_support
bimalkjha Jul 10, 2019
36a47f7
fix(client-side-test): more test
HeGanjie Jul 11, 2019
9211cf5
Merge commit '52fd7074610079' into sugo-db2-support
HeGanjie Jul 11, 2019
d59c0f1
fix(client-side-test): add bulk create test
HeGanjie Jul 11, 2019
0d8c9f6
fix(types): bulkInsert stringify
xjandwqz Jul 11, 2019
08015c7
fix(client-side-filter): more data, more todo
HeGanjie Jul 11, 2019
312887e
fix(types): merge ibm db2-support
xjandwqz Jul 11, 2019
f1c28e9
fix(client-side-filter): fix prefix
HeGanjie Jul 12, 2019
4e5b984
fix(types): support json update、delete
xjandwqz Jul 12, 2019
39c4c21
Merge branch 'sugo-db2-support' of github.com:Datafruit/sugo-sequeliz…
xjandwqz Jul 12, 2019
1e2e4c8
fix(client-side-test): implement pagination in client side
HeGanjie Jul 12, 2019
6d8e26d
fix(types): support json findCount
xjandwqz Jul 12, 2019
a61d0ca
fix(client-side-filter): omit non json filter
HeGanjie Jul 12, 2019
1c5631c
fix(client-side-filter): partial implement batchQuery
HeGanjie Jul 12, 2019
cb1bda2
feat(batch-query): implement batchQuery
HeGanjie Jul 13, 2019
5f7ccb8
fix(types): like query
xjandwqz Jul 13, 2019
a3e94da
fix(types): merge
xjandwqz Jul 13, 2019
000d664
fix(types): support limit offset
xjandwqz Jul 13, 2019
1206f4e
fix(client-side-test): more non json test
HeGanjie Jul 13, 2019
0e5a8c3
fix(client-side-test): more test
HeGanjie Jul 13, 2019
3e76e8c
fix(types): support ilike
xjandwqz Jul 13, 2019
d59f871
fix(client-side-filter): more test
HeGanjie Jul 13, 2019
a31f777
fix(client-side-filter): fix test
HeGanjie Jul 15, 2019
aff0aae
fix(is-json-filter): faster
HeGanjie Jul 15, 2019
0dcc15e
fix(types): support or json
xjandwqz Jul 16, 2019
c8e7bc2
fix(types): data default value
xjandwqz Jul 16, 2019
076ebea
fix(types): support includes dataType Convert
xjandwqz Jul 19, 2019
6933372
fix(types): update version
xjandwqz Jul 19, 2019
1231e48
fix(types): modify like query
xjandwqz Aug 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,14 @@ modules.exports = function sequelizeAdditions(Sequelize) {
}
}

DataTypes.NEWTYPE = NEWTYPE;

// Mandatory, set key
DataTypes.NEWTYPE.prototype.key = DataTypes.NEWTYPE.key = 'NEWTYPE'


// Optional, disable escaping after stringifier. Not recommended.
// Warning: disables Sequelize protection against SQL injections
//DataTypes.NEWTYPE.escape = false
// DataTypes.NEWTYPE.escape = false

// For convenience
// `classToInvokable` allows you to use the datatype without `new`
Expand Down
4 changes: 3 additions & 1 deletion docs/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,13 @@ new Sequelize(..., {

### Connection Hooks

Sequelize provides two hooks that are executed immediately before and after a database connection is obtained:
Sequelize provides four hooks that are executed immediately before and after a database connection is obtained or released:

```text
beforeConnect(config)
afterConnect(connection, config)
beforeDisconnect(connection)
afterDisconnect(connection)
```

These hooks can be useful if you need to asynchronously obtain database credentials, or need to directly access the low-level database connection after it has been created.
Expand Down
4 changes: 3 additions & 1 deletion docs/migrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ module.exports = {
return queryInterface.bulkInsert('Users', [{
firstName: 'John',
lastName: 'Doe',
email: '[email protected]'
email: '[email protected]',
createdAt: Date.now(),
updatedAt: Date.now()
}], {});
},

Expand Down
4 changes: 2 additions & 2 deletions docs/models-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Foo.init({
}
},

// It is possible to add coments on columns for MySQL, PostgreSQL and MSSQL only
// It is possible to add comments on columns for MySQL, PostgreSQL and MSSQL only
commentMe: {
type: Sequelize.INTEGER,

Expand Down Expand Up @@ -710,7 +710,7 @@ User.init({}, {
}
},

// A BTREE index with a ordered field
// A BTREE index with an ordered field
{
name: 'title_index',
using: 'BTREE',
Expand Down
2 changes: 2 additions & 0 deletions docs/models-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The method `findOrCreate` can be used to check if a certain element already exis

Let's assume we have an empty database with a `User` model which has a `username` and a `job`.

`where` option will be appended to `defaults` for create case.

```js
User
.findOrCreate({where: {username: 'sdepold'}, defaults: {job: 'Technical Lead JavaScript'}})
Expand Down
4 changes: 3 additions & 1 deletion lib/dialects/abstract/connection-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,9 @@ class ConnectionManager {
* @returns {Promise}
*/
_disconnect(connection) {
return this.dialect.connectionManager.disconnect(connection);
return this.sequelize.runHooks('beforeDisconnect', connection)
.then(() => this.dialect.connectionManager.disconnect(connection))
.then(() => this.sequelize.runHooks('afterDisconnect', connection));
}

/**
Expand Down
60 changes: 33 additions & 27 deletions lib/dialects/abstract/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ class QueryGenerator {
// dialect name
this.dialect = options._dialect.name;
this._dialect = options._dialect;

// template config
this._templateSettings = require('lodash').runInContext().templateSettings;
}

extractTableDetails(tableName, options) {
Expand Down Expand Up @@ -111,9 +108,9 @@ class QueryGenerator {
const quotedTable = this.quoteTable(table);
const bindParam = options.bindParam === undefined ? this.bindParam(bind) : options.bindParam;
let query;
let valueQuery = `<%= tmpTable %>INSERT<%= ignoreDuplicates %> INTO ${quotedTable} (<%= attributes %>)<%= output %> VALUES (<%= values %>)<%= onConflictDoNothing %>`;
let emptyQuery = `<%= tmpTable %>INSERT<%= ignoreDuplicates %> INTO ${quotedTable}<%= output %><%= onConflictDoNothing %>`;
let outputFragment;
let valueQuery = '';
let emptyQuery = '';
let outputFragment = '';
let identityWrapperRequired = false;
let tmpTable = ''; //tmpTable declaration for trigger

Expand Down Expand Up @@ -180,25 +177,6 @@ class QueryGenerator {
if (this._dialect.supports.EXCEPTION && options.exception) {
// Not currently supported with bind parameters (requires output of multiple queries)
options.bindParam = false;
// Mostly for internal use, so we expect the user to know what he's doing!
// pg_temp functions are private per connection, so we never risk this function interfering with another one.
if (semver.gte(this.sequelize.options.databaseVersion, '9.2.0')) {
// >= 9.2 - Use a UUID but prefix with 'func_' (numbers first not allowed)
const delimiter = `$func_${uuidv4().replace(/-/g, '')}$`;

options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';
valueQuery = `${`CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response ${quotedTable}, OUT sequelize_caught_exception text) RETURNS RECORD AS ${delimiter}` +
' BEGIN '}${valueQuery} INTO response; EXCEPTION ${options.exception} END ${delimiter
} LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc()`;
} else {
options.exception = 'WHEN unique_violation THEN NULL;';
valueQuery = `CREATE OR REPLACE FUNCTION pg_temp.testfunc() RETURNS SETOF ${quotedTable} AS $body$ BEGIN RETURN QUERY ${valueQuery}; EXCEPTION ${options.exception} END; $body$ LANGUAGE plpgsql; SELECT * FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();`;
}
}

if (this._dialect.supports['ON DUPLICATE KEY'] && options.onDuplicate) {
valueQuery += ` ON DUPLICATE KEY ${options.onDuplicate}`;
emptyQuery += ` ON DUPLICATE KEY ${options.onDuplicate}`;
}

valueHash = Utils.removeNullValuesFromHash(valueHash, this.options.omitNull);
Expand Down Expand Up @@ -239,6 +217,31 @@ class QueryGenerator {
tmpTable
};

valueQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable} (${replacements.attributes})${replacements.output} VALUES (${replacements.values})${replacements.onConflictDoNothing}${valueQuery}`;
emptyQuery = `${tmpTable}INSERT${replacements.ignoreDuplicates} INTO ${quotedTable}${replacements.output}${replacements.onConflictDoNothing}${emptyQuery}`;

if (this._dialect.supports.EXCEPTION && options.exception) {
// Mostly for internal use, so we expect the user to know what he's doing!
// pg_temp functions are private per connection, so we never risk this function interfering with another one.
if (semver.gte(this.sequelize.options.databaseVersion, '9.2.0')) {
// >= 9.2 - Use a UUID but prefix with 'func_' (numbers first not allowed)
const delimiter = `$func_${uuidv4().replace(/-/g, '')}$`;

options.exception = 'WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL;';
valueQuery = `${`CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response ${quotedTable}, OUT sequelize_caught_exception text) RETURNS RECORD AS ${delimiter}` +
' BEGIN '}${valueQuery} INTO response; EXCEPTION ${options.exception} END ${delimiter
} LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc()`;
} else {
options.exception = 'WHEN unique_violation THEN NULL;';
valueQuery = `CREATE OR REPLACE FUNCTION pg_temp.testfunc() RETURNS SETOF ${quotedTable} AS $body$ BEGIN RETURN QUERY ${valueQuery}; EXCEPTION ${options.exception} END; $body$ LANGUAGE plpgsql; SELECT * FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();`;
}
}

if (this._dialect.supports['ON DUPLICATE KEY'] && options.onDuplicate) {
valueQuery += ` ON DUPLICATE KEY ${options.onDuplicate}`;
emptyQuery += ` ON DUPLICATE KEY ${options.onDuplicate}`;
}

query = `${replacements.attributes.length ? valueQuery : emptyQuery};`;
if (this._dialect.supports.finalTable) {
query = `SELECT * FROM FINAL TABLE(${ replacements.attributes.length ? valueQuery : emptyQuery });`;
Expand All @@ -247,7 +250,6 @@ class QueryGenerator {
query = `SET IDENTITY_INSERT ${quotedTable} ON; ${query} SET IDENTITY_INSERT ${quotedTable} OFF;`;
}

query = _.template(query, this._templateSettings)(replacements);
// Used by Postgres upsertQuery and calls to here with options.exception set to true
const result = { query };
if (options.bindParam !== false) {
Expand Down Expand Up @@ -2122,7 +2124,10 @@ class QueryGenerator {
}
}

if (key === Op.or || key === Op.and || key === Op.not) {
if (key === Op.or || key === Op.and || key === Op.not) {
if (key === Op.or) {
options.hasOr = true;
}
return this._whereGroupBind(key, value, options);
}

Expand Down Expand Up @@ -2531,6 +2536,7 @@ class QueryGenerator {
}
}

// Object.assign(QueryGenerator.prototype, require('../db2/query-generator/operators'));
Object.assign(QueryGenerator.prototype, require('./query-generator/operators'));
Object.assign(QueryGenerator.prototype, require('./query-generator/transaction'));

Expand Down
40 changes: 37 additions & 3 deletions lib/dialects/db2/data-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ module.exports = BaseTypes => {
BaseTypes.ENUM.types.db2 = ['VARCHAR'];
BaseTypes.REAL.types.db2 = ['REAL'];
BaseTypes.DOUBLE.types.db2 = ['DOUBLE'];
BaseTypes.JSON.types.db2 = ['JSON', 'JSONB'];
BaseTypes.GEOMETRY.types.db2 = false;

class BLOB extends BaseTypes.BLOB {
Expand Down Expand Up @@ -86,6 +87,29 @@ module.exports = BaseTypes => {
}
}

class JSONTYPE extends BaseTypes.JSON {
toSql() {
return 'CLOB(32672)';
}
_stringify(value) {
return JSON.stringify(value);
}

defaultType() {
return 'JSON';
}

static parse(value) {
return JSON.parse(value);
}
}

class JSONB extends BaseTypes.JSON {
defaultType() {
return 'JSONB';
}
}

class STRING extends BaseTypes.STRING {
toSql() {
if (!this._binary) {
Expand Down Expand Up @@ -134,7 +158,7 @@ module.exports = BaseTypes => {
}
if (len > 0 ) { this._length = len; }
} else { this._length = 32672; }
if ( this._length > 32672 )
if ( this._length > 4000 )
{
len = `CLOB(${ this._length })`;
}
Expand All @@ -149,7 +173,7 @@ module.exports = BaseTypes => {

class BOOLEAN extends BaseTypes.BOOLEAN {
toSql() {
return 'BOOLEAN';
return 'INTEGER';
}
_sanitize(value) {
if (value !== null && value !== undefined) {
Expand All @@ -171,6 +195,10 @@ module.exports = BaseTypes => {

return value;
}

defaultType() {
return 'BOOLEAN';
}
}
BOOLEAN.parse = BOOLEAN.prototype._sanitize;

Expand Down Expand Up @@ -213,6 +241,10 @@ module.exports = BaseTypes => {
value = new Date(moment.utc(value));
return value;
}

// defaultType () {
// return 'DATE'
// }
}

class DATEONLY extends BaseTypes.DATEONLY {
Expand Down Expand Up @@ -330,6 +362,8 @@ module.exports = BaseTypes => {
BIGINT,
REAL,
FLOAT,
TEXT
TEXT,
JSON: JSONTYPE,
JSONB
};
};
Loading