You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

210 line
7.1 KiB

  1. const knex = require('knex');
  2. knex.QueryBuilder.extend('whereGroup', function(condition, rules) {
  3. condition = condition.toLowerCase();
  4. // TODO: Escape likes
  5. for (let rule of rules) {
  6. if (!rule.condition) {
  7. let where = condition == 'or' ? 'orWhere' : 'where';
  8. let column = rule.data ? rule.data.column : rule.column;
  9. if (rule.data && rule.data.table) {
  10. if (rule.data.schema) {
  11. column = rule.data.schema + '.' + rule.data.table + '.' + column;
  12. } else {
  13. column = rule.data.table + '.' + column;
  14. }
  15. } else if (rule.table) {
  16. if (rule.schema) {
  17. column = rule.schema + '.' + rule.table + '.' + column;
  18. } else {
  19. column = rule.table + '.' + column;
  20. }
  21. }
  22. if (typeof rule.value == 'undefined') {
  23. rule.value = null;
  24. }
  25. if (rule.operator == 'between') {
  26. this[where + 'Between'](column, rule.value);
  27. } else if (rule.operator == 'not_between') {
  28. this[where + 'NotBetween'](column, rule.value);
  29. } else if (rule.operator == 'is_null') {
  30. this[where + 'Null'](column);
  31. } else if (rule.operator == 'is_not_null') {
  32. this[where + 'NotNull'](column);
  33. } else if (rule.operator == 'in') {
  34. this[where + 'In'](column, rule.value);
  35. } else if (rule.operator == 'not_in') {
  36. this[where + 'NotIn'](column, rule.value);
  37. } else if (rule.operator == 'begins_with') {
  38. this[where](column, 'like', rule.value + '%');
  39. } else if (rule.operator == 'not_begins_with') {
  40. this[where + 'Not'](column, 'like', rule.value + '%');
  41. } else if (rule.operator == 'ends_with') {
  42. this[where](column, 'like', '%' + rule.value);
  43. } else if (rule.operator == 'not_ends_with') {
  44. this[where + 'Not'](column, 'like', '%' + rule.value);
  45. } else if (rule.operator == 'contains') {
  46. this[where](column, 'like', '%' + rule.value + '%');
  47. } else if (rule.operator == 'not_contains') {
  48. this[where + 'Not'](column, 'like', '%' + rule.value + '%');
  49. } else {
  50. this[where](column, rule.operation, rule.value);
  51. }
  52. } else {
  53. this[condition + 'Where'](function() {
  54. this.whereGroup(rule.condition, rule.rules);
  55. });
  56. }
  57. }
  58. return this;
  59. });
  60. knex.QueryBuilder.extend('fromJSON', function(ast, meta) {
  61. if (ast.type == 'count') {
  62. return this.count('* as Total').from(function() {
  63. this.fromJSON(Object.assign({}, ast, {
  64. type: 'select',
  65. offset: null,
  66. limit: null,
  67. orders: null
  68. })).as('t1');
  69. }).first();
  70. } else if (ast.type == 'insert' || ast.type == 'update') {
  71. let values = {};
  72. for (let val of ast.values) {
  73. if (val.type == 'json') {
  74. // json support
  75. values[val.column] = JSON.stringify(val.value);
  76. } else {
  77. values[val.column] = val.value;
  78. }
  79. }
  80. this[ast.type](values);
  81. } else {
  82. this[ast.type]();
  83. }
  84. if (ast.returning) {
  85. // Adding the option includeTriggerModifications allows you
  86. // to run statements on tables that contain triggers. Only affects MSSQL.
  87. this.returning(ast.returning, { includeTriggerModifications: true });
  88. }
  89. if (ast.table) {
  90. let table = ast.table.name || ast.table;
  91. if (ast.table.schema) {
  92. table = ast.table.schema + '.' + table;
  93. }
  94. if (ast.table.alias) {
  95. table += ' as ' + ast.table.alias;
  96. }
  97. this.from(table);
  98. }
  99. if ((ast.type == 'select' || ast.type == 'first') && ast.joins && ast.joins.length) {
  100. for (let join of ast.joins) {
  101. let table = join.table;
  102. if (join.schema) {
  103. table = join.schema + '.' + table;
  104. }
  105. if (join.alias) {
  106. table += ' as ' + join.alias;
  107. }
  108. this[(join.type || 'inner').toLowerCase() + 'Join'](table, function() {
  109. for (let clause of join.clauses.rules) {
  110. this.on(
  111. (clause.schema ? clause.schema + '.' : '') + clause.table + '.' + clause.column,
  112. clause.operation,
  113. (clause.value.schema ? clause.value.schema + '.' : '') + clause.value.table + '.' + clause.value.column
  114. );
  115. }
  116. });
  117. }
  118. }
  119. if ((ast.type == 'select' || ast.type == 'first') && ast.columns) {
  120. for (let col of ast.columns) {
  121. let column = col.column || col;
  122. if (ast.joins && ast.joins.length && col.table) {
  123. column = col.table + '.' + column;
  124. if (col.schema) {
  125. column = col.schema + '.' + column;
  126. }
  127. }
  128. if (col.alias) {
  129. column += ' as ' + col.alias;
  130. }
  131. this[col.aggregate ? col.aggregate.toLowerCase() : 'column'](column);
  132. }
  133. }
  134. if ((ast.type == 'select' || ast.type == 'first') && ast.groupBy && ast.groupBy.length) {
  135. for (let col of ast.groupBy) {
  136. if (ast.joins && ast.joins.length && col.table) {
  137. if (col.schema) {
  138. this.groupBy(col.schema + '.' + col.table + '.' + col.column);
  139. } else {
  140. this.groupBy(col.table + '.' + col.column);
  141. }
  142. } else {
  143. this.groupBy(col.column || col);
  144. }
  145. }
  146. }
  147. if (ast.wheres && ast.wheres.condition) {
  148. this.whereGroup(ast.wheres.condition, ast.wheres.rules);
  149. }
  150. if ((ast.type == 'select' || ast.type == 'first') && ast.orders && ast.orders.length) {
  151. for (let order of ast.orders) {
  152. if (ast.joins && ast.joins.length && order.table) {
  153. if (order.schema) {
  154. this.orderBy(order.schema + '.' + order.table + '.' + order.column, order.direction);
  155. } else {
  156. this.orderBy(order.table + '.' + order.column, order.direction);
  157. }
  158. } else {
  159. this.orderBy(order.column, order.direction);
  160. }
  161. }
  162. }
  163. if (ast.distinct) {
  164. this.distinct();
  165. }
  166. if (ast.type == 'select' && ast.limit) {
  167. this.limit(ast.limit);
  168. }
  169. if (ast.type == 'select' && ast.offset) {
  170. this.offset(ast.offset);
  171. }
  172. if (meta) {
  173. this.queryContext(meta);
  174. }
  175. return this;
  176. });
  177. module.exports = knex;