ts-sql-query
Version:
Type-safe SQL query builder like QueryDSL or JOOQ in Java or Linq in .Net for TypeScript with MariaDB, MySql, Oracle, PostgreSql, Sqlite and SqlServer support.
850 lines (849 loc) • 38.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractConnection = void 0;
const ITableOrView_1 = require("../utils/ITableOrView");
const InsertQueryBuilder_1 = require("../queryBuilders/InsertQueryBuilder");
const UpdateQueryBuilder_1 = require("../queryBuilders/UpdateQueryBuilder");
const DeleteQueryBuilder_1 = require("../queryBuilders/DeleteQueryBuilder");
const values_1 = require("../expressions/values");
const ValueSourceImpl_1 = require("../internal/ValueSourceImpl");
const Default_1 = require("../expressions/Default");
const SelectQueryBuilder_1 = require("../queryBuilders/SelectQueryBuilder");
const chained_error_1 = require("chained-error");
const FragmentQueryBuilder_1 = require("../queryBuilders/FragmentQueryBuilder");
const attachSource_1 = require("../utils/attachSource");
const symbols_1 = require("../utils/symbols");
const PromiseProvider_1 = require("../utils/PromiseProvider");
const DynamicConditionBuilder_1 = require("../queryBuilders/DynamicConditionBuilder");
const RawFragmentImpl_1 = require("../internal/RawFragmentImpl");
const ComposeSliptQueryBuilder_1 = require("../queryBuilders/ComposeSliptQueryBuilder");
class AbstractConnection {
constructor(queryRunner, sqlBuilder) {
this.allowEmptyString = false;
this.defaultTypeAdapter = this; // transform protected methods to public
sqlBuilder._defaultTypeAdapter = this.defaultTypeAdapter;
this.__sqlBuilder = sqlBuilder;
this.queryRunner = queryRunner;
sqlBuilder._queryRunner = queryRunner;
sqlBuilder._connectionConfiguration = this; // transform protected methods to public
}
pushTransactionStack() {
if (this.onCommit || this.onCommitStack || this.onRollback || this.onRollbackStack || this.beforeCommit || this.beforeCommitStack || this.transactionMetadata || this.transactionMetadataStack) {
if (!this.beforeCommitStack) {
this.beforeCommitStack = [];
}
this.beforeCommitStack.push(this.beforeCommit || undefined);
this.beforeCommit = undefined;
if (!this.onCommitStack) {
this.onCommitStack = [];
}
this.onCommitStack.push(this.onCommit || undefined);
this.onCommit = undefined;
if (!this.onRollbackStack) {
this.onRollbackStack = [];
}
this.onRollbackStack.push(this.onRollback || undefined);
this.onRollback = undefined;
if (!this.transactionMetadataStack) {
this.transactionMetadataStack = [];
}
this.transactionMetadataStack.push(this.transactionMetadata || undefined);
this.transactionMetadata = undefined;
}
}
popTransactionStack() {
if (this.beforeCommitStack) {
this.beforeCommit = this.beforeCommitStack.pop();
if (this.beforeCommitStack.length <= 0) {
this.beforeCommitStack = undefined;
}
}
else {
this.beforeCommit = undefined;
}
if (this.onCommitStack) {
this.onCommit = this.onCommitStack.pop();
if (this.onCommitStack.length <= 0) {
this.onCommitStack = undefined;
}
}
else {
this.onCommit = undefined;
}
if (this.onRollbackStack) {
this.onRollback = this.onRollbackStack.pop();
if (this.onRollbackStack.length <= 0) {
this.onRollbackStack = undefined;
}
}
else {
this.onRollback = undefined;
}
if (this.transactionMetadataStack) {
this.transactionMetadata = this.transactionMetadataStack.pop();
if (this.transactionMetadataStack.length <= 0) {
this.transactionMetadataStack = undefined;
}
}
else {
this.transactionMetadata = undefined;
}
}
executeBeforeNextCommit(fn) {
if (!this.queryRunner.isMocked() && !this.isTransactionActive()) {
throw new Error('There is no open transaction');
}
if (this.onRollback === null) {
throw new Error('You cannot call executeBeforeNextCommit inside an executeAfterNextRollback');
}
if (this.onCommit === null) {
throw new Error('You cannot call executeBeforeNextCommit inside an executeAfterNextCommit');
}
if (this.beforeCommit === null) {
throw new Error('You cannot call executeBeforeNextCommit inside an executeBeforeNextCommit');
}
if (!this.beforeCommit) {
this.beforeCommit = [];
}
this.beforeCommit.push(fn);
}
executeAfterNextCommit(fn) {
if (!this.queryRunner.isMocked() && !this.isTransactionActive()) {
throw new Error('There is no open transaction');
}
if (this.onRollback === null) {
throw new Error('You cannot call executeAfterNextCommit inside an executeAfterNextRollback');
}
if (this.onCommit === null) {
throw new Error('You cannot call executeAfterNextCommit inside an executeAfterNextCommit');
}
if (!this.onCommit) {
this.onCommit = [];
}
this.onCommit.push(fn);
}
executeAfterNextRollback(fn) {
if (!this.queryRunner.isMocked() && !this.isTransactionActive()) {
throw new Error('There is no open transaction');
}
if (this.onRollback === null) {
throw new Error('You cannot call executeAfterNextRollback inside an executeAfterNextRollback');
}
if (!this.onRollback) {
this.onRollback = [];
}
this.onRollback.push(fn);
}
getTransactionMetadata() {
if (!this.queryRunner.isMocked() && !this.isTransactionActive()) {
throw new Error('There is no open transaction');
}
if (!this.transactionMetadata) {
this.transactionMetadata = new Map();
}
return this.transactionMetadata;
}
transaction(fn) {
const source = new Error('Transaction executed at');
try {
return this.queryRunner.executeInTransaction(() => {
this.pushTransactionStack();
try {
const result = fn();
if ((0, PromiseProvider_1.isPromise)(result)) {
return result.then((fnResult) => {
const beforeCommit = this.beforeCommit;
this.beforeCommit = null;
return (0, PromiseProvider_1.callDeferredFunctionsStoppingOnError)('before next commit', beforeCommit, fnResult, source);
});
}
else if (this.beforeCommit) {
throw new Error('before next commit not supported with high level transaction that return an array');
}
return result;
}
catch (e) {
// TODO: remove when no more array in transaction
this.popTransactionStack();
throw e;
}
}, this.queryRunner).then((result) => {
const onCommit = this.onCommit;
this.onCommit = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next commit', onCommit, result, source);
}, (e) => {
const throwError = (0, attachSource_1.attachTransactionSource)(new chained_error_1.default(e), source);
const onRollback = this.onRollback;
this.onRollback = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next rollback', onRollback, undefined, source, e, throwError);
}).finally(() => {
this.popTransactionStack();
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
beginTransaction() {
const source = new Error('Query executed at');
try {
return this.queryRunner.executeBeginTransaction().then((result) => {
this.pushTransactionStack();
return result;
}, (e) => {
throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
commit() {
const source = new Error('Query executed at');
const beforeCommit = this.beforeCommit;
if (beforeCommit) {
this.beforeCommit = null;
const result = (0, PromiseProvider_1.callDeferredFunctionsStoppingOnError)('before next commit', beforeCommit, undefined, source);
if ((0, PromiseProvider_1.isPromise)(result)) {
return result.then(() => {
try {
return this.queryRunner.executeCommit().then(() => {
const onCommit = this.onCommit;
this.onCommit = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next commit', onCommit, undefined, source);
}, (e) => {
// Transaction only closed when commit successful, in case of error there is still an open transaction
// No rollback yet, then no executeAfterNextRollback will be executed
throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}).then(() => {
this.popTransactionStack();
});
}
}
try {
return this.queryRunner.executeCommit().then(() => {
const onCommit = this.onCommit;
this.onCommit = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next commit', onCommit, undefined, source);
}, (e) => {
// Transaction only closed when commit successful, in case of error there is still an open transaction
// No rollback yet, then no executeAfterNextRollback will be executed
throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
}).then(() => {
this.popTransactionStack();
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
rollback() {
const source = new Error('Query executed at');
try {
return this.queryRunner.executeRollback().then(() => {
const onRollback = this.onRollback;
this.onRollback = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next rollback', onRollback, undefined, source);
}, (e) => {
const throwError = (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
const onRollback = this.onRollback;
this.onRollback = null;
return (0, PromiseProvider_1.callDeferredFunctions)('after next rollback', onRollback, undefined, source, e, throwError);
}).finally(() => {
this.popTransactionStack();
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
isTransactionActive() {
return this.queryRunner.isTransactionActive();
}
insertInto(table) {
return new InsertQueryBuilder_1.InsertQueryBuilder(this.__sqlBuilder, table);
}
update(table) {
return new UpdateQueryBuilder_1.UpdateQueryBuilder(this.__sqlBuilder, table, false);
}
updateAllowingNoWhere(table) {
return new UpdateQueryBuilder_1.UpdateQueryBuilder(this.__sqlBuilder, table, true);
}
deleteFrom(table) {
return new DeleteQueryBuilder_1.DeleteQueryBuilder(this.__sqlBuilder, table, false);
}
deleteAllowingNoWhereFrom(table) {
return new DeleteQueryBuilder_1.DeleteQueryBuilder(this.__sqlBuilder, table, true);
}
selectFrom(table) {
return new SelectQueryBuilder_1.SelectQueryBuilder(this.__sqlBuilder, [table], false); // cast to any to improve typescript performace
}
selectDistinctFrom(table) {
return new SelectQueryBuilder_1.SelectQueryBuilder(this.__sqlBuilder, [table], true); // cast to any to improve typescript performace
}
selectFromNoTable() {
return new SelectQueryBuilder_1.SelectQueryBuilder(this.__sqlBuilder, [], false); // cast to any to improve typescript performace
}
subSelectUsing(...tables) {
const result = new SelectQueryBuilder_1.SelectQueryBuilder(this.__sqlBuilder, [], false);
result.__subSelectUsing = tables;
return result; // cast to any to improve typescript performace
}
subSelectDistinctUsing(...tables) {
const result = new SelectQueryBuilder_1.SelectQueryBuilder(this.__sqlBuilder, [], false);
result.__subSelectUsing = tables;
return result; // cast to any to improve typescript performace
}
default() {
return new Default_1.DefaultImpl();
}
pi() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_pi', 'double', 'double', 'required', undefined);
}
random() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_random', 'double', 'double', 'required', undefined);
}
currentDate() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_currentDate', 'localDate', 'localDate', 'required', undefined);
}
currentTime() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_currentTime', 'localTime', 'localTime', 'required', undefined);
}
currentDateTime() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_currentTimestamp', 'localDateTime', 'localDateTime', 'required', undefined);
}
currentTimestamp() {
return new ValueSourceImpl_1.SqlOperationStatic0ValueSource('_currentTimestamp', 'localDateTime', 'localDateTime', 'required', undefined);
}
const(value, type, adapter, adapter2) {
if (typeof adapter === 'string') {
return new ValueSourceImpl_1.SqlOperationConstValueSource(value, type, adapter, 'required', adapter2);
}
return new ValueSourceImpl_1.SqlOperationConstValueSource(value, type, type, 'required', adapter);
}
optionalConst(value, type, adapter, adapter2) {
if (typeof adapter === 'string') {
return new ValueSourceImpl_1.SqlOperationConstValueSource(value, type, adapter, 'optional', adapter2);
}
return new ValueSourceImpl_1.SqlOperationConstValueSource(value, type, type, 'optional', adapter);
}
true() {
return new ValueSourceImpl_1.SqlOperationStaticBooleanValueSource('_true');
}
false() {
return new ValueSourceImpl_1.SqlOperationStaticBooleanValueSource('_false');
}
exists(select) {
return new ValueSourceImpl_1.SqlOperationStatic1ValueSource('_exists', select, 'boolean', 'boolean', 'required', undefined);
}
notExists(select) {
return new ValueSourceImpl_1.SqlOperationStatic1ValueSource('_notExists', select, 'boolean', 'boolean', 'required', undefined);
}
executeProcedure(procedureName, params) {
try {
const queryParams = [];
const query = this.__sqlBuilder._buildCallProcedure(queryParams, procedureName, params);
const source = new Error('Query executed at');
(0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, params);
return this.__sqlBuilder._queryRunner.executeProcedure(query, queryParams).catch((e) => {
throw new chained_error_1.default(e);
}).catch((e) => {
throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
executeFunction(functionName, params, returnType, required, adapter, adapter2) {
try {
if (typeof adapter === 'string') {
returnType = required;
required = adapter;
}
else {
adapter2 = adapter;
}
const queryParams = [];
const query = this.__sqlBuilder._buildCallFunction(queryParams, functionName, params);
const source = new Error('Query executed at');
(0, ComposeSliptQueryBuilder_1.__setQueryMetadata)(source, params);
return this.__sqlBuilder._queryRunner.executeFunction(query, queryParams).then((value) => {
let result;
if (adapter2) {
result = adapter2.transformValueFromDB(value, returnType, this.__sqlBuilder._defaultTypeAdapter);
}
else {
result = this.__sqlBuilder._defaultTypeAdapter.transformValueFromDB(value, returnType);
}
if (result === null || result === undefined) {
if (required !== 'optional') {
throw new Error('Expected a value as result of the function `' + functionName + '`, but null or undefined value was found');
}
}
return result;
}).catch((e) => {
throw new chained_error_1.default(e);
}).catch((e) => {
throw (0, attachSource_1.attachSource)(new chained_error_1.default(e), source);
});
}
catch (e) {
throw new chained_error_1.default(e);
}
}
fragmentWithType(type, required, adapter, adapter2) {
if (typeof adapter === 'string') {
type = required;
required = adapter;
}
else {
adapter2 = adapter;
}
return new FragmentQueryBuilder_1.FragmentQueryBuilder(type, type, required, adapter2);
}
arg(type, required, adapter, adapter2) {
if (typeof adapter === 'string') {
return new values_1.Argument(type, adapter, required, 'combined', adapter2);
}
else {
return new values_1.Argument(type, type, required, 'combined', adapter);
}
}
valueArg(type, required, adapter, adapter2) {
if (typeof adapter === 'string') {
return new values_1.Argument(type, adapter, required, 'value', adapter2);
}
else {
return new values_1.Argument(type, type, required, 'value', adapter);
}
}
buildFragmentWithArgs(...args) {
return new FragmentQueryBuilder_1.FragmentFunctionBuilder(args);
}
buildFragmentWithArgsIfValue(...args) {
return new FragmentQueryBuilder_1.FragmentFunctionBuilderIfValue(this, args); // make this protected fields as public
}
buildFragmentWithMaybeOptionalArgs(...args) {
return new FragmentQueryBuilder_1.FragmentFunctionBuilderMaybeOptional(this, args);
}
rawFragment(sql, ...params) {
return new RawFragmentImpl_1.RawFragmentImpl(sql, params);
}
createTableOrViewCustomization(fn) {
return (tableOrView, name, ...params) => {
const as = (0, ITableOrView_1.__getTableOrViewPrivate)(tableOrView).__as;
const result = tableOrView.as(as);
const table = new ValueSourceImpl_1.TableOrViewRawFragmentValueSource(result, '_rawFragmentTableName');
const alias = new ValueSourceImpl_1.TableOrViewRawFragmentValueSource(result, '_rawFragmentTableAlias');
const template = fn(table, alias, ...params);
const p = (0, ITableOrView_1.__getTableOrViewPrivate)(result);
p.__template = template;
p.__customizationName = name;
return result;
};
}
noValueBoolean() {
return new ValueSourceImpl_1.SqlOperationValueSourceIfValueAlwaysNoop();
}
dynamicBooleanExpressionUsing(..._tables) {
return new ValueSourceImpl_1.SqlOperationValueSourceIfValueAlwaysNoop();
}
countAll() {
return new ValueSourceImpl_1.AggregateFunctions0ValueSource('_countAll', 'int', 'int', 'required', undefined);
}
count(value) {
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_count', value, 'int', 'int', 'required', undefined);
}
countDistinct(value) {
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_countDistinct', value, 'int', 'int', 'required', undefined);
}
max(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return (new ValueSourceImpl_1.AggregateFunctions1ValueSource('_max', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter));
}
min(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return (new ValueSourceImpl_1.AggregateFunctions1ValueSource('_min', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter));
}
sum(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_sum', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
sumDistinct(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_sumDistinct', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
average(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_average', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
averageDistinct(value) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1ValueSource('_averageDistinct', value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
stringConcat(value, separator) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1or2ValueSource('_stringConcat', separator, value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
stringConcatDistinct(value, separator) {
const valuePrivate = (0, values_1.__getValueSourcePrivate)(value);
return new ValueSourceImpl_1.AggregateFunctions1or2ValueSource('_stringConcatDistinct', separator, value, valuePrivate.__valueType, valuePrivate.__valueTypeName, 'optional', valuePrivate.__typeAdapter);
}
aggregateAsArray(columns) {
return new ValueSourceImpl_1.AggregateValueAsArrayValueSource(columns, 'InnerResultObject', 'required', false);
}
aggregateAsArrayOfOneColumn(value) {
return new ValueSourceImpl_1.AggregateValueAsArrayValueSource(value, 'InnerResultObject', 'required', false);
}
aggregateAsArrayDistinct(columns) {
return new ValueSourceImpl_1.AggregateValueAsArrayValueSource(columns, 'InnerResultObject', 'required', true);
}
aggregateAsArrayOfOneColumnDistinct(value) {
return new ValueSourceImpl_1.AggregateValueAsArrayValueSource(value, 'InnerResultObject', 'required', true);
}
dynamicConditionFor(definition, extension) {
return new DynamicConditionBuilder_1.DynamicConditionBuilder(this.__sqlBuilder, definition, extension);
}
transformValueFromDB(value, type) {
if (value === undefined) {
return null;
}
if (value === null) {
return null;
}
if (value === '' && !this.allowEmptyString) {
return null;
}
switch (type) {
case 'boolean':
if (typeof value === 'boolean') {
return value;
}
if (typeof value === 'number') {
return !!value;
}
if (typeof value === 'bigint') {
return !!value;
}
throw new Error('Invalid boolean value received from the db: ' + value);
case 'int':
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
throw new Error('Invalid int value received from the db: ' + value);
}
return value;
}
if (typeof value === 'string') {
if (!/^(-?\d+)$/g.test(value)) {
throw new Error('Invalid int value received from the db: ' + value);
}
const result = +value;
if (!Number.isSafeInteger(result)) {
throw new Error('Unnoticed precition lost transforming a string to int number. Value: ' + value);
}
return result;
}
if (typeof value === 'bigint') {
const result = Number(value);
if (!Number.isSafeInteger(result)) {
throw new Error('Unnoticed precition lost transforming a bigint to int number. Value: ' + value);
}
return result;
}
throw new Error('Invalid int value received from the db: ' + value);
case 'stringInt':
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
throw new Error('Invalid stringInt value received from the db: ' + value);
}
return value;
}
if (typeof value === 'string') {
if (!/^-?\d+$/g.test(value)) {
throw new Error('Invalid stringInt value received from the db: ' + value);
}
return value;
}
if (typeof value === 'bigint') {
const result = Number(value);
if (!Number.isSafeInteger(result)) {
return '' + value;
}
return result;
}
throw new Error('Invalid stringInt value received from the db: ' + value);
case 'bigint':
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
throw new Error('Invalid bigint value received from the db: ' + value);
}
return BigInt(value);
}
if (typeof value === 'string') {
try {
return BigInt(value);
}
catch {
throw new Error('Invalid bigint value received from the db: ' + value);
}
}
if (typeof value === 'bigint') {
return value;
}
throw new Error('Invalid int value received from the db: ' + value);
case 'double':
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
if (!/^(-?\d+(\.\d+)?|NaN|-?Infinity)$/g.test(value)) {
throw new Error('Invalid double value received from the db: ' + value);
}
const result = +value;
return result;
}
if (typeof value === 'bigint') {
return Number(value);
}
throw new Error('Invalid double value received from the db: ' + value);
case 'stringDouble':
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
if (!/^(-?\d+(\.\d+)?|NaN|-?Infinity)$/g.test(value)) {
throw new Error('Invalid stringDouble value received from the db: ' + value);
}
return value;
}
if (typeof value === 'bigint') {
const result = Number(value);
if (!Number.isSafeInteger(result)) {
return '' + value;
}
return result;
}
throw new Error('Invalid stringDouble value received from the db: ' + value);
case 'string':
if (typeof value === 'string') {
return value;
}
throw new Error('Invalid string value received from the db: ' + value);
case 'uuid':
if (typeof value === 'string') {
return value;
}
throw new Error('Invalid uuid value received from the db: ' + value);
case 'localDate': {
let result;
if (value instanceof Date) {
// This time fix works in almost every timezone (from -10 to +13, but not +14, -11, -12, almost uninhabited)
result = new Date(Date.UTC(value.getFullYear(), value.getMonth(), value.getDate()));
result.setUTCMinutes(600);
}
else if (typeof value === 'string') {
result = new Date(value + ' 00:00'); // If time is omited, UTC timezone will be used instead the local one
// This time fix works in almost every timezone (from -10 to +13, but not +14, -11, -12, almost uninhabited)
result = new Date(Date.UTC(result.getFullYear(), result.getMonth(), result.getDate()));
result.setUTCMinutes(600);
}
else {
throw new Error('Invalid localDate value received from the db: ' + value);
}
if (isNaN(result.getTime())) {
throw new Error('Invalid localDate value received from the db: ' + value);
}
result.___type___ = 'localDate';
return result;
}
case 'localTime': {
let result;
if (value instanceof Date) {
result = value;
}
else if (typeof value === 'string') {
result = new Date('1970-01-01 ' + value);
}
else {
throw new Error('Invalid localTime value received from the db: ' + value);
}
if (isNaN(result.getTime())) {
throw new Error('Invalid localTime value received from the db: ' + value);
}
result.___type___ = 'localTime';
return result;
}
case 'localDateTime': {
let result;
if (value instanceof Date) {
result = value;
}
else if (typeof value === 'string') {
result = new Date(value);
}
else {
throw new Error('Invalid localDateTime value received from the db: ' + value);
}
if (isNaN(result.getTime())) {
throw new Error('Invalid localDateTime value received from the db: ' + value);
}
result.___type___ = 'LocalDateTime';
return result;
}
case 'aggregatedArray': {
throw new Error('This would not happened, something went wrong handling aggregate arrays coming from the database');
}
default:
return value;
}
}
transformValueToDB(value, type) {
if (value === undefined) {
return null;
}
if (value === null) {
return null;
}
if (value === '' && !this.allowEmptyString) {
return null;
}
switch (type) {
case 'boolean':
if (typeof value === 'boolean') {
return value;
}
throw new Error('Invalid boolean value to send to the db: ' + value);
case 'int':
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
throw new Error('Invalid int value to send to the db: ' + value);
}
return value;
}
throw new Error('Invalid int value to send to the db: ' + value);
case 'bigint':
if (typeof value === 'bigint') {
return value;
}
throw new Error('Invalid int value to send to the db: ' + value);
case 'stringInt':
if (typeof value === 'number') {
if (!Number.isInteger(value)) {
throw new Error('Invalid stringInt value to send to the db: ' + value);
}
return value;
}
if (typeof value === 'string') {
if (!/^-?\d+$/g.test(value)) {
throw new Error('Invalid stringInt value to send to the db: ' + value);
}
return value;
}
throw new Error('Invalid stringInt value to send to the db: ' + value);
case 'double':
if (typeof value === 'number') {
return value;
}
throw new Error('Invalid double value to send to the db: ' + value);
case 'stringDouble':
if (typeof value === 'number') {
return value;
}
if (typeof value === 'string') {
if (!/^(-?\d+(\.\d+)?|NaN|-?Infinity)$/g.test(value)) {
throw new Error('Invalid stringDouble value to send to the db: ' + value);
}
return value;
}
throw new Error('Invalid stringDouble value to send to the db: ' + value);
case 'string':
if (typeof value === 'string') {
return value;
}
throw new Error('Invalid string value to send to the db: ' + value);
case 'uuid':
if (typeof value === 'string') {
return value;
}
throw new Error('Invalid uuid value to send to the db: ' + value);
case 'localDate':
if (value instanceof Date && !isNaN(value.getTime())) {
return value;
}
throw new Error('Invalid localDate value to send to the db: ' + value);
case 'localTime':
if (value instanceof Date && !isNaN(value.getTime())) {
let result = '';
if (value.getHours() > 9) {
result += value.getHours();
}
else {
result += '0' + value.getHours();
}
result += ':';
if (value.getMinutes() > 9) {
result += value.getMinutes();
}
else {
result += '0' + value.getMinutes();
}
result += ':';
if (value.getSeconds() > 9) {
result += value.getSeconds();
}
else {
result += '0' + value.getSeconds();
}
if (value.getMilliseconds() > 0) {
result += '.';
if (value.getMilliseconds() > 99) {
result += value.getMilliseconds();
}
else if (value.getMilliseconds() > 9) {
result += '0' + value.getMilliseconds();
}
else {
result += '00' + value.getMilliseconds();
}
}
return result;
}
throw new Error('Invalid localTime value to send to the db: ' + value);
case 'localDateTime':
if (value instanceof Date && !isNaN(value.getTime())) {
return value;
}
throw new Error('Invalid localDateTime value to send to the db: ' + value);
case 'aggregatedArray': {
throw new Error('This would not happened, something went wrong handling aggregate arrays, aggregated arrays cannot be sent to the database');
}
default:
return value;
}
}
transformPlaceholder(placeholder, _type, _forceTypeCast, _valueSentToDB) {
return placeholder;
}
isReservedKeyword(word) {
return this.__sqlBuilder._isReservedKeyword(word);
}
forceAsIdentifier(identifier) {
return this.__sqlBuilder._forceAsIdentifier(identifier);
}
escape(identifier, strict) {
if (strict && !/^[a-zA-Z_][a-zA-Z0-9_]+$/.test(identifier)) {
return this.forceAsIdentifier(identifier);
}
if (this.isReservedKeyword(identifier) || identifier.indexOf(' ') >= 0) {
return this.forceAsIdentifier(identifier);
}
return identifier;
}
}
exports.AbstractConnection = AbstractConnection;