jonbell-mongo 1.3.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/LICENSE.txt +190 -0
  2. data/README.md +333 -0
  3. data/Rakefile +215 -0
  4. data/bin/mongo_console +21 -0
  5. data/docs/CREDITS.md +123 -0
  6. data/docs/FAQ.md +116 -0
  7. data/docs/GridFS.md +158 -0
  8. data/docs/HISTORY.md +263 -0
  9. data/docs/RELEASES.md +33 -0
  10. data/docs/REPLICA_SETS.md +72 -0
  11. data/docs/TUTORIAL.md +247 -0
  12. data/docs/WRITE_CONCERN.md +28 -0
  13. data/lib/mongo.rb +97 -0
  14. data/lib/mongo/collection.rb +895 -0
  15. data/lib/mongo/connection.rb +926 -0
  16. data/lib/mongo/cursor.rb +474 -0
  17. data/lib/mongo/db.rb +617 -0
  18. data/lib/mongo/exceptions.rb +71 -0
  19. data/lib/mongo/gridfs/grid.rb +107 -0
  20. data/lib/mongo/gridfs/grid_ext.rb +57 -0
  21. data/lib/mongo/gridfs/grid_file_system.rb +146 -0
  22. data/lib/mongo/gridfs/grid_io.rb +485 -0
  23. data/lib/mongo/gridfs/grid_io_fix.rb +38 -0
  24. data/lib/mongo/repl_set_connection.rb +356 -0
  25. data/lib/mongo/util/conversions.rb +89 -0
  26. data/lib/mongo/util/core_ext.rb +60 -0
  27. data/lib/mongo/util/pool.rb +177 -0
  28. data/lib/mongo/util/server_version.rb +71 -0
  29. data/lib/mongo/util/support.rb +82 -0
  30. data/lib/mongo/util/uri_parser.rb +185 -0
  31. data/mongo.gemspec +34 -0
  32. data/test/auxillary/1.4_features.rb +166 -0
  33. data/test/auxillary/authentication_test.rb +68 -0
  34. data/test/auxillary/autoreconnect_test.rb +41 -0
  35. data/test/auxillary/fork_test.rb +30 -0
  36. data/test/auxillary/repl_set_auth_test.rb +58 -0
  37. data/test/auxillary/slave_connection_test.rb +36 -0
  38. data/test/auxillary/threaded_authentication_test.rb +101 -0
  39. data/test/bson/binary_test.rb +15 -0
  40. data/test/bson/bson_test.rb +654 -0
  41. data/test/bson/byte_buffer_test.rb +208 -0
  42. data/test/bson/hash_with_indifferent_access_test.rb +38 -0
  43. data/test/bson/json_test.rb +17 -0
  44. data/test/bson/object_id_test.rb +154 -0
  45. data/test/bson/ordered_hash_test.rb +210 -0
  46. data/test/bson/timestamp_test.rb +24 -0
  47. data/test/collection_test.rb +910 -0
  48. data/test/connection_test.rb +324 -0
  49. data/test/conversions_test.rb +119 -0
  50. data/test/cursor_fail_test.rb +75 -0
  51. data/test/cursor_message_test.rb +43 -0
  52. data/test/cursor_test.rb +483 -0
  53. data/test/db_api_test.rb +738 -0
  54. data/test/db_connection_test.rb +15 -0
  55. data/test/db_test.rb +315 -0
  56. data/test/grid_file_system_test.rb +259 -0
  57. data/test/grid_io_test.rb +209 -0
  58. data/test/grid_test.rb +258 -0
  59. data/test/load/thin/load.rb +24 -0
  60. data/test/load/unicorn/load.rb +23 -0
  61. data/test/replica_sets/connect_test.rb +112 -0
  62. data/test/replica_sets/connection_string_test.rb +32 -0
  63. data/test/replica_sets/count_test.rb +35 -0
  64. data/test/replica_sets/insert_test.rb +53 -0
  65. data/test/replica_sets/pooled_insert_test.rb +55 -0
  66. data/test/replica_sets/query_secondaries.rb +108 -0
  67. data/test/replica_sets/query_test.rb +51 -0
  68. data/test/replica_sets/replication_ack_test.rb +66 -0
  69. data/test/replica_sets/rs_test_helper.rb +27 -0
  70. data/test/safe_test.rb +68 -0
  71. data/test/support/hash_with_indifferent_access.rb +186 -0
  72. data/test/support/keys.rb +45 -0
  73. data/test/support_test.rb +18 -0
  74. data/test/test_helper.rb +102 -0
  75. data/test/threading/threading_with_large_pool_test.rb +90 -0
  76. data/test/threading_test.rb +87 -0
  77. data/test/tools/auth_repl_set_manager.rb +14 -0
  78. data/test/tools/repl_set_manager.rb +266 -0
  79. data/test/unit/collection_test.rb +130 -0
  80. data/test/unit/connection_test.rb +85 -0
  81. data/test/unit/cursor_test.rb +109 -0
  82. data/test/unit/db_test.rb +94 -0
  83. data/test/unit/grid_test.rb +49 -0
  84. data/test/unit/pool_test.rb +9 -0
  85. data/test/unit/repl_set_connection_test.rb +59 -0
  86. data/test/unit/safe_test.rb +125 -0
  87. data/test/uri_test.rb +91 -0
  88. metadata +224 -0
