rethinkdb 1.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rethinkdb.rb ADDED
@@ -0,0 +1,16 @@
1
+ # Copyright 2010-2012 RethinkDB, all rights reserved.
2
+ require 'rubygems'
3
+ require 'query_language.pb.rb'
4
+ require 'socket'
5
+ require 'pp'
6
+
7
+ load 'bt.rb'
8
+ load 'utils.rb'
9
+ load 'protob_compiler.rb'
10
+
11
+ load 'net.rb'
12
+
13
+ load 'data_collectors.rb'
14
+ load 'base_classes.rb'
15
+ load 'query.rb'
16
+ load 'rql.rb'
data/lib/rql.rb ADDED
@@ -0,0 +1,458 @@
1
+ # Copyright 2010-2012 RethinkDB, all rights reserved.
2
+ module RethinkDB
3
+ module Mixin_H4x # :nodoc:
4
+ def &(l,r) # :nodoc:
5
+ RQL.all_h4x(l,r)
6
+ end
7
+ end
8
+
9
+ # This module contains the RQL query construction functions. By far
10
+ # the most common way of gaining access to those functions, however,
11
+ # is to include/extend RethinkDB::Shortcuts to gain access to the
12
+ # shortcut <b>+r+</b>. That shortcut is used in all the examples
13
+ # below.
14
+ #
15
+ # Also, many of the functions here can be called as if they were
16
+ # instance methods of a RQL query. So the following are all equivalent:
17
+ # r.add(1,2)
18
+ # r(1).add(2)
19
+ # r(1) + 2
20
+ # r.+(1, 2)
21
+ module RQL
22
+ # Construct a javascript expression, which may refer to variables in scope
23
+ # (use <b>+to_s+</b> to get the name of a variable query, or simply splice
24
+ # it in). Defaults to a javascript expression, but if the optional second
25
+ # argument is <b>+:func+</b>, then you may instead provide the body of a
26
+ # javascript function. If you have a table <b>+table+</b>, the following
27
+ # are equivalent:
28
+ # table.map{|row| row[:id]}
29
+ # table.map{|row| r.js("#{row}.id")}
30
+ # table.map{r.js("this.id")} #implicit variable
31
+ # table.map{r.js("return this.id;", :func)} #implicit variable
32
+ # As are:
33
+ # r.let(:a => 1, :b => 2) { r.add(r.letvar('a'), r.letvar('b'), 1) }
34
+ # r.let(:a => 1, :b => 2) { r.js('a+b+1') }
35
+ def self.js(str, type=:expr);
36
+ if type == :expr then JSON_Expression.new [:js, "return #{str}"]
37
+ elsif type == :func then JSON_Expression.new [:js, str]
38
+ else raise TypeError, 'Type of javascript must be either :expr or :func.'
39
+ end
40
+ end
41
+
42
+ # Refer to the database named <b>+db_name+</b>. Usually used as a
43
+ # stepping stone to a table reference. For instance, to refer to
44
+ # the table 'tbl' in the database 'db':
45
+ # db('db').table('tbl')
46
+ def self.db(db_name); Database.new db_name; end
47
+
48
+ # Convert from a Ruby datatype to an RQL query. Numbers, strings, booleans,
49
+ # arrays, objects, and nil are all converted to their respective JSON types.
50
+ # <b>Note:</b> this function is idempotent, so the following are equivalent:
51
+ # r.expr(5)
52
+ # r.expr(r.expr(5))
53
+ # The shortcut `r` also acts like this when used as a function, so
54
+ # the following are equivalent:
55
+ # r.expr(1)
56
+ # r(1)
57
+ def self.expr x
58
+ return x if x.kind_of? RQL_Query
59
+ BT.alt_inspect(case x.class().hash
60
+ when Table.hash then x.to_mrs
61
+ when String.hash then JSON_Expression.new [:string, x]
62
+ when Fixnum.hash then JSON_Expression.new [:number, x]
63
+ when Float.hash then JSON_Expression.new [:number, x]
64
+ when TrueClass.hash then JSON_Expression.new [:bool, x]
65
+ when FalseClass.hash then JSON_Expression.new [:bool, x]
66
+ when NilClass.hash then JSON_Expression.new [:json_null]
67
+ when Array.hash then JSON_Expression.new [:array, *x.map{|y| expr(y)}]
68
+ when Hash.hash then
69
+ JSON_Expression.new [:object, *x.map{|var,term| [S.checkdict(var), expr(term)]}]
70
+
71
+ else raise TypeError, "RQL::expr can't handle object `#{x.inspect}` of class `#{x.class()}`.
72
+ Make sure you're providing a RQL expression or an object that can be coerced
73
+ to a JSON type (a String, Fixnum, Float, TrueClass, FalseClass, NilClass, Array,
74
+ or Hash)."
75
+ end) { x.inspect } end
76
+
77
+ # Explicitly construct an RQL variable from a string. See RQL::let.
78
+ # r.letvar('varname')
79
+ def self.letvar(varname)
80
+ BT.alt_inspect(Var_Expression.new [:var, varname]) { "letvar(#{varname.inspect})" }
81
+ end
82
+
83
+ # Provide a literal JSON string that will be parsed by the server. For
84
+ # example, the following are equivalent:
85
+ # r.expr({"a" => 5})
86
+ # r.json('{"a": 5}')
87
+ def self.json(str); JSON_Expression.new [:json, str]; end
88
+
89
+ # Construct an error. This is usually used in the branch of an <b>+if+</b>
90
+ # expression. For example:
91
+ # r.if(r(1) > 2, false, r.error('unreachable'))
92
+ # will only run the error query if 1 is greater than 2. If an error query
93
+ # does get run, it will be received as a RuntimeError in Ruby, so be
94
+ # prepared to handle it.
95
+ def self.error(err); JSON_Expression.new [:error, err]; end
96
+
97
+ # Test a predicate and execute one of two branches (just like
98
+ # Ruby's <b>+if+</b>). For example, if we have a table
99
+ # <b>+table+</b>:
100
+ # table.update{|row| r.if(row[:score] < 10, {:score => 10}, {})}
101
+ # will change every row with score below 10 in <b>+table+</b> to have score 10.
102
+ def self.branch(test, t_branch, f_branch)
103
+ tb = S.r(t_branch)
104
+ fb = S.r(f_branch)
105
+ if tb.kind_of? fb.class
106
+ resclass = fb.class
107
+ elsif fb.kind_of? tb.class
108
+ resclass = tb.class
109
+ else
110
+ raise TypeError, "Both branches of IF must be of compatible types."
111
+ end
112
+ resclass.new [:branch, S.r(test), S.r(t_branch), S.r(f_branch)]
113
+ end
114
+
115
+ # Construct a query that binds some values to variable (as
116
+ # specified by <b>+varbinds+</b>) and then executes <b>+body+</b>
117
+ # with those variables accessible through RQL::letvar. For
118
+ # example, the following are equivalent:
119
+ # r.let(:a => 2, :b => 3) { r.letvar('a') + r.letvar('b') }
120
+ # r.expr(5)
121
+ def self.let(varbinds, &body)
122
+ varbinds = varbinds.to_a
123
+ varbinds.map! {|name, value| [name.to_s, expr(value)]}
124
+ res = S.r(body.call)
125
+ res.class.new [:let, varbinds, res]
126
+ end
127
+
128
+ # Negate a boolean. May also be called as if it were an instance method of
129
+ # JSON_Expression for convenience. The following are equivalent:
130
+ # r.not(true)
131
+ # r(true).not
132
+ def self.not(pred); JSON_Expression.new [:call, [:not], [S.r(pred)]]; end
133
+
134
+ # Add two or more numbers together. May also be called as if it
135
+ # were a instance method of JSON_Expression for convenience, and
136
+ # overloads <b><tt>+</tt></b> if the lefthand side is a query.
137
+ # The following are all equivalent:
138
+ # r.add(1,2)
139
+ # r(1).add(2)
140
+ # (r(1) + 2) # Note that (1 + r(2)) is *incorrect* because Ruby only
141
+ # # overloads based on the lefthand side.
142
+ # The following is also legal:
143
+ # r.add(1,2,3)
144
+ # Add may also be used to concatenate arrays. The following are equivalent:
145
+ # r([1,2,3])
146
+ # r.add([1, 2], [3])
147
+ # r([1,2]) + [3]
148
+ def self.add(a, b, *rest)
149
+ JSON_Expression.new [:call, [:add], [S.r(a), S.r(b), *(rest.map{|x| S.r x})]];
150
+ end
151
+
152
+ # Subtract one number from another.
153
+ # May also be called as if it were a instance method of JSON_Expression for
154
+ # convenience, and overloads <b><tt>-</tt></b> if the lefthand side is a
155
+ # query. Also has the shorter synonym <b>+sub+</b>. The following are all
156
+ # equivalent:
157
+ # r.subtract(1,2)
158
+ # r(1).subtract(2)
159
+ # r.sub(1,2)
160
+ # r(1).sub(2)
161
+ # (r(1) - 2) # Note that (1 - r(2)) is *incorrect* because Ruby only
162
+ # # overloads based on the lefthand side.
163
+ def self.subtract(a, b); JSON_Expression.new [:call, [:subtract], [S.r(a), S.r(b)]]; end
164
+
165
+ # Multiply two numbers together. May also be called as if it were
166
+ # a instance method of JSON_Expression for convenience, and
167
+ # overloads <b><tt>+</tt></b> if the lefthand side is a query.
168
+ # Also has the shorter synonym <b>+mul+</b>. The following are
169
+ # all equivalent:
170
+ # r.multiply(1,2)
171
+ # r(1).multiply(2)
172
+ # r.mul(1,2)
173
+ # r(1).mul(2)
174
+ # (r(1) * 2) # Note that (1 * r(2)) is *incorrect* because Ruby only
175
+ # # overloads based on the lefthand side.
176
+ # The following is also legal:
177
+ # r.multiply(1,2,3)
178
+ def self.multiply(a, b, *rest)
179
+ JSON_Expression.new [:call, [:multiply], [S.r(a), S.r(b), *(rest.map{|x| S.r x})]];
180
+ end
181
+
182
+ # Divide one number by another. May also be called as if it were
183
+ # a instance method of JSON_Expression for convenience, and
184
+ # overloads <b><tt>/</tt></b> if the lefthand side is a query.
185
+ # Also has the shorter synonym <b>+div+</b>. The following are
186
+ # all equivalent:
187
+ # r.divide(1,2)
188
+ # r(1).divide(2)
189
+ # r.div(1,2)
190
+ # r(1).div(2)
191
+ # (r(1) / 2) # Note that (1 / r(2)) is *incorrect* because Ruby only
192
+ # # overloads based on the lefthand side.
193
+ def self.divide(a, b); JSON_Expression.new [:call, [:divide], [S.r(a), S.r(b)]]; end
194
+
195
+ # Take one number modulo another. May also be called as if it
196
+ # were a instance method of JSON_Expression for convenience, and
197
+ # overloads <b><tt>%</tt></b> if the lefthand side is a query.
198
+ # Also has the shorter synonym <b>+mod+</b>. The following are all
199
+ # equivalent:
200
+ # r.modulo(1,2)
201
+ # r(1).modulo(2)
202
+ # r.mod(1,2)
203
+ # r(1).mod(2)
204
+ # (r(1) % 2) # Note that (1 % r(2)) is *incorrect* because Ruby only
205
+ # # overloads based on the lefthand side.
206
+ def self.modulo(a, b); JSON_Expression.new [:call, [:modulo], [S.r(a), S.r(b)]]; end
207
+
208
+ # Returns true if any of its arguments are true, like <b>+or+</b>
209
+ # in ruby (but with arbitrarily many arguments). May also be
210
+ # called as if it were a instance method of JSON_Expression for
211
+ # convenience, and overloads <b><tt>|</tt></b> if the lefthand
212
+ # side is a query. Also has the synonym <b>+or+</b>. The
213
+ # following are all equivalent:
214
+ # r(true)
215
+ # r.any(false, true)
216
+ # r.or(false, true)
217
+ # r(false).any(true)
218
+ # r(false).or(true)
219
+ # (r(false) | true) # Note that (false | r(true)) is *incorrect* because
220
+ # # Ruby only overloads based on the lefthand side
221
+ def self.any(pred, *rest)
222
+ JSON_Expression.new [:call, [:any], [S.r(pred), *(rest.map{|x| S.r x})]];
223
+ end
224
+
225
+ # Returns true if all of its arguments are true, like <b>+and+</b>
226
+ # in ruby (but with arbitrarily many arguments). May also be
227
+ # called as if it were a instance method of JSON_Expression for
228
+ # convenience, and overloads <b><tt>&</tt></b> if the lefthand
229
+ # side is a query. Also has the synonym <b>+and+</b>. The
230
+ # following are all equivalent:
231
+ # r(false)
232
+ # r.all(false, true)
233
+ # r.and(false, true)
234
+ # r(false).all(true)
235
+ # r(false).and(true)
236
+ # (r(false) & true) # Note that (false & r(true)) is *incorrect* because
237
+ # # Ruby only overloads based on the lefthand side
238
+ def self.all(pred, *rest)
239
+ JSON_Expression.new [:call, [:all], [S.r(pred), *(rest.map{|x| S.r x})]];
240
+ end
241
+
242
+ # Take the union of 2 or more sequences <b>+seqs+</b>. Note that
243
+ # unlike normal set union, duplicate values are preserved. May
244
+ # also be called as if it were a instance method of RQL_Query,
245
+ # for convenience. For example, if we have a table
246
+ # <b>+table+</b>, the following are equivalent:
247
+ # r.union(table.map{|row| r[:id]}, table.map{|row| row[:num]})
248
+ # table.map{|row| row[:id]}.union(table.map{|row| row[:num]})
249
+ def self.union(*seqs)
250
+ #TODO: this looks wrong...
251
+ if seqs.all? {|x| x.kind_of? Stream_Expression}
252
+ resclass = Stream_Expression
253
+ elsif seqs.all? {|x| x.kind_of? JSON_Expression}
254
+ resclass = JSON_Expression
255
+ else
256
+ seqs = seqs.map {|x| self.expr x}
257
+ resclass = JSON_Expression
258
+ end
259
+ resclass.new [:call, [:union], seqs.map{|x| S.r x}];
260
+ end
261
+
262
+ # Merge two objects together with a preference for the object on the right.
263
+ # The resulting object has all the attributes in both objects, and if the
264
+ # two objects share an attribute, the value from the object on the right
265
+ # "wins" and is included in the final object. May also be called as if it
266
+ # were an instance method of JSON_Expression, for convenience. The following are
267
+ # equivalent:
268
+ # r({:a => 10, :b => 2, :c => 30})
269
+ # r.merge({:a => 1, :b => 2}, {:a => 10, :c => 30})
270
+ # r({:a => 1, :b => 2}).merge({:a => 10, :c => 30})
271
+ def self.merge(obj1, obj2)
272
+ JSON_Expression.new [:call, [:merge], [S.r(obj1), S.r(obj2)]]
273
+ end
274
+
275
+ # Check whether two JSON expressions are equal. May also be called as
276
+ # if it were a member function of JSON_Expression for convenience. Has the
277
+ # synonym <b>+equals+</b>. The following are all equivalent:
278
+ # r(true)
279
+ # r.eq 1,1
280
+ # r(1).eq(1)
281
+ # r.equals 1,1
282
+ # r(1).equals(1)
283
+ # May also be used with more than two arguments. The following are
284
+ # equivalent:
285
+ # r(false)
286
+ # r.eq(1, 1, 2)
287
+ def self.eq(*args)
288
+ JSON_Expression.new [:call, [:compare, :eq], args.map{|x| S.r x}]
289
+ end
290
+
291
+ # Check whether two JSON expressions are *not* equal. May also be
292
+ # called as if it were a member function of JSON_Expression for convenience. The
293
+ # following are all equivalent:
294
+ # r(true)
295
+ # r.ne 1,2
296
+ # r(1).ne(2)
297
+ # r.not r.eq(1,2)
298
+ # r(1).eq(2).not
299
+ # May also be used with more than two arguments. The following are
300
+ # equivalent:
301
+ # r(true)
302
+ # r.ne(1, 1, 2)
303
+ def self.ne(*args)
304
+ JSON_Expression.new [:call, [:compare, :ne], args.map{|x| S.r x}]
305
+ end
306
+
307
+ # Check whether one JSON expression is less than another. May also be
308
+ # called as if it were a member function of JSON_Expression for convenience. May
309
+ # also be called as the infix operator <b><tt> < </tt></b> if the lefthand
310
+ # side is a query. The following are all equivalent:
311
+ # r(true)
312
+ # r.lt 1,2
313
+ # r(1).lt(2)
314
+ # r(1) < 2
315
+ # Note that the following is illegal, because Ruby only overloads infix
316
+ # operators based on the lefthand side:
317
+ # 1 < r(2)
318
+ # May also be used with more than two arguments. The following are
319
+ # equivalent:
320
+ # r(true)
321
+ # r.lt(1, 2, 3)
322
+ def self.lt(*args)
323
+ JSON_Expression.new [:call, [:compare, :lt], args.map{|x| S.r x}]
324
+ end
325
+
326
+ # Check whether one JSON expression is less than or equal to another.
327
+ # May also be called as if it were a member function of JSON_Expression for
328
+ # convenience. May also be called as the infix operator <b><tt> <= </tt></b>
329
+ # if the lefthand side is a query. The following are all equivalent:
330
+ # r(true)
331
+ # r.le 1,1
332
+ # r(1).le(1)
333
+ # r(1) <= 1
334
+ # Note that the following is illegal, because Ruby only overloads infix
335
+ # operators based on the lefthand side:
336
+ # 1 <= r(1)
337
+ # May also be used with more than two arguments. The following are
338
+ # equivalent:
339
+ # r(true)
340
+ # r.le(1, 2, 2)
341
+ def self.le(*args)
342
+ JSON_Expression.new [:call, [:compare, :le], args.map{|x| S.r x}]
343
+ end
344
+
345
+ # Check whether one JSON expression is greater than another.
346
+ # May also be called as if it were a member function of JSON_Expression for
347
+ # convenience. May also be called as the infix operator <b><tt> > </tt></b>
348
+ # if the lefthand side is an RQL query. The following are all equivalent:
349
+ # r(true)
350
+ # r.gt 2,1
351
+ # r(2).gt(1)
352
+ # r(2) > 1
353
+ # Note that the following is illegal, because Ruby only overloads infix
354
+ # operators based on the lefthand side:
355
+ # 2 > r(1)
356
+ # May also be used with more than two arguments. The following are
357
+ # equivalent:
358
+ # r(true)
359
+ # r.gt(3, 2, 1)
360
+ def self.gt(*args)
361
+ JSON_Expression.new [:call, [:compare, :gt], args.map{|x| S.r x}]
362
+ end
363
+
364
+ # Check whether one JSON expression is greater than or equal to another.
365
+ # May also be called as if it were a member function of JSON_Expression for
366
+ # convenience. May also be called as the infix operator <b><tt> >= </tt></b>
367
+ # if the lefthand side is a query. The following are all equivalent:
368
+ # r(true)
369
+ # r.ge 1,1
370
+ # r(1).ge(1)
371
+ # r(1) >= 1
372
+ # Note that the following is illegal, because Ruby only overloads infix
373
+ # operators based on the lefthand side:
374
+ # 1 >= r(1)
375
+ # May also be used with more than two arguments. The following are
376
+ # equivalent:
377
+ # r(true)
378
+ # r.ge(2, 2, 1)
379
+ def self.ge(*args)
380
+ JSON_Expression.new [:call, [:compare, :ge], args.map{|x| S.r x}]
381
+ end
382
+
383
+ # Create a new database with name <b>+db_name+</b>. Either
384
+ # returns <b>+nil+</b> or raises an error.
385
+ def self.db_create(db_name); Meta_Query.new [:create_db, db_name]; end
386
+
387
+ # List all databases. Either returns an array of strings or raises an error.
388
+ def self.db_list(); Meta_Query.new [:list_dbs]; end
389
+
390
+ # Drop the database with name <b>+db_name+</b>. Either returns
391
+ # <b>+nil+</b> or raises an error.
392
+ def self.db_drop(db_name); Meta_Query.new [:drop_db, db_name]; end
393
+
394
+ # Dereference aliases (see utils.rb)
395
+ def self.method_missing(m, *args, &block) # :nodoc:
396
+ (m2 = C.method_aliases[m]) ? self.send(m2, *args, &block) : super(m, *args, &block)
397
+ end
398
+
399
+ # Refer to a table by name. When run over a connection, this query uses the
400
+ # default database of that connection. If we have a connection <b>+c+</b>
401
+ # like so:
402
+ # c = r.connect('localhost', 28015, 'db_name')
403
+ # then the following are equivalent:
404
+ # c.run(r.table('tbl_name'))
405
+ # c.run(r.db('db_name').table('tbl_name')
406
+ def self.table(name, opts={})
407
+ Table.new(:default_db, name, opts)
408
+ end
409
+
410
+ # A shortcut for Data_Collectors::count
411
+ def self.count(*args); Data_Collectors.count(*args); end
412
+ # A shortcut for Data_Collectors::sum
413
+ def self.sum(*args); Data_Collectors.sum(*args); end
414
+ # A shortcut for Data_Collectors::avg
415
+ def self.avg(*args); Data_Collectors.avg(*args); end
416
+
417
+ def self.boolprop(op, l, r) # :nodoc:
418
+ badop = l.boolop? ? l : r
419
+ if l.boolop? || r.boolop?
420
+ raise RuntimeError,"Error: Cannot use infix #{op} operator on infix boolean expression:
421
+ #{badop.inspect}
422
+ This is almost always a precedence error; try adding parentheses. If you
423
+ actually need to compare booleans, use non-infix operators like `r.all(a,b)`
424
+ instead of `a & b`."
425
+ end
426
+ return RQL.send(op, l, r)
427
+ end
428
+ # def self.boolprop(op, l, r) # :nodoc:
429
+ # if l.boolop?
430
+ # larg,rarg = l.body[2]
431
+ # sexp = [l.body[0], l.body[1], [larg, boolprop(op, rarg, r)]]
432
+ # elsif r.boolop?
433
+ # larg,rarg = r.body[2]
434
+ # sexp = [r.body[0], r.body[1], [boolprop(op, l, larg), rarg]]
435
+ # else
436
+ # return RQL.send(op, l, r);
437
+ # end
438
+ # return S.mark_boolop(JSON_Expression.new sexp)
439
+ # end
440
+
441
+ # See RQL::lt
442
+ def self.< (l,r); boolprop(:lt, S.r(l), S.r(r)); end
443
+ # See RQL::le
444
+ def self.<=(l,r); boolprop(:le, S.r(l), S.r(r)); end
445
+ # See RQL::gt
446
+ def self.> (l,r); boolprop(:gt, S.r(l), S.r(r)); end
447
+ # See RQL::ge
448
+ def self.>=(l,r); boolprop(:ge, S.r(l), S.r(r)); end
449
+
450
+ def self.|(l,r) # :nodoc:
451
+ S.mark_boolop(any(l,r))
452
+ end
453
+ extend Mixin_H4x
454
+ def self.all_h4x(l,r) # :nodoc:
455
+ S.mark_boolop(all(l,r))
456
+ end
457
+ end
458
+ end