knex 0.14.0 → 0.14.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/CONTRIBUTING.md +76 -0
  3. package/README.md +3 -1
  4. package/bin/cli.js +4 -3
  5. package/lib/client.js +91 -82
  6. package/lib/dialects/maria/index.js +7 -4
  7. package/lib/dialects/mssql/index.js +5 -4
  8. package/lib/dialects/mssql/query/compiler.js +19 -4
  9. package/lib/dialects/mssql/schema/columncompiler.js +2 -0
  10. package/lib/dialects/mssql/schema/tablecompiler.js +2 -2
  11. package/lib/dialects/mysql/index.js +12 -7
  12. package/lib/dialects/mysql/query/compiler.js +11 -1
  13. package/lib/dialects/mysql/schema/columncompiler.js +1 -1
  14. package/lib/dialects/mysql/schema/tablecompiler.js +3 -3
  15. package/lib/dialects/mysql2/index.js +2 -60
  16. package/lib/dialects/oracle/index.js +1 -1
  17. package/lib/dialects/oracle/query/compiler.js +11 -1
  18. package/lib/dialects/oracle/schema/columncompiler.js +4 -0
  19. package/lib/dialects/oracledb/index.js +2 -2
  20. package/lib/dialects/oracledb/query/compiler.js +2 -0
  21. package/lib/dialects/postgres/index.js +51 -6
  22. package/lib/dialects/postgres/query/compiler.js +18 -4
  23. package/lib/dialects/postgres/schema/columncompiler.js +5 -0
  24. package/lib/dialects/postgres/schema/compiler.js +2 -2
  25. package/lib/dialects/redshift/index.js +102 -0
  26. package/lib/dialects/redshift/query/compiler.js +128 -0
  27. package/lib/dialects/redshift/schema/columnbuilder.js +34 -0
  28. package/lib/dialects/redshift/schema/columncompiler.js +73 -0
  29. package/lib/dialects/redshift/schema/compiler.js +26 -0
  30. package/lib/dialects/redshift/schema/tablecompiler.js +97 -0
  31. package/lib/dialects/redshift/transaction.js +56 -0
  32. package/lib/dialects/sqlite3/query/compiler.js +26 -6
  33. package/lib/formatter.js +5 -3
  34. package/lib/helpers.js +16 -3
  35. package/lib/migrate/index.js +5 -6
  36. package/lib/query/builder.js +4 -0
  37. package/lib/query/compiler.js +24 -13
  38. package/lib/query/string.js +2 -2
  39. package/lib/raw.js +4 -4
  40. package/lib/runner.js +13 -1
  41. package/lib/schema/builder.js +6 -0
  42. package/lib/schema/columnbuilder.js +4 -0
  43. package/lib/schema/columncompiler.js +4 -1
  44. package/lib/schema/compiler.js +11 -1
  45. package/lib/schema/helpers.js +23 -1
  46. package/lib/schema/tablebuilder.js +2 -0
  47. package/lib/schema/tablecompiler.js +12 -1
  48. package/package.json +51 -47
  49. package/scripts/runkit-example.js +32 -0
  50. package/scripts/stress-test/README.txt +18 -0
  51. package/scripts/stress-test/debug.log +0 -0
  52. package/scripts/stress-test/docker-compose.yml +44 -0
  53. package/scripts/stress-test/knex-stress-test.js +162 -0
  54. package/scripts/stress-test/mysql2-random-hanging-every-now-and-then.js +132 -0
  55. package/scripts/stress-test/mysql2-sudden-exit-without-error.js +98 -0
  56. package/scripts/stress-test/reconnect-test-mysql-based-drivers.js +174 -0
  57. package/src/client.js +99 -78
  58. package/src/dialects/maria/index.js +8 -5
  59. package/src/dialects/mssql/index.js +6 -5
  60. package/src/dialects/mssql/query/compiler.js +17 -6
  61. package/src/dialects/mssql/schema/columncompiler.js +2 -0
  62. package/src/dialects/mssql/schema/tablecompiler.js +2 -2
  63. package/src/dialects/mysql/index.js +15 -11
  64. package/src/dialects/mysql/query/compiler.js +8 -2
  65. package/src/dialects/mysql/schema/columncompiler.js +1 -1
  66. package/src/dialects/mysql/schema/tablecompiler.js +3 -3
  67. package/src/dialects/mysql2/index.js +4 -49
  68. package/src/dialects/oracle/index.js +1 -1
  69. package/src/dialects/oracle/query/compiler.js +8 -2
  70. package/src/dialects/oracle/schema/columncompiler.js +6 -1
  71. package/src/dialects/oracledb/index.js +2 -2
  72. package/src/dialects/oracledb/query/compiler.js +5 -3
  73. package/src/dialects/postgres/index.js +32 -6
  74. package/src/dialects/postgres/query/compiler.js +15 -5
  75. package/src/dialects/postgres/schema/columncompiler.js +5 -1
  76. package/src/dialects/postgres/schema/compiler.js +2 -2
  77. package/src/dialects/redshift/index.js +74 -0
  78. package/src/dialects/redshift/query/compiler.js +101 -0
  79. package/src/dialects/redshift/schema/columnbuilder.js +23 -0
  80. package/src/dialects/redshift/schema/columncompiler.js +59 -0
  81. package/src/dialects/redshift/schema/compiler.js +14 -0
  82. package/src/dialects/redshift/schema/tablecompiler.js +73 -0
  83. package/src/dialects/redshift/transaction.js +21 -0
  84. package/src/dialects/sqlite3/query/compiler.js +19 -6
  85. package/src/dialects/sqlite3/schema/ddl.js +21 -21
  86. package/src/formatter.js +5 -3
  87. package/src/helpers.js +24 -3
  88. package/src/migrate/index.js +5 -4
  89. package/src/query/builder.js +4 -0
  90. package/src/query/compiler.js +26 -13
  91. package/src/query/string.js +2 -2
  92. package/src/raw.js +4 -4
  93. package/src/runner.js +22 -10
  94. package/src/schema/builder.js +11 -0
  95. package/src/schema/columnbuilder.js +4 -1
  96. package/src/schema/columncompiler.js +9 -4
  97. package/src/schema/compiler.js +8 -2
  98. package/src/schema/helpers.js +14 -1
  99. package/src/schema/tablebuilder.js +2 -0
  100. package/src/schema/tablecompiler.js +12 -3
  101. package/src/transaction.js +26 -26
  102. package/src/util/batchInsert.js +1 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,69 @@
