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.
191 lines (190 loc) • 7.17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MssqlPoolQueryRunner = void 0;
const mssql_1 = require("mssql");
const PromiseBasedQueryRunner_1 = require("./PromiseBasedQueryRunner");
class MssqlPoolQueryRunner extends PromiseBasedQueryRunner_1.PromiseBasedQueryRunner {
constructor(pool) {
super();
this.predefinedTypes = {
boolean: mssql_1.TYPES.Bit,
stringInt: mssql_1.TYPES.BigInt,
int: mssql_1.TYPES.Int,
bigint: mssql_1.TYPES.BigInt,
stringDouble: mssql_1.TYPES.Float,
double: mssql_1.TYPES.Real,
string: mssql_1.TYPES.NVarChar,
uuid: mssql_1.TYPES.UniqueIdentifier,
localDate: mssql_1.TYPES.Date,
localTime: mssql_1.TYPES.Time,
localDateTime: mssql_1.TYPES.DateTime2,
customInt: mssql_1.TYPES.BigInt,
customDouble: mssql_1.TYPES.Float,
customUuid: mssql_1.TYPES.UniqueIdentifier,
customLocalDate: mssql_1.TYPES.Date,
customLocalTime: mssql_1.TYPES.Time,
customLocalDateTime: mssql_1.TYPES.DateTime2
};
this.pool = pool;
this.database = 'sqlServer';
}
useDatabase(database) {
if (database !== 'sqlServer') {
throw new Error('Unsupported database: ' + database + '. MssqlPoolQueryRunner only supports sqlServer databases');
}
}
getNativeRunner() {
return this.pool;
}
getCurrentNativeTransaction() {
return this.transaction;
}
execute(fn) {
return fn(this.pool, this.transaction);
}
executeQueryReturning(query, params) {
const req = this.request();
for (var i = 0, length = params.length; i < length; i++) {
req.input('' + i, { type: this.getType(params, i) }, params[i]);
}
return req.query(query).then((result) => {
if (!result.recordset) {
return [];
}
return result.recordset;
});
}
executeMutation(query, params) {
const req = this.request();
for (var i = 0, length = params.length; i < length; i++) {
req.input('' + i, { type: this.getType(params, i) }, params[i]);
}
return req.query(query).then((result) => {
return result.rowsAffected[0];
});
}
executeBeginTransaction() {
if (this.transaction) {
return Promise.reject(new Error('Already in an transaction, you can only use one transaction'));
}
this.transaction = this.pool.transaction();
return this.transaction.begin().then(() => undefined);
}
executeCommit() {
if (!this.transaction) {
return Promise.reject(new Error('Not in an transaction, you cannot commit the transaction'));
}
return this.transaction.commit().then(() => {
// Transaction count only modified when commit successful, in case of error there is still an open transaction
this.transaction = undefined;
});
}
executeRollback() {
if (!this.transaction) {
return Promise.reject(new Error('Not in an transaction, you cannot rollback the transaction'));
}
return this.transaction.rollback().finally(() => {
this.transaction = undefined;
});
}
isTransactionActive() {
return !!this.transaction;
}
addParam(params, value) {
const index = params.length;
params.push(value);
return '@' + index;
}
request() {
if (this.transaction) {
return this.transaction.request();
}
else {
return this.pool.request();
}
}
getType(params, index) {
const definedType = params['@' + index];
if (definedType) {
const type = this.predefinedTypes[definedType];
if (type) {
return type;
}
}
return this.inferType(params[index]);
}
inferType(value) {
// Inspired by: https://github.com/Hypermediaisobar-admin/node-any-db-mssql/blob/master/index.js
if (value === null || value === undefined) {
return mssql_1.TYPES.Variant; // TYPES.Null not included in mssql
}
else if (typeof value === 'number') {
if (Number.isSafeInteger(value)) {
return mssql_1.TYPES.Int;
}
else {
return mssql_1.TYPES.Real;
}
}
else if (typeof value === 'bigint') {
return mssql_1.TYPES.BigInt;
}
else if (typeof value === 'boolean') {
return mssql_1.TYPES.Bit;
}
else if (value instanceof Array) {
return (value.length > 0 ? this.inferType(value[0]) : mssql_1.TYPES.Variant); // TYPES.Null not included in mssql
}
else if (value instanceof Date) {
switch (value.___type___) {
case 'LocalDateTime':
return mssql_1.TYPES.DateTime2;
case 'LocalDate':
return mssql_1.TYPES.Date;
case 'LocalTime':
return mssql_1.TYPES.Time;
default:
return mssql_1.TYPES.DateTime2; // Maybe: TYPES.DateTimeOffset
}
}
else if (typeof value === 'string') {
if (/^-?\d+$/.test(value)) {
if (value.length > 9) {
return mssql_1.TYPES.BigInt;
}
else {
return mssql_1.TYPES.Int;
}
}
else if (/^-?\d+\.\d+$/.test(value)) {
return mssql_1.TYPES.Real;
}
else if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
return mssql_1.TYPES.Date;
}
else if (/^\d{2}\:\d{2}(?:\:\d{2})?(?:\+\d{4})?$/.test(value)) {
return mssql_1.TYPES.Time;
}
else if (/^\d{4}-\d{2}-\d{2}\s+\d{2}\:\d{2}(?:\:\d{2}(?:\.\d+)?)?$/.test(value)) {
return mssql_1.TYPES.DateTime2;
}
else if (/^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}(?:\.\d+)?$/.test(value)) {
return mssql_1.TYPES.DateTime2;
}
else if (/^\d{4}-\d{2}-\d{2}\s+\d{2}\:\d{2}(?:\:\d{2}(?:\.\d+)?)?(?:[\+\-]\d{2}\:\d{2}|Z)?$/.test(value)) {
return mssql_1.TYPES.DateTimeOffset;
}
else if (/^\d{4}-\d{2}-\d{2}T\d{2}\:\d{2}\:\d{2}(?:\.\d+)?(?:[\+\-]\d{2}\:\d{2}|Z)?$/.test(value)) {
return mssql_1.TYPES.DateTimeOffset;
}
else if (/^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i.test(value)) {
return mssql_1.TYPES.UniqueIdentifier;
}
else {
return mssql_1.TYPES.NVarChar;
}
}
return mssql_1.TYPES.VarBinary;
}
}
exports.MssqlPoolQueryRunner = MssqlPoolQueryRunner;