rethinkdb 2.0.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +4 -4
  2. data/lib/exc.rb +15 -4
  3. data/lib/func.rb +2 -2
  4. data/lib/net.rb +88 -28
  5. data/lib/ql2.pb.rb +13 -0
  6. data/lib/shim.rb +22 -11
  7. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dae3d5d3b038eca2d30595a269cb259351d5bd98
4
- data.tar.gz: 7a03e7c5f271bbb2a7e2e63f74a2757864c4cdbb
3
+ metadata.gz: 4dbe3bed2b00fa519fa84f136b6b140da9e97c49
4
+ data.tar.gz: 478001c0afd50dcbad8d02d843ffa2602d7cec6d
5
5
  SHA512:
6
- metadata.gz: 308251a1089f50555e2e8177af64235bea9b5a36d35615aca7852f8f72530f17cb0c70569d6a727012aad0f273c6912262cedd9e6b6e1748d60d59e5ec4feb91
7
- data.tar.gz: 6f31e8e16757cdaa9fc98137fd732323fa32c7d03c0af3edc2fcad299dfa9dff0c3bad2db838e2e7db1426c07bf3ed3729b8c723b38d3f784396722b3ccfbe5a
6
+ metadata.gz: 34d05e329c5c523c91f324e67205cef95ad57c2af7ae9b01977ddd76e2bb03be110b45165fd42fbe36535865548bef1e8b82cb37925a21cc98dea9e25e1b9a6d
7
+ data.tar.gz: 07a54b27fba8686fd47b9a6a814f18e417400fc4636240f015c255aa7e52358ffc623fb2c375c66fc1b2a2f07d0fa044b07d609e1441ced43eab383b61f472de
data/lib/exc.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  module RethinkDB
2
- RqlError = Class.new(RuntimeError)
3
- RqlRuntimeError = Class.new(RqlError)
4
- RqlDriverError = Class.new(RqlError)
5
- RqlCompileError = Class.new(RqlError)
2
+ ReqlError = RqlError = Class.new(RuntimeError)
3
+
4
+ ReqlRuntimeError = RqlRuntimeError = Class.new(ReqlError)
5
+ ReqlInternalError = RqlInternalError = Class.new(ReqlRuntimeError)
6
+ ReqlResourceLimitError = RqlResourceLimitError = Class.new(ReqlRuntimeError)
7
+ ReqlQueryLogicError = RqlQueryLogicError = Class.new(ReqlRuntimeError)
8
+ ReqlNonExistenceError = RqlNonExistenceError = Class.new(ReqlQueryLogicError)
9
+ ReqlAvailabilityError = RqlAvailabilityError = Class.new(ReqlRuntimeError)
10
+ ReqlOpFailedError = RqlOpFailedError = Class.new(ReqlAvailabilityError)
11
+ ReqlOpIndeterminateError = RqlOpIndeterminateError = Class.new(ReqlAvailabilityError)
12
+ ReqlUserError = RqlUserError = Class.new(ReqlRuntimeError)
13
+
14
+ ReqlDriverError = RqlDriverError = Class.new(ReqlError)
15
+ ReqlAuthError = RqlAuthError = Class.new(ReqlDriverError)
16
+ ReqlCompileError = RqlCompileError = Class.new(ReqlError)
6
17
  end
data/lib/func.rb CHANGED
@@ -88,7 +88,7 @@ module RethinkDB
88
88
  "This is almost always a precedence error.\n" +
89
89
  "Note that `a < b | b < c` <==> `a < (b | b) < c`.\n" +
90
90
  "If you really want this behavior, use `.or` or `.and` instead."
91
- raise RqlDriverError, err
91
+ raise ReqlDriverError, err
92
92
  end
93
93
  }
94
94
  end
@@ -151,7 +151,7 @@ module RethinkDB
151
151
  def do(*args, &b)
152
152
  a = ((@body != RQL) ? [self] : []) + args.dup
153
153
  if a == [] && !b
154
- raise RqlDriverError, "Expected 1 or more arguments but found 0."
154
+ raise ReqlDriverError, "Expected 1 or more arguments but found 0."
155
155
  end
156
156
  funcall_args = (b ? [new_func(&b)] : [a.pop]) + a
157
157
  # PP.pp funcall_args
data/lib/net.rb CHANGED
@@ -4,6 +4,7 @@ require 'socket'
4
4
  require 'thread'
