mongodb-mongo 0.12 → 0.13

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.
Files changed (81) hide show
  1. data/README.rdoc +12 -12
  2. data/Rakefile +1 -1
  3. data/bin/bson_benchmark.rb +1 -1
  4. data/bin/mongo_console +3 -3
  5. data/bin/run_test_script +2 -2
  6. data/bin/standard_benchmark +3 -3
  7. data/examples/admin.rb +3 -3
  8. data/examples/benchmarks.rb +2 -2
  9. data/examples/blog.rb +4 -4
  10. data/examples/capped.rb +3 -3
  11. data/examples/cursor.rb +3 -3
  12. data/examples/gridfs.rb +4 -4
  13. data/examples/index_test.rb +11 -11
  14. data/examples/info.rb +3 -3
  15. data/examples/queries.rb +3 -3
  16. data/examples/simple.rb +3 -3
  17. data/examples/strict.rb +3 -3
  18. data/examples/types.rb +4 -9
  19. data/lib/mongo.rb +35 -3
  20. data/lib/mongo/admin.rb +56 -60
  21. data/lib/mongo/collection.rb +368 -320
  22. data/lib/mongo/connection.rb +166 -0
  23. data/lib/mongo/cursor.rb +206 -209
  24. data/lib/mongo/db.rb +478 -489
  25. data/lib/mongo/errors.rb +8 -9
  26. data/lib/mongo/gridfs/chunk.rb +66 -70
  27. data/lib/mongo/gridfs/grid_store.rb +406 -410
  28. data/lib/mongo/message/get_more_message.rb +8 -13
  29. data/lib/mongo/message/insert_message.rb +7 -11
  30. data/lib/mongo/message/kill_cursors_message.rb +7 -12
  31. data/lib/mongo/message/message.rb +58 -62
  32. data/lib/mongo/message/message_header.rb +19 -24
  33. data/lib/mongo/message/msg_message.rb +5 -9
  34. data/lib/mongo/message/opcodes.rb +10 -15
  35. data/lib/mongo/message/query_message.rb +42 -46
  36. data/lib/mongo/message/remove_message.rb +8 -12
  37. data/lib/mongo/message/update_message.rb +9 -13
  38. data/lib/mongo/query.rb +84 -88
  39. data/lib/mongo/types/binary.rb +13 -17
  40. data/lib/mongo/types/code.rb +9 -13
  41. data/lib/mongo/types/dbref.rb +10 -14
  42. data/lib/mongo/types/objectid.rb +103 -107
  43. data/lib/mongo/types/regexp_of_holding.rb +18 -22
  44. data/lib/mongo/types/undefined.rb +7 -10
  45. data/lib/mongo/util/bson.rb +4 -9
  46. data/lib/mongo/util/xml_to_ruby.rb +1 -3
  47. data/mongo-ruby-driver.gemspec +33 -32
  48. data/{tests → test}/mongo-qa/_common.rb +1 -1
  49. data/{tests → test}/mongo-qa/admin +1 -1
  50. data/{tests → test}/mongo-qa/capped +1 -1
  51. data/{tests → test}/mongo-qa/count1 +4 -4
  52. data/{tests → test}/mongo-qa/dbs +1 -1
  53. data/{tests → test}/mongo-qa/find +1 -1
  54. data/{tests → test}/mongo-qa/find1 +1 -1
  55. data/{tests → test}/mongo-qa/gridfs_in +2 -2
  56. data/{tests → test}/mongo-qa/gridfs_out +2 -2
  57. data/{tests → test}/mongo-qa/indices +2 -2
  58. data/{tests → test}/mongo-qa/remove +1 -1
  59. data/{tests → test}/mongo-qa/stress1 +1 -1
  60. data/{tests → test}/mongo-qa/test1 +1 -1
  61. data/{tests → test}/mongo-qa/update +1 -1
  62. data/{tests → test}/test_admin.rb +3 -3
  63. data/{tests → test}/test_bson.rb +4 -4
  64. data/{tests → test}/test_byte_buffer.rb +0 -0
  65. data/{tests → test}/test_chunk.rb +4 -4
  66. data/{tests → test}/test_collection.rb +42 -4
  67. data/{tests/test_mongo.rb → test/test_connection.rb} +35 -11
  68. data/test/test_cursor.rb +223 -0
  69. data/{tests → test}/test_db.rb +12 -12
  70. data/{tests → test}/test_db_api.rb +28 -33
  71. data/{tests → test}/test_db_connection.rb +3 -3
  72. data/{tests → test}/test_grid_store.rb +4 -4
  73. data/{tests → test}/test_message.rb +1 -1
  74. data/{tests → test}/test_objectid.rb +3 -3
  75. data/{tests → test}/test_ordered_hash.rb +0 -0
  76. data/{tests → test}/test_round_trip.rb +6 -2
  77. data/{tests → test}/test_threading.rb +3 -3
  78. data/test/test_xgen.rb +73 -0
  79. metadata +33 -32
  80. data/lib/mongo/mongo.rb +0 -164
  81. data/tests/test_cursor.rb +0 -121
