outlet-orm 6.5.0 → 7.0.0

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,345 @@
1
+ # Outlet ORM - Query Builder
2
+
3
+ [← Back to Index](SKILL.md) | [Previous: Models](MODELS.md) | [Next: Relationships →](RELATIONS.md)
4
+
5
+ > 📘 **TypeScript** : The`WhereOperator`type defines all available operators (`=`,`!=`,`>`,`<`,`LIKE`, etc.). See [TYPESCRIPT.md](TYPESCRIPT.md)
6
+
7
+ ---
8
+
9
+ ## Basic Queries
10
+
11
+ ```javascript
12
+ // All records
13
+ const users = await User.all();
14
+
15
+ // Find by ID
16
+ const user = await User.find(1);
17
+ const user = await User.findOrFail(1);
18
+
19
+ // First record
20
+ const user = await User.first();
21
+ const user = await User.firstOrFail();
22
+
23
+ // Get with conditions
24
+ const users = await User.where('status', 'active').get();
25
+ ```
26
+
27
+ ---
28
+
29
+ ## WHERE Clauses
30
+
31
+ ### Basic WHERE
32
+
33
+ ```javascript
34
+ // Equality
35
+ const users = await User.where('name', 'John').get();
36
+
37
+ // With operator
38
+ const users = await User.where('age', '>', 18).get();
39
+ const users = await User.where('age', '>=', 21).get();
40
+ const users = await User.where('age', '<', 65).get();
41
+ const users = await User.where('status', '!=', 'banned').get();
42
+
43
+ // LIKE
44
+ const users = await User.where('email', 'LIKE', '%@example.com').get();
45
+ ```
46
+
47
+ ### Chaining WHERE
48
+
49
+ ```javascript
50
+ const users = await User
51
+ .where('age', '>', 18)
52
+ .where('status', 'active')
53
+ .where('role', 'user')
54
+ .get();
55
+ ```
56
+
57
+ ### OR WHERE
58
+
59
+ ```javascript
60
+ const users = await User
61
+ .where('role', 'admin')
62
+ .orWhere('role', 'moderator')
63
+ .get();
64
+ ```
65
+
66
+ ### WHERE IN / NOT IN
67
+
68
+ ```javascript
69
+ // WHERE IN
70
+ const users = await User.whereIn('id', [1, 2, 3, 4, 5]).get();
71
+ const users = await User.whereIn('status', ['active', 'pending']).get();
72
+
73
+ // WHERE NOT IN
74
+ const users = await User.whereNotIn('status', ['banned', 'deleted']).get();
75
+ ```
76
+
77
+ ### WHERE NULL / NOT NULL
78
+
79
+ ```javascript
80
+ // NULL
81
+ const users = await User.whereNull('deleted_at').get();
82
+ const unverified = await User.whereNull('email_verified_at').get();
83
+
84
+ // NOT NULL
85
+ const verified = await User.whereNotNull('email_verified_at').get();
86
+ ```
87
+
88
+ ### WHERE BETWEEN
89
+
90
+ ```javascript
91
+ const adults = await User.whereBetween('age', [18, 65]).get();
92
+ const recent = await User.whereBetween('created_at', ['2024-01-01', '2024-12-31']).get();
93
+ ```
94
+
95
+ ### WHERE LIKE
96
+
97
+ ```javascript
98
+ const johns = await User.whereLike('name', '%john%').get();
99
+ const gmails = await User.whereLike('email', '%@gmail.com').get();
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Selecting Columns
105
+
106
+ ```javascript
107
+ // Select specific columns
108
+ const users = await User
109
+ .select('id', 'name', 'email')
110
+ .get();
111
+
112
+ // Alternative syntax
113
+ const users = await User
114
+ .columns(['id', 'name', 'email'])
115
+ .get();
116
+
117
+ // With alias
118
+ const users = await User
119
+ .select('id', 'name', 'email as user_email')
120
+ .get();
121
+
122
+ // Distinct
123
+ const roles = await User
124
+ .distinct()
125
+ .select('role')
126
+ .get();
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Ordering
132
+
133
+ ```javascript
134
+ // Ascending (default)
135
+ const users = await User.orderBy('name').get();
136
+ const users = await User.orderBy('name', 'asc').get();
137
+
138
+ // Descending
139
+ const users = await User.orderBy('created_at', 'desc').get();
140
+
141
+ // Multiple columns
142
+ const users = await User
143
+ .orderBy('role', 'asc')
144
+ .orderBy('name', 'asc')
145
+ .get();
146
+
147
+ // Alias (ordrer - typo preserved for compatibility)
148
+ const users = await User.ordrer('name', 'asc').get();
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Limiting & Offset
154
+
155
+ ```javascript
156
+ // Limit
157
+ const users = await User.limit(10).get();
158
+ const users = await User.take(10).get(); // Alias
159
+
160
+ // Offset
161
+ const users = await User.offset(20).get();
162
+ const users = await User.skip(20).get(); // Alias
163
+
164
+ // Combined (for manual pagination)
165
+ const users = await User
166
+ .orderBy('id')
167
+ .limit(10)
168
+ .offset(20)
169
+ .get();
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Pagination
175
+
176
+ ```javascript
177
+ const result = await User.paginate(1, 15); // page 1, 15 per page
178
+
179
+ console.log(result);
180
+ // {
181
+ // data: [...], // Array of users
182
+ // total: 100, // Total records
183
+ // per_page: 15, // Records per page
184
+ // current_page: 1, // Current page
185
+ // last_page: 7, // Last page number
186
+ // from: 1, // First record index
187
+ // to: 15 // Last record index
188
+ // }
189
+
190
+ // Next page
191
+ const page2 = await User.paginate(2, 15);
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Aggregations
197
+
198
+ ### Count
199
+
200
+ ```javascript
201
+ const count = await User.count();
202
+ const activeCount = await User.where('status', 'active').count();
203
+ ```
204
+
205
+ ### Exists
206
+
207
+ ```javascript
208
+ const hasAdmins = await User.where('role', 'admin').exists();
209
+ if (hasAdmins) {
210
+ console.log('Admin users exist');
211
+ }
212
+ ```
213
+
214
+ ### Group By & Having
215
+
216
+ ```javascript
217
+ const stats = await User
218
+ .select('status', 'COUNT(*) as count')
219
+ .groupBy('status')
220
+ .get();
221
+
222
+ const popular = await User
223
+ .select('role', 'COUNT(*) as count')
224
+ .groupBy('role')
225
+ .having('COUNT(*)', '>', 5)
226
+ .get();
227
+ ```
228
+
229
+ ---
230
+
231
+ ## Joins
232
+
233
+ ### Inner Join
234
+
235
+ ```javascript
236
+ const result = await User
237
+ .join('profiles', 'users.id', 'profiles.user_id')
238
+ .select('users.*', 'profiles.bio')
239
+ .get();
240
+ ```
241
+
242
+ ### Left Join
243
+
244
+ ```javascript
245
+ const result = await User
246
+ .leftJoin('profiles', 'users.id', 'profiles.user_id')
247
+ .select('users.*', 'profiles.bio')
248
+ .get();
249
+ ```
250
+
251
+ ### Multiple Joins
252
+
253
+ ```javascript
254
+ const result = await User
255
+ .join('profiles', 'users.id', 'profiles.user_id')
256
+ .leftJoin('countries', 'profiles.country_id', 'countries.id')
257
+ .select('users.*', 'profiles.bio', 'countries.name as country')
258
+ .get();
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Increment / Decrement
264
+
265
+ Atomic operations for counters:
266
+
267
+ ```javascript
268
+ // Increment by 1
269
+ await User.where('id', 1).increment('login_count');
270
+
271
+ // Increment by N
272
+ await User.where('id', 1).increment('points', 10);
273
+
274
+ // Decrement by 1
275
+ await User.where('id', 1).decrement('credits');
276
+
277
+ // Decrement by N
278
+ await User.where('id', 1).decrement('credits', 50);
279
+ ```
280
+
281
+ ---
282
+
283
+ ## Raw Queries
284
+
285
+ ```javascript
286
+ const db = Model.getConnection();
287
+
288
+ // Normalised results (cross-database)
289
+ const results = await db.executeRawQuery(
290
+ 'SELECT * FROM users WHERE age > ?',
291
+ [18]
292
+ );
293
+
294
+ // Native driver results
295
+ const native = await db.execute(
296
+ 'SELECT * FROM users WHERE status = ?',
297
+ ['active']
298
+ );
299
+ ```
300
+
301
+ ---
302
+
303
+ ## Query Builder Methods Summary
304
+
305
+ | Method | Description |
306
+ |--------|-------------|
307
+ |`select(...cols)`| Select columns |
308
+ |`columns([...])`| Select columns (alias) |
309
+ |`distinct()`| SELECT DISTINCT |
310
+ |`where(col, op?, val)`| WHERE clause |
311
+ |`orWhere(col, op?, val)`| OR WHERE |
312
+ |`whereIn(col, vals)`| WHERE IN |
313
+ |`whereNotIn(col, vals)`| WHERE NOT IN |
314
+ |`whereNull(col)`| WHERE IS NULL |
315
+ |`whereNotNull(col)`| WHERE IS NOT NULL |
316
+ |`whereBetween(col, [min, max])`| WHERE BETWEEN |
317
+ |`whereLike(col, pattern)`| WHERE LIKE |
318
+ |`orderBy(col, dir?)`| ORDER BY |
319
+ |`limit(n)`/`take(n)`| LIMIT |
320
+ |`offset(n)`/`skip(n)`| OFFSET |
321
+ |`groupBy(...cols)`| GROUP BY |
322
+ |`having(col, op, val)`| HAVING |
323
+ |`join(table, col1, op?, col2)`| INNER JOIN |
324
+ |`leftJoin(table, col1, op?, col2)`| LEFT JOIN |
325
+ |`get()`| Execute and get all |
326
+ |`first()`| Get first result |
327
+ |`firstOrFail()`| First or throw |
328
+ |`find(id)`| Find by ID |
329
+ |`findOrFail(id)`| Find or throw |
330
+ |`paginate(page, perPage)`| Pagination |
331
+ |`count()`| Count results |
332
+ |`exists()`| Check existence |
333
+ |`insert(data)`| Insert record(s) |
334
+ |`update(attrs)`| Update records |
335
+ |`delete()`| Delete records |
336
+ |`increment(col, amount?)`| Atomic increment |
337
+ |`decrement(col, amount?)`| Atomic decrement |
338
+ |`clone()`| Clone query builder |
339
+
340
+ ---
341
+
342
+ ## Next Steps
343
+
344
+ - [Relationships & Eager Loading →](RELATIONS.md)
345
+ - [Advanced Features →](ADVANCED.md)