@@ -0,0 +1,130 @@
1
+ require './test/test_helper'
2
+
3
+ class CollectionTest < Test::Unit::TestCase
4
+
5
+ context "Basic operations: " do
6
+ setup do
7
+ @logger = mock()
8
+ @logger.expects(:debug)
9
+ end
10
+
11
+ should "send update message" do
12
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
13
+ @db = @conn['testing']
14
+ @coll = @db.collection('books')
15
+ @conn.expects(:send_message).with do |op, msg, log|
16
+ op == 2001
17
+ end
18
+ @conn.stubs(:log_operation)
19
+ @coll.update({}, {:title => 'Moby Dick'})
20
+ end
21
+
22
+ should "send insert message" do
23
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
24
+ @db = @conn['testing']
25
+ @coll = @db.collection('books')
26
+ @conn.expects(:send_message).with do |op, msg, log|
27
+ op == 2002
28
+ end
29
+ @conn.expects(:log_operation).with do |name, payload|
30
+ (name == :insert) && payload[:documents][0][:title].include?('Moby')
31
+ end
32
+ @coll.insert({:title => 'Moby Dick'})
33
+ end
34
+
35
+ should "send sort data" do
36
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
37
+ @db = @conn['testing']
38
+ @coll = @db.collection('books')
39
+ @conn.expects(:receive_message).with do |op, msg, log, sock|
40
+ op == 2004
41
+ end.returns([[], 0, 0])
42
+ @conn.expects(:log_operation).with do |name, payload|
43
+ (name == :find) && payload[:selector][:title].include?('Moby')
44
+ end
45
+ @coll.find({:title => 'Moby Dick'}).sort([['title', 1], ['author', 1]]).next_document
46
+ end
47
+
48
+ should "not log binary data" do
49
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
50
+ @db = @conn['testing']
51
+ @coll = @db.collection('books')
52
+ data = BSON::Binary.new(("BINARY " * 1000).unpack("c*"))
53
+ @conn.expects(:send_message).with do |op, msg, log|
54
+ op == 2002
55
+ end
56
+ @conn.expects(:log_operation).with do |name, payload|
57
+ (name == :insert) && payload[:documents][0][:data].inspect.include?('Binary')
58
+ end
59
+ @coll.insert({:data => data})
60
+ end
61
+
62
+ should "send safe update message" do
63
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
64
+ @db = @conn['testing']
65
+ @coll = @db.collection('books')
66
+ @conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
67
+ op == 2001
68
+ end
69
+ @conn.expects(:log_operation).with do |name, payload|
70
+ (name == :update) && payload[:document][:title].include?('Moby')
71
+ end
72
+ @coll.update({}, {:title => 'Moby Dick'}, :safe => true)
73
+ end
74
+
75
+ should "send safe insert message" do
76
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
77
+ @db = @conn['testing']
78
+ @coll = @db.collection('books')
79
+ @conn.expects(:send_message_with_safe_check).with do |op, msg, db_name, log|
80
+ op == 2001
81
+ end
82
+ @conn.stubs(:log_operation)
83
+ @coll.update({}, {:title => 'Moby Dick'}, :safe => true)
84
+ end
85
+
86
+ should "not call insert for each ensure_index call" do
87
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
88
+ @db = @conn['testing']
89
+ @coll = @db.collection('books')
90
+ @coll.expects(:generate_indexes).once
91
+
92
+ @coll.ensure_index [["x", Mongo::DESCENDING]]
93
+ @coll.ensure_index [["x", Mongo::DESCENDING]]
94
+ end
95
+
96
+ should "call generate_indexes for a new direction on the same field for ensure_index" do
97
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
98
+ @db = @conn['testing']
99
+ @coll = @db.collection('books')
100
+ @coll.expects(:generate_indexes).twice
101
+
102
+ @coll.ensure_index [["x", Mongo::DESCENDING]]
103
+ @coll.ensure_index [["x", Mongo::ASCENDING]]
104
+
105
+ end
106
+
107
+ should "call generate_indexes twice because the cache time is 0 seconds" do
108
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
109
+ @db = @conn['testing']
110
+ @db.cache_time = 0
111
+ @coll = @db.collection('books')
112
+ @coll.expects(:generate_indexes).twice
113
+
114
+ @coll.ensure_index [["x", Mongo::DESCENDING]]
115
+ @coll.ensure_index [["x", Mongo::DESCENDING]]
116
+ end
117
+
118
+ should "call generate_indexes for each key when calling ensure_indexes" do
119
+ @conn = Connection.new('localhost', 27017, :logger => @logger, :connect => false)
120
+ @db = @conn['testing']
121
+ @db.cache_time = 300
122
+ @coll = @db.collection('books')
123
+ @coll.expects(:generate_indexes).once.with do |a, b, c|
124
+ a == {"x"=>-1, "y"=>-1}
125
+ end
126
+
127
+ @coll.ensure_index [["x", Mongo::DESCENDING], ["y", Mongo::DESCENDING]]
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,85 @@
1
+ require './test/test_helper'
2
+ include Mongo
3
+
4
+ class ConnectionTest < Test::Unit::TestCase
5
+ context "Initialization: " do
6
+ context "given a single node" do
7
+ setup do
8
+ @conn = Connection.new('localhost', 27017, :connect => false)
9
+ TCPSocket.stubs(:new).returns(new_mock_socket)
10
+
11
+ admin_db = new_mock_db
12
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1}).twice
13
+ @conn.expects(:[]).with('admin').returns(admin_db).twice
14
+ @conn.connect
15
+ end
16
+
17
+ should "set localhost and port to master" do
18
+ assert_equal 'localhost', @conn.primary_pool.host
19
+ assert_equal 27017, @conn.primary_pool.port
20
+ end
21
+
22
+ should "set connection pool to 1" do
23
+ assert_equal 1, @conn.primary_pool.size
24
+ end
25
+
26
+ should "default slave_ok to false" do
27
+ assert !@conn.slave_ok?
28
+ end
29
+ end
30
+
31
+ context "initializing with a mongodb uri" do
32
+ should "parse a simple uri" do
33
+ @conn = Connection.from_uri("mongodb://localhost", :connect => false)
34
+ assert_equal ['localhost', 27017], @conn.host_to_try
35
+ end
36
+
37
+ should "allow a complex host names" do
38
+ host_name = "foo.bar-12345.org"
39
+ @conn = Connection.from_uri("mongodb://#{host_name}", :connect => false)
40
+ assert_equal [host_name, 27017], @conn.host_to_try
41
+ end
42
+
43
+ should "parse a uri with a hyphen & underscore in the username or password" do
44
+ @conn = Connection.from_uri("mongodb://hyphen-user_name:p-s_s@localhost:27017/db", :connect => false)
45
+ assert_equal ['localhost', 27017], @conn.host_to_try
46
+ auth_hash = { 'db_name' => 'db', 'username' => 'hyphen-user_name', "password" => 'p-s_s' }
47
+ assert_equal auth_hash, @conn.auths[0]
48
+ end
49
+
50
+ should "attempt to connect" do
51
+ TCPSocket.stubs(:new).returns(new_mock_socket)
52
+ @conn = Connection.from_uri("mongodb://localhost", :connect => false)
53
+
54
+ admin_db = new_mock_db
55
+ admin_db.expects(:command).returns({'ok' => 1, 'ismaster' => 1}).twice
56
+ @conn.expects(:[]).with('admin').returns(admin_db).twice
57
+ @conn.connect
58
+ end
59
+
60
+ should "raise an error on invalid uris" do
61
+ assert_raise MongoArgumentError do
62
+ Connection.from_uri("mongo://localhost", :connect => false)
63
+ end
64
+
65
+ assert_raise MongoArgumentError do
66
+ Connection.from_uri("mongodb://localhost:abc", :connect => false)
67
+ end
68
+
69
+ assert_raise MongoArgumentError do
70
+ Connection.from_uri("mongodb://localhost:27017, my.db.com:27018, ", :connect => false)
71
+ end
72
+ end
73
+
74
+ should "require all of username, password, and database if any one is specified" do
75
+ assert_raise MongoArgumentError do
76
+ Connection.from_uri("mongodb://localhost/db", :connect => false)
77
+ end
78
+
79
+ assert_raise MongoArgumentError do
80
+ Connection.from_uri("mongodb://kyle:password@localhost", :connect => false)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,109 @@
1
+ require './test/test_helper'
2
+
3
+ class CursorTest < Test::Unit::TestCase
4
+ context "Cursor options" do
5
+ setup do
6
+ @logger = mock()
7
+ @logger.stubs(:debug)
8
+ @connection = stub(:class => Connection, :logger => @logger)
9
+ @db = stub(:name => "testing", :slave_ok? => false, :connection => @connection)
10
+ @collection = stub(:db => @db, :name => "items")
11
+ @cursor = Cursor.new(@collection)
12
+ end
13
+
14
+ should "set timeout" do
15
+ assert @cursor.timeout
16
+ assert @cursor.query_options_hash[:timeout]
17
+ end
18
+
19
+ should "set selector" do
20
+ assert_equal({}, @cursor.selector)
21
+
22
+ @cursor = Cursor.new(@collection, :selector => {:name => "Jones"})
23
+ assert_equal({:name => "Jones"}, @cursor.selector)
24
+ assert_equal({:name => "Jones"}, @cursor.query_options_hash[:selector])
25
+ end
26
+
27
+ should "set fields" do
28
+ assert_nil @cursor.fields
29
+
30
+ @cursor = Cursor.new(@collection, :fields => [:name, :date])
31
+ assert_equal({:name => 1, :date => 1}, @cursor.fields)
32
+ assert_equal({:name => 1, :date => 1}, @cursor.query_options_hash[:fields])
33
+ end
34
+
35
+ should "set mix fields 0 and 1" do
36
+ assert_nil @cursor.fields
37
+
38
+ @cursor = Cursor.new(@collection, :fields => {:name => 1, :date => 0})
39
+ assert_equal({:name => 1, :date => 0}, @cursor.fields)
40
+ assert_equal({:name => 1, :date => 0}, @cursor.query_options_hash[:fields])
41
+ end
42
+
43
+ should "set limit" do
44
+ assert_equal 0, @cursor.limit
45
+
46
+ @cursor = Cursor.new(@collection, :limit => 10)
47
+ assert_equal 10, @cursor.limit
48
+ assert_equal 10, @cursor.query_options_hash[:limit]
49
+ end
50
+
51
+
52
+ should "set skip" do
53
+ assert_equal 0, @cursor.skip
54
+
55
+ @cursor = Cursor.new(@collection, :skip => 5)
56
+ assert_equal 5, @cursor.skip
57
+ assert_equal 5, @cursor.query_options_hash[:skip]
58
+ end
59
+
60
+ should "set sort order" do
61
+ assert_nil @cursor.order
62
+
63
+ @cursor = Cursor.new(@collection, :order => "last_name")
64
+ assert_equal "last_name", @cursor.order
65
+ assert_equal "last_name", @cursor.query_options_hash[:order]
66
+ end
67
+
68
+ should "set hint" do
69
+ assert_nil @cursor.hint
70
+
71
+ @cursor = Cursor.new(@collection, :hint => "name")
72
+ assert_equal "name", @cursor.hint
73
+ assert_equal "name", @cursor.query_options_hash[:hint]
74
+ end
75
+
76
+ should "cache full collection name" do
77
+ assert_equal "testing.items", @cursor.full_collection_name
78
+ end
79
+ end
80
+
81
+ context "Query fields" do
82
+ setup do
83
+ @logger = mock()
84
+ @logger.stubs(:debug)
85
+ @connection = stub(:class => Connection, :logger => @logger)
86
+ @db = stub(:slave_ok? => true, :name => "testing", :connection => @connection)
87
+ @collection = stub(:db => @db, :name => "items")
88
+ end
89
+
90
+ should "when an array should return a hash with each key" do
91
+ @cursor = Cursor.new(@collection, :fields => [:name, :age])
92
+ result = @cursor.fields
93
+ assert_equal result.keys.sort{|a,b| a.to_s <=> b.to_s}, [:age, :name].sort{|a,b| a.to_s <=> b.to_s}
94
+ assert result.values.all? {|v| v == 1}
95
+ end
96
+
97
+ should "when a string, return a hash with just the key" do
98
+ @cursor = Cursor.new(@collection, :fields => "name")
99
+ result = @cursor.fields
100
+ assert_equal result.keys.sort, ["name"]
101
+ assert result.values.all? {|v| v == 1}
102
+ end
103
+
104
+ should "return nil when neither hash nor string nor symbol" do
105
+ @cursor = Cursor.new(@collection, :fields => 1234567)
106
+ assert_nil @cursor.fields
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,94 @@
1
+ require './test/test_helper'
2
+
3
+ def insert_message(db, documents)
4
+ documents = [documents] unless documents.is_a?(Array)
5
+ message = ByteBuffer.new
6
+ message.put_int(0)
7
+ Mongo::BSON_CODER.serialize_cstr(message, "#{db.name}.test")
8
+ documents.each { |doc| message.put_array(Mongo::BSON_CODER.new.serialize(doc, true).to_a) }
9
+ message = db.add_message_headers(Mongo::Constants::OP_INSERT, message)
10
+ end
11
+
12
+ class DBTest < Test::Unit::TestCase
13
+ context "DBTest: " do
14
+ context "DB commands" do
15
+ setup do
16
+ @conn = stub()
17
+ @conn.stubs(:safe)
18
+ @db = DB.new("testing", @conn)
19
+ @db.stubs(:safe)
20
+ @collection = mock()
21
+ @db.stubs(:system_command_collection).returns(@collection)
22
+ end
23
+
24
+ should "raise an error if given a hash with more than one key" do
25
+ if RUBY_VERSION < '1.9'
26
+ assert_raise MongoArgumentError do
27
+ @db.command(:buildinfo => 1, :somekey => 1)
28
+ end
29
+ end
30
+ end
31
+
32
+ should "raise an error if the selector is omitted" do
33
+ assert_raise MongoArgumentError do
34
+ @db.command({}, :check_response => true)
35
+ end
36
+ end
37
+
38
+ should "create the proper cursor" do
39
+ @cursor = mock(:next_document => {"ok" => 1})
40
+ Cursor.expects(:new).with(@collection,
41
+ :limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
42
+ command = {:buildinfo => 1}
43
+ @db.command(command, :check_response => true)
44
+ end
45
+
46
+ should "raise an error when the command fails" do
47
+ @cursor = mock(:next_document => {"ok" => 0})
48
+ Cursor.expects(:new).with(@collection,
49
+ :limit => -1, :selector => {:buildinfo => 1}, :socket => nil).returns(@cursor)
50
+ assert_raise OperationFailure do
51
+ command = {:buildinfo => 1}
52
+ @db.command(command, :check_response => true)
53
+ end
54
+ end
55
+
56
+ should "raise an error if logging out fails" do
57
+ @db.expects(:command).returns({})
58
+ @conn.expects(:pool_size).returns(1)
59
+ assert_raise Mongo::MongoDBError do
60
+ @db.logout
61
+ end
62
+ end
63
+
64
+ should "raise an error if collection creation fails" do
65
+ @db.expects(:collection_names).returns([])
66
+ @db.expects(:command).returns({'ok' => 0})
67
+ assert_raise Mongo::MongoDBError do
68
+ @db.create_collection("foo")
69
+ end
70
+ end
71
+
72
+ should "raise an error if getlasterror fails" do
73
+ @db.expects(:command).returns({})
74
+ assert_raise Mongo::MongoDBError do
75
+ @db.get_last_error
76
+ end
77
+ end
78
+
79
+ should "raise an error if drop_index fails" do
80
+ @db.expects(:command).returns({})
81
+ assert_raise Mongo::MongoDBError do
82
+ @db.drop_index("foo", "bar")
83
+ end
84
+ end
85
+
86
+ should "raise an error if set_profiling_level fails" do
87
+ @db.expects(:command).returns({})
88
+ assert_raise Mongo::MongoDBError do
89
+ @db.profiling_level = :slow_only
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,49 @@
1
+ require './test/test_helper'
2
+
3
+ class GridTest < Test::Unit::TestCase
4
+
5
+ context "GridFS: " do
6
+ setup do
7
+ @conn = stub()
8
+ @conn.stubs(:safe)
9
+ @db = DB.new("testing", @conn)
10
+ @files = mock()
11
+ @chunks = mock()
12
+
13
+ @db.expects(:[]).with('fs.files').returns(@files)
14
+ @db.expects(:[]).with('fs.chunks').returns(@chunks)
15
+ @db.stubs(:safe)
16
+ end
17
+
18
+ context "Grid classe with standard connections" do
19
+ setup do
20
+ @conn.expects(:slave_ok?).returns(false)
21
+ end
22
+
23
+ should "create indexes for Grid" do
24
+ @chunks.expects(:create_index)
25
+ Grid.new(@db)
26
+ end
27
+
28
+ should "create indexes for GridFileSystem" do
29
+ @files.expects(:create_index)
30
+ @chunks.expects(:create_index)
31
+ GridFileSystem.new(@db)
32
+ end
33
+ end
34
+
35
+ context "Grid classes with slave connection" do
36
+ setup do
37
+ @conn.expects(:slave_ok?).returns(true)
38
+ end
39
+
40
+ should "not create indexes for Grid" do
41
+ Grid.new(@db)
42
+ end
43
+
44
+ should "not create indexes for GridFileSystem" do
45
+ GridFileSystem.new(@db)
46
+ end
47
+ end
48
+ end
49
+ end