@@ -17,21 +17,17 @@
17
17
  require 'mongo/message/message'
18
18
  require 'mongo/message/opcodes'
19
19
 
20
- module XGen
21
- module Mongo
22
- module Driver
20
+ module Mongo
23
21
 
24
- class UpdateMessage < Message
22
+ class UpdateMessage < Message
25
23
 
26
- def initialize(db_name, collection_name, sel, obj, repsert)
27
- super(OP_UPDATE)
28
- write_int(0)
29
- write_string("#{db_name}.#{collection_name}")
30
- write_int(repsert ? 1 : 0) # 1 if a repsert operation (upsert)
31
- write_doc(sel)
32
- write_doc(obj)
33
- end
34
- end
24
+ def initialize(db_name, collection_name, sel, obj, repsert)
25
+ super(OP_UPDATE)
26
+ write_int(0)
27
+ write_string("#{db_name}.#{collection_name}")
28
+ write_int(repsert ? 1 : 0) # 1 if a repsert operation (upsert)
29
+ write_doc(sel)
30
+ write_doc(obj)
35
31
  end
36
32
  end
37
33
  end
data/lib/mongo/query.rb CHANGED
@@ -18,102 +18,98 @@ require 'mongo/collection'
18
18
  require 'mongo/message'
19
19
  require 'mongo/types/code'
20
20
 
21
- module XGen
22
- module Mongo
23
- module Driver
21
+ module Mongo
24
22
 
25
- # A query against a collection. A query's selector is a hash. See the
26
- # Mongo documentation for query details.
27
- class Query
23
+ # A query against a collection. A query's selector is a hash. See the
24
+ # Mongo documentation for query details.
25
+ class Query
28
26
 
29
- attr_accessor :number_to_skip, :number_to_return, :order_by, :snapshot
30
- # If true, $explain will be set in QueryMessage that uses this query.
31
- attr_accessor :explain
32
- # Either +nil+ or a hash (preferably an OrderedHash).
33
- attr_accessor :hint
34
- attr_reader :selector # writer defined below
27
+ attr_accessor :number_to_skip, :number_to_return, :order_by, :snapshot
28
+ # If true, $explain will be set in QueryMessage that uses this query.
29
+ attr_accessor :explain
30
+ # Either +nil+ or a hash (preferably an OrderedHash).
31
+ attr_accessor :hint
32
+ attr_reader :selector # writer defined below
35
33
 
