rethinkdb 1.12.0.2 → 1.13.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.
- checksums.yaml +4 -4
- data/lib/func.rb +19 -19
- data/lib/net.rb +96 -87
- data/lib/ql2.pb.rb +219 -323
- data/lib/rethinkdb.rb +3 -43
- data/lib/rpp.rb +108 -73
- data/lib/shim.rb +75 -189
- metadata +4 -32
data/lib/rethinkdb.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Copyright 2010-2012 RethinkDB, all rights reserved.
|
2
2
|
require 'rubygems'
|
3
3
|
require 'ql2.pb.rb'
|
4
|
-
|
5
4
|
require 'socket'
|
6
5
|
require 'pp'
|
7
6
|
|
@@ -11,45 +10,6 @@ load 'shim.rb'
|
|
11
10
|
load 'func.rb'
|
12
11
|
load 'rpp.rb'
|
13
12
|
|
14
|
-
class Term::AssocPair
|
15
|
-
def deep_dup
|
16
|
-
dup.tap { |pair| pair.val = pair.val.deep_dup }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class Term
|
21
|
-
attr_accessor :is_error
|
22
|
-
|
23
|
-
def deep_dup
|
24
|
-
dup.tap {|term|
|
25
|
-
term.args.map!(&:deep_dup)
|
26
|
-
term.optargs.map!(&:deep_dup)
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
def bt_tag bt
|
31
|
-
@is_error = true
|
32
|
-
begin
|
33
|
-
return if bt == []
|
34
|
-
frame, sub_bt = bt[0], bt [1..-1]
|
35
|
-
if frame.class == String
|
36
|
-
optargs.each {|optarg|
|
37
|
-
if optarg.key == frame
|
38
|
-
@is_error = false
|
39
|
-
optarg.val.bt_tag(sub_bt)
|
40
|
-
end
|
41
|
-
}
|
42
|
-
else
|
43
|
-
@is_error = false
|
44
|
-
args[frame].bt_tag(sub_bt)
|
45
|
-
end
|
46
|
-
rescue StandardError => e
|
47
|
-
@is_error = true
|
48
|
-
$stderr.puts "ERROR: Failed to parse backtrace (we'll take our best guess)."
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
13
|
module RethinkDB
|
54
14
|
module Shortcuts
|
55
15
|
def r(*args)
|
@@ -74,17 +34,17 @@ module RethinkDB
|
|
74
34
|
|
75
35
|
attr_accessor :body, :bitop
|
76
36
|
|
77
|
-
def initialize(body =
|
37
|
+
def initialize(body = RQL, bitop = nil)
|
78
38
|
@body = body
|
79
39
|
@bitop = bitop
|
80
40
|
end
|
81
41
|
|
82
42
|
def pp
|
83
|
-
unbound_if
|
43
|
+
unbound_if(@body == RQL)
|
84
44
|
RethinkDB::RPP.pp(@body)
|
85
45
|
end
|
86
46
|
def inspect
|
87
|
-
@body ? pp : super
|
47
|
+
(@body != RQL) ? pp : super
|
88
48
|
end
|
89
49
|
end
|
90
50
|
end
|
data/lib/rpp.rb
CHANGED
@@ -3,30 +3,33 @@ require 'prettyprint'
|
|
3
3
|
|
4
4
|
module RethinkDB
|
5
5
|
module RPP
|
6
|
-
@@termtype_to_str =
|
7
|
-
Term::TermType.constants.map{|x| [Term::TermType.const_get(x), x.to_s]}
|
8
|
-
]
|
6
|
+
@@termtype_to_str =
|
7
|
+
Hash[Term::TermType.constants.map{|x| [Term::TermType.const_get(x), x.to_s]}]
|
9
8
|
@@regex = if __FILE__ =~ /^(.*\/)[^\/]+.rb$/ then /^#{$1}/ else nil end
|
10
9
|
|
11
|
-
def self.
|
10
|
+
def self.bt_consume(bt, el)
|
11
|
+
(bt && bt[0] == el) ? bt[1..-1] : nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.pp_int_optargs(q, optargs, bt, pre_dot = false)
|
12
15
|
q.text("r(") if pre_dot
|
13
16
|
q.group(1, "{", "}") {
|
14
|
-
optargs.each_with_index {|optarg, i|
|
17
|
+
optargs.to_a.each_with_index {|optarg, i|
|
15
18
|
if i != 0
|
16
19
|
q.text(",")
|
17
20
|
q.breakable
|
18
21
|
end
|
19
|
-
q.text("
|
22
|
+
q.text("#{optarg[0].inspect} =>")
|
20
23
|
q.nest(2) {
|
21
24
|
q.breakable
|
22
|
-
pp_int(q, optarg
|
25
|
+
pp_int(q, optarg[1], bt_consume(bt, optarg[0]))
|
23
26
|
}
|
24
27
|
}
|
25
28
|
}
|
26
29
|
q.text(")") if pre_dot
|
27
30
|
end
|
28
31
|
|
29
|
-
def self.pp_int_args(q, args, pre_dot = false)
|
32
|
+
def self.pp_int_args(q, args, bt, pre_dot = false)
|
30
33
|
q.text("r(") if pre_dot
|
31
34
|
q.group(1, "[", "]") {
|
32
35
|
args.each_with_index {|arg, i|
|
@@ -34,7 +37,7 @@ module RethinkDB
|
|
34
37
|
q.text(",")
|
35
38
|
q.breakable
|
36
39
|
end
|
37
|
-
pp_int(q, arg)
|
40
|
+
pp_int(q, arg, bt_consume(bt, i))
|
38
41
|
}
|
39
42
|
}
|
40
43
|
q.text(")") if pre_dot
|
@@ -42,70 +45,104 @@ module RethinkDB
|
|
42
45
|
|
43
46
|
def self.pp_int_datum(q, dat, pre_dot)
|
44
47
|
q.text("r(") if pre_dot
|
45
|
-
q.text(
|
48
|
+
q.text(dat.inspect)
|
46
49
|
q.text(")") if pre_dot
|
47
50
|
end
|
48
51
|
|
49
|
-
def self.pp_int_func(q, func)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
q.
|
58
|
-
|
59
|
-
|
52
|
+
def self.pp_int_func(q, func, bt)
|
53
|
+
# PP.pp [:func, func.to_json, bt]
|
54
|
+
begin
|
55
|
+
# PP.pp func
|
56
|
+
func_args = func[1][0][1].map{|x| x.to_pb}
|
57
|
+
# PP.pp JSON.parse(func_args.to_json)
|
58
|
+
func_body = func[1][1]
|
59
|
+
q.text(" ")
|
60
|
+
q.group(0, "{", "}") {
|
61
|
+
if func_args != []
|
62
|
+
q.text(func_args.map{|x| :"var_#{x}"}.inspect.gsub(/\[|\]/,"|").gsub(":",""))
|
63
|
+
end
|
64
|
+
q.nest(2) {
|
65
|
+
q.breakable
|
66
|
+
pp_int(q, func_body, bt_consume(bt, 1))
|
67
|
+
}
|
68
|
+
q.breakable('')
|
60
69
|
}
|
61
|
-
|
62
|
-
|
70
|
+
rescue StandardError => e
|
71
|
+
q.text(" {#<unprintable function:`#{func}`>}")
|
72
|
+
end
|
63
73
|
end
|
64
74
|
|
65
75
|
def self.can_prefix (name, args)
|
66
|
-
return
|
67
|
-
return false if args.size == 1 && args[0].type == Term::TermType::DATUM
|
68
|
-
return true
|
76
|
+
return !["db", "table", "funcall", "args", "branch"].include?(name)
|
69
77
|
end
|
70
|
-
def self.pp_int(q, term, pre_dot=false)
|
71
|
-
q.text("\x7", 0) if
|
78
|
+
def self.pp_int(q, term, bt, pre_dot=false)
|
79
|
+
q.text("\x7", 0) if bt == []
|
72
80
|
|
73
|
-
if term.
|
74
|
-
|
75
|
-
|
76
|
-
|
81
|
+
term = term.to_pb if term.class == RQL
|
82
|
+
# PP.pp [:pp_int, term.to_json, bt]
|
83
|
+
if term.class != Array
|
84
|
+
if term.class == Hash
|
85
|
+
pp_int_optargs(q, term, bt, pre_dot)
|
86
|
+
else
|
87
|
+
pp_int_datum(q, term, pre_dot)
|
88
|
+
end
|
89
|
+
q.text("\x7", 0) if bt == []
|
90
|
+
return
|
77
91
|
end
|
78
92
|
|
79
|
-
|
93
|
+
type = term[0]
|
94
|
+
args = (term[1] || []).dup
|
95
|
+
optargs = (term[2] || {}).dup
|
96
|
+
if type == Term::TermType::VAR
|
80
97
|
q.text("var_")
|
81
|
-
res = pp_int_datum(q,
|
82
|
-
q.text("\x7", 0) if
|
83
|
-
return
|
84
|
-
elsif
|
98
|
+
res = pp_int_datum(q, args[0], false)
|
99
|
+
q.text("\x7", 0) if bt == []
|
100
|
+
return
|
101
|
+
elsif type == Term::TermType::FUNC
|
85
102
|
q.text("r(") if pre_dot
|
86
103
|
q.text("lambda")
|
87
|
-
|
104
|
+
pp_int_func(q, term, bt)
|
88
105
|
q.text(")") if pre_dot
|
89
|
-
q.text("\x7", 0) if
|
90
|
-
return
|
91
|
-
elsif
|
92
|
-
|
93
|
-
q.text("\x7", 0) if
|
94
|
-
return
|
95
|
-
elsif
|
96
|
-
|
97
|
-
|
98
|
-
|
106
|
+
q.text("\x7", 0) if bt == []
|
107
|
+
return
|
108
|
+
elsif type == Term::TermType::MAKE_ARRAY
|
109
|
+
pp_int_args(q, args, bt, pre_dot)
|
110
|
+
q.text("\x7", 0) if bt == []
|
111
|
+
return
|
112
|
+
elsif type == Term::TermType::FUNCALL
|
113
|
+
func = (args[0][0] == Term::TermType::FUNC) ? args[0] : nil
|
114
|
+
if args.size == 2
|
115
|
+
pp_int(q, args[1], bt_consume(bt, 1), pre_dot)
|
116
|
+
q.text(".do")
|
117
|
+
if !func
|
118
|
+
q.text("(")
|
119
|
+
pp_int(q, args[0], bt_consume(bt, 0)) if !func
|
120
|
+
q.text(")")
|
121
|
+
end
|
122
|
+
else
|
123
|
+
q.text("r.do(")
|
124
|
+
(1...args.size).each {|i|
|
125
|
+
q.text(", ") if i != 1
|
126
|
+
pp_int(q, args[i], bt_consume(bt, i))
|
127
|
+
}
|
128
|
+
if !func
|
129
|
+
q.text(", ")
|
130
|
+
pp_int(q, args[0], bt_consume(bt, 0))
|
131
|
+
end
|
132
|
+
q.text(")")
|
133
|
+
end
|
134
|
+
pp_int_func(q, args[0], bt_consume(bt, 0)) if func
|
135
|
+
return
|
99
136
|
end
|
100
137
|
|
101
|
-
name = @@termtype_to_str[
|
102
|
-
args = term.args.dup
|
103
|
-
optargs = term.optargs.dup
|
138
|
+
name = @@termtype_to_str[type].downcase
|
104
139
|
|
105
140
|
if can_prefix(name, args) && first_arg = args.shift
|
106
|
-
pp_int(q, first_arg, true)
|
141
|
+
pp_int(q, first_arg, bt_consume(bt, 0), true)
|
142
|
+
arg_offset = 1
|
107
143
|
else
|
108
144
|
q.text("r")
|
145
|
+
arg_offset = 0
|
109
146
|
end
|
110
147
|
if name == "getattr"
|
111
148
|
argstart, argstop = "[", "]"
|
@@ -115,13 +152,17 @@ module RethinkDB
|
|
115
152
|
argstart, argstop = "(", ")"
|
116
153
|
end
|
117
154
|
|
118
|
-
|
155
|
+
if args[-1] && args[-1].class == Array && args[-1][0] == Term::TermType::FUNC
|
156
|
+
func_bt = bt_consume(bt, args.size() - 1 + arg_offset)
|
157
|
+
func = args.pop
|
158
|
+
# PP.pp [:func_bt, bt, arg_offset, (args.size() - 1) + arg_offset, func_bt]
|
159
|
+
end
|
119
160
|
|
120
|
-
if args != [] || optargs !=
|
161
|
+
if args != [] || optargs != {}
|
121
162
|
q.group(0, argstart, argstop) {
|
122
163
|
pushed = nil
|
123
164
|
q.nest(2) {
|
124
|
-
args.
|
165
|
+
args.each_with_index {|arg, index|
|
125
166
|
if !pushed
|
126
167
|
pushed = true
|
127
168
|
q.breakable('')
|
@@ -129,35 +170,30 @@ module RethinkDB
|
|
129
170
|
q.text(",")
|
130
171
|
q.breakable
|
131
172
|
end
|
132
|
-
|
173
|
+
# PP.pp [:int, arg.to_json, bt_consume(bt, index)]
|
174
|
+
pp_int(q, arg, bt_consume(bt, index + arg_offset))
|
133
175
|
}
|
134
|
-
if optargs !=
|
176
|
+
if optargs != {}
|
135
177
|
if pushed
|
136
178
|
q.text(",")
|
137
179
|
q.breakable
|
138
180
|
end
|
139
|
-
pp_int_optargs(q, optargs)
|
140
|
-
end
|
141
|
-
if func && name == "grouped_map_reduce"
|
142
|
-
q.text(",")
|
143
|
-
q.breakable
|
144
|
-
q.text("lambda")
|
145
|
-
pp_int_func(q, func)
|
146
|
-
func = nil
|
181
|
+
pp_int_optargs(q, optargs, bt)
|
147
182
|
end
|
148
183
|
}
|
149
184
|
q.breakable('')
|
150
185
|
}
|
151
186
|
end
|
152
187
|
|
153
|
-
pp_int_func(q, func) if func
|
154
|
-
q.text("\x7", 0) if
|
188
|
+
pp_int_func(q, func, func_bt) if func
|
189
|
+
q.text("\x7", 0) if bt == []
|
155
190
|
end
|
156
191
|
|
157
|
-
def self.pp
|
192
|
+
def self.pp(term, bt=nil)
|
193
|
+
# PP.pp bt
|
158
194
|
begin
|
159
195
|
q = PrettyPrint.new
|
160
|
-
pp_int(q, term, true)
|
196
|
+
pp_int(q, term, bt, true)
|
161
197
|
q.flush
|
162
198
|
|
163
199
|
in_bt = false
|
@@ -165,16 +201,15 @@ module RethinkDB
|
|
165
201
|
line = line.gsub(/^ */) {|x| x+"\x7"} if in_bt
|
166
202
|
arr = line.split("\x7")
|
167
203
|
if arr[1]
|
168
|
-
in_bt = !(arr[2] || (line[-1] ==
|
204
|
+
in_bt = !(arr[2] || (line[-1] == "\x7"))
|
169
205
|
[arr.join(""), " "*arr[0].size + "^"*arr[1].size]
|
170
206
|
else
|
171
207
|
line
|
172
208
|
end
|
173
209
|
}.flatten.join("\n")
|
174
|
-
|
175
|
-
raise e
|
210
|
+
rescue Exception => e
|
176
211
|
"AN ERROR OCCURED DURING PRETTY-PRINTING:\n#{e.inspect}\n" +
|
177
|
-
"FALLING BACK TO
|
212
|
+
"FALLING BACK TO GENERIC PRINTER.\n#{term.inspect}"
|
178
213
|
end
|
179
214
|
end
|
180
215
|
end
|
data/lib/shim.rb
CHANGED
@@ -1,225 +1,111 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'time'
|
3
|
-
|
4
1
|
module RethinkDB
|
2
|
+
require 'json'
|
3
|
+
require 'time'
|
5
4
|
module Shim
|
6
|
-
def self.
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.convert_time(obj)
|
11
|
-
t = Time.at(obj['epoch_time'])
|
12
|
-
tz = obj['timezone']
|
13
|
-
(tz && tz != "" && tz != "Z") ? t.getlocal(tz) : t.utc
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.is_grouped_data(obj)
|
17
|
-
obj.is_a? Hash and obj["$reql_type$"] == "GROUPED_DATA"
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.convert_grouped_data(obj, opts)
|
21
|
-
convert_reql_types!(obj['data'], opts)
|
22
|
-
Hash[obj["data"]]
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.maybe_convert_type(obj, opts)
|
26
|
-
if opts[:time_format] != 'raw' && is_reql_time(obj)
|
27
|
-
convert_time(obj)
|
28
|
-
elsif opts[:group_format] != 'raw' && is_grouped_data(obj)
|
29
|
-
convert_grouped_data(obj, opts)
|
30
|
-
else
|
31
|
-
nil
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.convert_reql_types!(result, opts)
|
36
|
-
case result
|
5
|
+
def self.recursive_munge(x, parse_time, parse_group)
|
6
|
+
case x
|
37
7
|
when Hash
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
8
|
+
if parse_time && x['$reql_type$'] == 'TIME'
|
9
|
+
t = Time.at(x['epoch_time'])
|
10
|
+
tz = x['timezone']
|
11
|
+
return (tz && tz != "" && tz != "Z") ? t.getlocal(tz) : t.utc
|
12
|
+
elsif parse_group && x['$reql_type$'] == 'GROUPED_DATA'
|
13
|
+
return Hash[x['data']]
|
14
|
+
else
|
15
|
+
x.each {|k, v|
|
16
|
+
v2 = recursive_munge(v, parse_time, parse_group)
|
17
|
+
x[k] = v2 if v.object_id != v2.object_id
|
18
|
+
}
|
19
|
+
end
|
45
20
|
when Array
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
else
|
50
|
-
convert_reql_types!(result[i], opts)
|
51
|
-
end
|
21
|
+
x.each_with_index {|v, i|
|
22
|
+
v2 = recursive_munge(v, parse_time, parse_group)
|
23
|
+
x[i] = v2 if v.object_id != v2.object_id
|
52
24
|
}
|
53
25
|
end
|
54
|
-
|
26
|
+
return x
|
55
27
|
end
|
56
28
|
|
57
|
-
def self.
|
58
|
-
|
59
|
-
|
29
|
+
def self.load_json(target, opts=nil)
|
30
|
+
recursive_munge(JSON.parse(target, max_nesting: false),
|
31
|
+
opts && opts[:time_format] != 'raw',
|
32
|
+
opts && opts[:group_format] != 'raw')
|
60
33
|
end
|
61
34
|
|
62
|
-
def self.
|
63
|
-
|
64
|
-
dt = Datum::DatumType
|
65
|
-
case d.type
|
66
|
-
when dt::R_NUM then d.r_num == d.r_num.to_i ? d.r_num.to_i : d.r_num
|
67
|
-
when dt::R_STR then d.r_str
|
68
|
-
when dt::R_BOOL then d.r_bool
|
69
|
-
when dt::R_NULL then nil
|
70
|
-
when dt::R_ARRAY then d.r_array.map{|d2| datum_to_native(d2, opts)}
|
71
|
-
when dt::R_OBJECT then
|
72
|
-
obj = Hash[d.r_object.map{|x| [x.key, datum_to_native(x.val, opts)]}]
|
73
|
-
postprocess!(obj, opts)
|
74
|
-
when dt::R_JSON then
|
75
|
-
postprocess!(JSON.parse("[" + d.r_str + "]")[0], opts)
|
76
|
-
else raise RqlRuntimeError, "#{dt} Unimplemented."
|
77
|
-
end
|
35
|
+
def self.dump_json(x)
|
36
|
+
JSON.generate(x, max_nesting: false)
|
78
37
|
end
|
79
38
|
|
80
39
|
def self.response_to_native(r, orig_term, opts)
|
81
40
|
rt = Response::ResponseType
|
82
|
-
if r.backtrace
|
83
|
-
bt = r.backtrace.frames.map {|x|
|
84
|
-
x.type == Frame::FrameType::POS ? x.pos : x.opt
|
85
|
-
}
|
86
|
-
else
|
87
|
-
bt = []
|
88
|
-
end
|
89
|
-
|
90
41
|
begin
|
91
|
-
case r
|
92
|
-
when rt::SUCCESS_ATOM
|
93
|
-
when rt::
|
94
|
-
when rt::
|
95
|
-
when rt::
|
96
|
-
|
97
|
-
when rt::COMPILE_ERROR
|
98
|
-
|
99
|
-
when rt::CLIENT_ERROR then
|
100
|
-
raise RqlDriverError, "#{r.response[0].r_str}"
|
42
|
+
case r['t']
|
43
|
+
when rt::SUCCESS_ATOM then r['r'][0]
|
44
|
+
when rt::SUCCESS_FEED then r['r']
|
45
|
+
when rt::SUCCESS_PARTIAL then r['r']
|
46
|
+
when rt::SUCCESS_SEQUENCE then r['r']
|
47
|
+
when rt::RUNTIME_ERROR then raise RqlRuntimeError, r['r'][0]
|
48
|
+
when rt::COMPILE_ERROR then raise RqlCompileError, r['r'][0]
|
49
|
+
when rt::CLIENT_ERROR then raise RqlDriverError, r['r'][0]
|
101
50
|
else raise RqlRuntimeError, "Unexpected response: #{r.inspect}"
|
102
51
|
end
|
103
52
|
rescue RqlError => e
|
104
|
-
|
105
|
-
term.bt_tag(bt)
|
106
|
-
raise e.class, "#{e.message}\nBacktrace:\n#{RPP.pp(term)}"
|
53
|
+
raise e.class, "#{e.message}\nBacktrace:\n#{RPP.pp(orig_term, r['b'])}"
|
107
54
|
end
|
108
55
|
end
|
109
|
-
|
110
|
-
def self.native_to_datum_term x
|
111
|
-
dt = Datum::DatumType
|
112
|
-
d = Datum.new
|
113
|
-
case x
|
114
|
-
when Fixnum then d.type = dt::R_NUM; d.r_num = x
|
115
|
-
when Float then d.type = dt::R_NUM; d.r_num = x
|
116
|
-
when Bignum then d.type = dt::R_NUM; d.r_num = x
|
117
|
-
when String then d.type = dt::R_STR; d.r_str = x
|
118
|
-
when Symbol then d.type = dt::R_STR; d.r_str = x.to_s
|
119
|
-
when TrueClass then d.type = dt::R_BOOL; d.r_bool = x
|
120
|
-
when FalseClass then d.type = dt::R_BOOL; d.r_bool = x
|
121
|
-
when NilClass then d.type = dt::R_NULL
|
122
|
-
else raise RqlRuntimeError, "UNREACHABLE"
|
123
|
-
end
|
124
|
-
t = Term.new
|
125
|
-
t.type = Term::TermType::DATUM
|
126
|
-
t.datum = d
|
127
|
-
return t
|
128
|
-
end
|
129
56
|
end
|
130
57
|
|
131
58
|
class RQL
|
132
|
-
def
|
133
|
-
|
134
|
-
@@datum_types = [Fixnum, Float, Bignum, String, Symbol,
|
135
|
-
TrueClass, FalseClass, NilClass]
|
136
|
-
|
137
|
-
def any_to_pb(x)
|
138
|
-
return x.to_pb if x.class == RQL
|
139
|
-
t = Term.new
|
140
|
-
t.type = Term::TermType::JSON
|
141
|
-
t.args = [Shim.native_to_datum_term(x.to_json(:max_nesting => 500))]
|
142
|
-
return t
|
143
|
-
end
|
144
|
-
|
145
|
-
def timezone_from_offset(offset)
|
146
|
-
raw_offset = offset.abs
|
147
|
-
raw_hours = raw_offset / 3600
|
148
|
-
raw_minutes = (raw_offset / 60) - (raw_hours * 60)
|
149
|
-
return (offset < 0 ? "-" : "+") + sprintf("%02d:%02d", raw_hours, raw_minutes);
|
59
|
+
def to_json(*a, &b)
|
60
|
+
@body.to_json(*a, &b)
|
150
61
|
end
|
62
|
+
def to_pb; @body; end
|
151
63
|
|
152
|
-
def
|
153
|
-
return x if x.class == RQL
|
154
|
-
if @@datum_types.include?(x.class)
|
155
|
-
return x if allow_json
|
156
|
-
return RQL.new(Shim.native_to_datum_term(x), nil)
|
157
|
-
end
|
158
|
-
|
64
|
+
def self.safe_to_s(x)
|
159
65
|
case x
|
160
|
-
when
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
t.type = Term::TermType::MAKE_ARRAY
|
165
|
-
t.args = args.map{|y| any_to_pb(y)}
|
166
|
-
return RQL.new(t, nil)
|
167
|
-
when Hash
|
168
|
-
kvs = x.map{|k,v| [k, fast_expr(v, allow_json)]}
|
169
|
-
return x if allow_json && kvs.all? {|k,v|
|
170
|
-
(k.class == String || k.class == Symbol) && v.class != RQL
|
171
|
-
}
|
172
|
-
t = Term.new
|
173
|
-
t.type = Term::TermType::MAKE_OBJ
|
174
|
-
t.optargs = kvs.map{|k,v|
|
175
|
-
ap = Term::AssocPair.new;
|
176
|
-
if k.class == Symbol || k.class == String
|
177
|
-
ap.key = k.to_s
|
178
|
-
else
|
179
|
-
raise RqlDriverError, "Object keys must be strings or symbols." +
|
180
|
-
" (Got object `#{k.inspect}` of class `#{k.class}`.)"
|
181
|
-
end
|
182
|
-
ap.val = any_to_pb(v)
|
183
|
-
ap
|
184
|
-
}
|
185
|
-
return RQL.new(t, nil)
|
186
|
-
when Proc
|
187
|
-
t = RQL.new(nil, nil).new_func(&x).to_pb
|
188
|
-
return RQL.new(t, nil)
|
189
|
-
else raise RqlDriverError, "r.expr can't handle #{x.inspect} of type #{x.class}"
|
66
|
+
when String then x
|
67
|
+
when Symbol then x.to_s
|
68
|
+
else raise RqlDriverError, 'Object keys must be strings or symbols. '+
|
69
|
+
"(Got object `#{x.inspect}` of class `#{x.class}`.)"
|
190
70
|
end
|
191
71
|
end
|
192
72
|
|
193
|
-
def
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
when Array
|
201
|
-
|
202
|
-
when Hash
|
203
|
-
|
204
|
-
when
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
73
|
+
def self.fast_expr(x, max_depth)
|
74
|
+
if max_depth == 0
|
75
|
+
raise RqlDriverError, "Maximum expression depth exceeded " +
|
76
|
+
"(you can override this with `r.expr(X, MAX_DEPTH)`)."
|
77
|
+
end
|
78
|
+
case x
|
79
|
+
when RQL then x
|
80
|
+
when Array then RQL.new([Term::TermType::MAKE_ARRAY,
|
81
|
+
x.map{|y| fast_expr(y, max_depth-1)}])
|
82
|
+
when Hash then RQL.new(Hash[x.map{|k,v| [safe_to_s(k),
|
83
|
+
fast_expr(v, max_depth-1)]}])
|
84
|
+
when Proc then RQL.new.new_func(&x)
|
85
|
+
when String then RQL.new(x)
|
86
|
+
when Symbol then RQL.new(x)
|
87
|
+
when Numeric then RQL.new(x)
|
88
|
+
when FalseClass then RQL.new(x)
|
89
|
+
when TrueClass then RQL.new(x)
|
90
|
+
when NilClass then RQL.new(x)
|
91
|
+
when Time then
|
92
|
+
epoch_time = x.to_f
|
93
|
+
offset = x.utc_offset
|
94
|
+
raw_offset = offset.abs
|
95
|
+
raw_hours = raw_offset / 3600
|
96
|
+
raw_minutes = (raw_offset / 60) - (raw_hours * 60)
|
97
|
+
tz = (offset < 0 ? "-" : "+") + sprintf("%02d:%02d", raw_hours, raw_minutes);
|
98
|
+
RQL.new({ '$reql_type$' => 'TIME',
|
99
|
+
'epoch_time' => epoch_time,
|
100
|
+
'timezone' => tz })
|
101
|
+
else raise RqlDriverError, "r.expr can't handle #{x.inspect} of class #{x.class}."
|
212
102
|
end
|
213
103
|
end
|
214
104
|
|
215
|
-
def expr(x,
|
216
|
-
|
217
|
-
|
218
|
-
res = fast_expr(reql_typify(x), allow_json)
|
219
|
-
return res if res.class == RQL
|
220
|
-
return RQL.new(any_to_pb(res), nil)
|
105
|
+
def expr(x, max_depth=20)
|
106
|
+
unbound_if(@body != RQL)
|
107
|
+
RQL.fast_expr(x, max_depth)
|
221
108
|
end
|
222
|
-
|
223
109
|
def coerce(other)
|
224
110
|
[RQL.new.expr(other), self]
|
225
111
|
end
|