rethinkdb 1.4.0.2 → 1.5.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.
- data/lib/func.rb +4 -5
- data/lib/net.rb +17 -7
- data/lib/ql2.pb.rb +76 -31
- data/lib/rpp.rb +1 -1
- data/lib/shim.rb +29 -18
- metadata +7 -7
data/lib/func.rb
CHANGED
@@ -12,7 +12,9 @@ module RethinkDB
|
|
12
12
|
}
|
13
13
|
@@opt_off = {
|
14
14
|
:reduce => -1, :between => -1, :grouped_map_reduce => -1,
|
15
|
-
:table => -1, :table_create => -1
|
15
|
+
:table => -1, :table_create => -1,
|
16
|
+
:get_all => -1, :eq_join => -1,
|
17
|
+
:javascript => -1
|
16
18
|
}
|
17
19
|
@@rewrites = {
|
18
20
|
:< => :lt, :<= => :le, :> => :gt, :>= => :ge,
|
@@ -27,6 +29,7 @@ module RethinkDB
|
|
27
29
|
:type_of => :typeof
|
28
30
|
}
|
29
31
|
def method_missing(m, *a, &b)
|
32
|
+
unbound_if(m.to_s.downcase != m.to_s, m)
|
30
33
|
bitop = [:"|", :"&"].include?(m) ? [m, a, b] : nil
|
31
34
|
if [:<, :<=, :>, :>=, :+, :-, :*, :/, :%].include?(m)
|
32
35
|
a.each {|arg|
|
@@ -114,10 +117,6 @@ module RethinkDB
|
|
114
117
|
super(*a, &b)
|
115
118
|
end
|
116
119
|
|
117
|
-
def between(l=nil, r=nil)
|
118
|
-
super(Hash[(l ? [['left_bound', l]] : []) + (r ? [['right_bound', r]] : [])])
|
119
|
-
end
|
120
|
-
|
121
120
|
def -@; RQL.new.sub(0, self); end
|
122
121
|
|
123
122
|
def [](ind)
|
data/lib/net.rb
CHANGED
@@ -93,24 +93,34 @@ module RethinkDB
|
|
93
93
|
attr_reader :default_db, :conn_id
|
94
94
|
|
95
95
|
@@token_cnt = 0
|
96
|
-
def run_internal
|
96
|
+
def run_internal(q, noreply=false)
|
97
97
|
dispatch q
|
98
|
-
wait
|
98
|
+
noreply ? nil : wait(q.token)
|
99
99
|
end
|
100
100
|
def run(msg, opts)
|
101
|
+
raise RuntimeError, "Error: Connection Closed." if !@socket || !@listener
|
101
102
|
q = Query.new
|
102
103
|
q.type = Query::QueryType::START
|
103
104
|
q.query = msg
|
104
105
|
q.token = @@token_cnt += 1
|
105
106
|
|
106
|
-
@default_opts.merge(opts)
|
107
|
+
all_opts = @default_opts.merge(opts)
|
108
|
+
if all_opts.keys.include?(:noreply)
|
109
|
+
all_opts[:noreply] = !!all_opts[:noreply]
|
110
|
+
end
|
111
|
+
all_opts.each {|k,v|
|
107
112
|
ap = Query::AssocPair.new
|
108
113
|
ap.key = k.to_s
|
109
|
-
|
114
|
+
if v.class == RQL
|
115
|
+
ap.val = v.to_pb
|
116
|
+
else
|
117
|
+
ap.val = RQL.new.expr(v).to_pb
|
118
|
+
end
|
110
119
|
q.global_optargs << ap
|
111
120
|
}
|
112
121
|
|
113
|
-
res = run_internal
|
122
|
+
res = run_internal(q, all_opts[:noreply])
|
123
|
+
return res if !res
|
114
124
|
if res.type == Response::ResponseType::SUCCESS_PARTIAL
|
115
125
|
Cursor.new(Shim.response_to_native(res, msg), msg, self, q.token, true)
|
116
126
|
elsif res.type == Response::ResponseType::SUCCESS_SEQUENCE
|
@@ -121,7 +131,7 @@ module RethinkDB
|
|
121
131
|
end
|
122
132
|
|
123
133
|
def send packet
|
124
|
-
@socket.
|
134
|
+
@socket.write(packet)
|
125
135
|
end
|
126
136
|
|
127
137
|
def dispatch msg
|
@@ -201,7 +211,7 @@ module RethinkDB
|
|
201
211
|
return buf
|
202
212
|
end
|
203
213
|
end
|
204
|
-
@socket.
|
214
|
+
@socket.write([@@magic_number].pack('L<'))
|
205
215
|
@listener.terminate if @listener
|
206
216
|
@listener = Thread.new do
|
207
217
|
loop do
|
data/lib/ql2.pb.rb
CHANGED
@@ -4,13 +4,17 @@
|
|
4
4
|
# // THE HIGH-LEVEL VIEW //
|
5
5
|
# ////////////////////////////////////////////////////////////////////////////////
|
6
6
|
#
|
7
|
-
# // Process:
|
8
|
-
# // targetting (in the [Version]
|
9
|
-
# //
|
10
|
-
# //
|
11
|
-
# //
|
12
|
-
#
|
13
|
-
# //
|
7
|
+
# // Process: When you first open a connection, send the magic number
|
8
|
+
# // for the version of the protobuf you're targetting (in the [Version]
|
9
|
+
# // enum). This should **NOT** be sent as a protobuf; just send the
|
10
|
+
# // little-endian 32-bit integer over the wire raw. This number should
|
11
|
+
# // only be sent once per connection.
|
12
|
+
#
|
13
|
+
# // Next, for each query you want to send, construct a [Query] protobuf
|
14
|
+
# // and serialize it to a binary blob. Send the blob's size to the
|
15
|
+
# // server encoded as a little-endian 32-bit integer, followed by the
|
16
|
+
# // blob itself. You will recieve a [Response] protobuf back preceded
|
17
|
+
# // by its own size, once again encoded as a little-endian 32-bit
|
14
18
|
# // integer. You can see an example exchange below in **EXAMPLE**.
|
15
19
|
#
|
16
20
|
# // A query consists of a [Term] to evaluate and a unique-per-connection
|
@@ -48,7 +52,10 @@
|
|
48
52
|
# // A [Term] is how we represent the operations we want a query to perform.
|
49
53
|
# optional Term query = 2; // only present when [type] = [START]
|
50
54
|
# optional int64 token = 3;
|
51
|
-
#
|
55
|
+
# // This flag is ignored on the server. `noreply` should be added
|
56
|
+
# // to `global_optargs` instead (the key "noreply" should map to
|
57
|
+
# // either true or false).
|
58
|
+
# optional bool OBSOLETE_noreply = 4 [default = false];
|
52
59
|
#
|
53
60
|
# message AssocPair {
|
54
61
|
# optional string key = 1;
|
@@ -162,6 +169,9 @@
|
|
162
169
|
# // terms). These are marked with a `!`.
|
163
170
|
# // Optional arguments are specified within curly braces as argname `:` value
|
164
171
|
# // type (e.x `{use_outdated:BOOL}`)
|
172
|
+
# // Many RQL operations are polymorphic. For these, alterantive type signatures
|
173
|
+
# // are separated by `|`.
|
174
|
+
# //
|
165
175
|
# // The RQL type hierarchy is as follows:
|
166
176
|
# // Top
|
167
177
|
# // DATUM
|
@@ -179,6 +189,7 @@
|
|
179
189
|
# // Table
|
180
190
|
# // Database
|
181
191
|
# // Function
|
192
|
+
# // Ordering - used only by ORDER_BY
|
182
193
|
# // Error
|
183
194
|
# message Term {
|
184
195
|
# enum TermType {
|
@@ -198,7 +209,8 @@
|
|
198
209
|
# // libraries, and because it's more efficient on the wire.)
|
199
210
|
# VAR = 10; // !NUMBER -> DATUM
|
200
211
|
# // Takes some javascript code and executes it.
|
201
|
-
# JAVASCRIPT = 11; // STRING -> DATUM |
|
212
|
+
# JAVASCRIPT = 11; // STRING {timeout: !NUMBER} -> DATUM |
|
213
|
+
# // STRING {timeout: !NUMBER} -> Function(*)
|
202
214
|
# // Takes a string and throws an error with that message.
|
203
215
|
# ERROR = 12; // STRING -> Error
|
204
216
|
# // Takes nothing and returns a reference to the implicit variable.
|
@@ -209,9 +221,10 @@
|
|
209
221
|
# DB = 14; // STRING -> Database
|
210
222
|
# // Returns a reference to a table.
|
211
223
|
# TABLE = 15; // Database, STRING, {use_outdated:BOOL} -> Table | STRING, {use_outdated:BOOL} -> Table
|
212
|
-
# // Gets a single element from a table by its primary key.
|
224
|
+
# // Gets a single element from a table by its primary or a secondary key.
|
213
225
|
# GET = 16; // Table, STRING -> SingleSelection | Table, NUMBER -> SingleSelection |
|
214
|
-
# // Table, STRING -> NULL | Table, NUMBER -> NULL
|
226
|
+
# // Table, STRING -> NULL | Table, NUMBER -> NULL |
|
227
|
+
# GET_ALL = 78; // Table, JSON {index:!STRING} => ARRAY
|
215
228
|
#
|
216
229
|
# // Simple DATUM Ops
|
217
230
|
# EQ = 17; // DATUM... -> BOOL
|
@@ -253,14 +266,14 @@
|
|
253
266
|
#
|
254
267
|
# // Sequence Ops
|
255
268
|
# // Get all elements of a sequence between two values.
|
256
|
-
# BETWEEN = 36; // StreamSelection,
|
269
|
+
# BETWEEN = 36; // StreamSelection, DATUM, DATUM, {:index:!STRING} -> StreamSelection
|
257
270
|
# REDUCE = 37; // Sequence, Function(2), {base:DATUM} -> DATUM
|
258
271
|
# MAP = 38; // Sequence, Function(1) -> Sequence
|
259
272
|
# FILTER = 39; // Sequence, Function(1) -> Sequence | Sequence, OBJECT -> Sequence
|
260
273
|
# // Map a function over a sequence and then concatenate the results together.
|
261
274
|
# CONCATMAP = 40; // Sequence, Function(1) -> Sequence
|
262
275
|
# // Order a sequence based on one or more attributes.
|
263
|
-
# ORDERBY = 41; // Sequence, !STRING... -> Sequence
|
276
|
+
# ORDERBY = 41; // Sequence, (!STRING | Ordering)... -> Sequence
|
264
277
|
# // Get all distinct elements of a sequence (like `uniq`).
|
265
278
|
# DISTINCT = 42; // Sequence -> Sequence
|
266
279
|
# // Count the number of elements in a sequence.
|
@@ -275,11 +288,17 @@
|
|
275
288
|
# // - A reduction to apply to each of the groups.
|
276
289
|
# GROUPED_MAP_REDUCE = 46; // Sequence, Function(1), Function(1), Function(2), {base:DATUM} -> Sequence
|
277
290
|
# // Groups a sequence by one or more attributes, and then applies a reduction.
|
278
|
-
#
|
291
|
+
# // The third argument is a special object literal giving the kind of operation to be
|
292
|
+
# // performed and any necessary arguments.
|
293
|
+
# // At present, GROUPBY suports the following operations
|
294
|
+
# // * {'COUNT': <ignored>} - count the size of the group
|
295
|
+
# // * {'SUM': attr} - sum the values of the given attribute across the group
|
296
|
+
# // * {'AVG': attr} - average the values of the given attribute across the group
|
297
|
+
# GROUPBY = 47; // Sequence, ARRAY, !GROUP_BY_OBJECT -> Sequence
|
279
298
|
# INNER_JOIN = 48; // Sequence, Sequence, Function(2) -> Sequence
|
280
299
|
# OUTER_JOIN = 49; // Sequence, Sequence, Function(2) -> Sequence
|
281
300
|
# // An inner-join that does an equality comparison on two attributes.
|
282
|
-
# EQ_JOIN = 50; // Sequence, !STRING, Sequence -> Sequence
|
301
|
+
# EQ_JOIN = 50; // Sequence, !STRING, Sequence, {index:!STRING} -> Sequence
|
283
302
|
# ZIP = 72; // Sequence -> Sequence
|
284
303
|
#
|
285
304
|
#
|
@@ -315,12 +334,28 @@
|
|
315
334
|
# DB_DROP = 58; // STRING -> OBJECT
|
316
335
|
# // Lists all the databases by name. (Takes no arguments)
|
317
336
|
# DB_LIST = 59; // -> ARRAY
|
318
|
-
# // Creates a table with a particular name in a particular
|
319
|
-
#
|
320
|
-
# //
|
337
|
+
# // Creates a table with a particular name in a particular
|
338
|
+
# // database. (You may omit the first argument to use the
|
339
|
+
# // default database.)
|
340
|
+
# TABLE_CREATE = 60; // Database, STRING, {datacenter:STRING, primary_key:STRING, cache_size:NUMBER, hard_durability:BOOL} -> OBJECT
|
341
|
+
# // STRING, {datacenter:STRING, primary_key:STRING, cache_size:NUMBER, hard_durability:BOOL} -> OBJECT
|
342
|
+
# // Drops a table with a particular name from a particular
|
343
|
+
# // database. (You may omit the first argument to use the
|
344
|
+
# // default database.)
|
321
345
|
# TABLE_DROP = 61; // Database, STRING -> OBJECT
|
322
|
-
#
|
346
|
+
# // STRING -> OBJECT
|
347
|
+
# // Lists all the tables in a particular database. (You may
|
348
|
+
# // omit the first argument to use the default database.)
|
323
349
|
# TABLE_LIST = 62; // Database -> ARRAY
|
350
|
+
# // -> ARRAY
|
351
|
+
#
|
352
|
+
# // * Secondary indexes OPs
|
353
|
+
# // Creates a new secondary index with a particular name and definition.
|
354
|
+
# INDEX_CREATE = 75; // Table, STRING, Function(1) -> OBJECT
|
355
|
+
# // Drops a secondary index with a particular name from the specified table.
|
356
|
+
# INDEX_DROP = 76; // Table, STRING -> OBJECT
|
357
|
+
# // Lists all secondary indexes on a particular table.
|
358
|
+
# INDEX_LIST = 77; // Table -> ARRAY
|
324
359
|
#
|
325
360
|
# // * Control Operators
|
326
361
|
# // Calls a function on data
|
@@ -381,8 +416,13 @@
|
|
381
416
|
# // }];
|
382
417
|
# FUNC = 69; // ARRAY, Top -> ARRAY -> Top
|
383
418
|
#
|
384
|
-
#
|
385
|
-
#
|
419
|
+
# // Indicates to ORDER_BY that this attribute is to be sorted in ascending order.
|
420
|
+
# ASC = 73; // !STRING -> Ordering
|
421
|
+
# // Indicates to ORDER_BY that this attribute is to be sorted in descending order.
|
422
|
+
# DESC = 74; // !STRING -> Ordering
|
423
|
+
#
|
424
|
+
# // Gets info about anything. INFO is most commonly called on tables.
|
425
|
+
# INFO = 79; // Top -> OBJECT
|
386
426
|
# }
|
387
427
|
# optional TermType type = 1;
|
388
428
|
#
|
@@ -413,24 +453,24 @@
|
|
413
453
|
# // args = [Term {
|
414
454
|
# // type = TABLE;
|
415
455
|
# // args = [Term {
|
416
|
-
# // type =
|
417
|
-
# //
|
456
|
+
# // type = DATUM;
|
457
|
+
# // datum = Datum { type = R_STR; r_str = "tbl"; };
|
418
458
|
# // }];
|
419
459
|
# // optargs = [["use_outdated",
|
420
460
|
# // Term {
|
421
|
-
# // type =
|
422
|
-
# //
|
461
|
+
# // type = DATUM;
|
462
|
+
# // datum = Datum { type = R_BOOL; r_bool = true; };
|
423
463
|
# // }]];
|
424
464
|
# // },
|
425
465
|
# // Term {
|
426
|
-
# // type =
|
466
|
+
# // type = MAKE_ARRAY;
|
427
467
|
# // args = [Term {
|
428
|
-
# // type =
|
429
|
-
# //
|
468
|
+
# // type = DATUM;
|
469
|
+
# // datum = Datum { type = R_OBJECT; r_object = [["id", 0]]; };
|
430
470
|
# // },
|
431
471
|
# // Term {
|
432
|
-
# // type =
|
433
|
-
# //
|
472
|
+
# // type = DATUM;
|
473
|
+
# // datum = Datum { type = R_OBJECT; r_object = [["id", 1]]; };
|
434
474
|
# // }];
|
435
475
|
# // }]
|
436
476
|
# // }
|
@@ -471,7 +511,7 @@ class Query < ::Protobuf::Message
|
|
471
511
|
optional :QueryType, :type, 1
|
472
512
|
optional :Term, :query, 2
|
473
513
|
optional :int64, :token, 3
|
474
|
-
optional :bool, :
|
514
|
+
optional :bool, :OBSOLETE_noreply, 4, :default => false
|
475
515
|
class AssocPair < ::Protobuf::Message
|
476
516
|
defined_in __FILE__
|
477
517
|
optional :string, :key, 1
|
@@ -548,6 +588,7 @@ class Term < ::Protobuf::Message
|
|
548
588
|
DB = value(:DB, 14)
|
549
589
|
TABLE = value(:TABLE, 15)
|
550
590
|
GET = value(:GET, 16)
|
591
|
+
GET_ALL = value(:GET_ALL, 78)
|
551
592
|
EQ = value(:EQ, 17)
|
552
593
|
NE = value(:NE, 18)
|
553
594
|
LT = value(:LT, 19)
|
@@ -597,6 +638,9 @@ class Term < ::Protobuf::Message
|
|
597
638
|
TABLE_CREATE = value(:TABLE_CREATE, 60)
|
598
639
|
TABLE_DROP = value(:TABLE_DROP, 61)
|
599
640
|
TABLE_LIST = value(:TABLE_LIST, 62)
|
641
|
+
INDEX_CREATE = value(:INDEX_CREATE, 75)
|
642
|
+
INDEX_DROP = value(:INDEX_DROP, 76)
|
643
|
+
INDEX_LIST = value(:INDEX_LIST, 77)
|
600
644
|
FUNCALL = value(:FUNCALL, 64)
|
601
645
|
BRANCH = value(:BRANCH, 65)
|
602
646
|
ANY = value(:ANY, 66)
|
@@ -605,6 +649,7 @@ class Term < ::Protobuf::Message
|
|
605
649
|
FUNC = value(:FUNC, 69)
|
606
650
|
ASC = value(:ASC, 73)
|
607
651
|
DESC = value(:DESC, 74)
|
652
|
+
INFO = value(:INFO, 79)
|
608
653
|
end
|
609
654
|
optional :TermType, :type, 1
|
610
655
|
optional :Datum, :datum, 2
|
data/lib/rpp.rb
CHANGED
@@ -178,7 +178,7 @@ module RethinkDB
|
|
178
178
|
end
|
179
179
|
}.flatten.join("\n") +
|
180
180
|
(@@context ?
|
181
|
-
"\
|
181
|
+
"\nErroneous_Portion_Constructed:\n" +
|
182
182
|
"#{@@context.map{|x| "\tfrom "+x}.join("\n")}" +
|
183
183
|
"\nCalled:" : "")
|
184
184
|
rescue Exception => e
|
data/lib/shim.rb
CHANGED
@@ -4,7 +4,7 @@ module RethinkDB
|
|
4
4
|
raise RqlRuntimeError, "SHENANIGANS" if d.class != Datum
|
5
5
|
dt = Datum::DatumType
|
6
6
|
case d.type
|
7
|
-
when dt::R_NUM then d.r_num
|
7
|
+
when dt::R_NUM then d.r_num == d.r_num.to_i ? d.r_num.to_i : d.r_num
|
8
8
|
when dt::R_STR then d.r_str
|
9
9
|
when dt::R_BOOL then d.r_bool
|
10
10
|
when dt::R_NULL then nil
|
@@ -48,15 +48,15 @@ module RethinkDB
|
|
48
48
|
def self.native_to_datum_term x
|
49
49
|
dt = Datum::DatumType
|
50
50
|
d = Datum.new
|
51
|
-
case x
|
52
|
-
when Fixnum
|
53
|
-
when Float
|
54
|
-
when Bignum
|
55
|
-
when String
|
56
|
-
when Symbol
|
57
|
-
when TrueClass
|
58
|
-
when FalseClass
|
59
|
-
when NilClass
|
51
|
+
case x
|
52
|
+
when Fixnum then d.type = dt::R_NUM; d.r_num = x
|
53
|
+
when Float then d.type = dt::R_NUM; d.r_num = x
|
54
|
+
when Bignum then d.type = dt::R_NUM; d.r_num = x
|
55
|
+
when String then d.type = dt::R_STR; d.r_str = x
|
56
|
+
when Symbol then d.type = dt::R_STR; d.r_str = x.to_s
|
57
|
+
when TrueClass then d.type = dt::R_BOOL; d.r_bool = x
|
58
|
+
when FalseClass then d.type = dt::R_BOOL; d.r_bool = x
|
59
|
+
when NilClass then d.type = dt::R_NULL
|
60
60
|
else raise RqlRuntimeError, "UNREACHABLE"
|
61
61
|
end
|
62
62
|
t = Term.new
|
@@ -72,21 +72,32 @@ module RethinkDB
|
|
72
72
|
def expr(x)
|
73
73
|
unbound_if @body
|
74
74
|
return x if x.class == RQL
|
75
|
-
datum_types = [Fixnum, Float, Bignum, String, Symbol,
|
76
|
-
|
75
|
+
datum_types = [Fixnum, Float, Bignum, String, Symbol,
|
76
|
+
TrueClass, FalseClass, NilClass]
|
77
|
+
|
78
|
+
if datum_types.include? x.class
|
77
79
|
return RQL.new(Shim.native_to_datum_term(x))
|
78
80
|
end
|
79
81
|
|
80
82
|
t = Term.new
|
81
|
-
case x
|
82
|
-
when Array
|
83
|
+
case x
|
84
|
+
when Array
|
83
85
|
t.type = Term::TermType::MAKE_ARRAY
|
84
86
|
t.args = x.map{|y| expr(y).to_pb}
|
85
|
-
when Hash
|
87
|
+
when Hash
|
86
88
|
t.type = Term::TermType::MAKE_OBJ
|
87
|
-
t.optargs = x.map{|k,v|
|
88
|
-
ap
|
89
|
-
|
89
|
+
t.optargs = x.map{|k,v|
|
90
|
+
ap = Term::AssocPair.new;
|
91
|
+
if [Symbol, String].include? k.class
|
92
|
+
ap.key = k.to_s
|
93
|
+
else
|
94
|
+
raise RqlDriverError, "Object keys must be strings or symbols." +
|
95
|
+
" (Got object `#{k.inspect}` of class `#{k.class}`.)"
|
96
|
+
end
|
97
|
+
ap.val = expr(v).to_pb
|
98
|
+
ap
|
99
|
+
}
|
100
|
+
when Proc
|
90
101
|
t = RQL.new.new_func(&x).to_pb
|
91
102
|
else raise RqlDriverError, "r.expr can't handle #{x.inspect} of type #{x.class}"
|
92
103
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rethinkdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 119
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
8
|
+
- 5
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
version: 1.
|
10
|
+
- 0
|
11
|
+
version: 1.5.0.0
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- RethinkDB Inc.
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2013-
|
19
|
+
date: 2013-05-16 00:00:00 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: json
|
@@ -57,11 +57,11 @@ extra_rdoc_files: []
|
|
57
57
|
files:
|
58
58
|
- lib/exc.rb
|
59
59
|
- lib/ql2.pb.rb
|
60
|
-
- lib/
|
60
|
+
- lib/rethinkdb.rb
|
61
61
|
- lib/rpp.rb
|
62
62
|
- lib/shim.rb
|
63
63
|
- lib/func.rb
|
64
|
-
- lib/
|
64
|
+
- lib/net.rb
|
65
65
|
homepage: http://rethinkdb.com
|
66
66
|
licenses:
|
67
67
|
- Apache-2
|