36
- # sel :: A hash describing the query. See the Mongo docs for details.
37
- #
38
- # return_fields :: If not +nil+, a single field name or an array of
39
- # field names. Only those fields will be returned.
40
- # (Called :fields in calls to Collection#find.)
41
- #
42
- # number_to_skip :: Number of records to skip before returning
43
- # records. (Called :offset in calls to
44
- # Collection#find.) Default is 0.
45
- #
46
- # number_to_return :: Max number of records to return. (Called :limit
47
- # in calls to Collection#find.) Default is 0 (all
48
- # records).
49
- #
50
- # order_by :: If not +nil+, specifies record sort order. May be a
51
- # String, Hash, OrderedHash, or Array. If a string, the
52
- # results will be ordered by that field in ascending
53
- # order. If an array, it should be an array of field names
54
- # which will all be sorted in ascending order. If a hash,
55
- # it may be either a regular Hash or an OrderedHash. The
56
- # keys should be field names, and the values should be 1
57
- # (ascending) or -1 (descending). Note that if it is a
58
- # regular Hash then sorting by more than one field
59
- # probably will not be what you intend because key order
60
- # is not preserved. (order_by is called :sort in calls to
61
- # Collection#find.)
62
- #
63
- # hint :: If not +nil+, specifies query hint fields. Must be either
64
- # +nil+ or a hash (preferably an OrderedHash). See
65
- # Collection#hint.
66
- def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil)
67
- @number_to_skip, @number_to_return, @order_by, @hint, @snapshot =
68
- number_to_skip, number_to_return, order_by, hint, snapshot
69
- @explain = nil
70
- self.selector = sel
71
- self.fields = return_fields
72
- end
73
-
74
- # Set query selector hash. If sel is Code/string, it will be used as a
75
- # $where clause. (See Mongo docs for details.)
76
- def selector=(sel)
77
- @selector = case sel
78
- when nil
79
- {}
80
- when Code
81
- {"$where" => sel}
82
- when String
83
- {"$where" => Code.new(sel)}
84
- when Hash
85
- sel
86
- end
87
- end
34
+ # sel :: A hash describing the query. See the Mongo docs for details.
35
+ #
36
+ # return_fields :: If not +nil+, a single field name or an array of
37
+ # field names. Only those fields will be returned.
38
+ # (Called :fields in calls to Collection#find.)
39
+ #
40
+ # number_to_skip :: Number of records to skip before returning
41
+ # records. (Called :offset in calls to
42
+ # Collection#find.) Default is 0.
43
+ #
44
+ # number_to_return :: Max number of records to return. (Called :limit
45
+ # in calls to Collection#find.) Default is 0 (all
46
+ # records).
47
+ #
48
+ # order_by :: If not +nil+, specifies record sort order. May be a
49
+ # String, Hash, OrderedHash, or Array. If a string, the
50
+ # results will be ordered by that field in ascending
51
+ # order. If an array, it should be an array of field names
52
+ # which will all be sorted in ascending order. If a hash,
53
+ # it may be either a regular Hash or an OrderedHash. The
54
+ # keys should be field names, and the values should be 1
55
+ # (ascending) or -1 (descending). Note that if it is a
56
+ # regular Hash then sorting by more than one field
57
+ # probably will not be what you intend because key order
58
+ # is not preserved. (order_by is called :sort in calls to
59
+ # Collection#find.)
60
+ #
61
+ # hint :: If not +nil+, specifies query hint fields. Must be either
62
+ # +nil+ or a hash (preferably an OrderedHash). See
63
+ # Collection#hint.
64
+ def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil)
65
+ @number_to_skip, @number_to_return, @order_by, @hint, @snapshot =
66
+ number_to_skip, number_to_return, order_by, hint, snapshot
67
+ @explain = nil
68
+ self.selector = sel
69
+ self.fields = return_fields
70
+ end
88
71
 
89
- # Set fields to return. If +val+ is +nil+ or empty, all fields will be
90
- # returned.
91
- def fields=(val)
92
- @fields = val
93
- @fields = nil if @fields && @fields.empty?
94
- end
72
+ # Set query selector hash. If sel is Code/string, it will be used as a
73
+ # $where clause. (See Mongo docs for details.)
74
+ def selector=(sel)
75
+ @selector = case sel
76
+ when nil
77
+ {}
78
+ when Code
79
+ {"$where" => sel}
80
+ when String
81
+ {"$where" => Code.new(sel)}
82
+ when Hash
83
+ sel
84
+ end
85
+ end
95
86
 