5
5
  require 'timeout'
6
6
  require 'pp' # This is needed for pretty_inspect
7
+ require 'openssl'
7
8
 
8
9
  module RethinkDB
9
10
  module Faux_Abort
@@ -162,6 +163,12 @@ module RethinkDB
162
163
  handle(:on_close)
163
164
  end
164
165
  end
166
+ def handle_force_close
167
+ if !@closed
168
+ handle(:on_error, ReqlRuntimeError.new("Connection is closed."))
169
+ end
170
+ handle_close
171
+ end
165
172
  def safe_next_tick(&b)
166
173
  EM.next_tick {
167
174
  b.call if !@closed
@@ -194,6 +201,9 @@ module RethinkDB
194
201
  elsif (row.has_key?('new_val') && !row.has_key?('old_val') &&
195
202
  @handler.respond_to?(:on_initial_val))
196
203
  handle(:on_initial_val, row['new_val'])
204
+ elsif (row.has_key?('old_val') && !row.has_key?('new_val') &&
205
+ @handler.respond_to?(:on_uninitial_val))
206
+ handle(:on_uninitial_val, row['old_val'])
197
207
  elsif row.has_key?('error') && @handler.respond_to?(:on_change_error)
198
208
  handle(:on_change_error, row['error'])
199
209
  elsif row.has_key?('state') && @handler.respond_to?(:on_state)
@@ -317,6 +327,9 @@ module RethinkDB
317
327
  def run(*args, &b)
318
328
  unbound_if(@body == RQL)
319
329
  args = parse(*args, &b)
330
+ if args[:block].is_a?(Handler)
331
+ raise RuntimeError, "Cannot call `run` with a handler, did you mean `em_run`?"
332
+ end
320
333
  args[:conn].run(@body, args[:opts], args[:block])
321
334
  end
322
335
  def em_run(*args, &b)
@@ -373,13 +386,13 @@ module RethinkDB
373
386
  end
374
387
 
375
388
  def each(&block) # :nodoc:
376
- raise RqlRuntimeError, "Can only iterate over a cursor once." if @run
389
+ raise ReqlRuntimeError, "Can only iterate over a cursor once." if @run
377
390
  return enum_for(:each) if !block
378
391
  @run = true
379
392
  while true
380
393
  @results.each(&block)
381
394
  return self if !@more
382
- raise RqlRuntimeError, "Connection is closed." if @more && out_of_date
395
+ raise ReqlRuntimeError, "Connection is closed." if @more && out_of_date
383
396
  wait_for_batch(nil)
384
397
  end
385
398
  end
@@ -412,10 +425,10 @@ module RethinkDB
412
425
 
413
426
  def next(wait=true)
414
427
  if @run
415
- raise RqlRuntimeError, "Cannot call `next` on a cursor after calling `each`."
428
+ raise ReqlRuntimeError, "Cannot call `next` on a cursor after calling `each`."
416
429
  end
417
430
  if @more && out_of_date
418
- raise RqlRuntimeError, "Connection is closed."
431
+ raise ReqlRuntimeError, "Connection is closed."
419
432
  end
420
433
  timeout = wait
421
434
  if wait == true
@@ -434,6 +447,7 @@ module RethinkDB
434
447
  end
435
448
 
436
449
  class Connection
450
+ include OpenSSL
437
451
  def auto_reconnect(x=true)
438
452
  @auto_reconnect = x
439
453
  self
@@ -455,6 +469,7 @@ module RethinkDB
455
469
  @auth_key = opts[:auth_key] || ""
456
470
  @timeout = opts[:timeout].to_i
457
471
  @timeout = 20 if @timeout <= 0
472
+ @ssl_opts = opts[:ssl] || {}
458
473
 
459
474
  @@last = self
460
475
  @default_opts = @default_db ? {:db => RQL.new.db(@default_db)} : {}
@@ -475,7 +490,7 @@ module RethinkDB
475
490
  if !opts[:noreply]
476
491
  @mon.synchronize {
477
492
  if @waiters.has_key?(token)
478
- raise RqlDriverError, "Internal driver error, token already in use."
493
+ raise ReqlDriverError, "Internal driver error, token already in use."
479
494
  end
480
495
  @waiters[token] = callback ? callback : @mon.new_cond
481
496
  @opts[token] = opts
@@ -495,7 +510,7 @@ module RethinkDB
495
510
  end
496
511
  def run(msg, opts, b)
497
512
  reconnect(:noreply_wait => false) if @auto_reconnect && !is_open()
498
- raise RqlRuntimeError, "Connection is closed." if !is_open()
513
+ raise ReqlRuntimeError, "Connection is closed." if !is_open()
499
514
 
500
515
  global_optargs = {}
501
516
  all_opts = @default_opts.merge(opts)
@@ -550,14 +565,16 @@ module RethinkDB
550
565
  end
551
566
 
552
567
  def send packet
553
- written = 0
554
- while written < packet.length
555
- # Supposedly slice will not copy the array if it goes all the way to the end
556
- # We use IO::syswrite here rather than IO::write because of incompatibilities in
557
- # JRuby regarding filling up the TCP send buffer.
558
- # Reference: https://github.com/rethinkdb/rethinkdb/issues/3795
559
- written += @socket.syswrite(packet.slice(written, packet.length))
560
- end
568
+ @mon.synchronize {
569
+ written = 0
570
+ while written < packet.length
571
+ # Supposedly slice will not copy the array if it goes all the way to the end
572
+ # We use IO::syswrite here rather than IO::write because of incompatibilities in
573
+ # JRuby regarding filling up the TCP send buffer.
574
+ # Reference: https://github.com/rethinkdb/rethinkdb/issues/3795
575
+ written += @socket.syswrite(packet.slice(written, packet.length))
576
+ end
577
+ }
561
578
  end
562
579
 
563
580
  def dispatch(msg, token)
@@ -579,7 +596,7 @@ module RethinkDB
579
596
  # but this is safer in case someone makes changes to
580
597
  # `close` in the future.
581
598
  if !is_open() || !@waiters.has_key?(token)
582
- raise RqlRuntimeError, "Connection is closed."
599
+ raise ReqlRuntimeError, "Connection is closed."
583
600
  end
584
601
 
585
602
  if end_time
@@ -636,8 +653,7 @@ module RethinkDB
636
653
 
637
654
  def connect()
638
655
  raise RuntimeError, "Connection must be closed before calling connect." if @socket
639
- @socket = TCPSocket.open(@host, @port)
640
- @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
656
+ init_socket
641
657
  @mon = Monitor.new
642
658
  @waiters = {}
643
659
  @opts = {}
@@ -647,6 +663,46 @@ module RethinkDB
647
663
  self
648
664
  end
649
665
 
666
+ def init_socket
667
+ unless @ssl_opts.empty?
668
+ @tcp_socket = base_socket
669
+ context = create_context(@ssl_opts)
670
+ @socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
671
+ @socket.sync_close = true
672
+ @socket.connect
673
+ verify_cert!(@socket, context)
674
+ else
675
+ @socket = base_socket
676
+ end
677
+ end
678
+
679
+ def base_socket
680
+ socket = TCPSocket.open(@host, @port)
681
+ socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
682
+ socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
683
+ socket
684
+ end
685
+
686
+ def create_context(options)
687
+ context = OpenSSL::SSL::SSLContext.new
688
+ context.ssl_version = :TLSv1_2
689
+ if options[:ca_certs]
690
+ context.ca_file = options[:ca_certs]
691
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
692
+ else
693
+ raise 'ssl options provided but missing required "ca_certs" option'
694
+ end
695
+ context
696
+ end
697
+
698
+ def verify_cert!(socket, context)
699
+ if context.verify_mode == OpenSSL::SSL::VERIFY_PEER
700
+ unless OpenSSL::SSL.verify_certificate_identity(socket.peer_cert, host)
701
+ raise 'SSL handshake failed due to a hostname mismatch.'
702
+ end
703
+ end
704
+ end
705
+
650
706
  def is_open
651
707
  @socket && @listener
652
708
  end
@@ -669,7 +725,7 @@ module RethinkDB
669
725
  @waiters.each {|k,v|
670
726
  case v
671
727
  when QueryHandle
672
- v.handle_close
728
+ v.handle_force_close
673
729
  when MonitorMixin::ConditionVariable
674
730
  @waiters[k] = nil
675
731
  v.signal
@@ -690,25 +746,25 @@ module RethinkDB
690
746
  end
691
747
 
692
748
  def noreply_wait
693
- raise RqlRuntimeError, "Connection is closed." if !is_open()
749
+ raise ReqlRuntimeError, "Connection is closed." if !is_open()
694
750
  q = [Query::QueryType::NOREPLY_WAIT]
695
751
  res = run_internal(q, {noreply: false}, new_token)
696
752
  if res['t'] != Response::ResponseType::WAIT_COMPLETE
697
- raise RqlRuntimeError, "Unexpected response to noreply_wait: " + PP.pp(res, "")
753
+ raise ReqlRuntimeError, "Unexpected response to noreply_wait: " + PP.pp(res, "")
698
754
  end
699
755
  nil
700
756
  end
701
757
 
702
758
  def self.last
703
759
  return @@last if @@last
704
- raise RqlRuntimeError, "No last connection. Use RethinkDB::Connection.new."
760
+ raise ReqlRuntimeError, "No last connection. Use RethinkDB::Connection.new."
705
761
  end
706
762
 
707
763
  def remove_em_waiters
708
764
  @mon.synchronize {
709
765
  @waiters.each {|k,v|
710
766
  if v.is_a? QueryHandle
711
- v.handle_close
767
+ v.handle_force_close
712
768
  @waiters.delete(k)
713
769
  end
714
770
  }
@@ -727,7 +783,7 @@ module RethinkDB
727
783
  when nil
728
784
  # nothing
729
785
  else
730
- raise RqlDriverError, "Unrecognized value #{w.inspect} in `@waiters`."
786
+ raise ReqlDriverError, "Unrecognized value #{w.inspect} in `@waiters`."
731
787
  end
732
788
  end
733
789
 
@@ -749,7 +805,7 @@ module RethinkDB
749
805
  maybe_timeout(timeout_sec) {
750
806
  buf = read len
751
807
  if !buf || buf.length != len
752
- raise RqlRuntimeError, "Connection closed by server."
808
+ raise ReqlRuntimeError, "Connection closed by server."
753
809
  end
754
810
  return buf
755
811
  }
@@ -762,12 +818,16 @@ module RethinkDB
762
818
  response += @socket.read_exn(1, @timeout)
763
819
  end
764
820
  response = response[0...-1]
765
- if response != "SUCCESS"
766
- raise RqlRuntimeError, "Server dropped connection with message: \"#{response}\""
821
+ if response == "SUCCESS"
822
+ # do nothing
823
+ elsif response == "ERROR: Incorrect authorization key.\n"
824
+ raise ReqlAuthError, "Incorrect authorization key."
825
+ else
826
+ raise ReqlRuntimeError, "Server dropped connection with message: \"#{response}\""
767
827
  end
768
828
 
769
829
  if @listener
770
- raise RqlDriverError, "Internal driver error, listener already started."
830
+ raise ReqlDriverError, "Internal driver error, listener already started."
771
831
  end
772
832
  @listener = Thread.new {
773
833
  while true
@@ -779,7 +839,7 @@ module RethinkDB
779
839
  begin
780
840
  data = Shim.load_json(response, @opts[token])
781
841
  rescue Exception => e
782
- raise RqlRuntimeError, "Bad response, server is buggy.\n" +
842
+ raise ReqlRuntimeError, "Bad response, server is buggy.\n" +
783
843
  "#{e.inspect}\n" + response
784
844
  end
785
845
  @mon.synchronize{note_data(token, data)}
data/lib/ql2.pb.rb CHANGED
@@ -49,6 +49,16 @@ module RethinkDB
49
49
  RUNTIME_ERROR = 18
50
50
  end
51
51
 
52
+ module ErrorType
53
+ INTERNAL = 1000000
54
+ RESOURCE_LIMIT = 2000000
55
+ QUERY_LOGIC = 3000000
56
+ NON_EXISTENCE = 3100000
57
+ OP_FAILED = 4100000
58
+ OP_INDETERMINATE = 4200000
59
+ USER = 5000000
60
+ end
61
+
52
62
  module ResponseNote
53
63
  SEQUENCE_FEED = 1
54
64
  ATOM_FEED = 2
@@ -100,6 +110,9 @@ module RethinkDB
100
110
  MUL = 26
101
111
  DIV = 27
102
112
  MOD = 28
113
+ FLOOR = 183
114
+ CEIL = 184
115
+ ROUND = 185
103
116
  APPEND = 29
104
117
  PREPEND = 80
105
118
  DIFFERENCE = 95
data/lib/shim.rb CHANGED
@@ -57,17 +57,28 @@ module RethinkDB
57
57
 
58
58
  def self.response_to_native(r, orig_term, opts)
59
59
  rt = Response::ResponseType
60
+ re = Response::ErrorType
60
61
  begin
61
62
  case r['t']
62
- when rt::SUCCESS_ATOM then r['r'][0]
63
- when rt::SUCCESS_PARTIAL then r['r']
64
- when rt::SUCCESS_SEQUENCE then r['r']
65
- when rt::RUNTIME_ERROR then raise RqlRuntimeError, r['r'][0]
66
- when rt::COMPILE_ERROR then raise RqlCompileError, r['r'][0]
67
- when rt::CLIENT_ERROR then raise RqlDriverError, r['r'][0]
68
- else raise RqlRuntimeError, "Unexpected response: #{r.inspect}"
63
+ when rt::SUCCESS_ATOM then r['r'][0]
64
+ when rt::SUCCESS_PARTIAL then r['r']
65
+ when rt::SUCCESS_SEQUENCE then r['r']
66
+ when rt::RUNTIME_ERROR
67
+ case r['e']
68
+ when re::INTERNAL then raise ReqlInternalError, r['r'][0]
69
+ when re::RESOURCE_LIMIT then raise ReqlResourceLimitError, r['r'][0]
70
+ when re::QUERY_LOGIC then raise ReqlQueryLogicError, r['r'][0]
71
+ when re::NON_EXISTENCE then raise ReqlNonExistenceError, r['r'][0]
72
+ when re::OP_FAILED then raise ReqlOpFailedError, r['r'][0]
73
+ when re::OP_INDETERMINATE then raise ReqlOpIndeterminateError, r['r'][0]
74
+ when re::USER then raise ReqlUserError, r['r'][0]
75
+ else raise ReqlRuntimeError, r['r'][0]
76
+ end
77
+ when rt::COMPILE_ERROR then raise ReqlCompileError, r['r'][0]
78
+ when rt::CLIENT_ERROR then raise ReqlDriverError, r['r'][0]
79
+ else raise ReqlRuntimeError, "Unexpected response: #{r.inspect}"
69
80
  end
70
- rescue RqlError => e
81
+ rescue ReqlError => e
71
82
  raise e.class, "#{e.message}\nBacktrace:\n#{RPP.pp(orig_term, r['b'])}"
72
83
  end
73
84
  end
@@ -93,14 +104,14 @@ module RethinkDB
93
104
  case x
94
105
  when String then x
95
106
  when Symbol then x.to_s
96
- else raise RqlDriverError, 'Object keys must be strings or symbols. '+
107
+ else raise ReqlDriverError, 'Object keys must be strings or symbols. '+
97
108
  "(Got object `#{x.inspect}` of class `#{x.class}`.)"
98
109
  end
99
110
  end
100
111
 
101
112
  def self.fast_expr(x, max_depth)
102
113
  if max_depth == 0
103
- raise RqlDriverError, "Maximum expression depth exceeded " +
114
+ raise ReqlDriverError, "Maximum expression depth exceeded " +
104
115
  "(you can override this with `r.expr(X, MAX_DEPTH)`)."
105
116
  end
106
117
  case x
@@ -127,7 +138,7 @@ module RethinkDB
127
138
  RQL.new({ '$reql_type$' => 'TIME',
128
139
  'epoch_time' => epoch_time,
129
140
  'timezone' => tz })
130
- else raise RqlDriverError, "r.expr can't handle #{x.inspect} of class #{x.class}."
141
+ else raise ReqlDriverError, "r.expr can't handle #{x.inspect} of class #{x.class}."
131
142
  end
132
143
  end
133
144
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rethinkdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - RethinkDB Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -30,13 +30,13 @@ executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
- - lib/ql2.pb.rb
34
33
  - lib/exc.rb
35
34
  - lib/func.rb
36
35
  - lib/net.rb
37
36
  - lib/rethinkdb.rb
38
37
  - lib/rpp.rb
39
38
  - lib/shim.rb
39
+ - lib/ql2.pb.rb
40
40
  homepage: http://rethinkdb.com
41
41
  licenses:
42
42
  - Apache-2