1
1
 
2
2
  # Master (Unreleased)
3
3
 
4
+ # 0.14.4 - 19 Feb, 2018
5
+
6
+ ### Bug fixes:
7
+
8
+ - containsUndefined only validate plain objects. Fixes #1898 (#2468)
9
+ - Add warning when using .returning() in sqlite3. Fixes #1660 (#2471)
10
+ - Throw an error if .update() results in an empty sql (#2472)
11
+ - Removed unnecessary createTableIfNotExist and replaced with createTable (#2473)
12
+
13
+ ### New Features:
14
+
15
+ - Allow calling lock procedures (such as forUpdate) outside of transaction. Fixes #2403. (#2475)
16
+ - Added test and documentation for Event 'start' (#2488)
17
+
18
+ ### Test / internal changes
19
+
20
+ - Added stress test, which uses TCP proxy to simulate flaky connection #2460
21
+ - Removed old docker tests, new stress test setup (#2474)
22
+ - Removed unused property __cid on the base client (#2481)
23
+ - Changed rm to rimraf in 'npm run dev' (#2483)
24
+ - Changed babel preset and use latest node as target when running dev (#2484)
25
+
26
+ # 0.14.3 - 8 Feb, 2018
27
+
28
+ ### Bug fixes:
29
+
30
+ - Use tarn as pool instead of generic-pool which has been given various problems #2450
31
+ - Fixed mysql issue where add columns failed if using both after and collate #2432
32
+ - CLI sets exit-code 1 if the command supplied was not parseable #2358
33
+ - Set toNative() to be not enumerable #2388
34
+ - Use wrapIdentifier in columnInfo. fixes #2402 #2405
35
+ - Fixed a bug when using .returning (OUTPUT) in an update query with joins in MSSQL #2399
36
+ - Better error message when running migrations fail before even starting run migrations #2373
37
+ - Read oracle's UV_THREADPOOL_SIZE env variable correctly #2372
38
+ - Added decimal variable precision / scale support #2353
39
+
40
+ ### New Features:
41
+
42
+ - Added queryContext to schema and query builders #2314
43
+ - Added redshift dialect #2233
44
+ - Added warning when one uses .createTableIfNotExist and deprecated it from docs #2458
45
+
46
+ ### Test / internal changes
47
+
48
+ - Update dependencies and fix ESLint warnings accordingly #2433
49
+ - Disable oracledb tests from non LTS nodes #2407
50
+ - Update dependencies #2422
51
+
52
+
53
+ # 0.14.2 - 24 Nov, 2017
54
+
55
+ ### Bug fixes:
56
+
57
+ - Fix sqlite3 truncate method to work again #2348
58
+
59
+ # 0.14.1 - 19 Nov, 2017
60
+
61
+ ### Bug fixes:
62
+
63
+ - Fix support for multiple schema names in in postgres `searchPath` #2340
64
+ - Fix create new connection to pass errors to query instead of retry loop #2336
65
+ - Fix recognition of connections closed by server #2341
66
+
4
67
  # 0.14.0 - 6 Nov, 2017
5
68
 
6
69
  ### Breaking Changes:
package/CONTRIBUTING.md CHANGED
@@ -22,6 +22,82 @@ Documentation is no longer maintained in knex master repository. All the documen
22
22
 
23
23
  Documentation pull requests should not be merged before knex version which has the new documented feature is released.
24
24
 
25
+ ## I would like to add support for new dialect to knex, is it possible?
26
+
27
+ Currently there are already way too many dialects supported in `knex` and instead of adding new dialect to central codebase, all the dialects should be moved to separate npm packages out from `knex` core library with their respective maintainers and test suites.
28
+
29
+ So if you like to write your own dialect, you can just inherit own dialect from knex base classes and use it by passing dilaect to knex in knex configuration (https://runkit.com/embed/90b3cpyr4jh2):
30
+
31
+ ```js
32
+ // simple dialect overriding sqlite3 dialect to use sqlite3-offline driver
33
+ require('sqlite3-offline');
34
+ const Knex = require("knex");
35
+
36
+ const Dialect = require(`knex/lib/dialects/sqlite3/index.js`);
37
+ Dialect.prototype._driver = () => require('sqlite3-offline');
38
+
39
+ const knex = Knex({
40
+ client: Dialect,
41
+ connection: ':memory:'
42
+ });
43
+
44
+ console.log(
45
+ knex.select(knex.raw(1)).toSQL()
46
+ );
47
+
48
+ await knex.schema.createTable('fooobar', (t) => {
49
+ t.bigincrements('id');
50
+ t.string('data');
51
+ });
52
+ await knex('fooobar').insert({ data: 'nomnom' });
53
+
54
+ console.log("Gimme all the data:", await knex('fooobar'));
55
+ ```
56
+
57
+ ## What is minimal code to reproduce bug and why I have to provide that when I can just tell whats the problem is
58
+
59
+ Writing minimal reproduction code for the problem is timeconsuming and some times it also really hard when for
60
+ example when the original code where the bug happens is written using express or mocha. So why it is necessary
61
+ for me to commit so much time to it when the problem is in `knex`? Contributors should be grateful that I reported
62
+ the bug I found.
63
+
64
+ The point of runnable code to reproduce the problem is to easily verify that there really is a problem and that the one
65
+ who did the report did nothing wrong (surprisingly often problem is in the user code). So instead of just description
66
+ what to do the complete code encourages devs to actually test out that problem exists and start solving it and it
67
+ saves lots of time.
68
+
69
+ tl;dr list:
70
+
71
+ 1. Actually in most of the cases developer already figures out what was the problem when writing the minimal test case
72
+ or if there was problem how stuff was initilized or how async code was written it is easy to point out the problem.
73
+
74
+ 2. It motivates developer to actually try out if the bug really exist by not having to figure out from incomplete example
75
+ environment in which and how bug actually manifests.
76
+
77
+ 3. There are curently very few people fixing knex issues and if one has to put easily 15-30 minutes time to issue just
78
+ to see that I cannot reproduce this issue it just wastes development hours that were available for improving knex.
79
+
80
+
81
+ Test case should initialize needed tables, insert needed data and fail...
82
+
83
+ ```
84
+ const knex = require('knex')({
85
+ client: 'pg',
86
+ connection: 'postgres:///knex_test'
87
+ });
88
+
89
+ async function main() {
90
+ await knex.schema.createTable(...);
91
+ await knex('table').insert({foo: 'bar}');
92
+ await knex.destroy();
93
+ }
94
+
95
+ main();
96
+ ```
97
+
98
+ Usually issues without reproduction code available are just closed and if the same issue is reported multiple
99
+ times maybe someone looks into it.
100
+
25
101
  ## Integration Tests
26
102
 
27
103
  ### The Easy Way
package/README.md CHANGED
@@ -22,7 +22,9 @@ Node.js and the Browser, featuring:
22
22
 
23
23
  For support and questions, join the `#bookshelf` channel on freenode IRC
24
24
 
25
- For an Object Relational Mapper, see: http://bookshelfjs.org
25
+ For an Object Relational Mapper, see:
26
+ - http://bookshelfjs.org
27
+ - https://github.com/Vincit/objection.js
26
28
 
27
29
  To see the SQL that Knex will generate for a given query, see: [Knex Query Lab](http://michaelavila.com/knex-querylab/)
28
30
 
package/bin/cli.js CHANGED
@@ -13,9 +13,9 @@ var cliPkg = require('../package');
13
13
 
14
14
  function exit(text) {
15
15
  if (text instanceof Error) {
16
- chalk.red(console.error(text.stack));
16
+ console.error(chalk.red(text.stack));
17
17
  } else {
18
- chalk.red(console.error(text));
18
+ console.error(chalk.red(text));
19
19
  }
20
20
  process.exit(1);
21
21
  }
@@ -186,7 +186,8 @@ function invoke(env) {
186
186
  commander.parse(process.argv);
187
187
 
188
188
  Promise.resolve(pending).then(function() {
189
- commander.help();
189
+ commander.outputHelp();
190
+ exit('Unknown command-line options, exiting');
190
191
  });
191
192
  }
192
193
 
package/lib/client.js CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
 
5
- var _get2 = require('lodash/get');
5
+ var _assign2 = require('babel-runtime/core-js/object/assign');
6
6
 
7
- var _get3 = _interopRequireDefault(_get2);
7
+ var _assign3 = _interopRequireDefault(_assign2);
8
8
 
9
9
  var _defaults2 = require('lodash/defaults');
10
10
 
@@ -18,9 +18,9 @@ var _uniqueId2 = require('lodash/uniqueId');
18
18
 
19
19
  var _uniqueId3 = _interopRequireDefault(_uniqueId2);
20
20
 
21
- var _assign2 = require('lodash/assign');
21
+ var _assign4 = require('lodash/assign');
22
22
 
23
- var _assign3 = _interopRequireDefault(_assign2);
23
+ var _assign5 = _interopRequireDefault(_assign4);
24
24
 
25
25
  var _bluebird = require('bluebird');
26
26
 
@@ -78,13 +78,7 @@ var _columncompiler = require('./schema/columncompiler');
78
78
 
79
79
  var _columncompiler2 = _interopRequireDefault(_columncompiler);
80
80
 
81
- var _genericPool = require('generic-pool');
82
-
83
- var genericPool = _interopRequireWildcard(_genericPool);
84
-
85
- var _errors = require('generic-pool/lib/errors');
86
-
87
- var genericPoolErrors = _interopRequireWildcard(_errors);
81
+ var _tarn = require('tarn');
88
82
 
89
83
  var _inherits = require('inherits');
90
84
 
@@ -102,11 +96,6 @@ var debug = require('debug')('knex:client');
102
96
  var debugQuery = require('debug')('knex:query');
103
97
  var debugBindings = require('debug')('knex:bindings');
104
98
 
105
- var id = 0;
106
- function clientId() {
107
- return 'client' + id++;
108
- }
109
-
110
99
  // The base client provides the general structure
111
100
  // for a dialect specific client object.
112
101
  function Client() {
@@ -125,7 +114,6 @@ function Client() {
125
114
  if (this.driverName && config.connection) {
126
115
  this.initializeDriver();
127
116
  if (!config.pool || config.pool && config.pool.max !== 0) {
128
- this.__cid = clientId();
129
117
  this.initializePool(config);
130
118
  }
131
119
  }
@@ -136,9 +124,9 @@ function Client() {
136
124
  }
137
125
  (0, _inherits2.default)(Client, _events.EventEmitter);
138
126
 
139
- (0, _assign3.default)(Client.prototype, {
140
- formatter: function formatter() {
141
- return new _formatter2.default(this);
127
+ (0, _assign5.default)(Client.prototype, {
128
+ formatter: function formatter(builder) {
129
+ return new _formatter2.default(this, builder);
142
130
  },
143
131
  queryBuilder: function queryBuilder() {
144
132
  return new _builder2.default(this);
@@ -206,11 +194,11 @@ function Client() {
206
194
  obj.sql = this.positionBindings(obj.sql);
207
195
  obj.bindings = this.prepBindings(obj.bindings);
208
196
  debugQuery(obj.sql);
209
- this.emit('query', (0, _assign3.default)({ __knexUid: connection.__knexUid }, obj));
197
+ this.emit('query', (0, _assign5.default)({ __knexUid: connection.__knexUid }, obj));
210
198
  debugBindings(obj.bindings);
211
199
  return this._query(connection, obj).catch(function (err) {
212
200
  err.message = _this2._formatQuery(obj.sql, obj.bindings) + ' - ' + err.message;
213
- _this2.emit('query-error', err, (0, _assign3.default)({ __knexUid: connection.__knexUid }, obj));
201
+ _this2.emit('query-error', err, (0, _assign5.default)({ __knexUid: connection.__knexUid }, obj));
214
202
  throw err;
215
203
  });
216
204
  },
@@ -218,7 +206,7 @@ function Client() {
218
206
  if (typeof obj === 'string') obj = { sql: obj };
219
207
  obj.sql = this.positionBindings(obj.sql);
220
208
  obj.bindings = this.prepBindings(obj.bindings);
221
- this.emit('query', (0, _assign3.default)({ __knexUid: connection.__knexUid }, obj));
209
+ this.emit('query', (0, _assign5.default)({ __knexUid: connection.__knexUid }, obj));
222
210
  debugQuery(obj.sql);
223
211
  debugBindings(obj.bindings);
224
212
  return this._stream(connection, obj, _stream, options);
@@ -229,17 +217,20 @@ function Client() {
229
217
  positionBindings: function positionBindings(sql) {
230
218
  return sql;
231
219
  },
232
- postProcessResponse: function postProcessResponse(resp) {
220
+ postProcessResponse: function postProcessResponse(resp, queryContext) {
233
221
  if (this.config.postProcessResponse) {
234
- return this.config.postProcessResponse(resp);
222
+ return this.config.postProcessResponse(resp, queryContext);
235
223
  }
236
224
  return resp;
237
225
  },
238
- wrapIdentifier: function wrapIdentifier(value) {
226
+ wrapIdentifier: function wrapIdentifier(value, queryContext) {
227
+ return this.customWrapIdentifier(value, this.wrapIdentifierImpl, queryContext);
228
+ },
229
+ customWrapIdentifier: function customWrapIdentifier(value, origImpl, queryContext) {
239
230
  if (this.config.wrapIdentifier) {
240
- return this.config.wrapIdentifier(value, this.wrapIdentifierImpl);
231
+ return this.config.wrapIdentifier(value, origImpl, queryContext);
241
232
  }
242
- return this.wrapIdentifierImpl(value);
233
+ return origImpl(value);
243
234
  },
244
235
  wrapIdentifierImpl: function wrapIdentifierImpl(value) {
245
236
  return value !== '*' ? '"' + value.replace(/"/g, '""') + '"' : '*';
@@ -252,61 +243,59 @@ function Client() {
252
243
  }
253
244
  },
254
245
  poolDefaults: function poolDefaults() {
255
- return { min: 2, max: 10, Promise: _bluebird2.default };
246
+ return { min: 2, max: 10, propagateCreateError: true };
256
247
  },
257
248
  getPoolSettings: function getPoolSettings(poolConfig) {
258
249
  var _this3 = this;
259
250
 
260
251
  poolConfig = (0, _defaults3.default)({}, poolConfig, this.poolDefaults());
261
- var timeoutValidator = function timeoutValidator(config, path) {
262
- var timeout = (0, _get3.default)(config, path);
263
- if (timeout !== undefined) {
264
- timeout = parseInt(timeout, 10);
265
- if (isNaN(timeout) || timeout <= 0) {
266
- throw new Error(path + ' must be a positive int');
267
- }
252
+
253
+ ['maxWaitingClients', 'testOnBorrow', 'fifo', 'priorityRange', 'autostart', 'evictionRunIntervalMillis', 'numTestsPerRun', 'softIdleTimeoutMillis', 'Promise'].forEach(function (option) {
254
+ if (option in poolConfig) {
255
+ helpers.warn(['Pool config option "' + option + '" is no longer supported.', 'See https://github.com/Vincit/tarn.js for possible pool config options.'].join(' '));
268
256
  }
269
- return timeout;
270
- };
257
+ });
271
258
 
272
- // acquire connection timeout can be set on config or config.pool
273
- // choose the smallest, positive timeout setting and set on poolConfig
274
- var timeouts = [timeoutValidator(this.config, 'acquireConnectionTimeout') || 60000, timeoutValidator({ pool: poolConfig }, 'pool.acquireTimeoutMillis')].filter(function (timeout) {
259
+ var timeouts = [this.config.acquireConnectionTimeout || 60000, poolConfig.acquireTimeoutMillis].filter(function (timeout) {
275
260
  return timeout !== undefined;
276
261
  });
262
+
263
+ // acquire connection timeout can be set on config or config.pool
264
+ // choose the smallest, positive timeout setting and set on poolConfig
277
265
  poolConfig.acquireTimeoutMillis = Math.min.apply(Math, timeouts);
278
266
 
279
- return {
280
- config: poolConfig,
281
- factory: {
282
- create: function create() {
283
- return _this3.acquireRawConnection().tap(function (connection) {
284
- connection.__knexUid = (0, _uniqueId3.default)('__knexUid');
285
- if (poolConfig.afterCreate) {
286
- return _bluebird2.default.promisify(poolConfig.afterCreate)(connection);
287
- }
288
- });
289
- },
290
- destroy: function destroy(connection) {
291
- if (poolConfig.beforeDestroy) {
292
- helpers.warn('\n beforeDestroy is deprecated, please open an issue if you use this\n to discuss alternative apis\n ');
293
- poolConfig.beforeDestroy(connection, function () {});
294
- }
295
- if (connection !== void 0) {
296
- return _this3.destroyRawConnection(connection);
297
- }
267
+ return (0, _assign3.default)(poolConfig, {
268
+ create: function create() {
269
+ return _this3.acquireRawConnection().tap(function (connection) {
270
+ connection.__knexUid = (0, _uniqueId3.default)('__knexUid');
298
271
 
299
- return _bluebird2.default.resolve();
300
- },
301
- validate: function validate(connection) {
302
- if (connection.__knex__disposed) {
303
- helpers.warn('Connection Error: ' + connection.__knex__disposed);
304
- return _bluebird2.default.resolve(false);
272
+ if (poolConfig.afterCreate) {
273
+ return _bluebird2.default.promisify(poolConfig.afterCreate)(connection);
305
274
  }
306
- return _this3.validateConnection(connection);
275
+ });
276
+ },
277
+
278
+ destroy: function destroy(connection) {
279
+ if (poolConfig.beforeDestroy) {
280
+ helpers.warn('\n beforeDestroy is deprecated, please open an issue if you use this\n to discuss alternative apis\n ');
281
+
282
+ poolConfig.beforeDestroy(connection, function () {});
283
+ }
284
+
285
+ if (connection !== void 0) {
286
+ return _this3.destroyRawConnection(connection);
307
287
  }
288
+ },
289
+
290
+ validate: function validate(connection) {
291
+ if (connection.__knex__disposed) {
292
+ helpers.warn('Connection Error: ' + connection.__knex__disposed);
293
+ return false;
294
+ }
295
+
296
+ return _this3.validateConnection(connection);
308
297
  }
309
- };
298
+ });
310
299
  },
311
300
  initializePool: function initializePool(config) {
312
301
  if (this.pool) {
@@ -314,23 +303,26 @@ function Client() {
314
303
  return;
315
304
  }
316
305
 
317
- var poolSettings = this.getPoolSettings(config.pool);
318
-
319
- this.pool = genericPool.createPool(poolSettings.factory, poolSettings.config);
306
+ this.pool = new _tarn.Pool(this.getPoolSettings(config.pool));
320
307
  },
321
308
  validateConnection: function validateConnection(connection) {
322
- return _bluebird2.default.resolve(true);
309
+ return true;
323
310
  },
324
311
 
325
312
 
326
313
  // Acquire a connection from the pool.
327
314
  acquireConnection: function acquireConnection() {
315
+ var _this4 = this;
316
+
328
317
  if (!this.pool) {
329
318
  return _bluebird2.default.reject(new Error('Unable to acquire a connection'));
330
319
  }
331
- return this.pool.acquire().tap(function (connection) {
320
+
321
+ return _bluebird2.default.try(function () {
322
+ return _this4.pool.acquire().promise;
323
+ }).tap(function (connection) {
332
324
  debug('acquired connection from pool: %s', connection.__knexUid);
333
- }).catch(genericPoolErrors.TimeoutError, function () {
325
+ }).catch(_tarn.TimeoutError, function () {
334
326
  throw new _bluebird2.default.TimeoutError('Knex: Timeout acquiring a connection. The pool is probably full. ' + 'Are you missing a .transacting(trx) call?');
335
327
  });
336
328
  },
@@ -340,24 +332,41 @@ function Client() {
340
332
  // returning a promise resolved when the connection is released.
341
333
  releaseConnection: function releaseConnection(connection) {
342
334
  debug('releasing connection to pool: %s', connection.__knexUid);
343
- return this.pool.release(connection).catch(function () {
335
+ var didRelease = this.pool.release(connection);
336
+
337
+ if (!didRelease) {
344
338
  debug('pool refused connection: %s', connection.__knexUid);
345
- });
339
+ }
340
+
341
+ return _bluebird2.default.resolve();
346
342
  },
347
343
 
348
344
 
349
345
  // Destroy the current connection pool for the client.
350
346
  destroy: function destroy(callback) {
351
- var _this4 = this;
347
+ var _this5 = this;
348
+
349
+ var promise = null;
350
+
351
+ if (this.pool) {
352
+ promise = this.pool.destroy();
353
+ } else {
354
+ promise = _bluebird2.default.resolve();
355
+ }
356
+
357
+ return promise.then(function () {
358
+ _this5.pool = void 0;
352
359
 
353
- return _bluebird2.default.resolve(this.pool && this.pool.drain().then(function () {
354
- return _this4.pool.clear();
355
- }).then(function () {
356
- _this4.pool = void 0;
357
360
  if (typeof callback === 'function') {
358
361
  callback();
359
362
  }
360
- }));
363
+ }).catch(function (err) {
364
+ if (typeof callback === 'function') {
365
+ callback(err);
366
+ }
367
+
368
+ return _bluebird2.default.reject(err);
369
+ });
361
370
  },
362
371
 
363
372
 
@@ -69,16 +69,19 @@ function Client_MariaSQL(config) {
69
69
  var connection = new _this.driver();
70
70
  connection.connect((0, _assign3.default)({ metadata: true }, _this.connectionSettings));
71
71
  connection.on('ready', function () {
72
- connection.removeAllListeners('error');
73
72
  resolver(connection);
74
- }).on('error', rejecter);
73
+ }).on('error', function (err) {
74
+ connection.__knex__disposed = err;
75
+ rejecter(err);
76
+ });
75
77
  });
76
78
  },
77
79
  validateConnection: function validateConnection(connection) {
78
80
  if (connection.connected === true) {
79
- return _bluebird2.default.resolve(true);
81
+ return true;
80
82
  }
81
- return _bluebird2.default.resolve(false);
83
+
84
+ return false;
82
85
  },
83
86
 
84
87
 
@@ -104,7 +104,7 @@ var SQL_BIGINT_SAFE = { MIN: -9007199254740991, MAX: 9007199254740991
104
104
  return require('mssql');
105
105
  },
106
106
  formatter: function formatter() {
107
- return new MSSQL_Formatter(this);
107
+ return new (Function.prototype.bind.apply(MSSQL_Formatter, [null].concat([this], Array.prototype.slice.call(arguments))))();
108
108
  },
109
109
  transaction: function transaction() {
110
110
  return new (Function.prototype.bind.apply(_transaction2.default, [null].concat([this], Array.prototype.slice.call(arguments))))();
@@ -122,7 +122,7 @@ var SQL_BIGINT_SAFE = { MIN: -9007199254740991, MAX: 9007199254740991
122
122
  return new (Function.prototype.bind.apply(_columncompiler2.default, [null].concat([this], Array.prototype.slice.call(arguments))))();
123
123
  },
124
124
  wrapIdentifierImpl: function wrapIdentifierImpl(value) {
125
- return value !== '*' ? '[' + value.replace(/\[/g, '\[') + ']' : '*';
125
+ return value !== '*' ? '[' + value.replace(/\[/g, '[') + ']' : '*';
126
126
  },
127
127
 
128
128
 
@@ -146,9 +146,10 @@ var SQL_BIGINT_SAFE = { MIN: -9007199254740991, MAX: 9007199254740991
146
146
  },
147
147
  validateConnection: function validateConnection(connection) {
148
148
  if (connection.connected === true) {
149
- return _bluebird2.default.resolve(true);
149
+ return true;
150
150
  }
151
- return _bluebird2.default.resolve(false);
151
+
152
+ return false;
152
153
  },
153
154
 
154
155
 
@@ -6,6 +6,10 @@ var _typeof2 = require('babel-runtime/helpers/typeof');
6
6
 
7
7
  var _typeof3 = _interopRequireDefault(_typeof2);
8
8
 
9
+ var _identity2 = require('lodash/identity');
10
+
11
+ var _identity3 = _interopRequireDefault(_identity2);
12
+
9
13
  var _compact2 = require('lodash/compact');
10
14
 
11
15
  var _compact3 = _interopRequireDefault(_compact2);
@@ -108,7 +112,7 @@ var components = ['columns', 'join', 'lock', 'where', 'union', 'group', 'having'
108
112
  var returning = this.single.returning;
109
113
 
110
114
  return {
111
- sql: this.with() + ('update ' + (top ? top + ' ' : '') + this.tableName) + ' set ' + updates.join(', ') + (join ? ' from ' + this.tableName + ' ' + join : '') + (returning ? ' ' + this._returning('update', returning) : '') + (where ? ' ' + where : '') + (order ? ' ' + order : '') + (!returning ? this._returning('rowcount', '@@rowcount') : ''),
115
+ sql: this.with() + ('update ' + (top ? top + ' ' : '') + this.tableName) + ' set ' + updates.join(', ') + (returning ? ' ' + this._returning('update', returning) : '') + (join ? ' from ' + this.tableName + ' ' + join : '') + (where ? ' ' + where : '') + (order ? ' ' + order : '') + (!returning ? this._returning('rowcount', '@@rowcount') : ''),
112
116
  returning: returning || '@@rowcount'
113
117
  };
114
118
  },
@@ -182,12 +186,23 @@ var components = ['columns', 'join', 'lock', 'where', 'union', 'group', 'having'
182
186
  // Compiles a `columnInfo` query.
183
187
  columnInfo: function columnInfo() {
184
188
  var column = this.single.columnInfo;
189
+ var schema = this.single.schema;
190
+
191
+ // The user may have specified a custom wrapIdentifier function in the config. We
192
+ // need to run the identifiers through that function, but not format them as
193
+ // identifiers otherwise.
194
+ var table = this.client.customWrapIdentifier(this.single.table, _identity3.default);
195
+
196
+ if (schema) {
197
+ schema = this.client.customWrapIdentifier(schema, _identity3.default);
198
+ }
199
+
185
200
  var sql = 'select * from information_schema.columns where table_name = ? and table_catalog = ?';
186
- var bindings = [this.single.table, this.client.database()];
201
+ var bindings = [table, this.client.database()];
187
202
 
188
- if (this.single.schema) {
203
+ if (schema) {
189
204
  sql += ' and table_schema = ?';
190
- bindings.push(this.single.schema);
205
+ bindings.push(schema);
191
206
  } else {
192
207
  sql += ' and table_schema = \'dbo\'';
193
208
  }
@@ -75,6 +75,8 @@ function ColumnCompiler_MSSQL() {
75
75
 
76
76
  longtext: 'nvarchar(max)',
77
77
 
78
+ // TODO: mssql supports check constraints as of SQL Server 2008
79
+ // so make enu here more like postgres
78
80
  enu: 'nvarchar(100)',
79
81
 
80
82
  uuid: 'uniqueidentifier',
@@ -98,7 +98,7 @@ function TableCompiler_MSSQL() {
98
98
  this.pushQuery('exec sp_rename ' + this.formatter.parameter(this.tableName() + '.' + from) + ', ' + this.formatter.parameter(to) + ', \'COLUMN\'');
99
99
  },
100
100
  dropFKRefs: function dropFKRefs(runner, refs) {
101
- var formatter = this.client.formatter();
101
+ var formatter = this.client.formatter(this.tableBuilder);
102
102
  return _bluebird2.default.all(refs.map(function (ref) {
103
103
  var constraintName = formatter.wrap(ref.CONSTRAINT_NAME);
104
104
  var tableName = formatter.wrap(ref.TABLE_NAME);
@@ -108,7 +108,7 @@ function TableCompiler_MSSQL() {
108
108
  }));
109
109
  },
110
110
  createFKRefs: function createFKRefs(runner, refs) {
111
- var formatter = this.client.formatter();
111
+ var formatter = this.client.formatter(this.tableBuilder);
112
112
 
113
113
  return _bluebird2.default.all(refs.map(function (ref) {
114
114
  var tableName = formatter.wrap(ref.TABLE_NAME);
@@ -103,11 +103,15 @@ function Client_MySQL(config) {
103
103
 
104
104
  return new _bluebird2.default(function (resolver, rejecter) {
105
105
  var connection = _this.driver.createConnection(_this.connectionSettings);
106
+ connection.on('error', function (err) {
107
+ connection.__knex__disposed = err;
108
+ });
106
109
  connection.connect(function (err) {
107
- if (err) return rejecter(err);
108
- connection.on('error', function (err) {
109
- connection.__knex__disposed = err;
110
- });
110
+ if (err) {
111
+ // if connection is rejected, remove listener that was registered above...
112
+ connection.removeAllListeners();
113
+ return rejecter(err);
114
+ }
111
115
  resolver(connection);
112
116
  });
113
117
  });
@@ -117,16 +121,17 @@ function Client_MySQL(config) {
117
121
  // Used to explicitly close a connection, called internally by the pool
118
122
  // when a connection times out or the pool is shutdown.
119
123
  destroyRawConnection: function destroyRawConnection(connection) {
120
- connection.removeAllListeners();
121
124
  return _bluebird2.default.fromCallback(connection.end.bind(connection)).catch(function (err) {
122
125
  connection.__knex__disposed = err;
126
+ }).finally(function () {
127
+ return connection.removeAllListeners();
123
128
  });
124
129
  },
125
130
  validateConnection: function validateConnection(connection) {
126
131
  if (connection.state === 'connected' || connection.state === 'authenticated') {
127
- return _bluebird2.default.resolve(true);
132
+ return true;
128
133
  }
129
- return _bluebird2.default.resolve(false);
134
+ return false;
130
135
  },
131
136
 
132
137