mongo 0.1.0 → 0.15

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 (89) hide show
  1. data/README.rdoc +268 -71
  2. data/Rakefile +27 -62
  3. data/bin/bson_benchmark.rb +59 -0
  4. data/bin/mongo_console +3 -3
  5. data/bin/run_test_script +19 -0
  6. data/bin/standard_benchmark +109 -0
  7. data/examples/admin.rb +41 -0
  8. data/examples/benchmarks.rb +42 -0
  9. data/examples/blog.rb +76 -0
  10. data/examples/capped.rb +23 -0
  11. data/examples/cursor.rb +47 -0
  12. data/examples/gridfs.rb +87 -0
  13. data/examples/index_test.rb +125 -0
  14. data/examples/info.rb +30 -0
  15. data/examples/queries.rb +69 -0
  16. data/examples/simple.rb +23 -0
  17. data/examples/strict.rb +34 -0
  18. data/examples/types.rb +35 -0
  19. data/lib/mongo.rb +9 -2
  20. data/lib/mongo/admin.rb +65 -68
  21. data/lib/mongo/collection.rb +379 -117
  22. data/lib/mongo/connection.rb +151 -0
  23. data/lib/mongo/cursor.rb +271 -216
  24. data/lib/mongo/db.rb +500 -315
  25. data/lib/mongo/errors.rb +26 -0
  26. data/lib/mongo/gridfs.rb +16 -0
  27. data/lib/mongo/gridfs/chunk.rb +92 -0
  28. data/lib/mongo/gridfs/grid_store.rb +464 -0
  29. data/lib/mongo/message.rb +16 -0
  30. data/lib/mongo/message/get_more_message.rb +24 -13
  31. data/lib/mongo/message/insert_message.rb +29 -11
  32. data/lib/mongo/message/kill_cursors_message.rb +23 -12
  33. data/lib/mongo/message/message.rb +74 -62
  34. data/lib/mongo/message/message_header.rb +35 -24
  35. data/lib/mongo/message/msg_message.rb +21 -9
  36. data/lib/mongo/message/opcodes.rb +26 -15
  37. data/lib/mongo/message/query_message.rb +63 -43
  38. data/lib/mongo/message/remove_message.rb +29 -12
  39. data/lib/mongo/message/update_message.rb +30 -13
  40. data/lib/mongo/query.rb +97 -89
  41. data/lib/mongo/types/binary.rb +25 -21
  42. data/lib/mongo/types/code.rb +30 -0
  43. data/lib/mongo/types/dbref.rb +19 -23
  44. data/lib/mongo/types/objectid.rb +130 -116
  45. data/lib/mongo/types/regexp_of_holding.rb +27 -31
  46. data/lib/mongo/util/bson.rb +273 -160
  47. data/lib/mongo/util/byte_buffer.rb +32 -28
  48. data/lib/mongo/util/ordered_hash.rb +88 -42
  49. data/lib/mongo/util/xml_to_ruby.rb +18 -15
  50. data/mongo-ruby-driver.gemspec +103 -0
  51. data/test/mongo-qa/_common.rb +8 -0
  52. data/test/mongo-qa/admin +26 -0
  53. data/test/mongo-qa/capped +22 -0
  54. data/test/mongo-qa/count1 +18 -0
  55. data/test/mongo-qa/dbs +22 -0
  56. data/test/mongo-qa/find +10 -0
  57. data/test/mongo-qa/find1 +15 -0
  58. data/test/mongo-qa/gridfs_in +16 -0
  59. data/test/mongo-qa/gridfs_out +17 -0
  60. data/test/mongo-qa/indices +49 -0
  61. data/test/mongo-qa/remove +25 -0
  62. data/test/mongo-qa/stress1 +35 -0
  63. data/test/mongo-qa/test1 +11 -0
  64. data/test/mongo-qa/update +18 -0
  65. data/{tests → test}/test_admin.rb +25 -16
  66. data/test/test_bson.rb +268 -0
  67. data/{tests → test}/test_byte_buffer.rb +0 -0
  68. data/test/test_chunk.rb +84 -0
  69. data/test/test_collection.rb +282 -0
  70. data/test/test_connection.rb +101 -0
  71. data/test/test_cursor.rb +321 -0
  72. data/test/test_db.rb +196 -0
  73. data/test/test_db_api.rb +798 -0
  74. data/{tests → test}/test_db_connection.rb +4 -3
  75. data/test/test_grid_store.rb +284 -0
  76. data/{tests → test}/test_message.rb +1 -1
  77. data/test/test_objectid.rb +105 -0
  78. data/{tests → test}/test_ordered_hash.rb +55 -0
  79. data/{tests → test}/test_round_trip.rb +13 -9
  80. data/test/test_threading.rb +37 -0
  81. metadata +74 -32
  82. data/bin/validate +0 -51
  83. data/lib/mongo/mongo.rb +0 -74
  84. data/lib/mongo/types/undefined.rb +0 -31
  85. data/tests/test_bson.rb +0 -135
  86. data/tests/test_cursor.rb +0 -66
  87. data/tests/test_db.rb +0 -51
  88. data/tests/test_db_api.rb +0 -349
  89. data/tests/test_objectid.rb +0 -88
