animehunter-mongo 0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/README.rdoc +311 -0
  2. data/Rakefile +62 -0
  3. data/bin/bson_benchmark.rb +59 -0
  4. data/bin/mongo_console +21 -0
  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 +40 -0
  19. data/lib/mongo.rb +19 -0
  20. data/lib/mongo/admin.rb +87 -0
  21. data/lib/mongo/collection.rb +235 -0
  22. data/lib/mongo/cursor.rb +227 -0
  23. data/lib/mongo/db.rb +538 -0
  24. data/lib/mongo/gridfs.rb +16 -0
  25. data/lib/mongo/gridfs/chunk.rb +96 -0
  26. data/lib/mongo/gridfs/grid_store.rb +468 -0
  27. data/lib/mongo/message.rb +20 -0
  28. data/lib/mongo/message/get_more_message.rb +37 -0
  29. data/lib/mongo/message/insert_message.rb +35 -0
  30. data/lib/mongo/message/kill_cursors_message.rb +36 -0
  31. data/lib/mongo/message/message.rb +84 -0
  32. data/lib/mongo/message/message_header.rb +50 -0
  33. data/lib/mongo/message/msg_message.rb +33 -0
  34. data/lib/mongo/message/opcodes.rb +32 -0
  35. data/lib/mongo/message/query_message.rb +77 -0
  36. data/lib/mongo/message/remove_message.rb +36 -0
  37. data/lib/mongo/message/update_message.rb +37 -0
  38. data/lib/mongo/mongo.rb +164 -0
  39. data/lib/mongo/query.rb +119 -0
  40. data/lib/mongo/types/binary.rb +42 -0
  41. data/lib/mongo/types/code.rb +34 -0
  42. data/lib/mongo/types/dbref.rb +37 -0
  43. data/lib/mongo/types/objectid.rb +137 -0
  44. data/lib/mongo/types/regexp_of_holding.rb +44 -0
  45. data/lib/mongo/types/undefined.rb +31 -0
  46. data/lib/mongo/util/bson.rb +534 -0
  47. data/lib/mongo/util/byte_buffer.rb +167 -0
  48. data/lib/mongo/util/ordered_hash.rb +96 -0
  49. data/lib/mongo/util/xml_to_ruby.rb +107 -0
  50. data/mongo-ruby-driver.gemspec +99 -0
  51. data/tests/mongo-qa/_common.rb +8 -0
  52. data/tests/mongo-qa/admin +26 -0
  53. data/tests/mongo-qa/capped +22 -0
  54. data/tests/mongo-qa/count1 +18 -0
  55. data/tests/mongo-qa/dbs +22 -0
  56. data/tests/mongo-qa/find +10 -0
  57. data/tests/mongo-qa/find1 +15 -0
  58. data/tests/mongo-qa/gridfs_in +16 -0
  59. data/tests/mongo-qa/gridfs_out +17 -0
  60. data/tests/mongo-qa/indices +49 -0
  61. data/tests/mongo-qa/remove +25 -0
  62. data/tests/mongo-qa/stress1 +35 -0
  63. data/tests/mongo-qa/test1 +11 -0
  64. data/tests/mongo-qa/update +18 -0
  65. data/tests/test_admin.rb +69 -0
  66. data/tests/test_bson.rb +246 -0
  67. data/tests/test_byte_buffer.rb +69 -0
  68. data/tests/test_chunk.rb +84 -0
  69. data/tests/test_cursor.rb +121 -0
  70. data/tests/test_db.rb +160 -0
  71. data/tests/test_db_api.rb +701 -0
  72. data/tests/test_db_connection.rb +18 -0
  73. data/tests/test_grid_store.rb +284 -0
  74. data/tests/test_message.rb +35 -0
  75. data/tests/test_mongo.rb +78 -0
  76. data/tests/test_objectid.rb +98 -0
  77. data/tests/test_ordered_hash.rb +129 -0
  78. data/tests/test_round_trip.rb +116 -0
  79. metadata +133 -0
