moped 1.0.0.rc → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of moped might be problematic. Click here for more details.

Files changed (45) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/README.md +32 -467
  3. data/lib/moped.rb +0 -1
  4. data/lib/moped/bson.rb +3 -0
  5. data/lib/moped/bson/binary.rb +4 -4
  6. data/lib/moped/bson/code.rb +12 -10
  7. data/lib/moped/bson/extensions.rb +64 -54
  8. data/lib/moped/bson/extensions/array.rb +9 -6
  9. data/lib/moped/bson/extensions/boolean.rb +1 -1
  10. data/lib/moped/bson/extensions/false_class.rb +5 -2
  11. data/lib/moped/bson/extensions/float.rb +1 -2
  12. data/lib/moped/bson/extensions/hash.rb +4 -5
  13. data/lib/moped/bson/extensions/integer.rb +2 -4
  14. data/lib/moped/bson/extensions/nil_class.rb +1 -2
  15. data/lib/moped/bson/extensions/object.rb +13 -0
  16. data/lib/moped/bson/extensions/regexp.rb +5 -6
  17. data/lib/moped/bson/extensions/string.rb +24 -13
  18. data/lib/moped/bson/extensions/symbol.rb +12 -14
  19. data/lib/moped/bson/extensions/time.rb +4 -4
  20. data/lib/moped/bson/extensions/true_class.rb +5 -2
  21. data/lib/moped/bson/max_key.rb +1 -2
  22. data/lib/moped/bson/min_key.rb +1 -2
  23. data/lib/moped/bson/object_id.rb +44 -4
  24. data/lib/moped/bson/types.rb +1 -1
  25. data/lib/moped/cluster.rb +13 -5
  26. data/lib/moped/collection.rb +5 -1
  27. data/lib/moped/connection.rb +4 -4
  28. data/lib/moped/database.rb +58 -29
  29. data/lib/moped/logging.rb +3 -3
  30. data/lib/moped/node.rb +35 -6
  31. data/lib/moped/protocol/command.rb +1 -4
  32. data/lib/moped/protocol/delete.rb +2 -0
  33. data/lib/moped/protocol/get_more.rb +16 -1
  34. data/lib/moped/protocol/insert.rb +2 -0
  35. data/lib/moped/protocol/kill_cursors.rb +2 -0
  36. data/lib/moped/protocol/message.rb +31 -12
  37. data/lib/moped/protocol/query.rb +15 -3
  38. data/lib/moped/protocol/reply.rb +6 -4
  39. data/lib/moped/protocol/update.rb +2 -0
  40. data/lib/moped/query.rb +60 -5
  41. data/lib/moped/session.rb +53 -17
  42. data/lib/moped/session/context.rb +17 -7
  43. data/lib/moped/threaded.rb +2 -1
  44. data/lib/moped/version.rb +1 -1
  45. metadata +11 -6
@@ -1,7 +1,6 @@
1
1
  require "logger"
2
2
  require "stringio"
3
3
  require "monitor"
4
- require "forwardable"
5
4
 
6
5
  require "moped/bson"
7
6
  require "moped/cluster"
@@ -22,6 +22,9 @@ module Moped
22
22
 
23
23
  START_LENGTH = [0].pack(INT32_PACK).freeze
24
24
 
25
+ BINARY_ENCODING = Encoding.find 'binary'
26
+ UTF8_ENCODING = Encoding.find 'utf-8'
27
+
25
28
  class << self
26
29
 
27
30
  # Create a new object id from the provided string.
@@ -48,19 +48,19 @@ module Moped
48
48
  io << NULL_BYTE
49
49
 
50
50
  if type == :old
51
- io << [data.length + 4].pack(INT32_PACK)
51
+ io << [data.bytesize + 4].pack(INT32_PACK)
52
52
  io << SUBTYPE_MAP[type]
53
- io << [data.length].pack(INT32_PACK)
53
+ io << [data.bytesize].pack(INT32_PACK)
54
54
  io << data
55
55
  else
56
- io << [data.length].pack(INT32_PACK)
56
+ io << [data.bytesize].pack(INT32_PACK)
57
57
  io << SUBTYPE_MAP[type]
58
58
  io << data
59
59
  end
60
60
  end
61
61
 
62
62
  def inspect
63
- "#<#{self.class.name} type=#{type.inspect} length=#{data.length}>"
63
+ "#<#{self.class.name} type=#{type.inspect} length=#{data.bytesize}>"
64
64
  end
65
65
 
66
66
  end
@@ -24,7 +24,7 @@ module Moped
24
24
 
25
25
  class << self
26
26
  def __bson_load__(io)
