sql-love 0.9.1

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.
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Parse SQL and populate onto a Select query object
3
+ */
4
+ export default class Parser {
5
+ query;
6
+ /**
7
+ * Create a new instance
8
+ * @param query A Select object on which to build parsed conditions
9
+ */
10
+ constructor(query) {
11
+ this.query = query;
12
+ }
13
+ /**
14
+ * Strip single-line and multi-line comment blocks
15
+ * @param sql The SQL string
16
+ * @return The SQL string without comments
17
+ * @private
18
+ */
19
+ _stripComments(sql) {
20
+ // multiline comments
21
+ sql = sql.replace(/\/\*[\s\S]*?\*\//g, '');
22
+ // single line comments -- dashes
23
+ sql = sql.replace(/--([\r\n]|\s+[^\r\n]+[\r\n])/g, '');
24
+ // single line comments #hashes
25
+ sql = sql.replace(/#[^\r\n]+[\r\n]/g, '');
26
+ return sql;
27
+ }
28
+ /**
29
+ * Before splitting into SQL clauses, extract some regex-able subQueries
30
+ * @param sql The unparsed sql string
31
+ * @return An array with new sql and subQueries
32
+ * @private
33
+ */
34
+ _extractSubQueries(sql) {
35
+ const subQueries = {};
36
+ let i = 0;
37
+ const extractor = $0 => {
38
+ const placeholder = `~~SUBQUERY_${i++}~~`;
39
+ subQueries[placeholder] = $0;
40
+ return placeholder;
41
+ };
42
+ // subselect in FROM clause
43
+ sql = sql.replace(/\(\s*SELECT\s+.+\)\s+AS\s+[^\s,]+/, extractor);
44
+ // IF() in FROM clause
45
+ sql = sql.replace(/\bIF\s*\(.+\)\s+AS\s+[^\s,]+/, extractor);
46
+ // IN (SELECT *) in JOINs, WHERE or HAVING
47
+ sql = sql.replace(/\bIN\s*\(\s*SELECT\s.+?\)/, extractor);
48
+ return { sql, subQueries };
49
+ }
50
+ /**
51
+ * Inject column subQueries back into this object
52
+ * @param subQueries The lookup of extracted subQueries
53
+ * @private
54
+ */
55
+ _injectSubQueries(subQueries) {
56
+ const replacer = $0 => {
57
+ return subQueries[$0] || $0;
58
+ };
59
+ const mapper = clause => {
60
+ return clause.replace(/~~SUBQUERY_\d+~~/g, replacer);
61
+ };
62
+ this.query._columns = this.query._columns.map(replacer);
63
+ this.query._joins = this.query._joins.map(mapper);
64
+ this.query._wheres = this.query._wheres.map(mapper);
65
+ this.query._havings = this.query._havings.map(mapper);
66
+ }
67
+ /**
68
+ * Split SQL into clauses (used by parse())
69
+ * @param sql The SQL to split
70
+ * @return
71
+ * @private
72
+ */
73
+ _split(sql) {
74
+ const splitter = /(?:^|\s)(SELECT|FROM|(?:INNER|LEFT\s+OUTER|RIGHT\s+OUTER|LEFT|RIGHT|CROSS|FULL|FULL\s+OUTER)\s+JOIN|WHERE|GROUP\s+BY|HAVING|ORDER\s+BY|LIMIT|OFFSET|FETCH\s+NEXT)\b/i;
75
+ return sql.split(splitter);
76
+ }
77
+ /**
78
+ * Get a QuickSelect object representing the given SQL SELECT statement
79
+ * @param rawSql The raw SQL for the SELECT statement
80
+ * @return True if the SQL was parsed successfully
81
+ */
82
+ parse(rawSql) {
83
+ const stripped = this._stripComments(rawSql);
84
+ const { sql, subQueries } = this._extractSubQueries(stripped);
85
+ const expressions = this._split(sql);
86
+ let i = 1;
87
+ while (i < expressions.length) {
88
+ const rawKeyword = expressions[i++].trim();
89
+ const keyword = rawKeyword.toUpperCase().replace(/\s+/g, '_');
90
+ const clause = expressions[i++].trim();
91
+ const handler = `_handle${keyword}`;
92
+ this[handler](clause);
93
+ }
94
+ this._injectSubQueries(subQueries);
95
+ return true;
96
+ }
97
+ /**
98
+ * Handle SQL_CALC_FOUND_ROWS and column names
99
+ * @param clause The clause after the SELECT
100
+ * @private
101
+ */
102
+ _handleSELECT(clause) {
103
+ let columns = clause.split(/s*,s*/);
104
+ // now handle parenthesis expressions that contain commas
105
+ let buffer = '';
106
+ columns.forEach((column, i) => {
107
+ if (i === 0) {
108
+ const optionRegex = /^(SQL_CALC_FOUND_ROWS)\s+/i;
109
+ const match = column.match(optionRegex);
110
+ if (match) {
111
+ this.query.option(match[1]);
112
+ column = column.replace(optionRegex, '');
113
+ }
114
+ }
115
+ if (buffer.length) {
116
+ // we are in the middle of an expression containing parenthesis
117
+ if (column.indexOf(')') > 0) {
118
+ // we have an end parenthesis
119
+ buffer += column;
120
+ this.query.column(buffer.trim());
121
+ buffer = '';
122
+ }
123
+ else {
124
+ buffer += column + ',';
125
+ }
126
+ }
127
+ else if (column.match(/\([^)]+$/)) {
128
+ buffer = column + ',';
129
+ }
130
+ else {
131
+ this.query.column(column.trim());
132
+ }
133
+ });
134
+ }
135
+ /**
136
+ * Handle table names
137
+ * @param clause The clause after the FROM
138
+ * @private
139
+ */
140
+ _handleFROM(clause) {
141
+ const tables = clause.split(/\s*,\s*/);
142
+ tables.forEach(table => this.query.table(table));
143
+ }
144
+ /**
145
+ * Handle INNER JOIN statements
146
+ * @param clause The clause after the INNER JOIN
147
+ * @private
148
+ */
149
+ _handleINNER_JOIN(clause) {
150
+ this.query.innerJoin(clause);
151
+ }
152
+ /**
153
+ * Handle LEFT JOIN statements
154
+ * @param clause The clause after the LEFT JOIN
155
+ * @private
156
+ */
157
+ _handleLEFT_JOIN(clause) {
158
+ this.query.leftJoin(clause);
159
+ }
160
+ /**
161
+ * Handle LEFT OUTER JOIN statements
162
+ * @param clause The clause after the LEFT OUTER JOIN
163
+ * @private
164
+ */
165
+ _handleLEFT_OUTER_JOIN(clause) {
166
+ this.query.leftOuterJoin(clause);
167
+ }
168
+ /**
169
+ * Handle RIGHT JOIN statements
170
+ * @param clause The clause after the RIGHT JOIN
171
+ * @private
172
+ */
173
+ _handleRIGHT_JOIN(clause) {
174
+ this.query.rightJoin(clause);
175
+ }
176
+ /**
177
+ * Handle RIGHT OUTER JOIN statements
178
+ * @param clause The clause after the RIGHT OUTER JOIN
179
+ * @private
180
+ */
181
+ _handleRIGHT_OUTER_JOIN(clause) {
182
+ this.query.rightOuterJoin(clause);
183
+ }
184
+ /**
185
+ * Handle CROSS JOIN statements
186
+ * @param clause The clause after the CROSS JOIN
187
+ * @private
188
+ */
189
+ _handleCROSS_JOIN(clause) {
190
+ this.query.crossJoin(clause);
191
+ }
192
+ /**
193
+ * Handle FULL JOIN statements
194
+ * @param clause The clause after the FULL JOIN
195
+ * @private
196
+ */
197
+ _handleFULL_JOIN(clause) {
198
+ this.query.fullJoin(clause);
199
+ }
200
+ /**
201
+ * Handle FULL OUTER JOIN statements
202
+ * @param clause The clause after the FULL OUTER JOIN
203
+ * @private
204
+ */
205
+ _handleFULL_OUTER_JOIN(clause) {
206
+ this.query.fullOuterJoin(clause);
207
+ }
208
+ /**
209
+ * Handle WHERE conditions
210
+ * @param clause All the conditions after WHERE
211
+ * @private
212
+ */
213
+ _handleWHERE(clause) {
214
+ if (/^(1|'1'|true)$/i.test(clause)) {
215
+ this.query._wheres.push(clause);
216
+ }
217
+ else {
218
+ this._handleConditions('where', clause);
219
+ }
220
+ }
221
+ /**
222
+ * Handle HAVING statements
223
+ * @param clause All the conditions after HAVING
224
+ * @private
225
+ */
226
+ _handleHAVING(clause) {
227
+ this._handleConditions('having', clause);
228
+ }
229
+ /**
230
+ * Build a conditions list
231
+ * @param type Either where or having
232
+ * @param clause The expressions following the type keyword
233
+ * @private
234
+ */
235
+ _handleConditions(type, clause) {
236
+ const andGroups = clause.split(/\bAND\b/i);
237
+ andGroups.forEach(andGroup => {
238
+ const orPieces = andGroup.split(/\bOR\b/i).map(str => str.trim());
239
+ if (orPieces.length === 1) {
240
+ // no OR operators
241
+ const fn = type; // either where or having
242
+ this.query[fn](orPieces[0]);
243
+ }
244
+ else {
245
+ // some OR operators
246
+ // either orWhere or orHaving
247
+ const orFn = type === 'where' ? 'orWhere' : 'orHaving';
248
+ this.query[orFn](orPieces.map(p => [p]));
249
+ }
250
+ });
251
+ }
252
+ /**
253
+ * Handle GROUP BY statements
254
+ * @param clause The clauses after the GROUP BY
255
+ * @private
256
+ */
257
+ _handleGROUP_BY(clause) {
258
+ const columns = clause.split(/\s*,\s*/);
259
+ columns.forEach(column => this.query.groupBy(column));
260
+ }
261
+ /**
262
+ * Handle ORDER BY statements
263
+ * @param clause The clause after the ORDER BY
264
+ * @private
265
+ */
266
+ _handleORDER_BY(clause) {
267
+ const columns = clause.split(/\s*,\s*/);
268
+ columns.forEach(column => this.query.orderBy(column));
269
+ }
270
+ /**
271
+ * Handle LIMIT statements including "LIMIT #" and "LIMIT #, #"
272
+ * @param clause The clause after the LIMIT
273
+ * @private
274
+ */
275
+ _handleLIMIT(clause) {
276
+ const offsetLimit = clause.match(/^(\d+|\?|:\w+)\s*,\s*(\d+|\?|:\w+)$/);
277
+ if (offsetLimit) {
278
+ this.query.offset(offsetLimit[1]);
279
+ this.query.limit(offsetLimit[2]);
280
+ }
281
+ else {
282
+ clause = clause.replace(/ ROWS$/i, '');
283
+ this.query.limit(clause);
284
+ }
285
+ }
286
+ /**
287
+ * Handle OFFSET statements
288
+ * @param clause The number after the OFFSET
289
+ * @private
290
+ */
291
+ _handleOFFSET(clause) {
292
+ clause = clause.replace(/^(\d+) ROWS$/i, '$1');
293
+ this.query.offset(clause);
294
+ }
295
+ /**
296
+ * Handle OFFSET statements
297
+ * @param clause The number after the OFFSET
298
+ * @private
299
+ */
300
+ _handleFETCH_NEXT(clause) {
301
+ clause = clause.replace(/^(\d+) ROWS ONLY$/i, '$1');
302
+ this.query.limit(clause);
303
+ }
304
+ }
@@ -0,0 +1,355 @@
1
+ export type FieldName = 'option' | 'options' | 'select' | 'column' | 'columns' | 'table' | 'tables' | 'join' | 'joins' | 'where' | 'wheres' | 'having' | 'havings' | 'groupBy' | 'groupBys' | 'orderBy' | 'orderBys' | 'limit' | 'offset' | 'page';
2
+ export type EngineStyle = 'mssql' | 'mysql' | 'oracle' | 'pg';
3
+ export type WhereCriteria = [string, string, any] | [string, any] | [string] | [Record<string, any>];
4
+ /**
5
+ * Build a select query
6
+ * Class Select
7
+ */
8
+ export default class SelectBuilder {
9
+ /**
10
+ * The list of values to bind to the query
11
+ * @private
12
+ */
13
+ _bindings: any[];
14
+ /**
15
+ * The list of strings to come immediately after "SELECT"
16
+ * and before column names
17
+ * @private
18
+ */
19
+ _options: string[];
20
+ /**
21
+ * The list of column names to select
22
+ * @private
23
+ */
24
+ _tables: string[];
25
+ /**
26
+ * The list of tables in the FROM clause
27
+ * @private
28
+ */
29
+ _columns: string[];
30
+ /**
31
+ * The list of JOIN strings to add
32
+ * @private
33
+ */
34
+ _joins: string[];
35
+ /**
36
+ * The list of WHERE clauses to join with AND
37
+ * @private
38
+ */
39
+ _wheres: string[];
40
+ /**
41
+ * The list of GROUP BY clauses to join with commas
42
+ * @private
43
+ */
44
+ _groupBys: string[];
45
+ /**
46
+ * The list of HAVING clauses to join with AND
47
+ * @private
48
+ */
49
+ _havings: string[];
50
+ /**
51
+ * The list of ORDER BY clauses to join with commas
52
+ * @private
53
+ */
54
+ _orderBys: string[];
55
+ /**
56
+ * The LIMIT to use
57
+ * @private
58
+ */
59
+ _limit: number;
60
+ /**
61
+ * The OFFSET to use
62
+ * @private
63
+ */
64
+ _offset: number;
65
+ /**
66
+ * The page used to construct an OFFSET based on the LIMIT
67
+ * @private
68
+ */
69
+ _page: number;
70
+ /**
71
+ * Select constructor
72
+ * @param [sql] A base SQL query to parse
73
+ * @param [bindings] Placeholders to bind to the query
74
+ */
75
+ constructor(sql?: string, bindings?: Record<string, any>);
76
+ /**
77
+ * Get the SQL as a pretty-printed string alongside an array of bindings
78
+ * @param engineStyle The database engine style (mssql, mysql, oracle, pg)
79
+ * @return The SQL query as a string
80
+ */
81
+ compile(engineStyle?: EngineStyle): {
82
+ sql: string;
83
+ bindings: any;
84
+ };
85
+ _compileLIMIT(engineStyle: EngineStyle, limit: number): string;
86
+ _compileOFFSET(engineStyle: EngineStyle, offset: number): string;
87
+ /**
88
+ * Get SQL needed to return the found rows of this query
89
+ * @param countExpr The expression to use inside the COUNT()
90
+ * @param engineStyle The database engine style (mssql, mysql, oracle, pg)
91
+ */
92
+ compileCount(countExpr?: string, engineStyle?: EngineStyle): {
93
+ sql: string;
94
+ bindings: any;
95
+ };
96
+ /**
97
+ * @param [fieldOrFields] If given, reset the given component(s), otherwise reset all query components
98
+ * Valid components: option, column, table, where, orWhere, having, groupBy, orderBy, limit, offset, page
99
+ * @return This object
100
+ */
101
+ reset(fieldOrFields?: FieldName | FieldName[]): this;
102
+ /**
103
+ * Clone this builder object
104
+ */
105
+ getClone(): SelectBuilder;
106
+ /**
107
+ * Build a version of this query that simply returns COUNT(*)
108
+ * @param [countExpr="*"] Use to specify `DISTINCT colname` if needed
109
+ */
110
+ getFoundRowsQuery(countExpr?: string): SelectBuilder;
111
+ /**
112
+ * Add an array of column names to fetch
113
+ * @param columnNames The names of columns
114
+ */
115
+ select(columnNames: string[]): this;
116
+ /**
117
+ * Add an array of column names to fetch
118
+ * @param columnNames The names of columns
119
+ */
120
+ columns(columnNames: string[]): this;
121
+ /**
122
+ * Add a column name to fetch
123
+ * @param columnName The name of the column
124
+ */
125
+ column(columnName: string): this;
126
+ /**
127
+ * Add an option expression such as "TOP 10" or "SQL_CALC_FOUND_ROWS"
128
+ * @param optionExpression Expression to go after "SELECT" and before column list
129
+ */
130
+ option(optionExpression: string): this;
131
+ /**
132
+ * Add a table to the "FROM" clause (same as .from())
133
+ * @param {String} tableName The name of the table to query
134
+ * @return {Select}
135
+ */
136
+ table(tableName: string): this;
137
+ /**
138
+ * Add multiple table to the "FROM" clause
139
+ * @param {Array} tableNames The names of the tables to query
140
+ * @return {Select}
141
+ */
142
+ tables(tableNames: string[]): this;
143
+ /**
144
+ * Add a table to the "FROM" clause (same as .table())
145
+ * @param {String} tableName The name of the table to query
146
+ * @return {Select}
147
+ */
148
+ from(tableName: string): this;
149
+ /**
150
+ * Add the given join type expression
151
+ * @param joinType The type of join (e.g. "INNER JOIN", "LEFT JOIN", etc.)
152
+ * @param expression The expression following the INNER JOIN keyword
153
+ * @param bindings A list of values to bind to ? placeholders in the expression
154
+ * @example
155
+ * query.join('posts p ON p.id = c.post_id');
156
+ * query.join('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
157
+ */
158
+ _addJoin(joinType: string, expression: string, bindings?: any[]): void;
159
+ /**
160
+ * Add a JOIN expression
161
+ * @param expression The expression following the INNER JOIN keyword
162
+ * @param bindings A list of values to bind to ? placeholders in the expression
163
+ * @example
164
+ * query.join('posts p ON p.id = c.post_id');
165
+ * query.join('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
166
+ */
167
+ join(expression: string, bindings?: any[]): this;
168
+ /**
169
+ * Add a LEFT JOIN expression
170
+ * @param expression The expression following the LEFT JOIN keyword
171
+ * @param bindings A list of values to bind to ? placeholders in the expression
172
+ * @example
173
+ * query.leftJoin('posts p ON p.id = c.post_id');
174
+ * query.leftJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
175
+ */
176
+ leftJoin(expression: string, bindings?: any[]): this;
177
+ /**
178
+ * Add a FULL JOIN expression
179
+ * @param expression The expression following the FULL JOIN keyword
180
+ * @param bindings A list of values to bind to ? placeholders in the expression
181
+ * @example
182
+ * query.fullJoin('posts p ON p.id = c.post_id');
183
+ * query.fullJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
184
+ */
185
+ fullJoin(expression: string, bindings?: any[]): this;
186
+ /**
187
+ * Add a RIGHT JOIN expression
188
+ * @param expression The expression following the RIGHT JOIN keyword
189
+ * @param bindings A list of values to bind to ? placeholders in the expression
190
+ * @example
191
+ * query.rightJoin('posts p ON p.id = c.post_id');
192
+ * query.rightJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
193
+ */
194
+ rightJoin(expression: string, bindings?: any[]): this;
195
+ /**
196
+ * Add a CROSS JOIN expression
197
+ * @param expression The expression following the CROSS JOIN keyword
198
+ * @param bindings A list of values to bind to ? placeholders in the expression
199
+ * @example
200
+ * query.crossJoin('posts p ON p.id = c.post_id');
201
+ * query.crossJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
202
+ */
203
+ crossJoin(expression: string, bindings?: any[]): this;
204
+ /**
205
+ * Add an INNER JOIN expression (same as ->join())
206
+ * @param expression The expression following the INNER JOIN keyword
207
+ * @param bindings A list of values to bind to ? placeholders in the expression
208
+ * @example
209
+ * query.innerJoin('posts p ON p.id = c.post_id');
210
+ * query.innerJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
211
+ */
212
+ innerJoin(expression: string, bindings?: any[]): this;
213
+ /**
214
+ * Add a LEFT OUTER JOIN expression
215
+ * @param expression The expression following the LEFT OUTER JOIN keyword
216
+ * @param bindings A list of values to bind to ? placeholders in the expression
217
+ * @example
218
+ * query.leftOuterJoin('posts p ON p.id = c.post_id');
219
+ * query.leftOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
220
+ */
221
+ leftOuterJoin(expression: string, bindings?: any[]): this;
222
+ /**
223
+ * Add a FULL OUTER JOIN expression
224
+ * @param expression The expression following the FULL OUTER JOIN keyword
225
+ * @param bindings A list of values to bind to ? placeholders in the expression
226
+ * @example
227
+ * query.fullOuterJoin('posts p ON p.id = c.post_id');
228
+ * query.fullOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
229
+ */
230
+ fullOuterJoin(expression: string, bindings?: any[]): this;
231
+ /**
232
+ * Add a RIGHT OUTER JOIN expression
233
+ * @param expression The expression following the RIGHT OUTER JOIN keyword
234
+ * @param bindings A list of values to bind to ? placeholders in the expression
235
+ * @example
236
+ * query.rightOuterJoin('posts p ON p.id = c.post_id');
237
+ * query.rightOuterJoin('posts p ON p.id = c.post_id AND p.deleted_at < ?', [myDate]);
238
+ */
239
+ rightOuterJoin(expression: string, bindings?: any[]): this;
240
+ /**
241
+ * Remove a join condition with the specified table
242
+ * @param table The name of the table or tables in the first part of the join statement
243
+ */
244
+ unjoin(table: string | string[]): this;
245
+ /**
246
+ * Utility function to add conditions for a clause (WHERE, HAVING)
247
+ * @param collection The collection to add the clauses to (e.g. this._wheres or this._havings)
248
+ * @param criteria Criteria adhering to WhereCriteria type
249
+ * @example The following are equivalent
250
+ * this._conditions(this._wheres, ['deleted_at IS NULL']);
251
+ * this._conditions(this._wheres, ['deleted_at', null]);
252
+ * this._conditions(this._wheres, ['deleted_at', '=', null]);
253
+ * @example More examples
254
+ * this._conditions(this._wheres, ['fname', 'LIKE', 'joe']); // `fname` LIKE 'joe'
255
+ * this._conditions(this._wheres, ['fname', 'LIKE ?', 'joe']); // `fname` LIKE 'joe'
256
+ * this._conditions(this._wheres, ['fname LIKE %?%', 'joe']); // `fname` LIKE '%joe%'
257
+ * this._conditions(this._wheres, ['fname LIKE ?%', 'joe']); // `fname` LIKE 'joe%'
258
+ * this._conditions(this._wheres, ['fname', 'LIKE ?%', 'joe']); // `fname` LIKE 'joe%'
259
+ * this._conditions(this._wheres, ['price >', 10]); // `price` > 10
260
+ * this._conditions(this._wheres, ['price', '>', 10]); // `price` > 10
261
+ * this._conditions(this._wheres, ['price =', 10]); // `price` = 10
262
+ * this._conditions(this._wheres, ['price !=', 10]); // `price` != 10
263
+ * this._conditions(this._wheres, ['price', 10]); // `price` = 10
264
+ * this._conditions(this._wheres, ['price', '=', 10]); // `price` = 10
265
+ * this._conditions(this._wheres, ['price', '!=', 10]); // `price` != 10
266
+ * this._conditions(this._wheres, ['price', 'BETWEEN', [10,20]]); // `price` BETWEEN 10 AND 20
267
+ * this._conditions(this._wheres, ['price', 'NOT BETWEEN', [10,20]]); // `price` NOT BETWEEN 10 AND 20
268
+ * this._conditions(this._wheres, ['price', [10,20]]); // `price` IN(10,20)
269
+ * this._conditions(this._wheres, ['price', '=', [10,20]]); // `price` IN(10,20)
270
+ * this._conditions(this._wheres, ['price', 'IN', [10,20]]); // `price` IN(10,20)
271
+ * this._conditions(this._wheres, ['price', 'NOT IN', [10,20]]); // `price` NOT IN(10,20)
272
+ */
273
+ _conditions(collection: string[], criteria: WhereCriteria): this;
274
+ /**
275
+ * Add a group by column or expression
276
+ * @param column The name of a column (or expression) to group by
277
+ */
278
+ groupBy(column: string): this;
279
+ /**
280
+ * Add WHERE clauses to conditions (See _conditions for usage)
281
+ */
282
+ where(...args: WhereCriteria): this;
283
+ /**
284
+ * Add a WHERE clause with a BETWEEN condition
285
+ * @param column The column name
286
+ * @param twoValueArray The two values to be between
287
+ */
288
+ whereBetween(column: string, twoValueArray: [any, any]): this;
289
+ /**
290
+ * Add a series of WHERE clauses joined by OR (See _conditions for usage)
291
+ * @param conditions
292
+ */
293
+ _orConditions(conditions: WhereCriteria[] | Record<string, any>[]): string;
294
+ /**
295
+ * Add WHERE conditions to place inside an OR block (See _conditions for usage)
296
+ * @param conditions A list or object where each item is an array with parameters that would be taken by where()
297
+ */
298
+ orWhere(conditions: WhereCriteria[] | Record<string, any>[]): this;
299
+ /**
300
+ * Add an OR with conditions under the HAVING clause
301
+ * @param conditions A list or object where each item is an array with parameters that would be taken by having()
302
+ */
303
+ orHaving(conditions: WhereCriteria[] | Record<string, any>[]): this;
304
+ /**
305
+ * Add a HAVING condition (See _conditions for usage)
306
+ */
307
+ having(...args: WhereCriteria): this;
308
+ /**
309
+ * Add a column or expression to order by
310
+ * @param column The column name or expression to sort by. Include DESC or prefix with - to sort descending
311
+ * @param [direction] The direction to sort by (ASC or DESC)
312
+ * @example
313
+ * query.sortField('modified_at'); // ORDER BY modified_at
314
+ * query.sortField('-modified_at'); // ORDER BY modified_at DESC
315
+ * query.sortField('COUNT(*)'); // ORDER BY COUNT(*)
316
+ * query.sortField('COUNT(*) DESC'); // ORDER BY COUNT(*) DESC
317
+ */
318
+ orderBy(column: string, direction?: 'ASC' | 'DESC'): this;
319
+ /**
320
+ * Sort by the given column, with a map of columns to translate
321
+ * @param column The column name such as "created_at" or "-created_at" for descending
322
+ * @param [mapNames] Column names to translate from one name to another
323
+ * @example
324
+ * query.sortField('-modified_at'); // ORDER BY modified_at DESC
325
+ * query.sortField('created_at', {'created_at': 'created'}); // ORDER BY created
326
+ */
327
+ sortField(column: string, mapNames?: Record<string, string>): this;
328
+ /**
329
+ * Check to see if the given string is 0 or all digits not starting with 0
330
+ * @param string The input string
331
+ * @private
332
+ */
333
+ _isEntirelyDigits(string: string): boolean;
334
+ /**
335
+ * Check to see if the given string is all digits
336
+ * @param string The input string
337
+ * @private
338
+ */
339
+ _isEntirelyDigitsNoZeros(string: string): boolean;
340
+ /**
341
+ * Limit results to the given number
342
+ * @param max The number to limit by (placeholder string or integer greater than 0)
343
+ */
344
+ limit(max: number | string): this;
345
+ /**
346
+ * Fetch results from the given offset
347
+ * @param number The offset (placeholder string or integer greater than or equal to 0)
348
+ */
349
+ offset(number: number | string): this;
350
+ /**
351
+ * Set the offset based on the limit with the given page number
352
+ * @param number The page number (integer greater than 0)
353
+ */
354
+ page(number: number | string): this;
355
+ }