init source

This commit is contained in:
Le Viet
2022-03-07 22:07:57 +07:00
parent e4376f3777
commit 8aba590a8d
11240 changed files with 1012977 additions and 0 deletions
@@ -0,0 +1,87 @@
/**
* Quote helpers implement quote ability for all dialects.
* These are basic block of query building
*
* Its better to implement all dialect implementation together here. Which will allow
* even abstract generator to use them by just specifying dialect type.
*
* Defining these helpers in each query dialect will leave
* code in dual dependency of abstract <-> specific dialect
*/
'use strict';
const Utils = require('../../../../utils');
/**
* list of reserved words in PostgreSQL 10
* source: https://www.postgresql.org/docs/10/static/sql-keywords-appendix.html
*
* @private
*/
const postgresReservedWords = 'all,analyse,analyze,and,any,array,as,asc,asymmetric,authorization,binary,both,case,cast,check,collate,collation,column,concurrently,constraint,create,cross,current_catalog,current_date,current_role,current_schema,current_time,current_timestamp,current_user,default,deferrable,desc,distinct,do,else,end,except,false,fetch,for,foreign,freeze,from,full,grant,group,having,ilike,in,initially,inner,intersect,into,is,isnull,join,lateral,leading,left,like,limit,localtime,localtimestamp,natural,not,notnull,null,offset,on,only,or,order,outer,overlaps,placing,primary,references,returning,right,select,session_user,similar,some,symmetric,table,tablesample,then,to,trailing,true,union,unique,user,using,variadic,verbose,when,where,window,with'.split(',');
/**
*
* @param {string} dialect Dialect name
* @param {string} identifier Identifier to quote
* @param {Object} [options]
* @param {boolean} [options.force=false]
* @param {boolean} [options.quoteIdentifiers=true]
*
* @returns {string}
* @private
*/
function quoteIdentifier(dialect, identifier, options) {
if (identifier === '*') return identifier;
options = Utils.defaults(options || {}, {
force: false,
quoteIdentifiers: true
});
switch (dialect) {
case 'sqlite':
case 'mariadb':
case 'mysql':
return Utils.addTicks(Utils.removeTicks(identifier, '`'), '`');
case 'postgres':
const rawIdentifier = Utils.removeTicks(identifier, '"');
if (
options.force !== true &&
options.quoteIdentifiers === false &&
!identifier.includes('.') &&
!identifier.includes('->') &&
!postgresReservedWords.includes(rawIdentifier.toLowerCase())
) {
// In Postgres, if tables or attributes are created double-quoted,
// they are also case sensitive. If they contain any uppercase
// characters, they must always be double-quoted. This makes it
// impossible to write queries in portable SQL if tables are created in
// this way. Hence, we strip quotes if we don't want case sensitivity.
return rawIdentifier;
}
return Utils.addTicks(rawIdentifier, '"');
case 'mssql':
return `[${identifier.replace(/[[\]']+/g, '')}]`;
default:
throw new Error(`Dialect "${dialect}" is not supported`);
}
}
module.exports.quoteIdentifier = quoteIdentifier;
/**
* Test if a give string is already quoted
*
* @param {string} identifier
*
* @returns {boolean}
* @private
*/
function isIdentifierQuoted(identifier) {
return /^\s*(?:([`"'])(?:(?!\1).|\1{2})*\1\.?)+\s*$/i.test(identifier);
}
module.exports.isIdentifierQuoted = isIdentifierQuoted;
@@ -0,0 +1,84 @@
'use strict';
const _ = require('lodash');
const Op = require('../../../operators');
const Utils = require('../../../utils');
const OperatorHelpers = {
OperatorMap: {
[Op.eq]: '=',
[Op.ne]: '!=',
[Op.gte]: '>=',
[Op.gt]: '>',
[Op.lte]: '<=',
[Op.lt]: '<',
[Op.not]: 'IS NOT',
[Op.is]: 'IS',
[Op.in]: 'IN',
[Op.notIn]: 'NOT IN',
[Op.like]: 'LIKE',
[Op.notLike]: 'NOT LIKE',
[Op.iLike]: 'ILIKE',
[Op.notILike]: 'NOT ILIKE',
[Op.startsWith]: 'LIKE',
[Op.endsWith]: 'LIKE',
[Op.substring]: 'LIKE',
[Op.regexp]: '~',
[Op.notRegexp]: '!~',
[Op.iRegexp]: '~*',
[Op.notIRegexp]: '!~*',
[Op.between]: 'BETWEEN',
[Op.notBetween]: 'NOT BETWEEN',
[Op.overlap]: '&&',
[Op.contains]: '@>',
[Op.contained]: '<@',
[Op.adjacent]: '-|-',
[Op.strictLeft]: '<<',
[Op.strictRight]: '>>',
[Op.noExtendRight]: '&<',
[Op.noExtendLeft]: '&>',
[Op.any]: 'ANY',
[Op.all]: 'ALL',
[Op.and]: ' AND ',
[Op.or]: ' OR ',
[Op.col]: 'COL',
[Op.placeholder]: '$$PLACEHOLDER$$'
},
OperatorsAliasMap: {},
setOperatorsAliases(aliases) {
if (!aliases || _.isEmpty(aliases)) {
this.OperatorsAliasMap = false;
} else {
this.OperatorsAliasMap = Object.assign({}, aliases);
}
},
_replaceAliases(orig) {
const obj = {};
if (!this.OperatorsAliasMap) {
return orig;
}
Utils.getOperators(orig).forEach(op => {
const item = orig[op];
if (_.isPlainObject(item)) {
obj[op] = this._replaceAliases(item);
} else {
obj[op] = item;
}
});
_.forOwn(orig, (item, prop) => {
prop = this.OperatorsAliasMap[prop] || prop;
if (_.isPlainObject(item)) {
item = this._replaceAliases(item);
}
obj[prop] = item;
});
return obj;
}
};
module.exports = OperatorHelpers;
@@ -0,0 +1,80 @@
'use strict';
const uuidv4 = require('uuid/v4');
const TransactionQueries = {
/**
* Returns a query that sets the transaction isolation level.
*
* @param {string} value The isolation level.
* @param {Object} options An object with options.
* @returns {string} The generated sql query.
* @private
*/
setIsolationLevelQuery(value, options) {
if (options.parent) {
return;
}
return `SET TRANSACTION ISOLATION LEVEL ${value};`;
},
generateTransactionId() {
return uuidv4();
},
/**
* Returns a query that starts a transaction.
*
* @param {Transaction} transaction
* @returns {string} The generated sql query.
* @private
*/
startTransactionQuery(transaction) {
if (transaction.parent) {
// force quoting of savepoint identifiers for postgres
return `SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;
}
return 'START TRANSACTION;';
},
deferConstraintsQuery() {},
setConstraintQuery() {},
setDeferredQuery() {},
setImmediateQuery() {},
/**
* Returns a query that commits a transaction.
*
* @param {Transaction} transaction An object with options.
* @returns {string} The generated sql query.
* @private
*/
commitTransactionQuery(transaction) {
if (transaction.parent) {
return;
}
return 'COMMIT;';
},
/**
* Returns a query that rollbacks a transaction.
*
* @param {Transaction} transaction
* @returns {string} The generated sql query.
* @private
*/
rollbackTransactionQuery(transaction) {
if (transaction.parent) {
// force quoting of savepoint identifiers for postgres
return `ROLLBACK TO SAVEPOINT ${this.quoteIdentifier(transaction.name, true)};`;
}
return 'ROLLBACK;';
}
};
module.exports = TransactionQueries;