@@ -1,58 +1,78 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
1
17
  require 'mongo/message/message'
2
18
  require 'mongo/message/opcodes'
3
19
  require 'mongo/util/ordered_hash'
4
20
 
5
- module XGen
6
- module Mongo
7
- module Driver
21
+ module Mongo
8
22
 
9
- class QueryMessage < Message
23
+ class QueryMessage < Message
10
24
 
11
- attr_reader :query
25
+ attr_reader :query
12
26
 
13
- def initialize(db_name, collection_name, query)
14
- super(OP_QUERY)
15
- @query = query
16
- write_int(0)
17
- write_string("#{db_name}.#{collection_name}")
18
- write_int(query.number_to_skip)
19
- write_int(query.number_to_return)
20
- sel = query.selector
21
- if query.contains_special_fields
22
- sel = OrderedHash.new
23
- sel['query'] = query.selector
24
- if query.order_by && query.order_by.length > 0
25
- sel['orderby'] = case query.order_by
27
+ def initialize(db_name, collection_name, query)
28
+ super(OP_QUERY)
29
+ @query = query
30
+ @collection_name = collection_name
31
+ write_int(0)
32
+ write_string("#{db_name}.#{collection_name}")
33
+ write_int(query.number_to_skip)
34
+ write_int(query.number_to_return)
35
+ sel = query.selector
36
+ if query.contains_special_fields
37
+ sel = OrderedHash.new
38
+ sel['query'] = query.selector
39
+ if query.order_by && query.order_by.length > 0
40
+ sel['orderby'] = case query.order_by
41
+ when String
42
+ {query.order_by => 1}
43
+ when Array
44
+ h = OrderedHash.new
45
+ query.order_by.each { |ob|
46
+ case ob
26
47
  when String
27
- {query.order_by => 1}
28
- when Array
29
- h = OrderedHash.new
30
- query.order_by.each { |ob| h[ob] = 1 }
31
- h
32
- when Hash # Should be an ordered hash, but this message doesn't care
33
- query.order_by
48
+ h[ob] = 1
49
+ when Hash # should have one entry; will handle all
50
+ ob.each { |k,v| h[k] = v }
34
51
  else
35
- raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
52
+ raise "illegal query order_by value #{query.order_by.inspect}"
36
53
  end
37
- end
38
- if query.hint_fields && query.hint_fields.length > 0
39
- hints = OrderedHash.new
40
- query.hint_fields.each { |hf| hints[hf] = 1 }
41
- sel['$hint'] = hints
42
- end
43
- if query.explain
44
- sel['$explain'] = true
45
- end
46
-
47
- end
48
- write_doc(sel)
49
- write_doc(query.fields) if query.fields
50
- end
51
-
52
- def first_key(key)
53
- @first_key = key
54
+ }
55
+ h
56
+ when Hash # Should be an ordered hash, but this message doesn't care
57
+ query.order_by
58
+ else
59
+ raise "illegal order_by: is a #{query.order_by.class.name}, must be String, Array, Hash, or OrderedHash"
60
+ end
54
61
  end
