fauna 1.3.4 → 2.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,601 @@
1
+ module Fauna
2
+ ##
3
+ # Helpers modeling the FaunaDB \Query language.
4
+ #
5
+ # Helpers are usually used via a concise DSL notation. A DSL block
6
+ # may be used directly with Fauna::Client
7
+ #
8
+ # client.query { create(ref('classes', 'spells'), { data: { name: 'Magic Missile' } }) }
9
+ #
10
+ # To build and return an query expression to execute later, use Fauna::Query.expr
11
+ #
12
+ # Fauna::Query.expr { create(ref('classes', 'spells'), { data: { name: 'Magic Missile' } }) }
13
+ #
14
+ # Or, you may directly use the helper methods:
15
+ #
16
+ # Fauna::Query.create(Fauna::Query.ref('classes', 'spells'), { data: { name: 'Magic Missile' } })
17
+ module Query
18
+ extend self
19
+
20
+ class QueryDSLContext < DSLContext # :nodoc:
21
+ include Query
22
+ end
23
+
24
+ ##
25
+ # Build a query expression.
26
+ #
27
+ # Allows for unscoped calls to Fauna::Query methods within the
28
+ # provided block. The block should return the constructed query
29
+ # expression.
30
+ #
31
+ # Example: <code>Fauna::Query.expr { add(1, 2, subtract(3, 2)) }</code>
32
+ def self.expr(&block)
33
+ return nil if block.nil?
34
+
35
+ dsl = QueryDSLContext.new
36
+
37
+ Expr.wrap DSLContext.eval_dsl(dsl, &block)
38
+ end
39
+
40
+ # :section: Values
41
+
42
+ ##
43
+ # Construct a ref value
44
+ #
45
+ # Reference: {FaunaDB Values}[https://faunadb.com/documentation/queries#values]
46
+ def ref(*args)
47
+ Ref.new(*args)
48
+ end
49
+
50
+ ##
51
+ # An object expression
52
+ #
53
+ # Query expression constructs can also take a regular ruby object, so the following are equivalent:
54
+ #
55
+ # Fauna.query { { x: 1, y: add(1, 2) } }
56
+ # Fauna.query { object(x: 1, y: add(1, 2)) }
57
+ #
58
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
59
+ def object(fields)
60
+ Expr.new object: Expr.wrap_values(fields)
61
+ end
62
+
63
+ # :section: Basic forms
64
+
65
+ ##
66
+ # A let expression
67
+ #
68
+ # Only one of +expr+ or +block+ should be provided.
69
+ #
70
+ # Block example: <code>Fauna.query { let(x: 2) { add(1, x) } }</code>.
71
+ #
72
+ # Expression example: <code>Fauna.query { let({ x: 2 }, add(1, var(:x))) }</code>.
73
+ #
74
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
75
+ def let(vars, expr = nil, &block)
76
+ in_ =
77
+ if block.nil?
78
+ expr
79
+ else
80
+ dsl = QueryDSLContext.new
81
+ dslcls = (class << dsl; self; end)
82
+
83
+ vars.keys.each do |v|
84
+ dslcls.send(:define_method, v) { var(v) }
85
+ end
86
+
87
+ DSLContext.eval_dsl(dsl, &block)
88
+ end
89
+
90
+ Expr.new let: Expr.wrap_values(vars), in: Expr.wrap(in_)
91
+ end
92
+
93
+ ##
94
+ # A var expression
95
+ #
96
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
97
+ def var(name)
98
+ Expr.new var: Expr.wrap(name)
99
+ end
100
+
101
+ ##
102
+ # An if expression
103
+ #
104
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
105
+ def if_(condition, then_, else_)
106
+ Expr.new if: Expr.wrap(condition), then: Expr.wrap(then_), else: Expr.wrap(else_)
107
+ end
108
+
109
+ ##
110
+ # A do expression
111
+ #
112
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
113
+ def do_(*expressions)
114
+ Expr.new do: Expr.wrap_varargs(expressions)
115
+ end
116
+
117
+ ##
118
+ # A lambda expression
119
+ #
120
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
121
+ #
122
+ # This form generates #var objects for you, and is called like:
123
+ #
124
+ # Query.lambda do |a|
125
+ # Query.add a, a
126
+ # end
127
+ # # Produces: {lambda: :a, expr: {add: [{var: :a}, {var: :a}]}}
128
+ #
129
+ # Query functions requiring lambdas can be passed blocks without explicitly calling #lambda.
130
+ #
131
+ # You can also use #lambda_expr and #var directly.
132
+ # +block+::
133
+ # Takes one or more #var expressions and uses them to construct an expression.
134
+ # If this takes more than one argument, the lambda destructures an array argument.
135
+ # (To destructure single-element arrays use #lambda_expr.)
136
+ def lambda(&block)
137
+ vars =
138
+ block.parameters.map do |kind, name|
139
+ fail ArgumentError, 'Splat parameters are not supported in lambda expressions.' if kind == :rest
140
+ name
141
+ end
142
+
143
+ case vars.length
144
+ when 0
145
+ fail ArgumentError, 'Block must take at least 1 argument.'
146
+ when 1
147
+ # When there's only 1 parameter, don't use an array pattern.
148
+ lambda_expr vars[0], block.call(var(vars[0]))
149
+ else
150
+ lambda_expr vars, block.call(*(vars.map { |v| var(v) }))
151
+ end
152
+ end
153
+
154
+ ##
155
+ # A raw lambda expression
156
+ #
157
+ # Reference: {FaunaDB Basic Forms}[https://faunadb.com/documentation/queries#basic_forms]
158
+ #
159
+ # See also #lambda.
160
+ def lambda_expr(var, expr)
161
+ Expr.new lambda: Expr.wrap(var), expr: Expr.wrap(expr)
162
+ end
163
+
164
+ # :section: Collection Functions
165
+
166
+ ##
167
+ # A map expression
168
+ #
169
+ # Only one of +lambda_expr+ or +lambda_block+ should be provided.
170
+ # For example: <code>Fauna.query { map(collection) { |a| add a, 1 } }</code>.
171
+ #
172
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
173
+ def map(collection, lambda_expr = nil, &lambda_block)
174
+ Expr.new map: Expr.wrap(lambda_expr || lambda_block), collection: Expr.wrap(collection)
175
+ end
176
+
177
+ ##
178
+ # A foreach expression
179
+ #
180
+ # Only one of +lambda_expr+ or +lambda_block+ should be provided.
181
+ # For example: <code>Fauna.query { foreach(collection) { |a| delete a } }</code>.
182
+ #
183
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
184
+ def foreach(collection, lambda_expr = nil, &lambda_block)
185
+ Expr.new foreach: Expr.wrap(lambda_expr || lambda_block), collection: Expr.wrap(collection)
186
+ end
187
+
188
+ ##
189
+ # A filter expression
190
+ #
191
+ # Only one of +lambda_expr+ or +lambda_block+ should be provided.
192
+ # For example: <code>Fauna.query { filter(collection) { |a| equals a, 1 } }</code>.
193
+ #
194
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
195
+ def filter(collection, lambda_expr = nil, &lambda_block)
196
+ Expr.new filter: Expr.wrap(lambda_expr || lambda_block), collection: Expr.wrap(collection)
197
+ end
198
+
199
+ ##
200
+ # A take expression
201
+ #
202
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
203
+ def take(number, collection)
204
+ Expr.new take: Expr.wrap(number), collection: Expr.wrap(collection)
205
+ end
206
+
207
+ ##
208
+ # A drop expression
209
+ #
210
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
211
+ def drop(number, collection)
212
+ Expr.new drop: Expr.wrap(number), collection: Expr.wrap(collection)
213
+ end
214
+
215
+ ##
216
+ # A prepend expression
217
+ #
218
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
219
+ def prepend(collection, elements)
220
+ Expr.new prepend: Expr.wrap(elements), collection: Expr.wrap(collection)
221
+ end
222
+
223
+ ##
224
+ # An append expression
225
+ #
226
+ # Reference: {FaunaDB Collections}[https://faunadb.com/documentation/queries#collection_functions]
227
+ def append(collection, elements)
228
+ Expr.new append: Expr.wrap(elements), collection: Expr.wrap(collection)
229
+ end
230
+
231
+ # :section: Read Functions
232
+
233
+ ##
234
+ # A get expression
235
+ #
236
+ # Reference: {FaunaDB Read functions}[https://faunadb.com/documentation/queries#read_functions]
237
+ def get(ref, params = {})
238
+ Expr.new Expr.wrap_values(params).merge(get: Expr.wrap(ref))
239
+ end
240
+
241
+ ##
242
+ # A paginate expression
243
+ #
244
+ # Reference: {FaunaDB Read functions}[https://faunadb.com/documentation/queries#read_functions]
245
+ def paginate(set, params = {})
246
+ Expr.new Expr.wrap_values(params).merge(paginate: Expr.wrap(set))
247
+ end
248
+
249
+ ##
250
+ # An exists expression
251
+ #
252
+ # Reference: {FaunaDB Read functions}[https://faunadb.com/documentation/queries#read_functions]
253
+ def exists(ref, params = {})
254
+ Expr.new Expr.wrap_values(params).merge(exists: Expr.wrap(ref))
255
+ end
256
+
257
+ ##
258
+ # A count expression
259
+ #
260
+ # Reference: {FaunaDB Read functions}[https://faunadb.com/documentation/queries#read_functions]
261
+ def count(set, params = {})
262
+ Expr.new Expr.wrap_values(params).merge(count: Expr.wrap(set))
263
+ end
264
+
265
+ # :section: Write Functions
266
+
267
+ ##
268
+ # A create expression
269
+ #
270
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
271
+ def create(class_ref, params)
272
+ Expr.new create: Expr.wrap(class_ref), params: Expr.wrap(params)
273
+ end
274
+
275
+ ##
276
+ # An update expression
277
+ #
278
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
279
+ def update(ref, params)
280
+ Expr.new update: Expr.wrap(ref), params: Expr.wrap(params)
281
+ end
282
+
283
+ ##
284
+ # A replace expression
285
+ #
286
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
287
+ def replace(ref, params)
288
+ Expr.new replace: Expr.wrap(ref), params: Expr.wrap(params)
289
+ end
290
+
291
+ ##
292
+ # A delete expression
293
+ #
294
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
295
+ def delete(ref)
296
+ Expr.new delete: Expr.wrap(ref)
297
+ end
298
+
299
+ ##
300
+ # An insert expression
301
+ #
302
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
303
+ def insert(ref, ts, action, params)
304
+ Expr.new insert: Expr.wrap(ref), ts: Expr.wrap(ts), action: Expr.wrap(action), params: Expr.wrap(params)
305
+ end
306
+
307
+ ##
308
+ # A remove expression
309
+ #
310
+ # Reference: {FaunaDB Write functions}[https://faunadb.com/documentation/queries#write_functions]
311
+ def remove(ref, ts, action)
312
+ Expr.new remove: Expr.wrap(ref), ts: Expr.wrap(ts), action: Expr.wrap(action)
313
+ end
314
+
315
+ # :section: Set Functions
316
+
317
+ ##
318
+ # A match expression
319
+ #
320
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
321
+ def match(index, *terms)
322
+ Expr.new match: Expr.wrap(index), terms: Expr.wrap_varargs(terms)
323
+ end
324
+
325
+ ##
326
+ # A union expression
327
+ #
328
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
329
+ def union(*sets)
330
+ Expr.new union: Expr.wrap_varargs(sets)
331
+ end
332
+
333
+ ##
334
+ # An intersection expression
335
+ #
336
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
337
+ def intersection(*sets)
338
+ Expr.new intersection: Expr.wrap_varargs(sets)
339
+ end
340
+
341
+ ##
342
+ # A difference expression
343
+ #
344
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
345
+ def difference(*sets)
346
+ Expr.new difference: Expr.wrap_varargs(sets)
347
+ end
348
+
349
+ ##
350
+ # A distinct expression
351
+ #
352
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
353
+ def distinct(set)
354
+ Expr.new distinct: Expr.wrap(set)
355
+ end
356
+
357
+ ##
358
+ # A join expression
359
+ #
360
+ # Only one of +target_expr+ or +target_block+ should be provided.
361
+ # For example: <code>Fauna.query { join(source) { |x| match some_index, x } }</code>.
362
+ #
363
+ # Reference: {FaunaDB Sets}[https://faunadb.com/documentation/queries#sets]
364
+ def join(source, target_expr = nil, &target_block)
365
+ Expr.new join: Expr.wrap(source), with: Expr.wrap(target_expr || target_block)
366
+ end
367
+
368
+ # :section: Authentication Functions
369
+
370
+ ##
371
+ # A login function
372
+ #
373
+ # Reference: {FaunaDB Authentication}[https://faunadb.com/documentation/queries#auth_functions]
374
+ def login(ref, params)
375
+ Expr.new login: Expr.wrap(ref), params: Expr.wrap(params)
376
+ end
377
+
378
+ ##
379
+ # A logout function
380
+ #
381
+ # Reference: {FaunaDB Authentication}[https://faunadb.com/documentation/queries#auth_functions]
382
+ def logout(all_tokens)
383
+ Expr.new logout: Expr.wrap(all_tokens)
384
+ end
385
+
386
+ ##
387
+ # An identify function
388
+ #
389
+ # Reference: {FaunaDB Authentication}[https://faunadb.com/documentation/queries#auth_functions]
390
+ def identify(ref, password)
391
+ Expr.new identify: Expr.wrap(ref), password: Expr.wrap(password)
392
+ end
393
+
394
+ # :section: String Functions
395
+
396
+ ##
397
+ # A concat function
398
+ #
399
+ # Reference: {FaunaDB String Functions}[https://faunadb.com/documentation/queries#string_functions]
400
+ def concat(strings, separator = nil)
401
+ if separator.nil?
402
+ Expr.new concat: Expr.wrap(strings)
403
+ else
404
+ Expr.new concat: Expr.wrap(strings), separator: Expr.wrap(separator)
405
+ end
406
+ end
407
+
408
+ ##
409
+ # A casefold function
410
+ #
411
+ # Reference: {FaunaDB String Functions}[https://faunadb.com/documentation/queries#string_functions]
412
+ def casefold(string)
413
+ Expr.new casefold: Expr.wrap(string)
414
+ end
415
+
416
+ # :section: Time and Date Functions
417
+
418
+ ##
419
+ # A time expression
420
+ #
421
+ # Reference: {FaunaDB Time Functions}[https://faunadb.com/documentation/queries#time_functions]
422
+ def time(string)
423
+ Expr.new time: Expr.wrap(string)
424
+ end
425
+
426
+ ##
427
+ # An epoch expression
428
+ #
429
+ # Reference: {FaunaDB Time Functions}[https://faunadb.com/documentation/queries#time_functions]
430
+ def epoch(number, unit)
431
+ Expr.new epoch: Expr.wrap(number), unit: Expr.wrap(unit)
432
+ end
433
+
434
+ ##
435
+ # A date expression
436
+ #
437
+ # Reference: {FaunaDB Time Functions}[https://faunadb.com/documentation/queries#time_functions]
438
+ def date(string)
439
+ Expr.new date: Expr.wrap(string)
440
+ end
441
+
442
+ # :section: Miscellaneous Functions
443
+
444
+ ##
445
+ # An equals function
446
+ #
447
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation#queries-misc_functions]
448
+ def equals(*values)
449
+ Expr.new equals: Expr.wrap_varargs(values)
450
+ end
451
+
452
+ ##
453
+ # A contains function
454
+ #
455
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
456
+ def contains(path, in_)
457
+ Expr.new contains: Expr.wrap(path), in: Expr.wrap(in_)
458
+ end
459
+
460
+ ##
461
+ # A select function
462
+ #
463
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
464
+ def select(path, from, params = {})
465
+ Expr.new Expr.wrap_values(params).merge(select: Expr.wrap(path), from: Expr.wrap(from))
466
+ end
467
+
468
+ ##
469
+ # An add function
470
+ #
471
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
472
+ def add(*numbers)
473
+ Expr.new add: Expr.wrap_varargs(numbers)
474
+ end
475
+
476
+ ##
477
+ # A multiply function
478
+ #
479
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
480
+ def multiply(*numbers)
481
+ Expr.new multiply: Expr.wrap_varargs(numbers)
482
+ end
483
+
484
+ ##
485
+ # A subtract function
486
+ #
487
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
488
+ def subtract(*numbers)
489
+ Expr.new subtract: Expr.wrap_varargs(numbers)
490
+ end
491
+
492
+ ##
493
+ # A divide function
494
+ #
495
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
496
+ def divide(*numbers)
497
+ Expr.new divide: Expr.wrap_varargs(numbers)
498
+ end
499
+
500
+ ##
501
+ # A modulo function
502
+ #
503
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
504
+ def modulo(*numbers)
505
+ Expr.new modulo: Expr.wrap_varargs(numbers)
506
+ end
507
+
508
+ ##
509
+ # A less than function
510
+ #
511
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
512
+ def lt(*values)
513
+ Expr.new lt: Expr.wrap_varargs(values)
514
+ end
515
+
516
+ ##
517
+ # A less than or equal function
518
+ #
519
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
520
+ def lte(*values)
521
+ Expr.new lte: Expr.wrap_varargs(values)
522
+ end
523
+
524
+ ##
525
+ # A greater than function
526
+ #
527
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
528
+ def gt(*values)
529
+ Expr.new gt: Expr.wrap_varargs(values)
530
+ end
531
+
532
+ ##
533
+ # A greater than or equal function
534
+ #
535
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
536
+ def gte(*values)
537
+ Expr.new gte: Expr.wrap_varargs(values)
538
+ end
539
+
540
+ ##
541
+ # An and function
542
+ #
543
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
544
+ def and_(*booleans)
545
+ Expr.new and: Expr.wrap_varargs(booleans)
546
+ end
547
+
548
+ ##
549
+ # An or function
550
+ #
551
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
552
+ def or_(*booleans)
553
+ Expr.new or: Expr.wrap_varargs(booleans)
554
+ end
555
+
556
+ ##
557
+ # A not function
558
+ #
559
+ # Reference: {FaunaDB Miscellaneous Functions}[https://faunadb.com/documentation/queries#misc_functions]
560
+ def not_(boolean)
561
+ Expr.new not: Expr.wrap(boolean)
562
+ end
563
+
564
+ class Expr # :nodoc:
565
+ attr_reader :raw
566
+ alias_method :to_hash, :raw
567
+
568
+ def initialize(obj)
569
+ @raw = obj
570
+ end
571
+
572
+ def to_s
573
+ "Expr(#{@raw})"
574
+ end
575
+
576
+ alias_method :inspect, :to_s
577
+
578
+ def self.wrap(obj)
579
+ if obj.is_a? Expr
580
+ obj
581
+ elsif obj.is_a? Proc
582
+ Query.lambda(&obj)
583
+ elsif obj.is_a? Hash
584
+ Expr.new object: wrap_values(obj)
585
+ elsif obj.is_a? Array
586
+ Expr.new obj.map { |v| wrap(v) }
587
+ else
588
+ obj
589
+ end
590
+ end
591
+
592
+ def self.wrap_values(obj)
593
+ obj.inject({}) { |h, (k, v)| h[k] = wrap(v); h }
594
+ end
595
+
596
+ def self.wrap_varargs(values)
597
+ wrap(values.length == 1 ? values[0] : values)
598
+ end
599
+ end
600
+ end
601
+ end