tablebuilder.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. // Each of the column types that we can add, we create a new ColumnBuilder
  86. // instance and push it onto the statements array.
  87. var columnTypes = [
  88. // Numeric
  89. 'tinyint', 'smallint', 'mediumint', 'int', 'bigint', 'decimal', 'float', 'double', 'real', 'bit', 'boolean', 'serial',
  90. // Date / Time
  91. 'date', 'datetime', 'timestamp', 'time', 'year',
  92. // String
  93. 'char', 'varchar', 'tinytext', 'tinyText', 'text', 'mediumtext', 'mediumText', 'longtext', 'longText', 'binary', 'varbinary', 'tinyblob', 'tinyBlob', 'mediumblob', 'mediumBlob', 'blob', 'longblob', 'longBlob', 'enum', 'set',
  94. // Increments, Aliases, and Additional
  95. 'bool', 'dateTime', 'increments', 'bigincrements', 'bigIncrements', 'integer', 'biginteger', 'bigInteger', 'string', 'json', 'jsonb', 'uuid', 'enu', 'specificType'];
  96. // For each of the column methods, create a new "ColumnBuilder" interface,
  97. // push it onto the "allStatements" stack, and then return the interface,
  98. // with which we can add indexes, etc.
  99. (0, _each3.default)(columnTypes, function (type) {
  100. TableBuilder.prototype[type] = function () {
  101. var args = (0, _toArray3.default)(arguments);
  102. var builder = this.client.columnBuilder(this, type, args);
  103. this._statements.push({
  104. grouping: 'columns',
  105. builder: builder
  106. });
  107. return builder;
  108. };
  109. });
  110. // The "timestamps" call is really just sets the `created_at` and `updated_at` columns.
  111. TableBuilder.prototype.timestamps = function timestamps() {
  112. var method = arguments[0] === true ? 'timestamp' : 'datetime';
  113. var createdAt = this[method]('created_at');
  114. var updatedAt = this[method]('updated_at');
  115. if (arguments[1] === true) {
  116. var now = this.client.raw('CURRENT_TIMESTAMP');
  117. createdAt.notNullable().defaultTo(now);
  118. updatedAt.notNullable().defaultTo(now);
  119. }
  120. return;
  121. };
  122. // Set the comment value for a table, they're only allowed to be called
  123. // once per table.
  124. TableBuilder.prototype.comment = function (value) {
  125. this._single.comment = value;
  126. };
  127. // Set a foreign key on the table, calling
  128. // `table.foreign('column_name').references('column').on('table').onDelete()...
  129. // Also called from the ColumnBuilder context when chaining.
  130. TableBuilder.prototype.foreign = function (column, keyName) {
  131. var foreignData = { column: column, keyName: keyName };
  132. this._statements.push({
  133. grouping: 'alterTable',
  134. method: 'foreign',
  135. args: [foreignData]
  136. });
  137. var returnObj = {
  138. references: function references(tableColumn) {
  139. var pieces = void 0;
  140. if ((0, _isString3.default)(tableColumn)) {
  141. pieces = tableColumn.split('.');
  142. }
  143. if (!pieces || pieces.length === 1) {
  144. foreignData.references = pieces ? pieces[0] : tableColumn;
  145. return {
  146. on: function on(tableName) {
  147. if (typeof tableName !== 'string') {
  148. throw new TypeError('Expected tableName to be a string, got: ' + (typeof tableName === 'undefined' ? 'undefined' : (0, _typeof3.default)(tableName)));
  149. }
  150. foreignData.inTable = tableName;
  151. return returnObj;
  152. },
  153. inTable: function inTable() {
  154. return this.on.apply(this, arguments);
  155. }
  156. };
  157. }
  158. foreignData.inTable = pieces[0];
  159. foreignData.references = pieces[1];
  160. return returnObj;
  161. },
  162. withKeyName: function withKeyName(keyName) {
  163. foreignData.keyName = keyName;
  164. return returnObj;
  165. },
  166. onUpdate: function onUpdate(statement) {
  167. foreignData.onUpdate = statement;
  168. return returnObj;
  169. },
  170. onDelete: function onDelete(statement) {
  171. foreignData.onDelete = statement;
  172. return returnObj;
  173. },
  174. _columnBuilder: function _columnBuilder(builder) {
  175. (0, _extend3.default)(builder, returnObj);
  176. returnObj = builder;
  177. return builder;
  178. }
  179. };
  180. return returnObj;
  181. };
  182. var AlterMethods = {
  183. // Renames the current column `from` the current
  184. // TODO: this.column(from).rename(to)
  185. renameColumn: function renameColumn(from, to) {
  186. this._statements.push({
  187. grouping: 'alterTable',
  188. method: 'renameColumn',
  189. args: [from, to]
  190. });
  191. return this;
  192. },
  193. dropTimestamps: function dropTimestamps() {
  194. return this.dropColumns(['created_at', 'updated_at']);
  195. }
  196. // TODO: changeType
  197. };
  198. // Drop a column from the current table.
  199. // TODO: Enable this.column(columnName).drop();
  200. AlterMethods.dropColumn = AlterMethods.dropColumns = function () {
  201. this._statements.push({
  202. grouping: 'alterTable',
  203. method: 'dropColumn',
  204. args: (0, _toArray3.default)(arguments)
  205. });
  206. return this;
  207. };
  208. exports.default = TableBuilder;
  209. module.exports = exports['default'];