96
- def fields
97
- case @fields
98
- when String
99
- {@fields => 1}
100
- when Array
101
- if @fields.length == 0
102
- nil
103
- else
104
- h = {}
105
- @fields.each { |field| h[field] = 1 }
106
- h
107
- end
108
- else # nil, anything else
109
- nil
110
- end
111
- end
87
+ # Set fields to return. If +val+ is +nil+ or empty, all fields will be
88
+ # returned.
89
+ def fields=(val)
90
+ @fields = val
91
+ @fields = nil if @fields && @fields.empty?
92
+ end
112
93
 
113
- def contains_special_fields
114
- (@order_by != nil && @order_by.length > 0) || @explain || @hint || @snapshot
94
+ def fields
95
+ case @fields
96
+ when String
97
+ {@fields => 1}
98
+ when Array
99
+ if @fields.length == 0
100
+ nil
101
+ else
102
+ h = {}
103
+ @fields.each { |field| h[field] = 1 }
104
+ h
115
105
  end
106
+ else # nil, anything else
107
+ nil
116
108
  end
117
109
  end
110
+
111
+ def contains_special_fields
112
+ (@order_by != nil && @order_by.length > 0) || @explain || @hint || @snapshot
113
+ end
118
114
  end
119
115
  end
@@ -16,27 +16,23 @@
16
16
 
17
17
  require 'mongo/util/byte_buffer'
18
18
 
19
- module XGen
20
- module Mongo
21
- module Driver
19
+ module Mongo
22
20
 
23
- # An array of binary bytes with a Mongo subtype value.
24
- class Binary < ByteBuffer
21
+ # An array of binary bytes with a Mongo subtype value.
22
+ class Binary < ByteBuffer
25
23
 
26
- SUBTYPE_BYTES = 0x02
27
- SUBTYPE_UUID = 0x03
28
- SUBTYPE_MD5 = 0x05
29
- SUBTYPE_USER_DEFINED = 0x80
24
+ SUBTYPE_BYTES = 0x02
25
+ SUBTYPE_UUID = 0x03
26
+ SUBTYPE_MD5 = 0x05
27
+ SUBTYPE_USER_DEFINED = 0x80
30
28
 
31
- # One of the SUBTYPE_* constants. Default is SUBTYPE_BYTES.
32
- attr_accessor :subtype
29
+ # One of the SUBTYPE_* constants. Default is SUBTYPE_BYTES.
30
+ attr_accessor :subtype
33
31
 
34
- def initialize(initial_data=[], subtype=SUBTYPE_BYTES)
35
- super(initial_data)
36
- @subtype = subtype
37
- end
38
-
39
- end
32
+ def initialize(initial_data=[], subtype=SUBTYPE_BYTES)
33
+ super(initial_data)
34
+ @subtype = subtype
40
35
  end
36
+
41
37
  end
42
38
  end
@@ -14,21 +14,17 @@
14
14
  # limitations under the License.
15
15
  # ++
16
16
 
17
- module XGen
18
- module Mongo
19
- module Driver
17
+ module Mongo
20
18
 
21
- # JavaScript code to be evaluated by MongoDB
22
- class Code < String
23
- # Hash mapping identifiers to their values
24
- attr_accessor :scope
19
+ # JavaScript code to be evaluated by MongoDB
20
+ class Code < String
21
+ # Hash mapping identifiers to their values
22
+ attr_accessor :scope
25
23
 
26
- def initialize(code, scope={})
27
- super(code)
28
- @scope = scope
29
- end
30
-
31
- end
24
+ def initialize(code, scope={})
25
+ super(code)
26
+ @scope = scope
32
27
  end
28
+
33
29
  end
34
30
  end
@@ -14,24 +14,20 @@
14
14
  # limitations under the License.
15
15
  # ++
16
16
 
17
- module XGen
18
- module Mongo
19
- module Driver
17
+ module Mongo
20
18
 
21
- class DBRef
19
+ class DBRef
22
20
 
23
- attr_reader :namespace, :object_id
21
+ attr_reader :namespace, :object_id
24
22
 
