mongodb-mongo 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/README.rdoc +216 -0
  2. data/Rakefile +54 -0
  3. data/bin/mongo_console +21 -0
  4. data/bin/validate +51 -0
  5. data/examples/benchmarks.rb +38 -0
  6. data/examples/blog.rb +76 -0
  7. data/examples/index_test.rb +128 -0
  8. data/examples/simple.rb +17 -0
  9. data/lib/mongo/admin.rb +86 -0
  10. data/lib/mongo/collection.rb +161 -0
  11. data/lib/mongo/cursor.rb +230 -0
  12. data/lib/mongo/db.rb +399 -0
  13. data/lib/mongo/message/get_more_message.rb +21 -0
  14. data/lib/mongo/message/insert_message.rb +19 -0
  15. data/lib/mongo/message/kill_cursors_message.rb +20 -0
  16. data/lib/mongo/message/message.rb +68 -0
  17. data/lib/mongo/message/message_header.rb +34 -0
  18. data/lib/mongo/message/msg_message.rb +17 -0
  19. data/lib/mongo/message/opcodes.rb +16 -0
  20. data/lib/mongo/message/query_message.rb +67 -0
  21. data/lib/mongo/message/remove_message.rb +20 -0
  22. data/lib/mongo/message/update_message.rb +21 -0
  23. data/lib/mongo/message.rb +4 -0
  24. data/lib/mongo/mongo.rb +98 -0
  25. data/lib/mongo/query.rb +110 -0
  26. data/lib/mongo/types/binary.rb +34 -0
  27. data/lib/mongo/types/dbref.rb +37 -0
  28. data/lib/mongo/types/objectid.rb +137 -0
  29. data/lib/mongo/types/regexp_of_holding.rb +44 -0
  30. data/lib/mongo/types/undefined.rb +31 -0
  31. data/lib/mongo/util/bson.rb +431 -0
  32. data/lib/mongo/util/byte_buffer.rb +163 -0
  33. data/lib/mongo/util/ordered_hash.rb +68 -0
  34. data/lib/mongo/util/xml_to_ruby.rb +102 -0
  35. data/lib/mongo.rb +12 -0
  36. data/mongo-ruby-driver.gemspec +62 -0
  37. data/tests/test_admin.rb +60 -0
  38. data/tests/test_bson.rb +135 -0
  39. data/tests/test_byte_buffer.rb +69 -0
  40. data/tests/test_cursor.rb +66 -0
  41. data/tests/test_db.rb +85 -0
  42. data/tests/test_db_api.rb +354 -0
  43. data/tests/test_db_connection.rb +17 -0
  44. data/tests/test_message.rb +35 -0
  45. data/tests/test_objectid.rb +98 -0
  46. data/tests/test_ordered_hash.rb +85 -0
  47. data/tests/test_round_trip.rb +116 -0
  48. metadata +100 -0
