mongo 0.0.1

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.
@@ -0,0 +1,134 @@
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
+ $ sudo gem install mongo
33
+
34
+ The source code is available at http://github.com/jimm/mongo-ruby-driver. You
35
+ can either clone the git repository or download a tarball or zip file. Once
36
+ you have the source, you can use it from wherever you downloaded it or you can
37
+ install it as a gem from the source by typing
38
+
39
+ $ rake gem:install
40
+
41
+
42
+ = Demo
43
+
44
+ You can see and run the examples if you've downloaded the source. Mongo must
45
+ be running, of course.
46
+
47
+ $ ruby examples/simple.rb
48
+
49
+ See also the test code, especially tests/test_db_api.rb.
50
+
51
+
52
+ = Testing
53
+
54
+ If you have the source code, you can run the tests.
55
+
56
+ $ rake test
57
+
58
+ The tests assume that the Mongo database is running on the default port.
59
+
60
+
61
+ = Documentation
62
+
63
+ This documentation is available online at http://mongo.rubyforge.org. You can
64
+ generate the documentation if you have the source by typing
65
+
66
+ $ rake rdoc
67
+
68
+ Then open the file html/index.html.
69
+
70
+
71
+ = Release Notes
72
+
73
+ See the git log comments.
74
+
75
+
76
+ = To Do
77
+
78
+ * Add group_by. Need to figure out how we are going to send functions. The
79
+ current thinking is that Mongo will allow a subset of JavaScript (which we
80
+ would have to send as a string), but this is still under discussion.
81
+
82
+ * Add explain and hint support.
83
+
84
+ * Only update message sizes once, not after every write of a value. This will
85
+ require an explicit call to update_message_length in each message subclass.
86
+
87
+ * Tests for update and repsert.
88
+
89
+ * Add a way to specify a collection of databases on startup (a simple array of
90
+ IP address/port numbers, perhaps, or a hash or something). The driver would
91
+ then find the master and, on each subsequent command, ask that machine if it
92
+ is the master before proceeding.
93
+
94
+ * Tests that prove that this driver's ObjectID and Geir's Java version do the
95
+ same thing. (I've done so manually.)
96
+
97
+ * Support more types: REF, SYMBOL, CODE_W_SCOPE, etc.
98
+
99
+ * Introduce optional per-database and per-collection PKInjector.
100
+
101
+ * More tests.
102
+
103
+ * Study src/main/ed/db/{dbcollection,dbcursor,db}.js and ByteEncoder.java in
104
+ the Babble code. That's what I should be writing to.
105
+
106
+
107
+ = Credits
108
+
109
+ Adrian Madrid, aemadrid@gmail.com
110
+ * bin/mongo_console
111
+ * examples/benchmarks.rb
112
+ * examples/irb.rb
113
+ * Modifications to examples/simple.rb
114
+ * Found plenty of bugs and missing features.
115
+ * Ruby 1.9 support.
116
+ * Gem support.
117
+ * Many other code suggestions and improvements.
118
+
119
+
120
+ = License
121
+
122
+ Copyright (C) 2008-2009 10gen Inc.
123
+
124
+ This program is free software: you can redistribute it and/or modify it under
125
+ the terms of the GNU Affero General Public License, version 3, as published by
126
+ the Free Software Foundation.
127
+
128
+ This program is distributed in the hope that it will be useful, but WITHOUT
129
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
130
+ FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
131
+ details.
132
+
133
+ See http://www.gnu.org/licenses for a copy of the GNU Affero General Public
134
+ License.
@@ -0,0 +1,86 @@
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
+ GEM = "mongo"
10
+ GEM_VERSION = '0.0.1'
11
+ SUMMARY = 'Simple pure-Ruby driver for the 10gen Mongo DB'
12
+ DESCRIPTION = 'This is a simple pure-Ruby driver for the 10gen Mongo DB. For more information about Mongo, see http://www.mongodb.org.'
13
+ AUTHOR = 'Jim Menard'
14
+ EMAIL = 'jimm@io.com'
15
+ HOMEPAGE = 'http://www.mongodb.org'
16
+ RUBYFORGE_USER = 'jimm'
17
+
18
+ spec = Gem::Specification.new do |s|
19
+ s.name = GEM
20
+ s.version = GEM_VERSION
21
+ s.platform = Gem::Platform::RUBY
22
+ s.summary = SUMMARY
23
+ s.description = DESCRIPTION
24
+
25
+ s.require_paths = ['lib']
26
+
27
+ s.files = FileList['bin/*', 'lib/**/*.rb', 'tests/**/*.rb', '[A-Z]*'].to_a
28
+
29
+ s.bindir = 'bin'
30
+ s.executables = %w( mongo_console )
31
+ s.has_rdoc = true
32
+
33
+ s.author = AUTHOR
34
+ s.email = EMAIL
35
+ s.homepage = HOMEPAGE
36
+
37
+ s.rubyforge_project = GEM # GitHub bug, gem isn't being build when this miss
38
+ end
39
+
40
+ # NOTE: some of the tests assume Mongo is running
41
+ Rake::TestTask.new do |t|
42
+ t.test_files = FileList['tests/test*.rb']
43
+ end
44
+
45
+ desc "Generate documentation"
46
+ task :rdoc do
47
+ FileUtils.rm_rf('html')
48
+ system "rdoc --main README.rdoc --op html --inline-source --quiet README.rdoc `find lib -name '*.rb'`"
49
+ end
50
+
51
+ desc "Publish documentation to mongo.rubyforge.org"
52
+ task :publish => [:rdoc] do
53
+ # Assumes docs are in ./html
54
+ Rake::RubyForgePublisher.new(GEM, RUBYFORGE_USER).upload
55
+ end
56
+
57
+ namespace :gem do
58
+
59
+ Rake::GemPackageTask.new(spec) do |pkg|
60
+ pkg.gem_spec = spec
61
+ end
62
+
63
+ desc "Install the gem locally"
64
+ task :install => [:package] do
65
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
66
+ end
67
+
68
+ desc "Install the gem locally with ruby 1.9"
69
+ task :'install19' => [:package] do
70
+ sh %{sudo gem19 install pkg/#{GEM}-#{GEM_VERSION}}
71
+ end
72
+
73
+ desc "Create a gemspec file"
74
+ task :make_spec do
75
+ File.open("#{GEM}.gemspec", "w") do |file|
76
+ file.puts spec.to_ruby
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ task :default => :list
83
+
84
+ task :list do
85
+ system 'rake -T'
86
+ end
@@ -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__)
@@ -0,0 +1,7 @@
1
+ require 'mongo/mongo'
2
+ require 'mongo/objectid'
3
+ require 'mongo/message'
4
+ require 'mongo/db'
5
+ require 'mongo/cursor'
6
+ require 'mongo/collection'
7
+ require 'mongo/admin'
@@ -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(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
@@ -0,0 +1,136 @@
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/query'
18
+
19
+ module XGen
20
+ module Mongo
21
+ module Driver
22
+
23
+ # A named collection of records in a database.
24
+ class Collection
25
+
26
+ attr_reader :db, :name
27
+
28
+ def initialize(db, name)
29
+ @db = db
30
+ @name = name
31
+ end
32
+
33
+ # Return records that match a +selector+ hash. See Mongo docs for
34
+ # details.
35
+ #
36
+ # Options:
37
+ # :fields :: Array of collection field names; only those will be returned (plus _id if defined)
38
+ # :offset :: Start at this record when returning records
39
+ # :limit :: Maximum number of records to return
40
+ # :sort :: Either hash of field names as keys and 1/-1 as values; 1 ==
41
+ # ascending, -1 == descending, or array of field names (all
42
+ # assumed to be sorted in ascending order).
43
+ def find(selector={}, options={})
44
+ fields = options.delete(:fields)
45
+ fields = nil if fields && fields.empty?
46
+ offset = options.delete(:offset) || 0
47
+ limit = options.delete(:limit) || 0
48
+ sort = options.delete(:sort)
49
+ raise RuntimeError, "Unknown options [#{options.inspect}]" unless options.empty?
50
+ @db.query(@name, Query.new(selector, fields, offset, limit, sort))
51
+ end
52
+
53
+ # Insert +objects+, which are hashes. "<<" is aliased to this method.
54
+ def insert(*objects)
55
+ objects = objects.first if objects.size == 1 && objects.first.is_a?(Array)
56
+ res = @db.insert_into_db(@name, objects)
57
+ res.size > 1 ? res : res.first
58
+ end
59
+ alias_method :<<, :insert
60
+
61
+ # Remove the records that match +selector+.
62
+ def remove(selector={})
63
+ @db.remove_from_db(@name, selector)
64
+ end
65
+
66
+ # Remove all records.
67
+ def clear
68
+ remove({})
69
+ end
70
+
71
+ # Update records that match +selector+ by applying +obj+ as an update.
72
+ # If no match, inserts (???).
73
+ def repsert(selector, obj)
74
+ @db.repsert_in_db(@name, selector, obj)
75
+ end
76
+
77
+ # Update records that match +selector+ by applying +obj+ as an update.
78
+ def replace(selector, obj)
79
+ @db.replace_in_db(@name, selector, obj)
80
+ end
81
+
82
+ # Update records that match +selector+ by applying +obj+ as an update.
83
+ # Both +selector+ and +modifier_obj+ are required.
84
+ def modify(selector, modifier_obj)
85
+ raise "no object" unless modifier_obj
86
+ raise "no selector" unless selector
87
+ @db.modify_in_db(@name, selector, modifier_obj)
88
+ end
89
+
90
+ # Create a new index named +index_name+. +fields+ should be an array
91
+ # of field names.
92
+ def create_index(name, *fields)
93
+ @db.create_index(@name, name, fields)
94
+ end
95
+
96
+ # Drop index +name+.
97
+ def drop_index(name)
98
+ @db.drop_index(@name, name)
99
+ end
100
+
101
+ # Drop all indexes.
102
+ def drop_indexes
103
+ # just need to call drop indexes with no args; will drop them all
104
+ @db.drop_index(@name, '*')
105
+ end
106
+
107
+ # Return an array of hashes, one for each index. Each hash contains:
108
+ #
109
+ # :name :: Index name
110
+ #
111
+ # :keys :: Hash whose keys are the names of the fields that make up
112
+ # the key and values are integers.
113
+ #
114
+ # :ns :: Namespace; same as this collection's name.
115
+ def index_information
116
+ @db.index_information(@name)
117
+ end
118
+
119
+ # Return a hash containing options that apply to this collection.
120
+ # 'create' will be the collection name. For the other possible keys
121
+ # and values, see DB#create_collection.
122
+ def options
123
+ @db.collections_info(@name).next_object()['options']
124
+ end
125
+
126
+ # Return the number of records that match +selector+. If +selector+ is
127
+ # +nil+ or an empty hash, returns the count of all records.
128
+ def count(selector={})
129
+ @db.count(@name, selector || {})
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+ end
136
+