27
- code = io.read(*io.read(4).unpack(INT32_PACK)).chop!.force_encoding('utf-8')
27
+ code = io.read(*io.read(4).unpack(INT32_PACK)).from_utf8_binary.chop!
28
28
  new code
29
29
  end
30
30
  end
@@ -32,14 +32,15 @@ module Moped
32
32
  def __bson_dump__(io, key)
33
33
  if scoped?
34
34
  io << Types::CODE_WITH_SCOPE
35
- io << key
36
- io << NULL_BYTE
35
+ io << key.to_bson_cstring
37
36
 
38
- code_start = io.length
37
+ code_start = io.bytesize
39
38
 
40
39
  io << START_LENGTH
41
- io << [code.bytesize+1].pack(INT32_PACK)
42
- io << code.encode('utf-8').force_encoding('binary')
40
+
41
+ data = code.to_utf8_binary
42
+ io << [data.bytesize+1].pack(INT32_PACK)
43
+ io << data
43
44
  io << NULL_BYTE
44
45
 
45
46
  scope.__bson_dump__(io)
@@ -48,10 +49,11 @@ module Moped
48
49
 
49
50
  else
50
51
  io << Types::CODE
51
- io << key
52
- io << NULL_BYTE
53
- io << [code.bytesize+1].pack(INT32_PACK)
54
- io << code.encode('utf-8').force_encoding('binary')
52
+ io << key.to_bson_cstring
53
+
54
+ data = code.to_utf8_binary
55
+ io << [data.bytesize+1].pack(INT32_PACK)
56
+ io << data
55
57
  io << NULL_BYTE
56
58
  end
57
59
  end
@@ -5,6 +5,7 @@ require "moped/bson/extensions/float"
5
5
  require "moped/bson/extensions/hash"
6
6
  require "moped/bson/extensions/integer"
7
7
  require "moped/bson/extensions/nil_class"
8
+ require "moped/bson/extensions/object"
8
9
  require "moped/bson/extensions/regexp"
9
10
  require "moped/bson/extensions/string"
10
11
  require "moped/bson/extensions/symbol"
@@ -12,70 +13,79 @@ require "moped/bson/extensions/time"
12
13
  require "moped/bson/extensions/true_class"
13
14
 
14
15
  module Moped
16
+ module BSON
17
+ module Extensions
15
18
 
16
- # @private
17
- class ::Array
18
- extend BSON::Extensions::Array::ClassMethods
19
- include BSON::Extensions::Array
20
- end
19
+ # @private
20
+ class ::Array
21
+ extend Moped::BSON::Extensions::Array::ClassMethods
22
+ include Moped::BSON::Extensions::Array
23
+ end
21
24
 
22
- # @private
23
- class ::FalseClass
24
- extend BSON::Extensions::Boolean::ClassMethods
25
- include BSON::Extensions::FalseClass
26
- end
25
+ # @private
26
+ class ::FalseClass
27
+ extend Moped::BSON::Extensions::Boolean::ClassMethods
28
+ include Moped::BSON::Extensions::FalseClass
29
+ end
27
30
 
28
- # @private
29
- class ::Float
30
- extend BSON::Extensions::Float::ClassMethods
31
- include BSON::Extensions::Float
32
- end
31
+ # @private
32
+ class ::Float
33
+ extend Moped::BSON::Extensions::Float::ClassMethods
34
+ include Moped::BSON::Extensions::Float
35
+ end
33
36
 
34
- # @private
35
- class ::Hash
36
- extend BSON::Extensions::Hash::ClassMethods
37
- include BSON::Extensions::Hash
38
- end
37
+ # @private
38
+ class ::Hash
39
+ extend Moped::BSON::Extensions::Hash::ClassMethods
40
+ include Moped::BSON::Extensions::Hash
41
+ end
39
42
 
40
- # @private
41
- class ::Integer
42
- extend BSON::Extensions::Integer::ClassMethods
43
- include BSON::Extensions::Integer
44
- end
43
+ # @private
44
+ class ::Integer
45
+ extend Moped::BSON::Extensions::Integer::ClassMethods
46
+ include Moped::BSON::Extensions::Integer
47
+ end
45
48
 
46
- # @private
47
- class ::NilClass
48
- extend BSON::Extensions::NilClass::ClassMethods
49
- include BSON::Extensions::NilClass
50
- end
49
+ # @private
50
+ class ::NilClass
51
+ extend Moped::BSON::Extensions::NilClass::ClassMethods
52
+ include Moped::BSON::Extensions::NilClass
53
+ end
51
54
 
