UNPKG

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.

534 lines (533 loc) 22.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MockQueryRunner = void 0; class MockQueryRunner { constructor(queryExecutor, databaseOrConfig = 'noopDB') { this.count = 0; this.queryExecutor = queryExecutor; if (typeof databaseOrConfig === 'string') { databaseOrConfig = { database: databaseOrConfig }; } this.database = databaseOrConfig.database || 'noopDB'; this.promise = databaseOrConfig.promise || Promise; } useDatabase(database) { // @ts-ignore this.database = database; } getNativeRunner() { return null; } getCurrentNativeTransaction() { return undefined; } execute(fn) { return fn(null); } executeSelectOneRow(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('selectOneRow', query, params, index); if (!isPlainObjectOrNoValue(result)) { throw new Error('Invalid test case result for a selectOneRow with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a plain object'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeSelectManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('selectManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a selectManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array of plain object'); } for (let i = 0; i < result.length; i++) { if (!isPlainObject(result[i])) { throw new Error('Invalid test case result for a selectManyRows with index ' + index + '. The returned array by the mock function provided to the MockQueryRunner contains a no plain object at position ' + i); } } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeSelectOneColumnOneRow(query, params = []) { // undefined result means no value returned by the database try { return this.promise.resolve(this.queryExecutor('selectOneColumnOneRow', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeSelectOneColumnManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('selectOneColumnManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a selectOneColumnManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeInsert(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('insert', query, params, index); if (result === undefined || result === null) { result = 1; } if (typeof result !== 'number') { throw new Error('Invalid test case result for an insert with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a number'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeInsertReturningLastInsertedId(query, params = []) { try { return this.promise.resolve(this.queryExecutor('insertReturningLastInsertedId', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeInsertReturningMultipleLastInsertedId(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('insertReturningMultipleLastInsertedId', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for an insertReturningMultipleLastInsertedId with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeInsertReturningOneRow(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('insertReturningOneRow', query, params, index); if (!isPlainObjectOrNoValue(result)) { throw new Error('Invalid test case result for a insertReturningOneRow with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a plain object'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeInsertReturningManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('insertReturningManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a insertReturningManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array of plain object'); } for (let i = 0; i < result.length; i++) { if (!isPlainObject(result[i])) { throw new Error('Invalid test case result for a insertReturningManyRows with index ' + index + '. The returned array by the mock function provided to the MockQueryRunner contains a no plain object at position ' + i); } } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeInsertReturningOneColumnOneRow(query, params = []) { // undefined result means no value returned by the database try { return this.promise.resolve(this.queryExecutor('insertReturningOneColumnOneRow', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeInsertReturningOneColumnManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('insertReturningOneColumnManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a insertReturningOneColumnManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeUpdate(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('update', query, params, index); if (result === undefined || result === null) { result = 0; } if (typeof result !== 'number') { throw new Error('Invalid test case result for an update with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a number'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeUpdateReturningOneRow(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('updateReturningOneRow', query, params, index); if (!isPlainObjectOrNoValue(result)) { throw new Error('Invalid test case result for a updateReturningOneRow with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a plain object'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeUpdateReturningManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('updateReturningManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a updateReturningManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array of plain object'); } for (let i = 0; i < result.length; i++) { if (!isPlainObject(result[i])) { throw new Error('Invalid test case result for a updateReturningManyRows with index ' + index + '. The returned array by the mock function provided to the MockQueryRunner contains a no plain object at position ' + i); } } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeUpdateReturningOneColumnOneRow(query, params = []) { // undefined result means no value returned by the database try { return this.promise.resolve(this.queryExecutor('updateReturningOneColumnOneRow', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeUpdateReturningOneColumnManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('updateReturningOneColumnManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a updateReturningOneColumnManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeDelete(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('delete', query, params, index); if (result === undefined || result === null) { result = 0; } if (typeof result !== 'number') { throw new Error('Invalid test case result for a delete with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a number'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeDeleteReturningOneRow(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('deleteReturningOneRow', query, params, index); if (!isPlainObjectOrNoValue(result)) { throw new Error('Invalid test case result for a deleteReturningOneRow with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or a plain object'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeDeleteReturningManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('deleteReturningManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a deleteReturningManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array of plain object'); } for (let i = 0; i < result.length; i++) { if (!isPlainObject(result[i])) { throw new Error('Invalid test case result for a deleteReturningManyRows with index ' + index + '. The returned array by the mock function provided to the MockQueryRunner contains a no plain object at position ' + i); } } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeDeleteReturningOneColumnOneRow(query, params = []) { // undefined result means no value returned by the database try { return this.promise.resolve(this.queryExecutor('deleteReturningOneColumnOneRow', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeDeleteReturningOneColumnManyRows(query, params = []) { try { const index = this.count++; let result = this.queryExecutor('deleteReturningOneColumnManyRows', query, params, index); if (result === undefined || result === null) { result = []; } if (!Array.isArray(result)) { throw new Error('Invalid test case result for a deleteReturningOneColumnManyRows with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined or an Array'); } return this.promise.resolve(result); } catch (e) { return this.promise.reject(e); } } executeProcedure(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('executeProcedure', query, params, index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for an executeProcedure with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } executeFunction(query, params = []) { try { return this.promise.resolve(this.queryExecutor('executeFunction', query, params, this.count++)); } catch (e) { return this.promise.reject(e); } } executeBeginTransaction() { try { const index = this.count++; const result = this.queryExecutor('beginTransaction', 'begin transaction', [], index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for a beginTransaction with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } executeCommit() { try { const index = this.count++; const result = this.queryExecutor('commit', 'commit', [], index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for a commit with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } executeRollback() { try { const index = this.count++; const result = this.queryExecutor('rollback', 'rollback', [], index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for a commit with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } isTransactionActive() { const index = this.count++; let result = this.queryExecutor('isTransactionActive', '', [], index); if (result !== undefined && result !== null) { result = false; } if (typeof result !== 'boolean') { throw new Error('Invalid test case result for an isTransactionActive with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null, undefined, or a boolean'); } return result; } executeDatabaseSchemaModification(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('executeDatabaseSchemaModification', query, params, index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for a executeDatabaseSchemaModification with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } executeConnectionConfiguration(query, params = []) { try { const index = this.count++; const result = this.queryExecutor('executeConnectionConfiguration', query, params, index); if (result !== undefined && result !== null) { throw new Error('Invalid test case result for a executeConnectionConfiguration with index ' + index + '. Your mock function provided to the MockQueryRunner must returns null or undefined'); } return this.promise.resolve(undefined); } catch (e) { return this.promise.reject(e); } } addParam(params, value) { const index = params.length; let result; switch (this.database) { case 'mariaDB': result = '?'; break; case 'mySql': result = '?'; break; case 'noopDB': result = '$' + index; break; case 'oracle': result = ':' + index; break; case 'postgreSql': result = '$' + (index + 1); break; case 'sqlite': result = '?'; break; case 'sqlServer': result = '@' + index; break; default: throw new Error('Unknown database ' + this.database); } params.push(value); return result; } addOutParam(params, name) { if (this.database !== 'oracle') { throw new Error('Unsupported output parameters'); } const index = params.length; if (name) { params.push({ dir: 3003 /*oracledb.BIND_OUT*/, as: name }); // See https://github.com/oracle/node-oracledb/blob/master/lib/oracledb.js } else { params.push({ dir: 3003 /*oracledb.BIND_OUT*/ }); // See https://github.com/oracle/node-oracledb/blob/master/lib/oracledb.js } return ':' + index; } executeInTransaction(fn, outermostQueryRunner) { return outermostQueryRunner.executeBeginTransaction().then(() => { let result = fn(); if (Array.isArray(result)) { result = this.createAllPromise(result); } return result.then((r) => { return outermostQueryRunner.executeCommit().then(() => { return r; }); }, (e) => { return outermostQueryRunner.executeRollback().then(() => { throw e; }, () => { // Throw the innermost error throw e; }); }); }); } executeCombined(fn1, fn2) { return fn1().then((r1) => { return fn2().then((r2) => { return [r1, r2]; }); }); } createResolvedPromise(result) { return this.promise.resolve(result); } createAllPromise(promises) { return this.promise.all(promises); } isMocked() { return true; } lowLevelTransactionManagementSupported() { return true; } } exports.MockQueryRunner = MockQueryRunner; function isPlainObject(value) { if (!value && typeof value !== 'object') { return false; } const prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; } function isPlainObjectOrNoValue(value) { if (value === null || value === undefined) { return true; } if (typeof value !== 'object') { return false; } const prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; }