62
+ sel['$hint'] = query.hint if query.hint && query.hint.length > 0
63
+ sel['$explain'] = true if query.explain
64
+ sel['$snapshot'] = true if query.snapshot
55
65
  end
66
+ write_doc(sel)
67
+ write_doc(query.fields) if query.fields
68
+ end
69
+
70
+ def first_key(key)
71
+ @first_key = key
72
+ end
73
+
74
+ def to_s
75
+ "db.#{@collection_name}.#{@query}"
56
76
  end
57
77
  end
58
78
  end
@@ -1,20 +1,37 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
1
17
  require 'mongo/message/message'
2
18
  require 'mongo/message/opcodes'
3
19
 
4
- module XGen
5
- module Mongo
6
- module Driver
20
+ module Mongo
21
+
22
+ class RemoveMessage < Message
7
23
 
8
- class RemoveMessage < Message
24
+ def initialize(db_name, collection_name, sel)
25
+ @collection_name = collection_name
26
+ super(OP_DELETE)
27
+ write_int(0)
28
+ write_string("#{db_name}.#{collection_name}")
29
+ write_int(0) # flags?
30
+ write_doc(sel)
31
+ end
9
32
 
10
- def initialize(db_name, collection_name, sel)
11
- super(OP_DELETE)
12
- write_int(0)
13
- write_string("#{db_name}.#{collection_name}")
14
- write_int(0) # flags?
15
- write_doc(sel)
16
- end
17
- end
33
+ def to_s
34
+ "#{@collection_name}.clear()"
18
35
  end
19
36
  end
20
37
  end
@@ -1,21 +1,38 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+
1
17
  require 'mongo/message/message'
2
18
  require 'mongo/message/opcodes'
3
19
 
4
- module XGen
5
- module Mongo
6
- module Driver
20
+ module Mongo
21
+
22
+ class UpdateMessage < Message
7
23
 
8
- class UpdateMessage < Message
24
+ def initialize(db_name, collection_name, sel, obj, repsert)
25
+ @collection_name = collection_name
26
+ super(OP_UPDATE)
27
+ write_int(0)
28
+ write_string("#{db_name}.#{collection_name}")
29
+ write_int(repsert ? 1 : 0) # 1 if a repsert operation (upsert)
30
+ write_doc(sel)
31
+ write_doc(obj)
32
+ end
9
33
 
10
- def initialize(db_name, collection_name, sel, obj, repsert)
11
- super(OP_UPDATE)
12
- write_int(0)
13
- write_string("#{db_name}.#{collection_name}")
14
- write_int(repsert ? 1 : 0) # 1 if a repsert operation (upsert)
15
- write_doc(sel)
16
- write_doc(obj)
17
- end
18
- end
34
+ def to_s
35
+ "db.#{@collection_name}.update(#{@sel.inspect}, #{@obj.inspect})"
19
36
  end
20
37
  end
21
38
  end
@@ -1,110 +1,118 @@
1
1
  # --
2
2
  # Copyright (C) 2008-2009 10gen Inc.
3
3
  #
4
- # This program is free software: you can redistribute it and/or modify it
5
- # under the terms of the GNU Affero General Public License, version 3, as
6
- # published by the Free Software Foundation.
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
7
  #
8
- # This program is distributed in the hope that it will be useful, but WITHOUT
9
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
11
- # for more details.
8
+ # http://www.apache.org/licenses/LICENSE-2.0
12
9
  #
13
- # You should have received a copy of the GNU Affero General Public License
14
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
15
  # ++
16
16
 