52
- # @private
53
- class ::Regexp
54
- extend BSON::Extensions::Regexp::ClassMethods
55
- include BSON::Extensions::Regexp
56
- end
55
+ # @private
56
+ class ::Object
57
+ include Moped::BSON::Extensions::Object
58
+ end
57
59
 
58
- # @private
59
- class ::String
60
- extend BSON::Extensions::String::ClassMethods
61
- include BSON::Extensions::String
62
- end
60
+ # @private
61
+ class ::Regexp
62
+ extend Moped::BSON::Extensions::Regexp::ClassMethods
63
+ include Moped::BSON::Extensions::Regexp
64
+ end
63
65
 
64
- # @private
65
- class ::Symbol
66
- extend BSON::Extensions::Symbol::ClassMethods
67
- include BSON::Extensions::Symbol
68
- end
66
+ # @private
67
+ class ::String
68
+ extend Moped::BSON::Extensions::String::ClassMethods
69
+ include Moped::BSON::Extensions::String
70
+ end
69
71
 
70
- # @private
71
- class ::Time
72
- extend BSON::Extensions::Time::ClassMethods
73
- include BSON::Extensions::Time
74
- end
72
+ # @private
73
+ class ::Symbol
74
+ extend Moped::BSON::Extensions::Symbol::ClassMethods
75
+ include Moped::BSON::Extensions::Symbol
76
+ end
77
+
78
+ # @private
79
+ class ::Time
80
+ extend Moped::BSON::Extensions::Time::ClassMethods
81
+ include Moped::BSON::Extensions::Time
82
+ end
75
83
 
76
- # @private
77
- class ::TrueClass
78
- extend BSON::Extensions::Boolean::ClassMethods
79
- include BSON::Extensions::TrueClass
84
+ # @private
85
+ class ::TrueClass
86
+ extend Moped::BSON::Extensions::Boolean::ClassMethods
87
+ include Moped::BSON::Extensions::TrueClass
88
+ end
89
+ end
80
90
  end
81
91
  end
@@ -20,20 +20,23 @@ module Moped
20
20
 
21
21
  def __bson_dump__(io, key)
22
22
  io << Types::ARRAY
23
- io << key
24
- io << NULL_BYTE
23
+ io << key.to_bson_cstring
25
24
 
26
- start = io.length
25
+ start = io.bytesize
27
26
 
28
27
  # write dummy length
29
28
  io << START_LENGTH
30
29
 
31
- each_with_index do |value, index|
32
- value.__bson_dump__(io, index.to_s)
30
+ index, length = 0, self.length
31
+
32
+ while index < length
33
+ slice(index).__bson_dump__(io, index.to_s)
34
+ index += 1
33
35
  end
36
+
34
37
  io << EOD
35
38
 
36
- stop = io.length
39
+ stop = io.bytesize
37
40
  io[start, 4] = [stop - start].pack(INT32_PACK)
38
41
 
39
42
  io
@@ -5,7 +5,7 @@ module Moped
5
5
  module Boolean
6
6
  module ClassMethods
7
7
  def __bson_load__(io)
8
- io.getbyte == 1
8
+ io.readbyte == 1
9
9
  end
10
10
  end
11
11
  end
@@ -5,10 +5,13 @@ module Moped
5
5
  module FalseClass
6
6
  def __bson_dump__(io, key)
7
7
  io << Types::BOOLEAN
8
- io << key
9
- io << NULL_BYTE
8
+ io << key.to_bson_cstring
10
9
  io << NULL_BYTE
11
10
  end
11
+
12
+ def __safe_options__
13
+ false
14
+ end
12
15
  end
13
16
  end
14
17
  end
@@ -12,8 +12,7 @@ module Moped
12
12
 
13
13
  def __bson_dump__(io, key)
14
14
  io << Types::FLOAT
15
- io << key
16
- io << NULL_BYTE
15
+ io << key.to_bson_cstring
17
16
  io << [self].pack(FLOAT_PACK)
18
17
  end
19
18
 
@@ -10,7 +10,7 @@ module Moped
10
10
  io.read 4
11
11
 
12
12
  while (buf = io.readbyte) != 0
13
- key = io.gets(NULL_BYTE).chop!
13
+ key = io.gets(NULL_BYTE).from_utf8_binary.chop!
14
14
 
15
15
  if native_class = Types::MAP[buf]
16
16
  doc[key] = native_class.__bson_load__(io)
@@ -24,11 +24,10 @@ module Moped
24
24
  def __bson_dump__(io = "", key = nil)
25
25
  if key
26
26
  io << Types::HASH
27
- io << key
28
- io << NULL_BYTE
27
+ io << key.to_bson_cstring
29
28
  end
30
29
 
