From f5bad1ae5462025b51e14a46df80ef21bae92d59 Mon Sep 17 00:00:00 2001 From: Tim Griesser Date: Tue, 13 Sep 2016 08:15:58 -0400 Subject: [PATCH] Simplifying internal client structure --- package.json | 1 + src/dialects/mssql/index.js | 36 ++++++++++++++++--- src/dialects/mssql/query/compiler.js | 4 +-- src/dialects/mysql/index.js | 16 ++++++--- src/dialects/oracle/formatter.js | 21 +++++++++++ src/dialects/oracle/index.js | 43 +++++++++------------- src/dialects/oracledb/index.js | 18 ++++++---- src/dialects/postgres/index.js | 16 ++++++--- src/dialects/sqlite3/index.js | 16 ++++++--- src/index.js | 7 ++-- src/transaction.js | 11 +++--- src/util/make-client.js | 47 ------------------------- test/integration/builder/transaction.js | 1 - test/integration/logger.js | 32 +++++++++++++---- 14 files changed, 155 insertions(+), 114 deletions(-) create mode 100644 src/dialects/oracle/formatter.js diff --git a/package.json b/package.json index 9b7c6bbe..14181085 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ }, "scripts": { "build": "npm run babel", + "debug_test": "node-debug _mocha -t 0 test/index.js", "babel": "rm -rf ./lib && babel src --out-dir lib --copy-files", "coveralls": "cat ./test/coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", "dev": "rm -rf ./lib && babel -w src --out-dir lib --copy-files", diff --git a/src/dialects/mssql/index.js b/src/dialects/mssql/index.js index e5625b29..01e4245a 100644 --- a/src/dialects/mssql/index.js +++ b/src/dialects/mssql/index.js @@ -8,6 +8,7 @@ import Client from '../../client'; import Promise from 'bluebird'; import * as helpers from '../../helpers'; +import Formatter from '../../formatter' import Transaction from './transaction'; import QueryCompiler from './query/compiler'; import SchemaCompiler from './schema/compiler'; @@ -41,17 +42,29 @@ assign(Client_MSSQL.prototype, { return require('mssql'); }, + formatter() { + return new MSSQL_Formatter(this) + }, + transaction() { return new Transaction(this, ...arguments) }, - QueryCompiler, + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, - SchemaCompiler, + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, - TableCompiler, + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, - ColumnCompiler, + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, wrapIdentifier(value) { return (value !== '*' ? `[${value.replace(/\[/g, '\[')}]` : '*') @@ -201,6 +214,21 @@ assign(Client_MSSQL.prototype, { }) +class MSSQL_Formatter extends Formatter { + + // Accepts a string or array of columns to wrap as appropriate. + columnizeWithPrefix(prefix, target) { + const columns = typeof target === 'string' ? [target] : target + let str = '', i = -1; + while (++i < columns.length) { + if (i > 0) str += ', ' + str += prefix + this.wrap(columns[i]) + } + return str + } + +} + // MSSQL Specific error handler function connectionErrorHandler(client, connection, err) { if (connection && err && err.fatal) { diff --git a/src/dialects/mssql/query/compiler.js b/src/dialects/mssql/query/compiler.js index 55868fdc..60930c3e 100644 --- a/src/dialects/mssql/query/compiler.js +++ b/src/dialects/mssql/query/compiler.js @@ -129,11 +129,11 @@ assign(QueryCompiler_MSSQL.prototype, { case 'update': case 'insert': return value - ? `output inserted.${this.formatter.columnize(value)}` + ? `output ${this.formatter.columnizeWithPrefix('inserted.', value)}` : ''; case 'del': return value - ? `output deleted.${this.formatter.columnize(value)}` + ? `output ${this.formatter.columnizeWithPrefix('deleted.', value)}` : ''; case 'rowcount': return value diff --git a/src/dialects/mysql/index.js b/src/dialects/mysql/index.js index 2bd0e78f..a5c6c131 100644 --- a/src/dialects/mysql/index.js +++ b/src/dialects/mysql/index.js @@ -34,13 +34,21 @@ assign(Client_MySQL.prototype, { return require('mysql') }, - QueryCompiler, + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, - SchemaCompiler, + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, - TableCompiler, + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, - ColumnCompiler, + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, transaction() { return new Transaction(this, ...arguments) diff --git a/src/dialects/oracle/formatter.js b/src/dialects/oracle/formatter.js new file mode 100644 index 00000000..8551b3b8 --- /dev/null +++ b/src/dialects/oracle/formatter.js @@ -0,0 +1,21 @@ +import Formatter from '../../formatter' +import {ReturningHelper} from './utils' + +export default class Oracle_Formatter extends Formatter { + + alias(first, second) { + return first + ' ' + second; + } + + parameter(value, notSetValue) { + // Returning helper uses always ROWID as string + if (value instanceof ReturningHelper && this.client.driver) { + value = new this.client.driver.OutParam(this.client.driver.OCCISTRING) + } + else if (typeof value === 'boolean') { + value = value ? 1 : 0 + } + return super.parameter(value, notSetValue) + } + +} diff --git a/src/dialects/oracle/index.js b/src/dialects/oracle/index.js index af01a0e3..d849b69d 100644 --- a/src/dialects/oracle/index.js +++ b/src/dialects/oracle/index.js @@ -8,7 +8,7 @@ import Client from '../../client'; import Promise from 'bluebird'; import * as helpers from '../../helpers'; import {bufferToString} from '../../query/string'; -import Formatter from '../../formatter'; +import Formatter from './formatter'; import Transaction from './transaction'; import QueryCompiler from './query/compiler'; @@ -42,18 +42,28 @@ assign(Client_Oracle.prototype, { }, formatter() { - return new Oracle_Formatter(this) + return new Formatter(this) }, - QueryCompiler, + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, - SchemaCompiler, + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, - ColumnBuilder, + columnBuilder() { + return new ColumnBuilder(this, ...arguments) + }, - ColumnCompiler, + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, - TableCompiler, + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, prepBindings(bindings) { return map(bindings, (value) => { @@ -174,22 +184,3 @@ assign(Client_Oracle.prototype, { } }) - -export class Oracle_Formatter extends Formatter { - - alias(first, second) { - return first + ' ' + second; - } - - parameter(value, notSetValue) { - // Returning helper uses always ROWID as string - if (value instanceof ReturningHelper && this.client.driver) { - value = new this.client.driver.OutParam(this.client.driver.OCCISTRING) - } - else if (typeof value === 'boolean') { - value = value ? 1 : 0 - } - return super.parameter(value, notSetValue) - } - -} diff --git a/src/dialects/oracledb/index.js b/src/dialects/oracledb/index.js index 810320ac..e1c9c4a4 100644 --- a/src/dialects/oracledb/index.js +++ b/src/dialects/oracledb/index.js @@ -11,10 +11,8 @@ const Promise = require('bluebird'); const stream = require('stream'); const helpers = require('../../helpers'); const Transaction = require('./transaction'); +const Client_Oracle = require('../oracle'); const Oracle_Formatter = require('../oracle/formatter'); -const BlobHelper = require('./utils').BlobHelper; - -import Client_Oracle, {Oracle_Formatter} from '../oracle'; function Client_Oracledb() { Client_Oracle.apply(this, arguments); @@ -33,12 +31,18 @@ Client_Oracledb.prototype._driver = function() { return oracledb; }; -Client_Oracledb.prototype.QueryCompiler = QueryCompiler; -Client_Oracledb.prototype.ColumnCompiler = ColumnCompiler; +Client_Oracledb.prototype.queryCompiler = function() { + return new QueryCompiler(this, ...arguments) +} +Client_Oracledb.prototype.columnCompiler = function() { + return new ColumnCompiler(this, ...arguments) +} Client_Oracledb.prototype.formatter = function() { return new Oracledb_Formatter(this) -}; -Client_Oracledb.prototype.Transaction = Transaction; +} +Client_Oracledb.prototype.transaction = function() { + return new Transaction(this, ...arguments) +} Client_Oracledb.prototype.prepBindings = function(bindings) { const self = this; diff --git a/src/dialects/postgres/index.js b/src/dialects/postgres/index.js index d1de21fe..c035a68e 100644 --- a/src/dialects/postgres/index.js +++ b/src/dialects/postgres/index.js @@ -26,13 +26,21 @@ inherits(Client_PG, Client) assign(Client_PG.prototype, { - QueryCompiler, + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, - ColumnCompiler, + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, - SchemaCompiler, + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, - TableCompiler, + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, dialect: 'postgresql', diff --git a/src/dialects/sqlite3/index.js b/src/dialects/sqlite3/index.js index e5d5c690..9a67ade8 100644 --- a/src/dialects/sqlite3/index.js +++ b/src/dialects/sqlite3/index.js @@ -37,13 +37,21 @@ assign(Client_SQLite3.prototype, { return require('sqlite3') }, - SchemaCompiler, + schemaCompiler() { + return new SchemaCompiler(this, ...arguments) + }, - QueryCompiler, + queryCompiler() { + return new QueryCompiler(this, ...arguments) + }, - ColumnCompiler, + columnCompiler() { + return new ColumnCompiler(this, ...arguments) + }, - TableCompiler, + tableCompiler() { + return new TableCompiler(this, ...arguments) + }, ddl(compiler, pragma, connection) { return new SQLite3_DDL(this, compiler, pragma, connection) diff --git a/src/index.js b/src/index.js index dcba1888..c113d0e2 100644 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,6 @@ import Raw from './raw'; import { warn } from './helpers'; import Client from './client'; -import makeClient from './util/make-client'; import makeKnex from './util/make-knex'; import parseConnection from './util/parse-connection'; @@ -24,12 +23,12 @@ export default function Knex(config) { } let Dialect; if (arguments.length === 0 || (!config.client && !config.dialect)) { - Dialect = makeClient(Client) + Dialect = Client } else if (typeof config.client === 'function' && config.client.prototype instanceof Client) { - Dialect = makeClient(config.client) + Dialect = config.client } else { const clientName = config.client || config.dialect - Dialect = makeClient(require(`./dialects/${aliases[clientName] || clientName}/index.js`)) + Dialect = require(`./dialects/${aliases[clientName] || clientName}/index.js`) } if (typeof config.connection === 'string') { config = assign({}, config, {connection: parseConnection(config.connection).connection}) diff --git a/src/transaction.js b/src/transaction.js index f9d65b49..50260fdd 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -162,11 +162,12 @@ function makeTransactor(trx, connection, trxClient) { const transactor = makeKnex(trxClient); - transactor.transaction = (container, options) => - new trxClient.Transaction(trxClient, container, options, trx); - - transactor.savepoint = (container, options) => - transactor.transaction(container, options); + transactor.transaction = function(container, options) { + return trxClient.transaction(container, options, trx); + } + transactor.savepoint = function(container, options) { + return transactor.transaction(container, options); + } if (trx.client.transacting) { transactor.commit = value => trx.release(connection, value) diff --git a/src/util/make-client.js b/src/util/make-client.js index 781d6975..d2518c10 100644 --- a/src/util/make-client.js +++ b/src/util/make-client.js @@ -1,8 +1,5 @@ - import inherits from 'inherits'; -import { assign } from 'lodash' - // Ensure the client has fresh objects so we can tack onto // the prototypes without mutating them globally. export default function makeClient(ParentClient) { @@ -16,49 +13,5 @@ export default function makeClient(ParentClient) { } inherits(Client, ParentClient) - function QueryBuilder(client) { - QueryBuilder.super_.call(this, client) - } - inherits(QueryBuilder, ParentClient.prototype.QueryBuilder) - - function SchemaBuilder(client) { - SchemaBuilder.super_.call(this, client) - } - inherits(SchemaBuilder, ParentClient.prototype.SchemaBuilder) - - function SchemaCompiler(client, builder) { - SchemaCompiler.super_.call(this, client, builder) - } - inherits(SchemaCompiler, ParentClient.prototype.SchemaCompiler) - - function TableBuilder(client, method, tableName, fn) { - TableBuilder.super_.call(this, client, method, tableName, fn) - } - inherits(TableBuilder, ParentClient.prototype.TableBuilder) - - function TableCompiler(client, tableBuilder) { - TableCompiler.super_.call(this, client, tableBuilder) - } - inherits(TableCompiler, ParentClient.prototype.TableCompiler) - - function ColumnBuilder(client, tableBuilder, type, args) { - ColumnBuilder.super_.call(this, client, tableBuilder, type, args) - } - inherits(ColumnBuilder, ParentClient.prototype.ColumnBuilder) - - function ColumnCompiler(client, tableCompiler, columnBuilder) { - ColumnCompiler.super_.call(this, client, tableCompiler, columnBuilder) - } - inherits(ColumnCompiler, ParentClient.prototype.ColumnCompiler) - - assign(Client.prototype, { - SchemaBuilder, - SchemaCompiler, - TableBuilder, - TableCompiler, - ColumnBuilder, - ColumnCompiler - }) - return Client } diff --git a/test/integration/builder/transaction.js b/test/integration/builder/transaction.js index 2d1e4dcd..a2267064 100644 --- a/test/integration/builder/transaction.js +++ b/test/integration/builder/transaction.js @@ -247,7 +247,6 @@ module.exports = function(knex) { }); it('should allow for nested transactions', function() { - return knex.transaction(function(trx) { return trx.select('*').from('accounts').then(function() { return trx.transaction(function() { diff --git a/test/integration/logger.js b/test/integration/logger.js index d085fc17..62038fcd 100644 --- a/test/integration/logger.js +++ b/test/integration/logger.js @@ -78,12 +78,32 @@ module.exports = function(knex) { }); } - client.Raw.prototype.testSql = - client.QueryBuilder.prototype.testSql = - client.SchemaBuilder.prototype.testSql = function Logger$testSql(handler) { - handler(testSqlTester.bind(null, this)); - return this; - }; + function makeTestSQL(builder) { + const tester = testSqlTester.bind(null, builder) + return function(handler) { + handler(tester) + return this + } + } + + const originalRaw = client.raw + const originalQueryBuilder = client.queryBuilder + const originalSchemaBuilder = client.schemaBuilder + client.raw = function() { + const raw = originalRaw.apply(this, arguments) + raw.testSql = makeTestSQL(raw) + return raw + } + client.queryBuilder = function() { + const qb = originalQueryBuilder.apply(this, arguments) + qb.testSql = makeTestSQL(qb) + return qb + } + client.schemaBuilder = function() { + const sb = originalSchemaBuilder.apply(this, arguments) + sb.testSql = makeTestSQL(sb) + return sb + } return knex; }