17
17
  require 'mongo/collection'
18
18
  require 'mongo/message'
19
+ require 'mongo/types/code'
19
20
 
20
- module XGen
21
- module Mongo
22
- module Driver
21
+ module Mongo
23
22
 
24
- # A query against a collection. A query's selector is a hash. See the
25
- # Mongo documentation for query details.
26
- 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
27
26
 
28
- attr_accessor :number_to_skip, :number_to_return, :order_by
29
- # If true, $explain will be set in QueryMessage that uses this query.
30
- attr_accessor :explain
31
- # Either +nil+ or an array of hint field names.
32
- attr_accessor :hint_fields
33
- 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
34
33
 
35
- # sel :: A hash describing the query. See the Mongo docs for details.
36
- #
37
- # return_fields :: If not +nil+, a single field name or an array of
38
- # field names. Only those fields will be returned.
39
- # (Called :fields in calls to Collection#find.)
40
- #
41
- # number_to_skip :: Number of records to skip before returning
42
- # records. (Called :offset in calls to
43
- # Collection#find.) Default is 0.
44
- #
45
- # number_to_return :: Max number of records to return. (Called :limit
46
- # in calls to Collection#find.) Default is 0 (all
47
- # records).
48
- #
49
- # order_by :: If not +nil+, specifies record sort order. May be a
50
- # String, Hash, OrderedHash, or Array. If a string, the
51
- # results will be ordered by that field in ascending
52
- # order. If an array, it should be an array of field names
53
- # which will all be sorted in ascending order. If a hash,
54
- # it may be either a regular Hash or an OrderedHash. The
55
- # keys should be field names, and the values should be 1
56
- # (ascending) or -1 (descending). Note that if it is a
57
- # regular Hash then sorting by more than one field
58
- # probably will not be what you intend because key order
59
- # is not preserved. (order_by is called :sort in calls to
60
- # Collection#find.)
61
- def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil)
62
- @number_to_skip, @number_to_return, @order_by = number_to_skip, number_to_return, order_by
63
- self.selector = sel
64
- self.fields = return_fields
65
- end
66
-
67
- # Set query selector hash. If sel is a string, it will be used as a
68
- # $where clause. (See Mongo docs for details.)
69
- def selector=(sel)
70
- @selector = case sel
71
- when nil
72
- {}
73
- when String
74
- {"$where" => sel}
75
- when Hash
76
- sel
77
- end
78
- 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. Default is 0.
42
+ #
43
+ # number_to_return :: Max number of records to return. (Called :limit
44
+ # in calls to Collection#find.) Default is 0 (all
45
+ # records).
46
+ #
47
+ # order_by :: If not +nil+, specifies record sort order. May be a
48
+ # String, Hash, OrderedHash, or Array. If a string, the
49
+ # results will be ordered by that field in ascending
50
+ # order. If an array, it should be an array of field names
51
+ # which will all be sorted in ascending order. If a hash,
52
+ # it may be either a regular Hash or an OrderedHash. The
53
+ # keys should be field names, and the values should be 1
54
+ # (ascending) or -1 (descending). Note that if it is a
55
+ # regular Hash then sorting by more than one field
56
+ # probably will not be what you intend because key order
57
+ # is not preserved. (order_by is called :sort in calls to
58
+ # Collection#find.)
59
+ #
60
+ # hint :: If not +nil+, specifies query hint fields. Must be either
61
+ # +nil+ or a hash (preferably an OrderedHash). See
62
+ # Collection#hint.
63
+ def initialize(sel={}, return_fields=nil, number_to_skip=0, number_to_return=0, order_by=nil, hint=nil, snapshot=nil)
64
+ @number_to_skip, @number_to_return, @order_by, @hint, @snapshot =
65
+ number_to_skip, number_to_return, order_by, hint, snapshot
66
+ @explain = nil
67
+ self.selector = sel
68
+ self.fields = return_fields
69
+ end
79
70
 