data/README.rdoc ADDED
@@ -0,0 +1,216 @@
1
+ = Introduction
2
+
3
+ This is a Ruby driver for the 10gen Mongo DB. For more information about
4
+ Mongo, see http://www.mongodb.org.
5
+
6
+ Note: this driver is still alpha quality. The API will change, as *may* the
7
+ data saved to the database (especially primary key values). Do *_not_* use
8
+ this for any production data yet.
9
+
10
+ Start by reading the XGen::Mongo::Driver::Mongo and XGen::Mongo::Driver::DB
11
+ documentation, then move on to XGen::Mongo::Driver::Collection and
12
+ XGen::Mongo::Driver::Cursor.
13
+
14
+ A quick code sample:
15
+
16
+ require 'mongo'
17
+
18
+ include XGen::Mongo::Driver
19
+
20
+ db = Mongo.new('localhost').db('sample-db')
21
+ coll = db.collection('test')
22
+
23
+ coll.clear
24
+ 3.times { |i| coll.insert({'a' => i+1}) }
25
+ puts "There are #{coll.count()} records. Here they are:"
26
+ coll.find().each { |doc| puts doc.inspect }
27
+
28
+ = Installation
29
+
30
+ Install the "mongo" gem by typing
31
+
32
+ $ gem sources -a http://gems.github.com
33
+ $ sudo gem install mongodb-mongo-ruby-driver
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
+
43
+ = Demo
44
+
45
+ You can see and run the examples if you've downloaded the source. Mongo must
46
+ be running, of course.
47
+
48
+ $ ruby examples/simple.rb
49
+
50
+ See also the test code, especially tests/test_db_api.rb.
51
+
52
+
53
+ = Notes
54
+
55
+ == String Encoding
56
+
57
+ The BSON ("Binary JSON") format used to communicate with Mongo requires that
58
+ strings be UTF-8 (http://en.wikipedia.org/wiki/UTF-8).
59
+
60
+ Ruby 1.9 has built-in character encoding support. All strings sent to Mongo
61
+ and received from Mongo are converted to UTF-8 when necessary, and strings
62
+ read from Mongo will have their character encodings set to UTF-8.
63
+
64
+ When used with Ruby 1.8, the bytes in each string are written to and read from
65
+ Mongo as-is. If the string is ASCII all is well, because ASCII is a subset of
66
+ UTF-8. If the string is not ASCII then it may not be a well-formed UTF-8
67
+ string.
68
+
69
+ == The DB class
70
+
71
+ === Primary Key Factories
72
+
73
+ A basic Mongo driver is not responsible for creating primary keys or knowing
74
+ how to interpret them. You can tell the Ruby Mongo driver how to create
75
+ primary keys by passing in the :pk option to the Mongo#db method.
76
+
77
+ include XGen::Mongo::Driver
78
+ db = Mongo.new.db('dbname', :pk => MyPKFactory)
79
+
80
+ A primary key factory object must respond to :create_pk, which should take a
81
+ hash and return a hash which merges the original hash with any primary key
82
+ fields the factory wishes to inject. NOTE: if the object already has a primary
83
+ key, the factory should not inject a new key; this means that the object is
84
+ being used in a repsert but it already exists. The idea here is that when ever
85
+ a record is inserted, the :pk object's +create_pk+ method will be called and
86
+ the new hash returned will be inserted.
87
+
88
+ Here is a sample primary key factory, taken from the tests:
89
+
90
+ class TestPKFactory
91
+ def create_pk(row)
92
+ row['_id'] ||= XGen::Mongo::Driver::ObjectID.new
93
+ row
94
+ end
95
+ end
96
+
97
+ A database's PK factory object may be changed, but this is not recommended.
98
+ The only reason it is changeable is so that libraries such as MongoRecord that
99
+ use this driver can set the PK factory after obtaining the database but before
100
+ using it for the first time.
101
+
102
+ === Strict mode
103
+
104
+ Each database has an optional strict mode. If strict mode is on, then asking
105
+ for a collection that does not exist will raise an error, as will asking to
106
+ create a collection that already exists. Note that both these operations are
107
+ completely harmless; strict mode is a programmer convenience only.
108
+
109
+ To turn on strict mode, either pass in :strict => true when obtaining a DB
110
+ object or call the :strict= method:
111
+
112
+ db = XGen::Mongo::Driver::Mongo.new.db('dbname', :strict => true)
113
+ # I'm feeling lax
114
+ db.strict = false
115
+ # No, I'm not!
116
+ db.strict = true
117
+
118
+ The method DB#strict? returns the current value of that flag.
119
+
120
+
121
+ = Testing
122
+
123
+ If you have the source code, you can run the tests.
124
+
125
+ $ rake test
126
+
127
+ The tests assume that the Mongo database is running on the default port.
128
+
129
+ The project mongo-qa (http://github.com/mongodb/mongo-qa) contains many more
130
+ Mongo driver tests that are language independent. To run thoses tests as part
131
+ of the "rake test" task, run
132
+
133
+ $ rake mongo_qa
134
+ $ rake test
135
+
136
+ The mongo_qa task uses the "git clone" command to make a copy of that project
137
+ in a directory named mongo-qa. If the directory already exists, then the
138
+ mongo_qa task uses "git pull" to updated the code that's there. The Ruby
139
+ driver tests will then use some of the data files from that project when it
140
+ runs BSON tests. You can delete this directory at any time if you don't want
141
+ to run those tests any more.
142
+
143
+ Additionally, the script bin/validate is used by the mongo-qa project's
144
+ validator script.
145
+
146
+
147
+ = Documentation
148
+
149
+ This documentation is available online at http://mongo.rubyforge.org. You can
150
+ generate the documentation if you have the source by typing
151
+
152
+ $ rake rdoc
153
+
154
+ Then open the file html/index.html.
155
+
156
+
157
+ = Release Notes
158
+
159
+ See the git log comments.
160
+
161
+
162
+ = To Do
163
+
164
+ * Add group_by. Need to figure out how we are going to send functions. The
165
+ current thinking is that Mongo will allow a subset of JavaScript (which we
166
+ would have to send as a string), but this is still under discussion.
167
+
168
+ * Tests for update and repsert.
169
+
170
+ * Add a way to specify a collection of databases on startup (a simple array of
171
+ IP address/port numbers, perhaps, or a hash or something). The driver would
172
+ then find the master and, on each subsequent command, ask that machine if it
173
+ is the master before proceeding.
174
+
175
+ * Introduce optional per-database and per-collection PKInjector.
176
+
177
+ * More tests.
178
+
179
+ == Optimizations
180
+
181
+ * Only update message sizes once, not after every write of a value. This will
182
+ require an explicit call to update_message_length in each message subclass.
183
+
184
+ * ensure_index commands should be cached to prevent excessive communication
185
+ with the database. (Or, the driver user should be informed that ensure_index
186
+ is not a lightweight operation for the particular driver.)
187
+
188
+
189
+ = Credits
190
+
191
+ Adrian Madrid, aemadrid@gmail.com
192
+ * bin/mongo_console
193
+ * examples/benchmarks.rb
194
+ * examples/irb.rb
195
+ * Modifications to examples/simple.rb
196
+ * Found plenty of bugs and missing features.
197
+ * Ruby 1.9 support.
198
+ * Gem support.
199
+ * Many other code suggestions and improvements.
200
+
201
+
202
+ = License
203
+
204
+ Copyright (C) 2008-2009 10gen Inc.
205
+
206
+ This program is free software: you can redistribute it and/or modify it under
207
+ the terms of the GNU Affero General Public License, version 3, as published by
208
+ the Free Software Foundation.
209
+
210
+ This program is distributed in the hope that it will be useful, but WITHOUT
211
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
212
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
213
+ details.
214
+
215
+ See http://www.gnu.org/licenses for a copy of the GNU Affero General Public
216
+ License.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rubygems/specification'
3
+ require 'fileutils'
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ # NOTE: some of the tests assume Mongo is running
10
+ Rake::TestTask.new do |t|
11
+ t.test_files = FileList['tests/test*.rb']
12
+ end
13
+
14
+ desc "Clone or pull (update) the mongo-qa project used for testing"
15
+ task :mongo_qa do
16
+ if File.exist?('mongo-qa')
17
+ Dir.chdir('mongo-qa') do
18
+ system('git pull')
19
+ end
20
+ else
21
+ system('git clone git://github.com/mongodb/mongo-qa.git')
22
+ end
23
+ end
24
+
25
+ desc "Generate documentation"
26
+ task :rdoc do
27
+ FileUtils.rm_rf('html')
28
+ system "rdoc --main README.rdoc --op html --inline-source --quiet README.rdoc `find lib -name '*.rb'`"
29
+ end
30
+
31
+ desc "Publish documentation to mongo.rubyforge.org"
32
+ task :publish => [:rdoc] do
33
+ # Assumes docs are in ./html
34
+ Rake::RubyForgePublisher.new(GEM, RUBYFORGE_USER).upload
35
+ end
36
+
37
+ namespace :gem do
38
+
39
+ desc "Install the gem locally"
40
+ task :install do
41
+ sh <<EOS
42
+ gem build mongo-ruby-driver.gemspec &&
43
+ sudo gem install mongo-*.gem &&
44
+ rm mongo-*.gem
45
+ EOS
46
+ end
47
+
48
+ end
49
+
50
+ task :default => :list
51
+
52
+ task :list do
53
+ system 'rake -T'
54
+ end
data/bin/mongo_console ADDED
@@ -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__)
data/bin/validate ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # usage: validate somefile.xson somefile.bson
4
+ #
5
+ # Reads somefile.xson file (XML that describes a Mongo-type document),
6
+ # converts it into a Ruby OrderedHash, runs that through the BSON
7
+ # serialization code, and writes the BSON bytes to somefile.bson.
8
+ #
9
+ # In addition, this script takes the generated BSON, reads it in then writes
10
+ # it back out to a temp BSON file. If they are different, we report that error
11
+ # to STDOUT.
12
+ #
13
+ # This script is used by the mongo-qa project
14
+ # (http://github.com/mongodb/mongo-qa).
15
+
16
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
17
+ require 'mongo'
18
+ require 'mongo/util/xml_to_ruby'
19
+
20
+ if ARGV.length < 2
21
+ $stderr.puts "usage: validate somefile.xson somefile.bson"
22
+ exit 1
23
+ end
24
+
25
+ # Translate the .xson XML into a Ruby object, turn that object into BSON, and
26
+ # write the BSON to the file as requested.
27
+ obj = File.open(ARGV[0], 'rb') { |f| XMLToRuby.new.xml_to_ruby(f) }
28
+ bson = BSON.new.serialize(obj).to_a
29
+ File.open(ARGV[1], 'wb') { |f| bson.each { |b| f.putc(b) } }
30
+
31
+ # Now the additional testing. Read the generated BSON back in, deserialize it,
32
+ # and re-serialize the results. Compare that BSON with the BSON from the file
33
+ # we output.
34
+ bson = File.open(ARGV[1], 'rb') { |f| f.read }
35
+ bson = if RUBY_VERSION >= '1.9'
36
+ bson.bytes.to_a
37
+ else
38
+ bson.split(//).collect { |c| c[0] }
39
+ end
40
+
41
+ # Turn the Ruby object into BSON bytes and compare with the BSON bytes from
42
+ # the file.
43
+ bson_from_ruby = BSON.new.serialize(obj).to_a
44
+
45
+ if bson.length != bson_from_ruby.length
46
+ $stderr.puts "error: round-trip BSON lengths differ when testing #{ARGV[0]}"
47
+ exit 1
48
+ elsif bson != bson_from_ruby
49
+ $stderr.puts "error: round-trip BSON contents differ when testing #{ARGV[0]}"
50
+ exit 1
51
+ end
@@ -0,0 +1,38 @@
1
+ require "rubygems"
2
+ require "benchmark"
3
+
4
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
5
+ require 'mongo'
6
+
7
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
8
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
9
+
10
+ puts "Connecting to #{host}:#{port}"
11
+ db = XGen::Mongo::Driver::Mongo.new(host, port).db('ruby-mongo-examples-complex')
12
+ coll = db.collection('test')
13
+ coll.clear
14
+
15
+ OBJS_COUNT = 100
16
+ TEST_COUNT = 100
17
+
18
+ puts "Generating benchmark data"
19
+ msgs = %w{hola hello aloha ciao}
20
+ arr = OBJS_COUNT.times.map {|x| { :number => x, :rndm => (rand(5)+1), :msg => msgs[rand(4)] }}
21
+
22
+ puts "Running benchmark"
23
+ Benchmark.bmbm do |results|
24
+ results.report("single object inserts: ") {
25
+ TEST_COUNT.times {
26
+ coll.clear
27
+ arr.each {|x| coll.insert(x)}
28
+ }
29
+ }
30
+ results.report("multiple object insert: ") {
31
+ TEST_COUNT.times {
32
+ coll.clear
33
+ coll.insert(arr)
34
+ }
35
+ }
36
+ end
37
+
38
+ coll.clear
data/examples/blog.rb ADDED
@@ -0,0 +1,76 @@
1
+ require "rubygems"
2
+
3
+ class Exception
4
+ def errmsg
5
+ "%s: %s\n%s" % [self.class, message, (backtrace || []).join("\n") << "\n"]
6
+ end
7
+ end
8
+
9
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
10
+ require 'mongo'
11
+
12
+ include XGen::Mongo::Driver
13
+
14
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
15
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
16
+
17
+ puts ">> Connecting to #{host}:#{port}"
18
+ DB = Mongo.new(host, port).db('ruby-mongo-blog')
19
+
20
+ LINE_SIZE = 120
21
+ puts "=" * LINE_SIZE
22
+ puts "Adding authors"
23
+ authors = DB.collection "authors"
24
+ authors.clear
25
+ authors.create_index "meta", '_id' => 1, 'name' => 1, 'age' => 1
26
+ puts "-" * LINE_SIZE
27
+ shaksp = authors << { :name => "William Shakespeare", :email => "william@shakespeare.com", :age => 587 }
28
+ puts "shaksp : #{shaksp.inspect}"
29
+ borges = authors << { :name => "Jorge Luis Borges", :email => "jorge@borges.com", :age => 123 }
30
+ puts "borges : #{borges.inspect}"
31
+ puts "-" * LINE_SIZE
32
+ puts "authors ordered by age ascending"
33
+ puts "-" * LINE_SIZE
34
+ authors.find({}, :sort => [{'age' => 1}]).each {|x| puts "%-25.25s : %-25.25s : %3i" % [x['name'], x['email'], x['age']]}
35
+
36
+ puts "=" * LINE_SIZE
37
+ puts "Adding users"
38
+ users = DB.collection "users"
39
+ users.clear
40
+ # users.create_index "meta", :_id => 1, :login => 1, :name => 1
41
+ puts "-" * LINE_SIZE
42
+ jdoe = users << { :login => "jdoe", :name => "John Doe", :email => "john@doe.com" }
43
+ puts "jdoe : #{jdoe.inspect}"
44
+ lsmt = users << { :login => "lsmith", :name => "Lucy Smith", :email => "lucy@smith.com" }
45
+ puts "lsmt : #{lsmt.inspect}"
46
+ puts "-" * LINE_SIZE
47
+ puts "users ordered by login ascending"
48
+ puts "-" * LINE_SIZE
49
+ users.find({}, :sort => [{'login' => 1}]).each {|x| puts "%-10.10s : %-25.25s : %-25.25s" % [x['login'], x['name'], x['email']]}
50
+
51
+ puts "=" * LINE_SIZE
52
+ puts "Adding articles"
53
+ articles = DB.collection "articles"
54
+ articles.clear
55
+ # articles.create_index "meta", :_id => 1, :author_id => 1, :title => 1
56
+ puts "-" * LINE_SIZE
57
+ begin
58
+ art1 = articles << { :title => "Caminando por Buenos Aires", :body => "Las callecitas de Buenos Aires tienen ese no se que...", :author_id => borges["_id"].to_s }
59
+ puts "art1 : #{art1.inspect}"
60
+ rescue => e
61
+ puts "Error: #{e.errmsg}"
62
+ end
63
+ begin
64
+ art2 = articles << { :title => "I must have seen thy face before", :body => "Thine eyes call me in a new way", :author_id => shaksp["_id"].to_s, :comments => [ { :user_id => jdoe["_id"].to_s, :body => "great article!" } ] }
65
+ puts "art2 : #{art2.inspect}"
66
+ rescue => e
67
+ puts "Error: #{e.errmsg}"
68
+ end
69
+ puts "-" * LINE_SIZE
70
+ puts "articles ordered by title ascending"
71
+ puts "-" * LINE_SIZE
72
+ articles.find({}, :sort => [{'title' => 1}]).each {|x| puts "%-25.25s : %-25.25s" % [x['title'], x['author_id']]}
73
+
74
+ puts ">> Closing connection"
75
+ DB.close
76
+ puts "closed"
@@ -0,0 +1,128 @@
1
+ require "rubygems"
2
+ require "benchwarmer"
3
+
4
+ class Exception
5
+ def errmsg
6
+ "%s: %s\n%s" % [self.class, message, (backtrace || []).join("\n") << "\n"]
7
+ end
8
+ end
9
+
10
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
11
+ require 'mongo'
12
+
13
+ include XGen::Mongo::Driver
14
+
15
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
16
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
17
+
18
+ puts ">> Connecting to #{host}:#{port}"
19
+ db = Mongo.new(host, port).db('ruby-mongo-index_test')
20
+
21
+ puts ">> Dropping collection test"
22
+ begin
23
+ res = db.drop_collection('test')
24
+ puts "dropped : #{res.inspect}"
25
+ rescue => e
26
+ puts "Error: #{e.errmsg}"
27
+ end
28
+
29
+ puts ">> Creating collection test"
30
+ begin
31
+ coll = db.collection('test')
32
+ puts "created : #{coll.inspect}"
33
+ rescue => e
34
+ puts "Error: #{e.errmsg}"
35
+ end
36
+
37
+ OBJS_COUNT = 100
38
+
39
+ puts ">> Generating test data"
40
+ msgs = %w{hola hello aloha ciao}
41
+ arr = OBJS_COUNT.times.map {|x| { :number => x, :rndm => (rand(5)+1), :msg => msgs[rand(4)] }}
42
+ puts "generated"
43
+
44
+ puts ">> Inserting data (#{arr.size})"
45
+ coll.insert(arr)
46
+ puts "inserted"
47
+
48
+ puts ">> Creating index"
49
+ res = coll.create_index "all", :_id => 1, :number => 1, :rndm => 1, :msg => 1
50
+ # res = coll.create_index "all", '_id' => 1, 'number' => 1, 'rndm' => 1, 'msg' => 1
51
+ puts "created index: #{res.inspect}"
52
+ # ============================ Mongo Log ============================
53
+ # Fri Dec 5 14:45:02 Adding all existing records for ruby-mongo-console.test to new index
54
+ # ***
55
+ # Bad data or size in BSONElement::size()
56
+ # bad type:30
57
+ # totalsize:11 fieldnamesize:4
58
+ # lastrec:
59
+ # Fri Dec 5 14:45:02 ruby-mongo-console.system.indexes Assertion failure false jsobj.cpp a0
60
+ # Fri Dec 5 14:45:02 database: ruby-mongo-console op:7d2 0
61
+ # Fri Dec 5 14:45:02 ns: ruby-mongo-console.system.indexes
62
+
63
+ puts ">> Gathering index information"
64
+ begin
65
+ res = coll.index_information
66
+ puts "index_information : #{res.inspect}"
67
+ rescue => e
68
+ puts "Error: #{e.errmsg}"
69
+ end
70
+ # ============================ Console Output ============================
71
+ # RuntimeError: Keys for index on return from db was nil. Coll = ruby-mongo-console.test
72
+ # from ./bin/../lib/mongo/db.rb:135:in `index_information'
73
+ # from (irb):11:in `collect'
74
+ # from ./bin/../lib/mongo/cursor.rb:47:in `each'
75
+ # from ./bin/../lib/mongo/db.rb:130:in `collect'
76
+ # from ./bin/../lib/mongo/db.rb:130:in `index_information'
77
+ # from ./bin/../lib/mongo/collection.rb:74:in `index_information'
78
+ # from (irb):11
79
+
80
+ puts ">> Dropping index"
81
+ begin
82
+ res = coll.drop_index "all"
83
+ puts "dropped : #{res.inspect}"
84
+ rescue => e
85
+ puts "Error: #{e.errmsg}"
86
+ end
87
+
88
+ # ============================ Console Output ============================
89
+ # => {"nIndexesWas"=>2.0, "ok"=>1.0}
90
+ # ============================ Mongo Log ============================
91
+ # 0x41802a 0x411549 0x42bac6 0x42c1f6 0x42c55b 0x42e6f7 0x41631e 0x41a89d 0x41ade2 0x41b448 0x4650d2 0x4695ad
92
+ # db/db(_Z12sayDbContextPKc+0x17a) [0x41802a]
93
+ # db/db(_Z8assertedPKcS0_j+0x9) [0x411549]
94
+ # db/db(_ZNK11BSONElement4sizeEv+0x1f6) [0x42bac6]
95
+ # db/db(_ZN7BSONObj8getFieldEPKc+0xa6) [0x42c1f6]
96
+ # db/db(_ZN7BSONObj14getFieldDottedEPKc+0x11b) [0x42c55b]
97
+ # db/db(_ZN7BSONObj19extractFieldsDottedES_R14BSONObjBuilder+0x87) [0x42e6f7]
98
+ # db/db(_ZN12IndexDetails17getKeysFromObjectER7BSONObjRSt3setIS0_St4lessIS0_ESaIS0_EE+0x24e) [0x41631e]
99
+ # db/db(_Z12_indexRecordR12IndexDetailsR7BSONObj7DiskLoc+0x5d) [0x41a89d]
100
+ # db/db(_Z18addExistingToIndexPKcR12IndexDetails+0xb2) [0x41ade2]
101
+ # db/db(_ZN11DataFileMgr6insertEPKcPKvib+0x508) [0x41b448]
102
+ # db/db(_Z14receivedInsertR7MessageRSt18basic_stringstreamIcSt11char_traitsIcESaIcEE+0x112) [0x4650d2]
103
+ # db/db(_Z10connThreadv+0xb4d) [0x4695ad]
104
+ # Fri Dec 5 14:45:02 ruby-mongo-console.system.indexes Caught Assertion insert, continuing
105
+ # Fri Dec 5 14:47:59 CMD: deleteIndexes ruby-mongo-console.test
106
+ # d->nIndexes was 2
107
+ # alpha implementation, space not reclaimed
108
+
109
+ puts ">> Gathering index information"
110
+ begin
111
+ res = coll.index_information
112
+ puts "index_information : #{res.inspect}"
113
+ rescue => e
114
+ puts "Error: #{e.errmsg}"
115
+ end
116
+ # ============================ Console Output ============================
117
+ # RuntimeError: Keys for index on return from db was nil. Coll = ruby-mongo-console.test
118
+ # from ./bin/../lib/mongo/db.rb:135:in `index_information'
119
+ # from (irb):15:in `collect'
120
+ # from ./bin/../lib/mongo/cursor.rb:47:in `each'
121
+ # from ./bin/../lib/mongo/db.rb:130:in `collect'
122
+ # from ./bin/../lib/mongo/db.rb:130:in `index_information'
123
+ # from ./bin/../lib/mongo/collection.rb:74:in `index_information'
124
+ # from (irb):15
125
+
126
+ puts ">> Closing connection"
127
+ db.close
128
+ puts "closed"
@@ -0,0 +1,17 @@
1
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'mongo'
3
+
4
+ include XGen::Mongo::Driver
5
+
6
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
7
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || XGen::Mongo::Driver::Mongo::DEFAULT_PORT
8
+
9
+ puts "Connecting to #{host}:#{port}"
10
+ db = Mongo.new(host, port).db('ruby-mongo-examples-simple')
11
+ coll = db.collection('test')
12
+ coll.clear
13
+
14
+ 3.times { |i| coll.insert({'a' => i+1}) }
15
+
16
+ puts "There are #{coll.count()} records in the test collection. Here they are:"
17
+ coll.find().each { |doc| puts doc.inspect }
@@ -0,0 +1,86 @@
1
+ # --
2
+ # Copyright (C) 2008-2009 10gen Inc.
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.
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.
12
+ #
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/>.
15
+ # ++
16
+
17
+ require 'mongo/util/ordered_hash'
18
+
19
+ module XGen
20
+ module Mongo
21
+ module Driver
22
+
23
+ # Provide administrative database methods: those having to do with
24
+ # profiling and validation.
25
+ class Admin
26
+
27
+ def initialize(db)
28
+ @db = db
29
+ end
30
+
31
+ # Return the current database profiling level.
32
+ def profiling_level
33
+ oh = OrderedHash.new
34
+ oh[:profile] = -1
35
+ doc = @db.db_command(oh)
36
+ raise "Error with profile command: #{doc.inspect}" unless @db.ok?(doc) && doc['was'].kind_of?(Numeric)
37
+ case doc['was'].to_i
38
+ when 0
39
+ :off
40
+ when 1
41
+ :slow_only
42
+ when 2
43
+ :all
44
+ else
45
+ raise "Error: illegal profiling level value #{doc['was']}"
46
+ end
47
+ end
48
+
49
+ # Set database profiling level to :off, :slow_only, or :all.
50
+ def profiling_level=(level)
51
+ oh = OrderedHash.new
52
+ oh[:profile] = case level
53
+ when :off
54
+ 0
55
+ when :slow_only
56
+ 1
57
+ when :all
58
+ 2
59
+ else
60
+ raise "Error: illegal profiling level value #{level}"
61
+ end
62
+ doc = @db.db_command(oh)
63
+ raise "Error with profile command: #{doc.inspect}" unless @db.ok?(doc)
64
+ end
65
+
66
+ # Return an array contining current profiling information from the
67
+ # database.
68
+ def profiling_info
69
+ @db.query(Collection.new(@db, DB::SYSTEM_PROFILE_COLLECTION), Query.new({})).to_a
70
+ end
71
+
72
+ # Validate a named collection by raising an exception if there is a
73
+ # problem or returning +true+ if all is well.
74
+ def validate_collection(name)
75
+ doc = @db.db_command(:validate => name)
76
+ raise "Error with validate command: #{doc.inspect}" unless @db.ok?(doc)
77
+ result = doc['result']
78
+ raise "Error with validation data: #{doc.inspect}" unless result.kind_of?(String)
79
+ raise "Error: invalid collection #{name}: #{doc.inspect}" if result =~ /\b(exception|corrupt)\b/i
80
+ true
81
+ end
82
+
83
+ end
84
+ end
85
+ end
86
+ end