31
- start = io.length
30
+ start = io.bytesize
32
31
 
33
32
  # write dummy length
34
33
  io << START_LENGTH
@@ -38,7 +37,7 @@ module Moped
38
37
  end
39
38
  io << EOD
40
39
 
41
- stop = io.length
40
+ stop = io.bytesize
42
41
  io[start, 4] = [stop - start].pack INT32_PACK
43
42
 
44
43
  io
@@ -18,13 +18,11 @@ module Moped
18
18
  def __bson_dump__(io, key)
19
19
  if self >= INT32_MIN && self <= INT32_MAX
20
20
  io << Types::INT32
21
- io << key
22
- io << NULL_BYTE
21
+ io << key.to_bson_cstring
23
22
  io << [self].pack(INT32_PACK)
24
23
  elsif self >= INT64_MIN && self <= INT64_MAX
25
24
  io << Types::INT64
26
- io << key
27
- io << NULL_BYTE
25
+ io << key.to_bson_cstring
28
26
  io << [self].pack(INT64_PACK)
29
27
  else
30
28
  raise RangeError.new("MongoDB can only handle 8-byte ints")
@@ -11,8 +11,7 @@ module Moped
11
11
 
12
12
  def __bson_dump__(io, key)
13
13
  io << Types::NULL
14
- io << key
15
- io << NULL_BYTE
14
+ io << key.to_bson_cstring
16
15
  end
17
16
  end
18
17
  end
@@ -0,0 +1,13 @@
1
+ module Moped
2
+ module BSON
3
+ # @private
4
+ module Extensions
5
+ module Object
6
+
7
+ def __safe_options__
8
+ self
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -5,9 +5,9 @@ module Moped
5
5
  module Regexp
6
6
  module ClassMethods
7
7
  def __bson_load__(io)
8
- source = io.gets(NULL_BYTE).chop!
8
+ source = io.gets(NULL_BYTE).from_utf8_binary.chop!
9
9
  options = 0
10
- while (option = io.getbyte) != 0
10
+ while (option = io.readbyte) != 0
11
11
  case option
12
12
  when 105 # 'i'
13
13
  options |= ::Regexp::IGNORECASE
@@ -24,10 +24,9 @@ module Moped
24
24
 
25
25
  def __bson_dump__(io, key)
26
26
  io << Types::REGEX
27
- io << key
28
- io << NULL_BYTE
29
- io << source
30
- io << NULL_BYTE
27
+ io << key.to_bson_cstring
28
+
29
+ io << source.to_bson_cstring
31
30
 
32
31
  io << 'i' if (options & ::Regexp::IGNORECASE) != 0
33
32
  io << 'ms' if (options & ::Regexp::MULTILINE) != 0
@@ -5,29 +5,40 @@ module Moped
5
5
  module String
6
6
  module ClassMethods
7
7
  def __bson_load__(io)
8
- io.read(*io.read(4).unpack(INT32_PACK)).chop!.force_encoding('utf-8')
8
+ io.read(*io.read(4).unpack(INT32_PACK)).from_utf8_binary.chop!
9
9
  end
10
10
  end
11
11
 
12
12
  def __bson_dump__(io, key)
13
13
  io << Types::STRING
14
- io << key
15
- io << NULL_BYTE
14
+ io << key.to_bson_cstring
15
+
16
+ data = to_utf8_binary
16
17
 
17
- begin
18
- data = encode('utf-8')
19
- rescue EncodingError
20
- data = dup
21
- data.force_encoding('utf-8')
18
+ io << [ data.bytesize + 1 ].pack(INT32_PACK)
19
+ io << data
20
+ io << NULL_BYTE
21
+ end
22
22
 
23
- raise unless data.valid_encoding?
23
+ def to_bson_cstring
24
+ if include? NULL_BYTE
25
+ raise EncodingError, "#{inspect} cannot be converted to a BSON " \
26
+ "cstring because it contains a null byte"
24
27
  end
25
28
 
26
- data.force_encoding('binary')
29
+ to_utf8_binary << NULL_BYTE
30
+ end
27
31
 
28
- io << [data.bytesize+1].pack(INT32_PACK)
29
- io << data
30
- io << NULL_BYTE
32
+ def to_utf8_binary
33
+ encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
34
+ rescue EncodingError
35
+ data = dup.force_encoding(UTF8_ENCODING)
36
+ raise unless data.valid_encoding?
37
+ data.force_encoding(BINARY_ENCODING)
38
+ end
39
+
40
+ def from_utf8_binary
41
+ force_encoding(UTF8_ENCODING).encode!
31
42
  end
32
43
  end
33
44
  end