tablebuilder.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. 'use strict';
  2. exports.__esModule = true;
  3. var _typeof2 = require('babel-runtime/helpers/typeof');
  4. var _typeof3 = _interopRequireDefault(_typeof2);
  5. var _isFunction2 = require('lodash/isFunction');
  6. var _isFunction3 = _interopRequireDefault(_isFunction2);
  7. var _isString2 = require('lodash/isString');
  8. var _isString3 = _interopRequireDefault(_isString2);
  9. var _toArray2 = require('lodash/toArray');
  10. var _toArray3 = _interopRequireDefault(_toArray2);
  11. var _each2 = require('lodash/each');
  12. var _each3 = _interopRequireDefault(_each2);
  13. var _extend2 = require('lodash/extend');
  14. var _extend3 = _interopRequireDefault(_extend2);
  15. var _helpers = require('../helpers');
  16. var helpers = _interopRequireWildcard(_helpers);
  17. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  18. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  19. function TableBuilder(client, method, tableName, fn) {
  20. this.client = client;
  21. this._fn = fn;
  22. this._method = method;
  23. this._schemaName = undefined;
  24. this._tableName = tableName;
  25. this._statements = [];
  26. this._single = {};
  27. if (!(0, _isFunction3.default)(this._fn)) {
  28. throw new TypeError('A callback function must be supplied to calls against `.createTable` ' + 'and `.table`');
  29. }
  30. }
  31. // TableBuilder
  32. // Takes the function passed to the "createTable" or "table/editTable"
  33. // functions and calls it with the "TableBuilder" as both the context and
  34. // the first argument. Inside this function we can specify what happens to the
  35. // method, pushing everything we want to do onto the "allStatements" array,
  36. // which is then compiled into sql.
  37. // ------
  38. TableBuilder.prototype.setSchema = function (schemaName) {
  39. this._schemaName = schemaName;
  40. };
  41. // Convert the current tableBuilder object "toSQL"
  42. // giving us additional methods if we're altering
  43. // rather than creating the table.
  44. TableBuilder.prototype.toSQL = function () {
  45. if (this._method === 'alter') {
  46. (0, _extend3.default)(this, AlterMethods);
  47. }
  48. this._fn.call(this, this);
  49. return this.client.tableCompiler(this).toSQL();
  50. };
  51. (0, _each3.default)([
  52. // Each of the index methods can be called individually, with the
  53. // column name to be used, e.g. table.unique('column').
  54. 'index', 'primary', 'unique',
  55. // Key specific
  56. 'dropPrimary', 'dropUnique', 'dropIndex', 'dropForeign'], function (method) {
  57. TableBuilder.prototype[method] = function () {
  58. this._statements.push({
  59. grouping: 'alterTable',
  60. method: method,
  61. args: (0, _toArray3.default)(arguments)
  62. });
  63. return this;
  64. };
  65. });
  66. // Warn for dialect-specific table methods, since that's the
  67. // only time these are supported.
  68. var specialMethods = {
  69. mysql: ['engine', 'charset', 'collate'],
  70. postgresql: ['inherits']
  71. };
  72. (0, _each3.default)(specialMethods, function (methods, dialect) {
  73. (0, _each3.default)(methods, function (method) {
  74. TableBuilder.prototype[method] = function (value) {
  75. if (this.client.dialect !== dialect) {
  76. helpers.warn('Knex only supports ' + method + ' statement with ' + dialect + '.');
  77. }
  78. if (this._method === 'alter') {
  79. helpers.warn('Knex does not support altering the ' + method + ' outside of create ' + 'table, please use knex.raw statement.');
  80. }
  81. this._single[method] = value;
  82. };
  83. });
  84. });
  85. helpers.addQueryContext(TableBuilder);
  86. // Each of the column types that we can add, we create a new ColumnBuilder
  87. // instance and push it onto the statements array.
  88. var columnTypes = [
  89. // Numeric
  90. 'tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'decimal', 'float', 'double', 'real', 'bit', 'boolean', 'serial',
  91. // Date / Time
  92. 'date', 'datetime', 'timestamp', 'time', 'year',
  93. // String
  94. 'char', 'varchar', 'tinytext', 'tinyText', 'text', 'mediumtext', 'mediumText', 'longtext', 'longText', 'binary', 'varbinary', 'tinyblob', 'tinyBlob', 'mediumblob', 'mediumBlob', 'blob', 'longblob', 'longBlob', 'enum', 'set',
  95. // Increments, Aliases, and Additional
  96. 'bool', 'dateTime', 'increments', 'bigincrements', 'bigIncrements', 'integer', 'biginteger', 'bigInteger', 'string', 'json', 'jsonb', 'uuid', 'enu', 'specificType'];
  97. // For each of the column methods, create a new "ColumnBuilder" interface,
  98. // push it onto the "allStatements" stack, and then return the interface,
  99. // with which we can add indexes, etc.
  100. (0, _each3.default)(columnTypes, function (type) {
  101. TableBuilder.prototype[type] = function () {
  102. var args = (0, _toArray3.default)(arguments);
  103. var builder = this.client.columnBuilder(this, type, args);
  104. this._statements.push({
  105. grouping: 'columns',
  106. builder: builder
  107. });
  108. return builder;
  109. };
  110. });
  111. // The "timestamps" call is really just sets the `created_at` and `updated_at` columns.
  112. TableBuilder.prototype.timestamps = function timestamps() {
  113. var method = arguments[0] === true ? 'timestamp' : 'datetime';
  114. var createdAt = this[method]('created_at');
  115. var updatedAt = this[method]('updated_at');
  116. if (arguments[1] === true) {
  117. var now = this.client.raw('CURRENT_TIMESTAMP');
  118. createdAt.notNullable().defaultTo(now);
  119. updatedAt.notNullable().defaultTo(now);
  120. }
  121. return;
  122. };
  123. // Set the comment value for a table, they're only allowed to be called
  124. // once per table.
  125. TableBuilder.prototype.comment = function (value) {
  126. if (typeof value !== 'string') {
  127. throw new TypeError('Table comment must be string');
  128. }
  129. this._single.comment = value;
  130. };
  131. // Set a foreign key on the table, calling
  132. // `table.foreign('column_name').references('column').on('table').onDelete()...
  133. // Also called from the ColumnBuilder context when chaining.
  134. TableBuilder.prototype.foreign = function (column, keyName) {
  135. var foreignData = { column: column, keyName: keyName };
  136. this._statements.push({
  137. grouping: 'alterTable',
  138. method: 'foreign',
  139. args: [foreignData]
  140. });
  141. var returnObj = {
  142. references: function references(tableColumn) {
  143. var pieces = void 0;
  144. if ((0, _isString3.default)(tableColumn)) {
  145. pieces = tableColumn.split('.');
  146. }
  147. if (!pieces || pieces.length === 1) {
  148. foreignData.references = pieces ? pieces[0] : tableColumn;
  149. return {
  150. on: function on(tableName) {
  151. if (typeof tableName !== 'string') {
  152. throw new TypeError('Expected tableName to be a string, got: ' + (typeof tableName === 'undefined' ? 'undefined' : (0, _typeof3.default)(tableName)));
  153. }
  154. foreignData.inTable = tableName;
  155. return returnObj;
  156. },
  157. inTable: function inTable() {
  158. return this.on.apply(this, arguments);
  159. }
  160. };
  161. }
  162. foreignData.inTable = pieces[0];
  163. foreignData.references = pieces[1];
  164. return returnObj;
  165. },
  166. withKeyName: function withKeyName(keyName) {
  167. foreignData.keyName = keyName;
  168. return returnObj;
  169. },
  170. onUpdate: function onUpdate(statement) {
  171. foreignData.onUpdate = statement;
  172. return returnObj;
  173. },
  174. onDelete: function onDelete(statement) {
  175. foreignData.onDelete = statement;
  176. return returnObj;
  177. },
  178. _columnBuilder: function _columnBuilder(builder) {
  179. (0, _extend3.default)(builder, returnObj);
  180. returnObj = builder;
  181. return builder;
  182. }
  183. };
  184. return returnObj;
  185. };
  186. var AlterMethods = {
  187. // Renames the current column `from` the current
  188. // TODO: this.column(from).rename(to)
  189. renameColumn: function renameColumn(from, to) {
  190. this._statements.push({
  191. grouping: 'alterTable',
  192. method: 'renameColumn',
  193. args: [from, to]
  194. });
  195. return this;
  196. },
  197. dropTimestamps: function dropTimestamps() {
  198. return this.dropColumns(['created_at', 'updated_at']);
  199. }
  200. // TODO: changeType
  201. };
  202. // Drop a column from the current table.
  203. // TODO: Enable this.column(columnName).drop();
  204. AlterMethods.dropColumn = AlterMethods.dropColumns = function () {
  205. this._statements.push({
  206. grouping: 'alterTable',
  207. method: 'dropColumn',
  208. args: (0, _toArray3.default)(arguments)
  209. });
  210. return this;
  211. };
  212. exports.default = TableBuilder;
  213. module.exports = exports['default'];