rethinkdb 1.12.0.2 → 1.13.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|