@@ -0,0 +1,311 @@
1
+ = Introduction
2
+
3
+ This is a Ruby driver for MongoDB[http://www.mongodb.org].
4
+
5
+ Here is a quick code sample. See the files in the "examples" subdirectory for
6
+ many more.
7
+
8
+ require 'mongo'
9
+
10
+ include XGen::Mongo::Driver
11
+
12
+ db = Mongo.new('localhost').db('sample-db')
13
+ coll = db.collection('test')
14
+
15
+ coll.clear
16
+ 3.times { |i| coll.insert({'a' => i+1}) }
17
+ puts "There are #{coll.count()} records. Here they are:"
18
+ coll.find().each { |doc| puts doc.inspect }
19
+
20
+ This driver also includes an implementation of a GridStore class, a Ruby
21
+ interface to Mongo's GridFS storage.
22
+
23
+ = Installation
24
+
25
+ Install the "mongo" gem by typing
26
+
27
+ $ gem sources -a http://gems.github.com
28
+ $ sudo gem install mongodb-mongo
29
+
30
+ The first line tells RubyGems to add the GitHub gem repository. You only need
31
+ to run this command once.
32
+
33
+ === From the GitHub source
34
+
35
+ The source code is available at http://github.com/mongodb/mongo-ruby-driver.
36
+ You can either clone the git repository or download a tarball or zip file.
37
+ Once you have the source, you can use it from wherever you downloaded it or
38
+ you can install it as a gem from the source by typing
39
+
40
+ $ rake gem:install
41
+
42
+ Note: when you install the gem this way it is called "mongo", not
43
+ "mongodb-mongo". In either case, you "require 'mongo'" in your source code.
44
+
45
+ === Optional C Extension
46
+
47
+ There is a separate gem containing optional C extensions that will increase the
48
+ performance of the driver. To use the optional extensions just install the gem
49
+ by typing
50
+
51
+ $ sudo gem install mongodb-mongo_ext
52
+
53
+ To install from source type this instead
54
+
55
+ $ rake gem:install_extensions
56
+
57
+ That's all there is to it!
58
+
59
+ = Examples
60
+
61
+ There are many examples in the "examples" subdirectory. Samples include using
62
+ the driver and using the GridFS class GridStore. Mongo must be running for
63
+ these examples to work, of course.
64
+
65
+ Here's how to start mongo and run the "simple.rb" example:
66
+
67
+ $ cd path/to/mongo
68
+ $ ./mongod run
69
+ ... then in another window ...
70
+ $ cd path/to/mongo-ruby-driver
71
+ $ ruby examples/simple.rb
72
+
73
+ See also the test code, especially tests/test_db_api.rb.
74
+
75
+ = The Driver
76
+
77
+ Here is some simple example code:
78
+
79
+ require 'rubygems' # not required for Ruby 1.9
80
+ require 'mongo'
81
+
82
+ include XGen::Mongo::Driver
83
+ db = Mongo.new.db('my-db-name')
84
+ things = db.collection('things')
85
+
86
+ things.clear
87
+ things.insert('a' => 42)
88
+ things.insert('a' => 99, 'b' => Time.now)
89
+ puts things.count # => 2
90
+ puts things.find('a' => 42).next_object.inspect # {"a"=>42}
91
+
92
+
93
+ = GridStore
94
+
95
+ The GridStore class is a Ruby implementation of Mongo's GridFS file storage
96
+ system. An instance of GridStore is like an IO object. See the rdocs for
97
+ details, and see examples/gridfs.rb for code that uses many of the GridStore
98
+ features like metadata, content type, rewind/seek/tell, etc.
99
+
100
+ Note that the GridStore class is not automatically required when you require
101
+ 'mongo'. You need to require 'mongo/gridfs'.
102
+
103
+ Example code:
104
+
105
+ GridStore.open(database, 'filename', 'w') { |f|
106
+ f.puts "Hello, world!"
107
+ }
108
+ GridStore.open(database, 'filename, 'r') { |f|
109
+ puts f.read # => Hello, world!\n
110
+ }
111
+ GridStore.open(database, 'filename', 'w+') { |f|
112
+ f.puts "But wait, there's more!"
113
+ }
114
+ GridStore.open(database, 'filename, 'r') { |f|
115
+ puts f.read # => Hello, world!\nBut wait, there's more!\n
116
+ }
117
+
118
+
119
+
120
+ = Notes
121
+
122
+ == String Encoding
123
+
124
+ The BSON ("Binary JSON") format used to communicate with Mongo requires that
125
+ strings be UTF-8 (http://en.wikipedia.org/wiki/UTF-8).
126
+
127
+ Ruby 1.9 has built-in character encoding support. All strings sent to Mongo
128
+ and received from Mongo are converted to UTF-8 when necessary, and strings
129
+ read from Mongo will have their character encodings set to UTF-8.
130
+
131
+ When used with Ruby 1.8, the bytes in each string are written to and read from
132
+ Mongo as-is. If the string is ASCII all is well, because ASCII is a subset of
133
+ UTF-8. If the string is not ASCII then it may not be a well-formed UTF-8
134
+ string.
135
+
136
+ == Primary Keys
137
+
138
+ The field _id is a primary key. It is treated specially by the database, and
139
+ its use makes many operations more efficient. The value of an _id may be of
140
+ any type. The database itself inserts an _id value if none is specified when
141
+ a record is inserted.
142
+
143
+ === Primary Key Factories
144
+
145
+ A primary key factory is a class you supply to a DB object that knows how to
146
+ generate _id values. If you want to control _id values or even their types,
147
+ using a PK factory lets you do so.
148
+
149
+ You can tell the Ruby Mongo driver how to create primary keys by passing in
150
+ the :pk option to the Mongo#db method.
151
+
152
+ include XGen::Mongo::Driver
153
+ db = Mongo.new.db('dbname', :pk => MyPKFactory.new)
154
+
155
+ A primary key factory object must respond to :create_pk, which should take a
156
+ hash and return a hash which merges the original hash with any primary key
157
+ fields the factory wishes to inject. NOTE: if the object already has a primary
158
+ key, the factory should not inject a new key; this means that the object is
159
+ being used in a repsert but it already exists. The idea here is that whenever
160
+ a record is inserted, the :pk object's +create_pk+ method will be called and
161
+ the new hash returned will be inserted.
162
+
163
+ Here is a sample primary key factory, taken from the tests:
164
+
165
+ class TestPKFactory
166
+ def create_pk(row)
167
+ row['_id'] ||= XGen::Mongo::Driver::ObjectID.new
168
+ row
169
+ end
170
+ end
171
+
172
+ Here's a slightly more sophisticated one that handles both symbol and string
173
+ keys. This is the PKFactory that comes with the MongoRecord code (an
174
+ ActiveRecord-like framework for non-Rails apps) and the AR Mongo adapter code
175
+ (for Rails):
176
+
177
+ class PKFactory
178
+ def create_pk(row)
179
+ return row if row[:_id]
180
+ row.delete(:_id) # in case it exists but the value is nil
181
+ row['_id'] ||= XGen::Mongo::Driver::ObjectID.new
182
+ row
183
+ end
184
+ end
185
+
186
+ A database's PK factory object may be set either when a DB object is created
187
+ or immediately after you obtain it, but only once. The only reason it is
188
+ changeable at all is so that libraries such as MongoRecord that use this
189
+ driver can set the PK factory after obtaining the database but before using it
190
+ for the first time.
191
+
192
+ == The DB Class
193
+
194
+ === Primary Key factories
195
+
196
+ See the section on "Primary Keys" above.
197
+
198
+ === Strict mode
199
+
200
+ Each database has an optional strict mode. If strict mode is on, then asking
201
+ for a collection that does not exist will raise an error, as will asking to
202
+ create a collection that already exists. Note that both these operations are
203
+ completely harmless; strict mode is a programmer convenience only.
204
+
205
+ To turn on strict mode, either pass in :strict => true when obtaining a DB
206
+ object or call the :strict= method:
207
+
208
+ db = XGen::Mongo::Driver::Mongo.new.db('dbname', :strict => true)
209
+ # I'm feeling lax
210
+ db.strict = false
211
+ # No, I'm not!
212
+ db.strict = true
213
+
214
+ The method DB#strict? returns the current value of that flag.
215
+
216
+ == Cursors
217
+
218
+ Random cursor fun facts:
219
+
220
+ - Cursors are enumerable.
221
+
222
+ - The query doesn't get run until you actually attempt to retrieve data from a
223
+ cursor.
224
+
225
+ - Cursors have a to_a method.
226
+
227
+
228
+
229
+ = Testing
230
+
231
+ If you have the source code, you can run the tests.
232
+
233
+ $ rake test
234
+
235
+ The tests assume that the Mongo database is running on the default port. You
236
+ can override the default host (localhost) and port (Mongo::DEFAULT_PORT) by
237
+ using the environment variables MONGO_RUBY_DRIVER_HOST and
238
+ MONGO_RUBY_DRIVER_PORT.
239
+
240
+ The project mongo-qa (http://github.com/mongodb/mongo-qa) contains many more
241
+ Mongo driver tests that are language independent. To run thoses tests as part
242
+ of the "rake test" task, download the code "next to" this directory. So, after
243
+ installing the mongo-qa code you would have these two directories next to each
244
+ other:
245
+
246
+ $ ls
247
+ mongo-qa
248
+ mongo-ruby-driver
249
+ $ rake test
250
+
251
+ The tests run just fine if the mongo-qa directory is not there.
252
+
253
+ Additionally, the script bin/validate is used by the mongo-qa project's
254
+ validator script.
255
+
256
+
257
+ = Documentation
258
+
259
+ This documentation is available online at http://mongo.rubyforge.org. You can
260
+ generate the documentation if you have the source by typing
261
+
262
+ $ rake rdoc
263
+
264
+ Then open the file html/index.html.
265
+
266
+
267
+ = Release Notes
268
+
269
+ See the git log comments.
270
+
271
+ = Credits
272
+
273
+ Adrian Madrid, aemadrid@gmail.com
274
+ * bin/mongo_console
275
+ * examples/benchmarks.rb
276
+ * examples/irb.rb
277
+ * Modifications to examples/simple.rb
278
+ * Found plenty of bugs and missing features.
279
+ * Ruby 1.9 support.
280
+ * Gem support.
281
+ * Many other code suggestions and improvements.
282
+
283
+ Aman Gupta, aman@tmm1.net
284
+ * Collection#save
285
+
286
+ Jon Crosby, jon@joncrosby.me
287
+ * Some code clean-up
288
+
289
+ John Nunemaker, http://railstips.org
290
+ * Collection#create_index takes symbols as well as strings
291
+ * Fix for Collection#save
292
+
293
+ David James, djames@sunlightfoundation.com
294
+ * Fix dates to return as UTC
295
+
296
+ = License
297
+
298
+ Copyright 2008-2009 10gen Inc.
299
+
300
+ Licensed under the Apache License, Version 2.0 (the "License");
301
+ you may not use this file except in compliance with the License.
302
+ You may obtain a copy of the License at
303
+
304
+ http://www.apache.org/licenses/LICENSE-2.0
305
+
306
+ Unless required by applicable law or agreed to in writing, software
307
+ distributed under the License is distributed on an "AS IS" BASIS,
308
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
309
+ See the License for the specific language governing permissions and
310
+ limitations under the License.
311
+
@@ -0,0 +1,62 @@
1
+ require 'rubygems'
2
+ require 'rubygems/specification'
3
+ require 'fileutils'
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'rake/gempackagetask'
7
+ begin
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ rescue LoadError
10
+ end
11
+ require 'rbconfig'
12
+ include Config
13
+
14
+ gem_command = "gem"
15
+ gem_command = "gem1.9" if CONFIG["MAJOR"] == "1" && CONFIG["MINOR"] == "9"
16
+
17
+ # NOTE: some of the tests assume Mongo is running
18
+ Rake::TestTask.new do |t|
19
+ t.test_files = FileList['tests/test*.rb']
20
+ end
21
+
22
+ desc "Generate documentation"
23
+ task :rdoc do
24
+ version = eval(File.read("mongo-ruby-driver.gemspec")).version
25
+ out = File.join('html', version.to_s)
26
+ FileUtils.rm_rf('html')
27
+ system "rdoc --main README.rdoc --op #{out} --inline-source --quiet README.rdoc `find lib -name '*.rb'`"
28
+ end
29
+
30
+ desc "Publish documentation to mongo.rubyforge.org"
31
+ task :publish => [:rdoc] do
32
+ # Assumes docs are in ./html
33
+ Rake::RubyForgePublisher.new(GEM, RUBYFORGE_USER).upload
34
+ end
35
+
36
+ namespace :gem do
37
+
38
+ desc "Install the gem locally"
39
+ task :install do
40
+ sh <<EOS
41
+ #{gem_command} build mongo-ruby-driver.gemspec &&
42
+ sudo #{gem_command} install mongo-*.gem &&
43
+ rm mongo-*.gem
44
+ EOS
45
+ end
46
+
47
+ desc "Install the optional c extensions"
48
+ task :install_extensions do
49
+ sh <<EOS
50
+ #{gem_command} build mongo-extensions.gemspec &&
51
+ sudo #{gem_command} install mongo_ext-*.gem &&
52
+ rm mongo_ext-*.gem
53
+ EOS
54
+ end
55
+
56
+ end
57
+
58
+ task :default => :list
59
+
60
+ task :list do
61
+ system 'rake -T'
62
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require 'mongo'
5
+
6
+ include XGen::Mongo::Driver
7
+
8
+ TRIALS = 100000
9
+
10
+ def encode(doc)
11
+ t0 = Time.new
12
+ b = BSON.new
13
+ TRIALS.times { |i|
14
+ b = BSON.new
15
+ b.serialize doc
16
+ }
17
+ print "took: #{Time.now.to_f - t0.to_f}\n"
18
+ return b
19
+ end
20
+
21
+ def decode(bson)
22
+ t0 = Time.new
23
+ doc = nil
24
+ TRIALS.times { |i|
25
+ doc = bson.deserialize
26
+ }
27
+ print "took: #{Time.now.to_f - t0.to_f}\n"
28
+ return doc
29
+ end
30
+
31
+ TEST_CASES = [{},
32
+ {
33
+ "hello" => "world"
34
+ },
35
+ {
36
+ "hello" => "world",
37
+ "mike" => "something",
38
+ "here's" => "another"
39
+ },
40
+ {
41
+ "int" => 200,
42
+ "bool" => true,
43
+ "an int" => 20,
44
+ "a bool" => false
45
+ },
46
+ {
47
+ "this" => 5,
48
+ "is" => {"a" => true},
49
+ "big" => [true, 5.5],
50
+ "object" => nil
51
+ }]
52
+
53
+ TEST_CASES.each { |doc|
54
+ print "case #{doc.inspect}\n"
55
+ print "enc bson\n"
56
+ enc_bson = encode(doc)
57
+ print "dec bson\n"
58
+ raise "FAIL" unless doc == decode(enc_bson)
59
+ }
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ org_argv = ARGV.dup
3
+ ARGV.clear
4
+
5
+ require 'irb'
6
+
7
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
8
+ require 'mongo'
9
+
10
+ include XGen::Mongo::Driver
11
+
12
+ host = org_argv[0] || ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
13
+ port = org_argv[1] || ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
14
+ dbnm = org_argv[2] || ENV['MONGO_RUBY_DRIVER_DB'] || 'ruby-mongo-console'
15
+
16
+ puts "Connecting to #{host}:#{port} (CONN) on with database #{dbnm} (DB)"
17
+ CONN = Mongo.new(host, port)
18
+ DB = CONN.db(dbnm)
19
+
20
+ puts "Starting IRB session..."
21
+ IRB.start(__FILE__)