mongodb-mongo 0.12 → 0.13

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