@xano/developer-mcp 1.0.20 → 1.0.22
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.
- package/README.md +100 -19
- package/dist/index.js +4 -227
- package/dist/meta_api_docs/format.d.ts +16 -1
- package/dist/meta_api_docs/format.js +24 -6
- package/dist/meta_api_docs/format.test.d.ts +1 -0
- package/dist/meta_api_docs/format.test.js +274 -0
- package/dist/meta_api_docs/index.test.d.ts +1 -0
- package/dist/meta_api_docs/index.test.js +128 -0
- package/dist/meta_api_docs/types.test.d.ts +1 -0
- package/dist/meta_api_docs/types.test.js +132 -0
- package/dist/run_api_docs/format.d.ts +1 -0
- package/dist/run_api_docs/format.js +3 -170
- package/dist/run_api_docs/format.test.d.ts +1 -0
- package/dist/run_api_docs/format.test.js +86 -0
- package/dist/run_api_docs/index.test.d.ts +1 -0
- package/dist/run_api_docs/index.test.js +127 -0
- package/dist/templates/init-workspace.js +4 -4
- package/dist/templates/xanoscript-index.d.ts +3 -1
- package/dist/templates/xanoscript-index.js +54 -51
- package/dist/xanoscript.d.ts +41 -0
- package/dist/xanoscript.js +261 -0
- package/dist/xanoscript.test.d.ts +1 -0
- package/dist/xanoscript.test.js +303 -0
- package/dist/xanoscript_docs/README.md +53 -37
- package/dist/xanoscript_docs/agents.md +1 -1
- package/dist/xanoscript_docs/apis.md +6 -3
- package/dist/xanoscript_docs/branch.md +239 -0
- package/dist/xanoscript_docs/functions.md +6 -6
- package/dist/xanoscript_docs/integrations.md +43 -1
- package/dist/xanoscript_docs/middleware.md +321 -0
- package/dist/xanoscript_docs/performance.md +1 -1
- package/dist/xanoscript_docs/realtime.md +113 -1
- package/dist/xanoscript_docs/tasks.md +2 -2
- package/dist/xanoscript_docs/tools.md +3 -3
- package/dist/xanoscript_docs/types.md +25 -8
- package/dist/xanoscript_docs/workspace.md +209 -0
- package/dist/xanoscript_docs_auto/README.md +119 -0
- package/dist/xanoscript_docs_auto/agents.md +446 -0
- package/dist/xanoscript_docs_auto/apis.md +517 -0
- package/dist/xanoscript_docs_auto/control-flow.md +543 -0
- package/dist/xanoscript_docs_auto/database.md +551 -0
- package/dist/xanoscript_docs_auto/debugging.md +527 -0
- package/dist/xanoscript_docs_auto/filters.md +464 -0
- package/dist/xanoscript_docs_auto/functions.md +431 -0
- package/dist/xanoscript_docs_auto/integrations.md +657 -0
- package/dist/xanoscript_docs_auto/mcp-servers.md +408 -0
- package/dist/xanoscript_docs_auto/operators.md +368 -0
- package/dist/xanoscript_docs_auto/syntax.md +287 -0
- package/dist/xanoscript_docs_auto/tables.md +447 -0
- package/dist/xanoscript_docs_auto/tasks.md +479 -0
- package/dist/xanoscript_docs_auto/testing.md +574 -0
- package/dist/xanoscript_docs_auto/tools.md +485 -0
- package/dist/xanoscript_docs_auto/triggers.md +595 -0
- package/dist/xanoscript_docs_auto/types.md +323 -0
- package/dist/xanoscript_docs_auto/variables.md +462 -0
- package/dist/xanoscript_docs_auto/version.json +5 -0
- package/package.json +6 -2
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "functions/**/*.xs,apis/**/*.xs,tasks/*.xs,tools/**/*.xs"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Database Operations
|
|
6
|
+
|
|
7
|
+
Complete reference for all db.* operations in XanoScript.
|
|
8
|
+
|
|
9
|
+
## Quick Reference
|
|
10
|
+
|
|
11
|
+
| Operation | Purpose |
|
|
12
|
+
|-----------|---------|
|
|
13
|
+
| `db.query` | Query records with filters, sorting, paging |
|
|
14
|
+
| `db.get` | Get single record by field value |
|
|
15
|
+
| `db.add` | Insert new record |
|
|
16
|
+
| `db.edit` | Full update (PUT-style) |
|
|
17
|
+
| `db.patch` | Partial update (PATCH-style) |
|
|
18
|
+
| `db.add_or_edit` | Upsert - insert or update |
|
|
19
|
+
| `db.del` | Delete record |
|
|
20
|
+
| `db.has` | Check if record exists |
|
|
21
|
+
| `db.transaction` | Atomic operations |
|
|
22
|
+
| `db.bulk.*` | Bulk operations |
|
|
23
|
+
| `db.direct_query` | Raw SQL execution |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## db.query
|
|
28
|
+
|
|
29
|
+
Query multiple records with filtering, sorting, and pagination:
|
|
30
|
+
|
|
31
|
+
```xs
|
|
32
|
+
db.query user {
|
|
33
|
+
where = $db.user.active == true
|
|
34
|
+
&& $db.user.created_at >= $start_date
|
|
35
|
+
order_by = {field: "created_at", direction: "desc"}
|
|
36
|
+
return = {type: "list", paging: {per_page: 20, page: $input.page}}
|
|
37
|
+
} as $users
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Where Clauses
|
|
41
|
+
|
|
42
|
+
```xs
|
|
43
|
+
// Comparison operators
|
|
44
|
+
$db.user.age >= 18
|
|
45
|
+
$db.user.status == "active"
|
|
46
|
+
$db.user.email != null
|
|
47
|
+
|
|
48
|
+
// Null-safe operators (ignore if value is null)
|
|
49
|
+
$db.product.category ==? $input.category
|
|
50
|
+
$db.product.price >=? $input.min_price
|
|
51
|
+
|
|
52
|
+
// Logical operators
|
|
53
|
+
$db.user.active == true && $db.user.verified == true
|
|
54
|
+
$db.user.role == "admin" || $db.user.role == "moderator"
|
|
55
|
+
|
|
56
|
+
// IN clause
|
|
57
|
+
$db.product.status in ["active", "pending"]
|
|
58
|
+
$db.product.category not in ["deleted", "hidden"]
|
|
59
|
+
|
|
60
|
+
// LIKE patterns
|
|
61
|
+
$db.user.name like "John%"
|
|
62
|
+
$db.user.email ilike "%@gmail.com"
|
|
63
|
+
|
|
64
|
+
// BETWEEN
|
|
65
|
+
$db.product.price between 10:100
|
|
66
|
+
$db.order.created_at between $start:$end
|
|
67
|
+
|
|
68
|
+
// Array operations
|
|
69
|
+
$db.product.tags|contains:"featured"
|
|
70
|
+
$db.post.categories|overlaps:["tech", "news"]
|
|
71
|
+
|
|
72
|
+
// JSON contains
|
|
73
|
+
$db.product.metadata @> {"featured": true}
|
|
74
|
+
|
|
75
|
+
// Regex
|
|
76
|
+
$db.product.sku ~ "^SKU-[0-9]+"
|
|
77
|
+
|
|
78
|
+
// Full-text search
|
|
79
|
+
$db.post.content search $input.query
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Return Types
|
|
83
|
+
|
|
84
|
+
```xs
|
|
85
|
+
// List with pagination
|
|
86
|
+
return = {type: "list", paging: {per_page: 20, page: 1}}
|
|
87
|
+
|
|
88
|
+
// All records (no pagination)
|
|
89
|
+
return = {type: "all"}
|
|
90
|
+
|
|
91
|
+
// Count only
|
|
92
|
+
return = {type: "count"}
|
|
93
|
+
|
|
94
|
+
// First record only
|
|
95
|
+
return = {type: "first"}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Ordering
|
|
99
|
+
|
|
100
|
+
```xs
|
|
101
|
+
// Single field
|
|
102
|
+
order_by = {field: "created_at", direction: "desc"}
|
|
103
|
+
|
|
104
|
+
// Multiple fields
|
|
105
|
+
order_by = [
|
|
106
|
+
{field: "priority", direction: "desc"},
|
|
107
|
+
{field: "created_at", direction: "asc"}
|
|
108
|
+
]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Field Selection
|
|
112
|
+
|
|
113
|
+
```xs
|
|
114
|
+
// Select specific fields
|
|
115
|
+
fields = ["id", "name", "email"]
|
|
116
|
+
|
|
117
|
+
// Exclude fields
|
|
118
|
+
exclude = ["password", "internal_notes"]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Joins (Addons)
|
|
122
|
+
|
|
123
|
+
```xs
|
|
124
|
+
db.query order {
|
|
125
|
+
where = $db.order.user_id == $input.user_id
|
|
126
|
+
addons = [user, order_items]
|
|
127
|
+
} as $orders
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## db.get
|
|
133
|
+
|
|
134
|
+
Retrieve a single record by field value:
|
|
135
|
+
|
|
136
|
+
```xs
|
|
137
|
+
db.get user {
|
|
138
|
+
field_name = "id"
|
|
139
|
+
field_value = $input.user_id
|
|
140
|
+
} as $user
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### By Custom Field
|
|
144
|
+
|
|
145
|
+
```xs
|
|
146
|
+
db.get user {
|
|
147
|
+
field_name = "email"
|
|
148
|
+
field_value = $input.email
|
|
149
|
+
} as $user
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### With Addons
|
|
153
|
+
|
|
154
|
+
```xs
|
|
155
|
+
db.get order {
|
|
156
|
+
field_name = "id"
|
|
157
|
+
field_value = $input.order_id
|
|
158
|
+
addons = [user, order_items, shipping_address]
|
|
159
|
+
} as $order
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## db.add
|
|
165
|
+
|
|
166
|
+
Insert a new record:
|
|
167
|
+
|
|
168
|
+
```xs
|
|
169
|
+
db.add user {
|
|
170
|
+
data = {
|
|
171
|
+
name: $input.name,
|
|
172
|
+
email: $input.email,
|
|
173
|
+
created_at: now
|
|
174
|
+
}
|
|
175
|
+
} as $new_user
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### With Returning Fields
|
|
179
|
+
|
|
180
|
+
```xs
|
|
181
|
+
db.add product {
|
|
182
|
+
data = {
|
|
183
|
+
name: $input.name,
|
|
184
|
+
price: $input.price,
|
|
185
|
+
sku: |uuid
|
|
186
|
+
}
|
|
187
|
+
return = ["id", "sku", "created_at"]
|
|
188
|
+
} as $product
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## db.edit
|
|
194
|
+
|
|
195
|
+
Full update (replaces all fields):
|
|
196
|
+
|
|
197
|
+
```xs
|
|
198
|
+
db.edit user {
|
|
199
|
+
field_name = "id"
|
|
200
|
+
field_value = $input.user_id
|
|
201
|
+
data = {
|
|
202
|
+
name: $input.name,
|
|
203
|
+
email: $input.email,
|
|
204
|
+
updated_at: now
|
|
205
|
+
}
|
|
206
|
+
} as $updated_user
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## db.patch
|
|
212
|
+
|
|
213
|
+
Partial update (only specified fields):
|
|
214
|
+
|
|
215
|
+
```xs
|
|
216
|
+
db.patch user {
|
|
217
|
+
field_name = "id"
|
|
218
|
+
field_value = $input.user_id
|
|
219
|
+
data = {
|
|
220
|
+
last_login: now
|
|
221
|
+
}
|
|
222
|
+
} as $patched_user
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Increment/Decrement
|
|
226
|
+
|
|
227
|
+
```xs
|
|
228
|
+
db.patch product {
|
|
229
|
+
field_name = "id"
|
|
230
|
+
field_value = $input.product_id
|
|
231
|
+
data = {
|
|
232
|
+
stock: $db.product.stock - $input.quantity,
|
|
233
|
+
sales_count: $db.product.sales_count + 1
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## db.add_or_edit
|
|
241
|
+
|
|
242
|
+
Upsert - insert if not exists, update if exists:
|
|
243
|
+
|
|
244
|
+
```xs
|
|
245
|
+
db.add_or_edit user_preference {
|
|
246
|
+
field_name = "user_id"
|
|
247
|
+
field_value = $input.user_id
|
|
248
|
+
data = {
|
|
249
|
+
user_id: $input.user_id,
|
|
250
|
+
theme: $input.theme,
|
|
251
|
+
updated_at: now
|
|
252
|
+
}
|
|
253
|
+
} as $preference
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## db.del
|
|
259
|
+
|
|
260
|
+
Delete a record:
|
|
261
|
+
|
|
262
|
+
```xs
|
|
263
|
+
db.del user {
|
|
264
|
+
field_name = "id"
|
|
265
|
+
field_value = $input.user_id
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Soft Delete Pattern
|
|
270
|
+
|
|
271
|
+
```xs
|
|
272
|
+
// Instead of deleting, mark as deleted
|
|
273
|
+
db.patch user {
|
|
274
|
+
field_name = "id"
|
|
275
|
+
field_value = $input.user_id
|
|
276
|
+
data = {
|
|
277
|
+
deleted_at: now,
|
|
278
|
+
active: false
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## db.has
|
|
286
|
+
|
|
287
|
+
Check if a record exists:
|
|
288
|
+
|
|
289
|
+
```xs
|
|
290
|
+
db.has user {
|
|
291
|
+
where = $db.user.email == $input.email
|
|
292
|
+
} as $email_exists
|
|
293
|
+
|
|
294
|
+
conditional {
|
|
295
|
+
if ($email_exists) {
|
|
296
|
+
throw {
|
|
297
|
+
name = "DuplicateError"
|
|
298
|
+
value = "Email already registered"
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## db.transaction
|
|
307
|
+
|
|
308
|
+
Execute multiple operations atomically:
|
|
309
|
+
|
|
310
|
+
```xs
|
|
311
|
+
db.transaction {
|
|
312
|
+
stack {
|
|
313
|
+
// Deduct from source account
|
|
314
|
+
db.patch account {
|
|
315
|
+
field_name = "id"
|
|
316
|
+
field_value = $input.from_account
|
|
317
|
+
data = {
|
|
318
|
+
balance: $db.account.balance - $input.amount
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Add to destination account
|
|
323
|
+
db.patch account {
|
|
324
|
+
field_name = "id"
|
|
325
|
+
field_value = $input.to_account
|
|
326
|
+
data = {
|
|
327
|
+
balance: $db.account.balance + $input.amount
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Record the transfer
|
|
332
|
+
db.add transfer {
|
|
333
|
+
data = {
|
|
334
|
+
from_account: $input.from_account,
|
|
335
|
+
to_account: $input.to_account,
|
|
336
|
+
amount: $input.amount,
|
|
337
|
+
created_at: now
|
|
338
|
+
}
|
|
339
|
+
} as $transfer
|
|
340
|
+
}
|
|
341
|
+
} as $result
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Bulk Operations
|
|
347
|
+
|
|
348
|
+
### db.bulk.add
|
|
349
|
+
|
|
350
|
+
Insert multiple records:
|
|
351
|
+
|
|
352
|
+
```xs
|
|
353
|
+
db.bulk.add product {
|
|
354
|
+
data = $input.products
|
|
355
|
+
} as $inserted
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### db.bulk.patch
|
|
359
|
+
|
|
360
|
+
Update multiple records:
|
|
361
|
+
|
|
362
|
+
```xs
|
|
363
|
+
db.bulk.patch product {
|
|
364
|
+
where = $db.product.category == "electronics"
|
|
365
|
+
data = {
|
|
366
|
+
on_sale: true,
|
|
367
|
+
updated_at: now
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### db.bulk.delete
|
|
373
|
+
|
|
374
|
+
Delete multiple records:
|
|
375
|
+
|
|
376
|
+
```xs
|
|
377
|
+
db.bulk.delete session {
|
|
378
|
+
where = $db.session.expires_at < now
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## db.direct_query
|
|
385
|
+
|
|
386
|
+
Execute raw SQL (use with caution):
|
|
387
|
+
|
|
388
|
+
```xs
|
|
389
|
+
db.direct_query {
|
|
390
|
+
query = "SELECT id, name FROM users WHERE created_at > $1"
|
|
391
|
+
params = [$start_date]
|
|
392
|
+
} as $results
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### External Databases
|
|
396
|
+
|
|
397
|
+
```xs
|
|
398
|
+
// PostgreSQL
|
|
399
|
+
db.external.postgres.direct_query {
|
|
400
|
+
connection = $env.EXTERNAL_PG_URL
|
|
401
|
+
query = "SELECT * FROM external_table"
|
|
402
|
+
} as $data
|
|
403
|
+
|
|
404
|
+
// MySQL
|
|
405
|
+
db.external.mysql.direct_query {
|
|
406
|
+
connection = $env.MYSQL_URL
|
|
407
|
+
query = "SELECT * FROM products"
|
|
408
|
+
} as $data
|
|
409
|
+
|
|
410
|
+
// SQL Server
|
|
411
|
+
db.external.mssql.direct_query {
|
|
412
|
+
connection = $env.MSSQL_URL
|
|
413
|
+
query = "SELECT TOP 10 * FROM orders"
|
|
414
|
+
} as $data
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## db.truncate
|
|
420
|
+
|
|
421
|
+
Delete all records from a table:
|
|
422
|
+
|
|
423
|
+
```xs
|
|
424
|
+
db.truncate temp_data
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## db.schema
|
|
430
|
+
|
|
431
|
+
Get table schema information:
|
|
432
|
+
|
|
433
|
+
```xs
|
|
434
|
+
db.schema user as $user_schema
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## db.set_datasource
|
|
440
|
+
|
|
441
|
+
Switch to a different datasource:
|
|
442
|
+
|
|
443
|
+
```xs
|
|
444
|
+
db.set_datasource {
|
|
445
|
+
name = "analytics"
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
db.query events {} as $events
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Query Filters
|
|
454
|
+
|
|
455
|
+
Use filters in where clauses:
|
|
456
|
+
|
|
457
|
+
### String Operations
|
|
458
|
+
|
|
459
|
+
```xs
|
|
460
|
+
$db.user.name|to_lower == $input.name|to_lower
|
|
461
|
+
$db.product.sku|substr:0:3 == "SKU"
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Numeric Operations
|
|
465
|
+
|
|
466
|
+
```xs
|
|
467
|
+
$db.product.price|floor >= 10
|
|
468
|
+
$db.stats.value|round:2 == 3.14
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Timestamp Operations
|
|
472
|
+
|
|
473
|
+
```xs
|
|
474
|
+
$db.order.created_at|timestamp_year == 2025
|
|
475
|
+
$db.event.start_time|timestamp_day_of_week == 1
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Vector Operations (AI/ML)
|
|
479
|
+
|
|
480
|
+
```xs
|
|
481
|
+
// Cosine similarity for vector search
|
|
482
|
+
db.query document {
|
|
483
|
+
where = $db.document.embedding|cosine_similarity:$input.vector > 0.8
|
|
484
|
+
order_by = {
|
|
485
|
+
field: $db.document.embedding|cosine_similarity:$input.vector,
|
|
486
|
+
direction: "desc"
|
|
487
|
+
}
|
|
488
|
+
return = {type: "list", paging: {per_page: 10}}
|
|
489
|
+
} as $similar_docs
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### Geo Operations
|
|
493
|
+
|
|
494
|
+
```xs
|
|
495
|
+
// Find locations within radius
|
|
496
|
+
db.query store {
|
|
497
|
+
where = $db.store.location|within:$input.point:5000
|
|
498
|
+
order_by = {
|
|
499
|
+
field: $db.store.location|distance:$input.point,
|
|
500
|
+
direction: "asc"
|
|
501
|
+
}
|
|
502
|
+
} as $nearby_stores
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Best Practices
|
|
508
|
+
|
|
509
|
+
### Use Indexes
|
|
510
|
+
|
|
511
|
+
Define indexes for frequently queried columns:
|
|
512
|
+
|
|
513
|
+
```xs
|
|
514
|
+
table user {
|
|
515
|
+
schema {
|
|
516
|
+
int id primary=true
|
|
517
|
+
text email
|
|
518
|
+
timestamp created_at
|
|
519
|
+
}
|
|
520
|
+
index idx_email { columns = [email] unique=true }
|
|
521
|
+
index idx_created { columns = [created_at] }
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Paginate Large Results
|
|
526
|
+
|
|
527
|
+
```xs
|
|
528
|
+
db.query product {
|
|
529
|
+
return = {type: "list", paging: {per_page: 100, page: $input.page}}
|
|
530
|
+
} as $products
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Select Only Needed Fields
|
|
534
|
+
|
|
535
|
+
```xs
|
|
536
|
+
db.query user {
|
|
537
|
+
fields = ["id", "name", "email"]
|
|
538
|
+
} as $users
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Use Transactions for Related Operations
|
|
542
|
+
|
|
543
|
+
```xs
|
|
544
|
+
db.transaction {
|
|
545
|
+
stack {
|
|
546
|
+
db.add order { ... } as $order
|
|
547
|
+
db.add order_item { ... } as $items
|
|
548
|
+
db.patch inventory { ... }
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
```
|