80
- # Set fields to return. If +val+ is +nil+ or empty, all fields will be
81
- # returned.
82
- def fields=(val)
83
- @fields = val
84
- @fields = nil if @fields && @fields.empty?
85
- end
71
+ # Set query selector hash. If sel is Code/string, it will be used as a
72
+ # $where clause. (See Mongo docs for details.)
73
+ def selector=(sel)
74
+ @selector = case sel
75
+ when nil
76
+ {}
77
+ when Code
78
+ {"$where" => sel}
79
+ when String
80
+ {"$where" => Code.new(sel)}
81
+ when Hash
82
+ sel
83
+ end
84
+ end
86
85
 
87
- def fields
88
- case @fields
89
- when String
90
- {@fields => 1}
91
- when Array
92
- if @fields.length == 0
93
- nil
94
- else
95
- h = {}
96
- @fields.each { |field| h[field] = 1 }
97
- h
98
- end
99
- else # nil, anything else
100
- nil
101
- end
102
- end
86
+ # Set fields to return. If +val+ is +nil+ or empty, all fields will be
87
+ # returned.
88
+ def fields=(val)
89
+ @fields = val
90
+ @fields = nil if @fields && @fields.empty?
91
+ end
103
92
 
104
- def contains_special_fields
105
- (@order_by != nil && @order_by.length > 0) || @explain || @hint_fields
93
+ def fields
94
+ case @fields
95
+ when String
96
+ {@fields => 1}
97
+ when Array
98
+ if @fields.length == 0
99
+ nil
100
+ else
101
+ h = {}
102
+ @fields.each { |field| h[field] = 1 }
103
+ h
106
104
  end
105
+ else # nil, anything else
106
+ nil
107
107
  end
108
108
  end
109
+
110
+ def contains_special_fields
111
+ (@order_by != nil && @order_by.length > 0) || @explain || @hint || @snapshot
112
+ end
113
+
114
+ def to_s
115
+ "find(#{@selector.inspect})" + (@order_by ? ".sort(#{@order_by.inspect})" : "")
116
+ end
109
117
  end
110
118
  end
@@ -1,34 +1,38 @@
1
1
  # --
2
2
  # Copyright (C) 2008-2009 10gen Inc.
3
3
  #
4
- # This program is free software: you can redistribute it and/or modify it
5
- # under the terms of the GNU Affero General Public License, version 3, as
6
- # published by the Free Software Foundation.
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
7
  #
8
- # This program is distributed in the hope that it will be useful, but WITHOUT
9
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
- # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
11
- # for more details.
8
+ # http://www.apache.org/licenses/LICENSE-2.0
12
9
  #
13
- # You should have received a copy of the GNU Affero General Public License
14
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
15
  # ++
16
16
 
17
- module XGen
18
- module Mongo
19
- module Driver
17
+ require 'mongo/util/byte_buffer'
20
18
 
21
- # An array of binary bytes. The only reason this exists is so that the
22
- # BSON encoder will know to output the Mongo BINARY type.
23
- class Binary < String; end
19
+ module Mongo
24
20
 
21
+ # An array of binary bytes with a Mongo subtype value.
22
+ class Binary < ByteBuffer
23
+
24
+ SUBTYPE_BYTES = 0x02
25
+ SUBTYPE_UUID = 0x03
26
+ SUBTYPE_MD5 = 0x05
27
+ SUBTYPE_USER_DEFINED = 0x80
28
+
29
+ # One of the SUBTYPE_* constants. Default is SUBTYPE_BYTES.
30
+ attr_accessor :subtype
31
+
32
+ def initialize(initial_data=[], subtype=SUBTYPE_BYTES)
33
+ super(initial_data)
34
+ @subtype = subtype
25
35
  end
26
- end
27
- end
28
36
 
29
- class String
30
- # Convert a string into a XGen::Mongo::Driver::Binary
31
- def to_mongo_binary
32
- XGen::Mongo::Driver::Binary.new(self)
33
37
  end
34
38
  end