25
- def initialize(namespace, object_id)
26
- @namespace, @object_id =
27
- namespace, object_id
28
- end
29
-
30
- def to_s
31
- "ns: #{namespace}, id: #{object_id}"
32
- end
23
+ def initialize(namespace, object_id)
24
+ @namespace, @object_id =
25
+ namespace, object_id
26
+ end
33
27
 
34
- end
28
+ def to_s
29
+ "ns: #{namespace}, id: #{object_id}"
35
30
  end
31
+
36
32
  end
37
33
  end
@@ -17,121 +17,117 @@
17
17
  require 'mutex_m'
18
18
  require 'mongo/util/byte_buffer'
19
19
 
20
- module XGen
21
- module Mongo
22
- module Driver
23
-
24
- # Implementation of the Babble OID. Object ids are not required by
25
- # Mongo, but they make certain operations more efficient.
26
- #
27
- # The driver does not automatically assign ids to records that are
28
- # inserted. (An upcoming feature will allow you to give an id "factory"
29
- # to a database and/or a collection.)
30
- #
31
- # 12 bytes
32
- # ---
33
- # 0 time
34
- # 1
35
- # 2
36
- # 3
37
- # 4 machine
38
- # 5
39
- # 6
40
- # 7 pid
41
- # 8
42
- # 9 inc
43
- # 10
44
- # 11
45
- class ObjectID
46
-
47
- MACHINE = ( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
48
- PID = ( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
49
-
50
- # The string representation of an OID is different than its internal
51
- # and BSON byte representations. The BYTE_ORDER here maps
52
- # internal/BSON byte position (the index in BYTE_ORDER) to the
53
- # position of the two hex characters representing that byte in the
54
- # string representation. For example, the 0th BSON byte corresponds to
55
- # the (0-based) 7th pair of hex chars in the string.
56
- BYTE_ORDER = [7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8]
57
-
58
- LOCK = Object.new
59
- LOCK.extend Mutex_m
60
-
61
- @@index_time = Time.new.to_i
62
- @@index = 0
63
-
64
- # Given a string representation of an ObjectID, return a new ObjectID
65
- # with that value.
66
- def self.from_string(str)
67
- raise "illegal ObjectID format" unless legal?(str)
68
- data = []
69
- BYTE_ORDER.each_with_index { |string_position, data_index|
70
- data[data_index] = str[string_position * 2, 2].to_i(16)
71
- }
72
- self.new(data)
73
- end
20
+ module Mongo
21
+
22
+ # Implementation of the Babble OID. Object ids are not required by
23
+ # Mongo, but they make certain operations more efficient.
24
+ #
25
+ # The driver does not automatically assign ids to records that are
26
+ # inserted. (An upcoming feature will allow you to give an id "factory"
27
+ # to a database and/or a collection.)
28
+ #
29
+ # 12 bytes
30
+ # ---
31
+ # 0 time
32
+ # 1
33
+ # 2
34
+ # 3
35
+ # 4 machine
36
+ # 5
37
+ # 6
38
+ # 7 pid
39
+ # 8
40
+ # 9 inc
41
+ # 10
42
+ # 11
43
+ class ObjectID
44
+
45
+ MACHINE = ( val = rand(0x1000000); [val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff] )
46
+ PID = ( val = rand(0x10000); [val & 0xff, (val >> 8) & 0xff]; )
47
+
48
+ # The string representation of an OID is different than its internal
49
+ # and BSON byte representations. The BYTE_ORDER here maps
50
+ # internal/BSON byte position (the index in BYTE_ORDER) to the
51
+ # position of the two hex characters representing that byte in the
52
+ # string representation. For example, the 0th BSON byte corresponds to
53
+ # the (0-based) 7th pair of hex chars in the string.
54
+ BYTE_ORDER = [7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8]
55
+
56
+ LOCK = Object.new
57
+ LOCK.extend Mutex_m
58
+
59
+ @@index_time = Time.new.to_i
60
+ @@index = 0
61
+
62
+ # Given a string representation of an ObjectID, return a new ObjectID
63
+ # with that value.
64
+ def self.from_string(str)
65
+ raise "illegal ObjectID format" unless legal?(str)
66
+ data = []
67
+ BYTE_ORDER.each_with_index { |string_position, data_index|
68
+ data[data_index] = str[string_position * 2, 2].to_i(16)
69
+ }
70
+ self.new(data)
71
+ end
74
72
 
75
- def self.legal?(str)
76
- len = BYTE_ORDER.length * 2
77
- str =~ /([0-9a-f]+)/i
78
- match = $1
79
- str && str.length == len && match == str
80
- end
73
+ def self.legal?(str)
74
+ len = BYTE_ORDER.length * 2
75
+ str =~ /([0-9a-f]+)/i
76
+ match = $1
77
+ str && str.length == len && match == str
78
+ end
81
79
 
82
- # +data+ is an array of bytes. If nil, a new id will be generated.
83
- # The time +t+ is only used for testing; leave it nil.
84
- def initialize(data=nil, t=nil)
85
- @data = data || generate_id(t)
86
- end
80
+ # +data+ is an array of bytes. If nil, a new id will be generated.
81
+ # The time +t+ is only used for testing; leave it nil.
82
+ def initialize(data=nil, t=nil)
83
+ @data = data || generate_id(t)
84
+ end
87
85
 
88
- def eql?(other)
89
- @data == other.instance_variable_get("@data")
90
- end
91
- alias_method :==, :eql?
86
+ def eql?(other)
87
+ @data == other.instance_variable_get("@data")
88
+ end
89
+ alias_method :==, :eql?
92
90
 
93
- def to_a
94
- @data.dup
95
- end
91
+ def to_a
92
+ @data.dup
93
+ end
96
94
 
97
- def to_s
98
- str = ' ' * 24
99
- BYTE_ORDER.each_with_index { |string_position, data_index|
100
- str[string_position * 2, 2] = '%02x' % @data[data_index]
101
- }
102
- str
103
- end
95
+ def to_s
96
+ str = ' ' * 24
97
+ BYTE_ORDER.each_with_index { |string_position, data_index|
98
+ str[string_position * 2, 2] = '%02x' % @data[data_index]
99
+ }
100
+ str
101
+ end
104
102
 
105
- # (Would normally be private, but isn't so we can test it.)
106
- def generate_id(t=nil)
107
- t ||= Time.new.to_i
108
- buf = ByteBuffer.new
109
- buf.put_int(t & 0xffffffff)
110
- buf.put_array(MACHINE)
111
- buf.put_array(PID)
112
- i = index_for_time(t)
113
- buf.put(i & 0xff)
114
- buf.put((i >> 8) & 0xff)
115
- buf.put((i >> 16) & 0xff)
116
-
117
- buf.rewind
118
- buf.to_a.dup
119
- end
103
+ # (Would normally be private, but isn't so we can test it.)
104
+ def generate_id(t=nil)
105
+ t ||= Time.new.to_i
106
+ buf = ByteBuffer.new
107
+ buf.put_int(t & 0xffffffff)
108
+ buf.put_array(MACHINE)
109
+ buf.put_array(PID)
110
+ i = index_for_time(t)
111
+ buf.put(i & 0xff)
112
+ buf.put((i >> 8) & 0xff)
113
+ buf.put((i >> 16) & 0xff)
114
+
115
+ buf.rewind
116
+ buf.to_a.dup
117
+ end
120
118
 
121
- # (Would normally be private, but isn't so we can test it.)
122
- def index_for_time(t)
123
- LOCK.mu_synchronize {
124
- if t != @@index_time
125
- @@index = 0
126
- @@index_time = t
127
- end
128
- retval = @@index
129
- @@index += 1
130
- retval
131
- }
119
+ # (Would normally be private, but isn't so we can test it.)
120
+ def index_for_time(t)
121
+ LOCK.mu_synchronize {
122
+ if t != @@index_time
123
+ @@index = 0
124
+ @@index_time = t
132
125
  end
133
-
134
- end
126
+ retval = @@index
127
+ @@index += 1
128
+ retval
129
+ }
135
130
  end
131
+
136
132
  end
137
133
  end