| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const _ = require('lodash/fp'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const helpers = require('./helpers'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 16:05:52 +02:00
										 |  |  | const createQueryBuilder = (uid, db, initialState = {}) => { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |   const meta = db.metadata.get(uid); | 
					
						
							|  |  |  |   const { tableName } = meta; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 16:05:52 +02:00
										 |  |  |   const state = _.defaults( | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       type: 'select', | 
					
						
							|  |  |  |       select: [], | 
					
						
							|  |  |  |       count: null, | 
					
						
							|  |  |  |       max: null, | 
					
						
							|  |  |  |       first: false, | 
					
						
							|  |  |  |       data: null, | 
					
						
							|  |  |  |       where: [], | 
					
						
							|  |  |  |       joins: [], | 
					
						
							|  |  |  |       populate: null, | 
					
						
							|  |  |  |       limit: null, | 
					
						
							|  |  |  |       offset: null, | 
					
						
							|  |  |  |       transaction: null, | 
					
						
							|  |  |  |       forUpdate: false, | 
					
						
							| 
									
										
										
										
											2022-09-20 15:53:17 +02:00
										 |  |  |       onConflict: null, | 
					
						
							|  |  |  |       merge: null, | 
					
						
							|  |  |  |       ignore: false, | 
					
						
							| 
									
										
										
										
											2022-08-05 16:05:52 +02:00
										 |  |  |       orderBy: [], | 
					
						
							|  |  |  |       groupBy: [], | 
					
						
							| 
									
										
										
										
											2022-09-15 11:15:05 +02:00
										 |  |  |       increments: [], | 
					
						
							|  |  |  |       decrements: [], | 
					
						
							| 
									
										
										
										
											2022-08-05 16:05:52 +02:00
										 |  |  |       aliasCounter: 0, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     initialState | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-05 19:44:58 +02:00
										 |  |  |   const getAlias = () => { | 
					
						
							| 
									
										
										
										
											2022-09-08 15:41:31 +02:00
										 |  |  |     const alias = `t${state.aliasCounter}`; | 
					
						
							| 
									
										
										
										
											2022-09-05 19:44:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 15:41:31 +02:00
										 |  |  |     state.aliasCounter += 1; | 
					
						
							| 
									
										
										
										
											2022-09-05 19:44:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return alias; | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     alias: getAlias(), | 
					
						
							|  |  |  |     getAlias, | 
					
						
							| 
									
										
										
										
											2021-10-13 14:06:16 +02:00
										 |  |  |     state, | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 16:05:52 +02:00
										 |  |  |     clone() { | 
					
						
							|  |  |  |       return createQueryBuilder(uid, db, state); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-06 10:51:34 +02:00
										 |  |  |     select(args) { | 
					
						
							|  |  |  |       state.type = 'select'; | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.select = _.uniq(_.castArray(args)); | 
					
						
							| 
									
										
										
										
											2021-08-11 09:34:55 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     addSelect(args) { | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.select = _.uniq([...state.select, ..._.castArray(args)]); | 
					
						
							| 
									
										
										
										
											2021-08-06 10:51:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     insert(data) { | 
					
						
							|  |  |  |       state.type = 'insert'; | 
					
						
							|  |  |  |       state.data = data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-20 15:53:17 +02:00
										 |  |  |     onConflict(args) { | 
					
						
							|  |  |  |       state.onConflict = args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     merge(args) { | 
					
						
							|  |  |  |       state.merge = args; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ignore() { | 
					
						
							|  |  |  |       state.ignore = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     delete() { | 
					
						
							|  |  |  |       state.type = 'delete'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |     ref(name) { | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |       return db.connection.ref(helpers.toColumnName(meta, name)); | 
					
						
							| 
									
										
										
										
											2021-09-13 12:03:12 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     update(data) { | 
					
						
							|  |  |  |       state.type = 'update'; | 
					
						
							|  |  |  |       state.data = data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 11:15:05 +02:00
										 |  |  |     increment(column, amount = 1) { | 
					
						
							|  |  |  |       state.type = 'update'; | 
					
						
							|  |  |  |       state.increments.push({ column, amount }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     decrement(column, amount = 1) { | 
					
						
							|  |  |  |       state.type = 'update'; | 
					
						
							|  |  |  |       state.decrements.push({ column, amount }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 10:45:58 +03:00
										 |  |  |     count(count = 'id') { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       state.type = 'count'; | 
					
						
							|  |  |  |       state.count = count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |     max(column) { | 
					
						
							|  |  |  |       state.type = 'max'; | 
					
						
							|  |  |  |       state.max = column; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-22 17:13:11 +02:00
										 |  |  |     where(where = {}) { | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       if (!_.isPlainObject(where)) { | 
					
						
							|  |  |  |         throw new Error('Where must be an object'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.where.push(where); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     limit(limit) { | 
					
						
							|  |  |  |       state.limit = limit; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     offset(offset) { | 
					
						
							|  |  |  |       state.offset = offset; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     orderBy(orderBy) { | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.orderBy = orderBy; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     groupBy(groupBy) { | 
					
						
							|  |  |  |       state.groupBy = groupBy; | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |       return this; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     populate(populate) { | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.populate = populate; | 
					
						
							| 
									
										
										
										
											2021-07-28 21:03:32 +02:00
										 |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-28 21:03:32 +02:00
										 |  |  |     search(query) { | 
					
						
							|  |  |  |       state.search = query; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-18 19:00:43 +02:00
										 |  |  |     transacting(transaction) { | 
					
						
							|  |  |  |       state.transaction = transaction; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     forUpdate() { | 
					
						
							|  |  |  |       state.forUpdate = true; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     init(params = {}) { | 
					
						
							| 
									
										
										
										
											2021-10-13 14:06:16 +02:00
										 |  |  |       const { _q, filters, where, select, limit, offset, orderBy, groupBy, populate } = params; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(where)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.where(where); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(_q)) { | 
					
						
							| 
									
										
										
										
											2021-07-28 21:03:32 +02:00
										 |  |  |         this.search(_q); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(select)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.select(select); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         this.select('*'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(limit)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.limit(limit); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(offset)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.offset(offset); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(orderBy)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.orderBy(orderBy); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(groupBy)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.groupBy(groupBy); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-09 18:20:27 +02:00
										 |  |  |       if (!_.isNil(populate)) { | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         this.populate(populate); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 14:06:16 +02:00
										 |  |  |       if (!_.isNil(filters)) { | 
					
						
							|  |  |  |         this.filters(filters); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 14:06:16 +02:00
										 |  |  |     filters(filters) { | 
					
						
							|  |  |  |       state.filters = filters; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     first() { | 
					
						
							|  |  |  |       state.first = true; | 
					
						
							|  |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     join(join) { | 
					
						
							| 
									
										
										
										
											2022-08-16 17:01:52 +02:00
										 |  |  |       if (!join.targetField) { | 
					
						
							|  |  |  |         state.joins.push(join); | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const model = db.metadata.get(uid); | 
					
						
							|  |  |  |       const attribute = model.attributes[join.targetField]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       helpers.createJoin( | 
					
						
							|  |  |  |         { db, qb: this }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           alias: this.alias, | 
					
						
							|  |  |  |           refAlias: join.alias, | 
					
						
							|  |  |  |           attributeName: join.targetField, | 
					
						
							|  |  |  |           attribute, | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |       return this; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |     mustUseAlias() { | 
					
						
							|  |  |  |       return ['select', 'count'].includes(state.type); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |     aliasColumn(key, alias) { | 
					
						
							|  |  |  |       if (typeof key !== 'string') { | 
					
						
							|  |  |  |         return key; | 
					
						
							| 
									
										
										
										
											2021-07-08 18:15:32 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |       if (key.indexOf('.') >= 0) { | 
					
						
							|  |  |  |         return key; | 
					
						
							| 
									
										
										
										
											2021-09-16 23:29:25 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       if (!_.isNil(alias)) { | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |         return `${alias}.${key}`; | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |       return this.mustUseAlias() ? `${this.alias}.${key}` : key; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-08 18:15:32 +02:00
										 |  |  |     raw(...args) { | 
					
						
							|  |  |  |       return db.connection.raw(...args); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |     shouldUseSubQuery() { | 
					
						
							|  |  |  |       return ['delete', 'update'].includes(state.type) && state.joins.length > 0; | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |     runSubQuery() { | 
					
						
							|  |  |  |       this.select('id'); | 
					
						
							|  |  |  |       const subQB = this.getKnexQuery(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |       const nestedSubQuery = db.getConnection().select('id').from(subQB.as('subQuery')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return db.getConnection(tableName)[state.type]().whereIn('id', nestedSubQuery); | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     processState() { | 
					
						
							|  |  |  |       state.orderBy = helpers.processOrderBy(state.orderBy, { qb: this, uid, db }); | 
					
						
							| 
									
										
										
										
											2021-10-13 14:06:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (!_.isNil(state.filters)) { | 
					
						
							|  |  |  |         if (_.isFunction(state.filters)) { | 
					
						
							|  |  |  |           const filters = state.filters({ qb: this, uid, meta, db }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (!_.isNil(filters)) { | 
					
						
							|  |  |  |             state.where.push(filters); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           state.where.push(state.filters); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       state.where = helpers.processWhere(state.where, { qb: this, uid, db }); | 
					
						
							|  |  |  |       state.populate = helpers.processPopulate(state.populate, { qb: this, uid, db }); | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |       state.data = helpers.toRow(meta, state.data); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       this.processSelect(); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 10:45:58 +03:00
										 |  |  |     shouldUseDistinct() { | 
					
						
							|  |  |  |       return state.joins.length > 0 && _.isEmpty(state.groupBy); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     processSelect() { | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |       state.select = state.select.map((field) => helpers.toColumnName(meta, field)); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |       if (this.shouldUseDistinct()) { | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |         const joinsOrderByColumns = state.joins.flatMap((join) => { | 
					
						
							|  |  |  |           return _.keys(join.orderBy).map((key) => this.aliasColumn(key, join.alias)); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  |         }); | 
					
						
							|  |  |  |         const orderByColumns = state.orderBy.map(({ column }) => column); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 20:10:48 +02:00
										 |  |  |         state.select = _.uniq([...joinsOrderByColumns, ...orderByColumns, ...state.select]); | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getKnexQuery() { | 
					
						
							| 
									
										
										
										
											2021-07-08 18:15:32 +02:00
										 |  |  |       if (!state.type) { | 
					
						
							|  |  |  |         this.select('*'); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |       const aliasedTableName = this.mustUseAlias() ? `${tableName} as ${this.alias}` : tableName; | 
					
						
							| 
									
										
										
										
											2021-09-16 22:18:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 19:42:03 +01:00
										 |  |  |       const qb = db.getConnection(aliasedTableName); | 
					
						
							| 
									
										
										
										
											2021-09-16 22:18:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       if (this.shouldUseSubQuery()) { | 
					
						
							|  |  |  |         return this.runSubQuery(); | 
					
						
							| 
									
										
										
										
											2021-09-16 22:18:13 +02:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  |       this.processState(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       switch (state.type) { | 
					
						
							|  |  |  |         case 'select': { | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |           qb.select(state.select.map((column) => this.aliasColumn(column))); | 
					
						
							| 
									
										
										
										
											2021-09-21 19:16:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-22 18:49:04 +02:00
										 |  |  |           if (this.shouldUseDistinct()) { | 
					
						
							|  |  |  |             qb.distinct(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |         case 'count': { | 
					
						
							| 
									
										
										
										
											2022-08-09 10:45:58 +03:00
										 |  |  |           const dbColumnName = this.aliasColumn(helpers.toColumnName(meta, state.count)); | 
					
						
							| 
									
										
										
										
											2022-08-03 12:59:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-09 10:45:58 +03:00
										 |  |  |           if (this.shouldUseDistinct()) { | 
					
						
							| 
									
										
										
										
											2022-08-03 14:46:07 +03:00
										 |  |  |             qb.countDistinct({ count: dbColumnName }); | 
					
						
							|  |  |  |           } else { | 
					
						
							|  |  |  |             qb.count({ count: dbColumnName }); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         case 'max': { | 
					
						
							| 
									
										
										
										
											2022-06-07 11:16:53 +02:00
										 |  |  |           const dbColumnName = this.aliasColumn(helpers.toColumnName(meta, state.max)); | 
					
						
							|  |  |  |           qb.max({ max: dbColumnName }); | 
					
						
							| 
									
										
										
										
											2022-06-03 16:21:52 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |         case 'insert': { | 
					
						
							|  |  |  |           qb.insert(state.data); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           if (db.dialect.useReturning() && _.has('id', meta.attributes)) { | 
					
						
							|  |  |  |             qb.returning('id'); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |         case 'update': { | 
					
						
							| 
									
										
										
										
											2022-09-15 11:15:05 +02:00
										 |  |  |           if (state.data) { | 
					
						
							|  |  |  |             qb.update(state.data); | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |         case 'delete': { | 
					
						
							| 
									
										
										
										
											2021-09-16 23:29:25 +02:00
										 |  |  |           qb.delete(); | 
					
						
							| 
									
										
										
										
											2021-09-21 13:26:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 22:18:13 +02:00
										 |  |  |           break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         case 'truncate': { | 
					
						
							|  |  |  |           db.truncate(); | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |         default: { | 
					
						
							|  |  |  |           throw new Error('Unknown query type'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-18 19:00:43 +02:00
										 |  |  |       if (state.transaction) { | 
					
						
							|  |  |  |         qb.transacting(state.transaction); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (state.forUpdate) { | 
					
						
							|  |  |  |         qb.forUpdate(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 11:15:05 +02:00
										 |  |  |       if (!_.isEmpty(state.increments)) { | 
					
						
							|  |  |  |         state.increments.forEach((incr) => qb.increment(incr.column, incr.amount)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!_.isEmpty(state.decrements)) { | 
					
						
							|  |  |  |         state.decrements.forEach((decr) => qb.decrement(decr.column, decr.amount)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-20 15:53:17 +02:00
										 |  |  |       if (state.onConflict) { | 
					
						
							|  |  |  |         if (state.merge) { | 
					
						
							|  |  |  |           qb.onConflict(state.onConflict).merge(state.merge); | 
					
						
							|  |  |  |         } else if (state.ignore) { | 
					
						
							|  |  |  |           qb.onConflict(state.onConflict).ignore(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       if (state.limit) { | 
					
						
							|  |  |  |         qb.limit(state.limit); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       if (state.offset) { | 
					
						
							|  |  |  |         qb.offset(state.offset); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (state.orderBy.length > 0) { | 
					
						
							|  |  |  |         qb.orderBy(state.orderBy); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (state.first) { | 
					
						
							|  |  |  |         qb.first(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (state.groupBy.length > 0) { | 
					
						
							|  |  |  |         qb.groupBy(state.groupBy); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 15:32:27 +02:00
										 |  |  |       // if there are joins and it is a delete or update use a sub query
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       if (state.where) { | 
					
						
							|  |  |  |         helpers.applyWhere(qb, state.where); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-16 15:32:27 +02:00
										 |  |  |       // if there are joins and it is a delete or update use a sub query
 | 
					
						
							| 
									
										
										
										
											2021-07-28 21:03:32 +02:00
										 |  |  |       if (state.search) { | 
					
						
							| 
									
										
										
										
											2022-08-08 23:33:39 +02:00
										 |  |  |         qb.where((subQb) => { | 
					
						
							| 
									
										
										
										
											2021-09-22 10:49:43 +02:00
										 |  |  |           helpers.applySearch(subQb, state.search, { qb: this, db, uid }); | 
					
						
							| 
									
										
										
										
											2021-07-28 21:03:32 +02:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-05 18:35:16 +02:00
										 |  |  |       if (state.joins.length > 0) { | 
					
						
							|  |  |  |         helpers.applyJoins(qb, state.joins); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return qb; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     async execute({ mapResults = true } = {}) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         const qb = this.getKnexQuery(); | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-28 21:37:44 +02:00
										 |  |  |         const rows = await qb; | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 20:00:03 +02:00
										 |  |  |         if (state.populate && !_.isNil(rows)) { | 
					
						
							|  |  |  |           await helpers.applyPopulate(_.castArray(rows), state.populate, { qb: this, uid, db }); | 
					
						
							| 
									
										
										
										
											2021-06-28 21:37:44 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 20:00:03 +02:00
										 |  |  |         let results = rows; | 
					
						
							|  |  |  |         if (mapResults && state.type === 'select') { | 
					
						
							| 
									
										
										
										
											2021-06-30 21:17:32 +02:00
										 |  |  |           results = helpers.fromRow(meta, rows); | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-24 18:28:36 +02:00
										 |  |  |         return results; | 
					
						
							|  |  |  |       } catch (error) { | 
					
						
							|  |  |  |         db.dialect.transformErrors(error); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-06-17 16:17:15 +02:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = createQueryBuilder; |