mongo 0.1.0 → 0.15

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