mongo 1.12.5 → 2.0.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CONTRIBUTING.md +64 -0
- data/LICENSE +1 -1
- data/README.md +21 -126
- data/Rakefile +39 -21
- data/bin/mongo_console +6 -38
- data/lib/mongo/address/ipv4.rb +85 -0
- data/lib/mongo/address/ipv6.rb +85 -0
- data/lib/mongo/address/unix.rb +76 -0
- data/lib/mongo/address.rb +111 -0
- data/lib/mongo/auth/cr/conversation.rb +119 -0
- data/lib/mongo/auth/cr.rb +44 -0
- data/lib/mongo/auth/executable.rb +52 -0
- data/lib/mongo/auth/ldap/conversation.rb +92 -0
- data/lib/mongo/auth/ldap.rb +48 -0
- data/lib/mongo/auth/roles.rb +104 -0
- data/lib/mongo/auth/scram/conversation.rb +450 -0
- data/lib/mongo/auth/scram.rb +53 -0
- data/lib/mongo/auth/user/view.rb +102 -0
- data/lib/mongo/auth/user.rb +159 -0
- data/lib/mongo/auth/x509/conversation.rb +92 -0
- data/lib/mongo/auth/x509.rb +48 -0
- data/lib/mongo/auth.rb +108 -0
- data/lib/mongo/bulk_write/bulk_writable.rb +191 -0
- data/lib/mongo/bulk_write/deletable.rb +60 -0
- data/lib/mongo/bulk_write/insertable.rb +52 -0
- data/lib/mongo/bulk_write/ordered_bulk_write.rb +48 -0
- data/lib/mongo/bulk_write/replacable.rb +57 -0
- data/lib/mongo/bulk_write/unordered_bulk_write.rb +46 -0
- data/lib/mongo/bulk_write/updatable.rb +68 -0
- data/lib/mongo/bulk_write.rb +52 -0
- data/lib/mongo/client.rb +246 -0
- data/lib/mongo/cluster/topology/replica_set.rb +160 -0
- data/lib/mongo/cluster/topology/sharded.rb +132 -0
- data/lib/mongo/cluster/topology/standalone.rb +132 -0
- data/lib/mongo/cluster/topology/unknown.rb +155 -0
- data/lib/mongo/cluster/topology.rb +60 -0
- data/lib/mongo/cluster.rb +203 -0
- data/lib/mongo/collection/view/aggregation.rb +108 -0
- data/lib/mongo/collection/view/explainable.rb +49 -0
- data/lib/mongo/collection/view/immutable.rb +43 -0
- data/lib/mongo/collection/view/iterable.rb +48 -0
- data/lib/mongo/collection/view/map_reduce.rb +191 -0
- data/lib/mongo/collection/view/readable.rb +363 -0
- data/lib/mongo/collection/view/writable.rb +185 -0
- data/lib/mongo/collection/view.rb +169 -0
- data/lib/mongo/collection.rb +130 -1101
- data/lib/mongo/cursor.rb +78 -681
- data/lib/mongo/database/view.rb +101 -0
- data/lib/mongo/database.rb +224 -0
- data/lib/mongo/error/bulk_write_error.rb +41 -0
- data/lib/mongo/error/invalid_bulk_operation.rb +36 -0
- data/lib/mongo/error/invalid_bulk_operation_type.rb +36 -0
- data/lib/mongo/error/invalid_collection_name.rb +39 -0
- data/lib/mongo/error/invalid_database_name.rb +39 -0
- data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
- data/lib/mongo/error/invalid_file.rb +38 -0
- data/lib/mongo/error/invalid_nonce.rb +46 -0
- data/lib/mongo/error/invalid_replacement_document.rb +39 -0
- data/lib/mongo/error/invalid_signature.rb +47 -0
- data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
- data/lib/mongo/error/max_bson_size.rb +40 -0
- data/lib/mongo/error/max_message_size.rb +42 -0
- data/{test/functional/db_connection_test.rb → lib/mongo/error/multi_index_drop.rb} +17 -8
- data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
- data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
- data/lib/mongo/error/parser.rb +77 -0
- data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
- data/lib/mongo/error/socket_timeout_error.rb +23 -0
- data/lib/mongo/error/unsupported_features.rb +43 -0
- data/lib/mongo/error.rb +82 -0
- data/lib/mongo/event/listeners.rb +63 -0
- data/lib/mongo/event/primary_elected.rb +53 -0
- data/lib/mongo/event/publisher.rb +42 -0
- data/lib/mongo/event/server_added.rb +53 -0
- data/lib/mongo/event/server_removed.rb +53 -0
- data/lib/mongo/event/subscriber.rb +41 -0
- data/lib/mongo/event.rb +40 -0
- data/lib/mongo/grid/file/chunk.rb +184 -0
- data/lib/mongo/grid/file/metadata.rb +229 -0
- data/lib/mongo/grid/file.rb +106 -0
- data/lib/mongo/grid/fs.rb +149 -0
- data/lib/mongo/{gridfs.rb → grid.rb} +3 -5
- data/lib/mongo/index/view.rb +261 -0
- data/lib/mongo/index.rb +64 -0
- data/lib/mongo/loggable.rb +126 -0
- data/lib/mongo/logger.rb +132 -0
- data/lib/mongo/operation/aggregate/result.rb +88 -0
- data/lib/mongo/operation/aggregate.rb +100 -0
- data/lib/mongo/operation/command.rb +62 -0
- data/lib/mongo/operation/executable.rb +105 -0
- data/lib/mongo/operation/kill_cursors.rb +39 -0
- data/lib/mongo/operation/limited.rb +37 -0
- data/lib/mongo/operation/list_collections/result.rb +114 -0
- data/lib/mongo/operation/list_indexes/result.rb +118 -0
- data/lib/mongo/operation/map_reduce/result.rb +122 -0
- data/lib/mongo/operation/map_reduce.rb +96 -0
- data/lib/mongo/operation/read/collections_info.rb +67 -0
- data/lib/mongo/operation/read/get_more.rb +71 -0
- data/lib/mongo/operation/read/indexes.rb +68 -0
- data/lib/mongo/operation/read/list_collections.rb +75 -0
- data/lib/mongo/operation/read/list_indexes.rb +77 -0
- data/lib/mongo/operation/read/query.rb +71 -0
- data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
- data/lib/mongo/operation/read_preferrable.rb +34 -0
- data/lib/mongo/operation/result.rb +259 -0
- data/lib/mongo/operation/specifiable.rb +397 -0
- data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +75 -0
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +144 -0
- data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +68 -0
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +129 -0
- data/lib/mongo/operation/write/bulk/bulk_mergable.rb +67 -0
- data/lib/mongo/operation/write/bulk/bulk_update/result.rb +162 -0
- data/lib/mongo/operation/write/bulk/bulk_update.rb +153 -0
- data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +83 -0
- data/lib/mongo/operation/write/bulk.rb +17 -0
- data/lib/mongo/operation/write/command/create_index.rb +50 -0
- data/lib/mongo/operation/write/command/create_user.rb +43 -0
- data/lib/mongo/operation/write/command/delete.rb +56 -0
- data/lib/mongo/operation/write/command/drop_index.rb +51 -0
- data/lib/mongo/operation/write/command/insert.rb +55 -0
- data/lib/mongo/operation/write/command/remove_user.rb +42 -0
- data/lib/mongo/operation/write/command/update.rb +60 -0
- data/lib/mongo/operation/write/command/writable.rb +61 -0
- data/lib/mongo/operation/write/command.rb +22 -0
- data/lib/mongo/operation/write/create_index.rb +89 -0
- data/lib/mongo/operation/write/create_user.rb +75 -0
- data/lib/mongo/operation/write/delete/result.rb +40 -0
- data/lib/mongo/operation/write/delete.rb +93 -0
- data/lib/mongo/operation/write/drop_index.rb +62 -0
- data/lib/mongo/{utils/thread_local_variable_manager.rb → operation/write/insert/result.rb} +15 -8
- data/lib/mongo/operation/write/insert.rb +90 -0
- data/lib/mongo/operation/write/remove_user.rb +70 -0
- data/lib/mongo/operation/write/update/result.rb +160 -0
- data/lib/mongo/operation/write/update.rb +103 -0
- data/lib/mongo/{connection/socket/socket_util.rb → operation/write.rb} +10 -24
- data/lib/mongo/operation.rb +25 -0
- data/lib/mongo/options/mapper.rb +78 -0
- data/lib/mongo/options.rb +15 -0
- data/lib/mongo/protocol/bit_vector.rb +61 -0
- data/lib/mongo/protocol/delete.rb +94 -0
- data/lib/mongo/protocol/get_more.rb +99 -0
- data/lib/mongo/protocol/insert.rb +99 -0
- data/lib/mongo/protocol/kill_cursors.rb +74 -0
- data/lib/mongo/protocol/message.rb +252 -0
- data/lib/mongo/protocol/query.rb +147 -0
- data/lib/mongo/protocol/reply.rb +72 -0
- data/lib/mongo/protocol/serializers.rb +180 -0
- data/lib/mongo/protocol/update.rb +111 -0
- data/lib/mongo/protocol.rb +15 -0
- data/lib/mongo/server/connectable.rb +110 -0
- data/lib/mongo/server/connection.rb +134 -0
- data/lib/mongo/server/connection_pool/queue.rb +182 -0
- data/lib/mongo/server/connection_pool.rb +141 -0
- data/lib/mongo/server/context.rb +66 -0
- data/lib/mongo/server/description/features.rb +85 -0
- data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
- data/lib/mongo/server/description/inspector/server_added.rb +59 -0
- data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
- data/lib/mongo/server/description/inspector.rb +79 -0
- data/lib/mongo/server/description.rb +450 -0
- data/lib/mongo/server/monitor/connection.rb +89 -0
- data/lib/mongo/server/monitor.rb +176 -0
- data/lib/mongo/server.rb +163 -0
- data/lib/mongo/server_selector/nearest.rb +94 -0
- data/lib/mongo/server_selector/primary.rb +88 -0
- data/lib/mongo/server_selector/primary_preferred.rb +94 -0
- data/lib/mongo/server_selector/secondary.rb +91 -0
- data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
- data/lib/mongo/server_selector/selectable.rb +209 -0
- data/lib/mongo/server_selector.rb +81 -0
- data/lib/mongo/socket/ssl.rb +130 -0
- data/lib/mongo/socket/tcp.rb +69 -0
- data/lib/mongo/socket/unix.rb +64 -0
- data/lib/mongo/socket.rb +179 -0
- data/lib/mongo/uri.rb +504 -0
- data/lib/mongo/version.rb +21 -0
- data/lib/mongo/write_concern/acknowledged.rb +52 -0
- data/lib/mongo/write_concern/normalizable.rb +51 -0
- data/lib/mongo/write_concern/unacknowledged.rb +55 -0
- data/lib/mongo/write_concern.rb +99 -0
- data/lib/mongo.rb +24 -82
- data/mongo.gemspec +17 -14
- data/spec/certificates/ca.pem +17 -0
- data/spec/certificates/client.pem +101 -0
- data/spec/certificates/crl.pem +10 -0
- data/spec/certificates/crl_client_revoked.pem +12 -0
- data/spec/certificates/password_protected.pem +51 -0
- data/spec/certificates/server.pem +34 -0
- data/spec/mongo/address/ipv4_spec.rb +74 -0
- data/spec/mongo/address/ipv6_spec.rb +74 -0
- data/spec/mongo/address/unix_spec.rb +30 -0
- data/spec/mongo/address_spec.rb +206 -0
- data/spec/mongo/auth/cr_spec.rb +59 -0
- data/spec/mongo/auth/ldap_spec.rb +40 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
- data/spec/mongo/auth/scram_spec.rb +55 -0
- data/spec/mongo/auth/user/view_spec.rb +76 -0
- data/spec/mongo/auth/user_spec.rb +190 -0
- data/spec/mongo/auth/x509_spec.rb +40 -0
- data/spec/mongo/auth_spec.rb +65 -0
- data/spec/mongo/bulk/bulk_write_spec.rb +262 -0
- data/spec/mongo/client_spec.rb +564 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
- data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
- data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
- data/spec/mongo/cluster/topology_spec.rb +65 -0
- data/spec/mongo/cluster_spec.rb +129 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +148 -0
- data/spec/mongo/collection/view/explainable_spec.rb +32 -0
- data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
- data/spec/mongo/collection/view/readable_spec.rb +603 -0
- data/spec/mongo/collection/view/writable_spec.rb +679 -0
- data/spec/mongo/collection/view_spec.rb +530 -0
- data/spec/mongo/collection_spec.rb +362 -0
- data/spec/mongo/crud_spec.rb +42 -0
- data/spec/mongo/cursor_spec.rb +295 -0
- data/spec/mongo/database_spec.rb +302 -0
- data/spec/mongo/error/parser_spec.rb +119 -0
- data/spec/mongo/event/publisher_spec.rb +50 -0
- data/spec/mongo/event/subscriber_spec.rb +34 -0
- data/spec/mongo/grid/file/chunk_spec.rb +226 -0
- data/spec/mongo/grid/file/metadata_spec.rb +92 -0
- data/spec/mongo/grid/file_spec.rb +172 -0
- data/spec/mongo/grid/fs_spec.rb +129 -0
- data/spec/mongo/index/view_spec.rb +330 -0
- data/spec/mongo/loggable_spec.rb +62 -0
- data/spec/mongo/logger_spec.rb +97 -0
- data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
- data/spec/mongo/operation/aggregate_spec.rb +127 -0
- data/spec/mongo/operation/command_spec.rb +98 -0
- data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
- data/spec/mongo/operation/limited_spec.rb +50 -0
- data/spec/mongo/operation/map_reduce_spec.rb +143 -0
- data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
- data/spec/mongo/operation/read/get_more_spec.rb +81 -0
- data/spec/mongo/operation/read/indexes_spec.rb +31 -0
- data/spec/mongo/operation/read/query_spec.rb +84 -0
- data/spec/mongo/operation/result_spec.rb +275 -0
- data/spec/mongo/operation/specifiable_spec.rb +53 -0
- data/spec/mongo/operation/write/bulk_delete_spec.rb +235 -0
- data/spec/mongo/operation/write/bulk_insert_spec.rb +235 -0
- data/spec/mongo/operation/write/bulk_update_spec.rb +236 -0
- data/spec/mongo/operation/write/command/delete_spec.rb +103 -0
- data/spec/mongo/operation/write/command/insert_spec.rb +103 -0
- data/spec/mongo/operation/write/command/update_spec.rb +109 -0
- data/spec/mongo/operation/write/create_index_spec.rb +63 -0
- data/spec/mongo/operation/write/create_user_spec.rb +44 -0
- data/spec/mongo/operation/write/delete_spec.rb +186 -0
- data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
- data/spec/mongo/operation/write/insert_spec.rb +244 -0
- data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
- data/spec/mongo/operation/write/response_spec.rb +85 -0
- data/spec/mongo/operation/write/update_spec.rb +228 -0
- data/spec/mongo/protocol/delete_spec.rb +167 -0
- data/spec/mongo/protocol/get_more_spec.rb +146 -0
- data/spec/mongo/protocol/insert_spec.rb +161 -0
- data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
- data/spec/mongo/protocol/query_spec.rb +285 -0
- data/spec/mongo/protocol/reply_spec.rb +157 -0
- data/spec/mongo/protocol/update_spec.rb +186 -0
- data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
- data/spec/mongo/server/connection_pool_spec.rb +120 -0
- data/spec/mongo/server/connection_spec.rb +312 -0
- data/spec/mongo/server/description/features_spec.rb +138 -0
- data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
- data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
- data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
- data/spec/mongo/server/description_spec.rb +510 -0
- data/spec/mongo/server/monitor_spec.rb +144 -0
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
- data/spec/mongo/server_selection_rtt_spec.rb +104 -0
- data/spec/mongo/server_selection_spec.rb +89 -0
- data/spec/mongo/server_selector/nearest_spec.rb +250 -0
- data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
- data/spec/mongo/server_selector/primary_spec.rb +114 -0
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
- data/spec/mongo/server_selector/secondary_spec.rb +196 -0
- data/spec/mongo/server_selector_spec.rb +101 -0
- data/spec/mongo/server_spec.rb +131 -0
- data/spec/mongo/uri_spec.rb +517 -0
- data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
- data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
- data/spec/spec_helper.rb +133 -0
- data/spec/support/authorization.rb +247 -0
- data/spec/support/crud/read.rb +144 -0
- data/spec/support/crud/write.rb +214 -0
- data/spec/support/crud.rb +203 -0
- data/spec/support/crud_tests/read/aggregate.yml +43 -0
- data/spec/support/crud_tests/read/count.yml +37 -0
- data/spec/support/crud_tests/read/distinct.yml +33 -0
- data/spec/support/crud_tests/read/find.yml +50 -0
- data/spec/support/crud_tests/write/deleteMany.yml +36 -0
- data/spec/support/crud_tests/write/deleteOne.yml +49 -0
- data/spec/support/crud_tests/write/findOneAndDelete.yml +54 -0
- data/spec/support/crud_tests/write/findOneAndReplace.yml +153 -0
- data/spec/support/crud_tests/write/findOneAndUpdate.yml +161 -0
- data/spec/support/crud_tests/write/insertMany.yml +24 -0
- data/spec/support/crud_tests/write/insertOne.yml +19 -0
- data/spec/support/crud_tests/write/replaceOne.yml +96 -0
- data/spec/support/crud_tests/write/updateMany.yml +83 -0
- data/spec/support/crud_tests/write/updateOne.yml +80 -0
- data/spec/support/helpers.rb +140 -0
- data/spec/support/matchers.rb +37 -0
- data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
- data/spec/support/sdam/rs/discover_passives.yml +41 -0
- data/spec/support/sdam/rs/discover_primary.yml +40 -0
- data/spec/support/sdam/rs/discover_secondary.yml +41 -0
- data/spec/support/sdam/rs/discovery.yml +195 -0
- data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
- data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
- data/spec/support/sdam/rs/member_reconfig.yml +68 -0
- data/spec/support/sdam/rs/member_standalone.yml +60 -0
- data/spec/support/sdam/rs/new_primary.yml +74 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
- data/spec/support/sdam/rs/non_rs_member.yml +31 -0
- data/spec/support/sdam/rs/normalize_case.yml +49 -0
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
- data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
- data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
- data/spec/support/sdam/rs/response_from_removed.yml +63 -0
- data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
- data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
- data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
- data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
- data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
- data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
- data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
- data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
- data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
- data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
- data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
- data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
- data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
- data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
- data/spec/support/sdam/single/not_ok_response.yml +39 -0
- data/spec/support/sdam/single/standalone_removed.yml +32 -0
- data/spec/support/sdam/single/unavailable_seed.yml +28 -0
- data/spec/support/server_discovery_and_monitoring.rb +167 -0
- data/spec/support/server_selection/rtt/first_value.yml +4 -0
- data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
- data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +21 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +33 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +26 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +31 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +31 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +29 -0
- data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +26 -0
- data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +26 -0
- data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +19 -0
- data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +11 -0
- data/spec/support/server_selection.rb +157 -0
- data/spec/support/server_selection_rtt.rb +41 -0
- data/spec/support/shared/bulk_write.rb +535 -0
- data/spec/support/shared/cursor.rb +38 -0
- data/spec/support/shared/operation.rb +77 -0
- data/spec/support/shared/protocol.rb +31 -0
- data/spec/support/shared/server_selector.rb +111 -0
- data/spec/support/shared/socket.rb +82 -0
- data/spec/support/travis.rb +14 -0
- data.tar.gz.sig +2 -3
- metadata +583 -186
- metadata.gz.sig +0 -0
- data/VERSION +0 -1
- data/lib/mongo/bulk_write_collection_view.rb +0 -387
- data/lib/mongo/collection_writer.rb +0 -364
- data/lib/mongo/connection/node.rb +0 -249
- data/lib/mongo/connection/pool.rb +0 -340
- data/lib/mongo/connection/pool_manager.rb +0 -320
- data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
- data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
- data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
- data/lib/mongo/connection/socket/unix_socket.rb +0 -39
- data/lib/mongo/db.rb +0 -808
- data/lib/mongo/exception.rb +0 -145
- data/lib/mongo/functional/authentication.rb +0 -455
- data/lib/mongo/functional/logging.rb +0 -85
- data/lib/mongo/functional/read_preference.rb +0 -183
- data/lib/mongo/functional/scram.rb +0 -556
- data/lib/mongo/functional/uri_parser.rb +0 -409
- data/lib/mongo/functional/write_concern.rb +0 -66
- data/lib/mongo/gridfs/grid.rb +0 -112
- data/lib/mongo/gridfs/grid_ext.rb +0 -53
- data/lib/mongo/gridfs/grid_file_system.rb +0 -163
- data/lib/mongo/gridfs/grid_io.rb +0 -484
- data/lib/mongo/legacy.rb +0 -140
- data/lib/mongo/mongo_client.rb +0 -697
- data/lib/mongo/mongo_replica_set_client.rb +0 -535
- data/lib/mongo/mongo_sharded_client.rb +0 -159
- data/lib/mongo/networking.rb +0 -372
- data/lib/mongo/utils/conversions.rb +0 -110
- data/lib/mongo/utils/core_ext.rb +0 -70
- data/lib/mongo/utils/server_version.rb +0 -69
- data/lib/mongo/utils/support.rb +0 -80
- data/test/functional/authentication_test.rb +0 -39
- data/test/functional/bulk_api_stress_test.rb +0 -133
- data/test/functional/bulk_write_collection_view_test.rb +0 -1198
- data/test/functional/client_test.rb +0 -627
- data/test/functional/collection_test.rb +0 -2175
- data/test/functional/collection_writer_test.rb +0 -83
- data/test/functional/conversions_test.rb +0 -163
- data/test/functional/cursor_fail_test.rb +0 -57
- data/test/functional/cursor_message_test.rb +0 -56
- data/test/functional/cursor_test.rb +0 -683
- data/test/functional/db_api_test.rb +0 -835
- data/test/functional/db_test.rb +0 -348
- data/test/functional/grid_file_system_test.rb +0 -285
- data/test/functional/grid_io_test.rb +0 -252
- data/test/functional/grid_test.rb +0 -273
- data/test/functional/pool_test.rb +0 -136
- data/test/functional/safe_test.rb +0 -98
- data/test/functional/support_test.rb +0 -62
- data/test/functional/timeout_test.rb +0 -60
- data/test/functional/uri_test.rb +0 -446
- data/test/functional/write_concern_test.rb +0 -118
- data/test/helpers/general.rb +0 -50
- data/test/helpers/test_unit.rb +0 -476
- data/test/replica_set/authentication_test.rb +0 -37
- data/test/replica_set/basic_test.rb +0 -189
- data/test/replica_set/client_test.rb +0 -393
- data/test/replica_set/connection_test.rb +0 -138
- data/test/replica_set/count_test.rb +0 -66
- data/test/replica_set/cursor_test.rb +0 -220
- data/test/replica_set/insert_test.rb +0 -157
- data/test/replica_set/max_values_test.rb +0 -151
- data/test/replica_set/pinning_test.rb +0 -105
- data/test/replica_set/query_test.rb +0 -73
- data/test/replica_set/read_preference_test.rb +0 -219
- data/test/replica_set/refresh_test.rb +0 -211
- data/test/replica_set/replication_ack_test.rb +0 -95
- data/test/sharded_cluster/basic_test.rb +0 -203
- data/test/shared/authentication/basic_auth_shared.rb +0 -260
- data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
- data/test/shared/authentication/gssapi_shared.rb +0 -176
- data/test/shared/authentication/sasl_plain_shared.rb +0 -96
- data/test/shared/authentication/scram_shared.rb +0 -92
- data/test/shared/ssl_shared.rb +0 -235
- data/test/test_helper.rb +0 -61
- data/test/threading/basic_test.rb +0 -120
- data/test/tools/mongo_config.rb +0 -708
- data/test/tools/mongo_config_test.rb +0 -160
- data/test/unit/client_test.rb +0 -381
- data/test/unit/collection_test.rb +0 -166
- data/test/unit/connection_test.rb +0 -335
- data/test/unit/cursor_test.rb +0 -307
- data/test/unit/db_test.rb +0 -136
- data/test/unit/grid_test.rb +0 -76
- data/test/unit/mongo_sharded_client_test.rb +0 -48
- data/test/unit/node_test.rb +0 -93
- data/test/unit/pool_manager_test.rb +0 -111
- data/test/unit/read_pref_test.rb +0 -406
- data/test/unit/read_test.rb +0 -159
- data/test/unit/safe_test.rb +0 -158
- data/test/unit/sharding_pool_manager_test.rb +0 -84
- data/test/unit/write_concern_test.rb +0 -175
data/lib/mongo/db.rb
DELETED
@@ -1,808 +0,0 @@
|
|
1
|
-
# Copyright (C) 2009-2013 MongoDB, Inc.
|
2
|
-
#
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
-
# You may obtain a copy of the License at
|
6
|
-
#
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
|
15
|
-
module Mongo
|
16
|
-
|
17
|
-
# A MongoDB database.
|
18
|
-
class DB
|
19
|
-
include Mongo::WriteConcern
|
20
|
-
|
21
|
-
SYSTEM_NAMESPACE_COLLECTION = 'system.namespaces'
|
22
|
-
SYSTEM_INDEX_COLLECTION = 'system.indexes'
|
23
|
-
SYSTEM_PROFILE_COLLECTION = 'system.profile'
|
24
|
-
SYSTEM_USER_COLLECTION = 'system.users'
|
25
|
-
SYSTEM_JS_COLLECTION = 'system.js'
|
26
|
-
SYSTEM_COMMAND_COLLECTION = '$cmd'
|
27
|
-
MAX_TIME_MS_CODE = 50
|
28
|
-
|
29
|
-
PROFILE_LEVEL = {
|
30
|
-
:off => 0,
|
31
|
-
:slow_only => 1,
|
32
|
-
:all => 2
|
33
|
-
}
|
34
|
-
|
35
|
-
# Counter for generating unique request ids.
|
36
|
-
@@current_request_id = 0
|
37
|
-
|
38
|
-
# Strict mode enforces collection existence checks. When +true+,
|
39
|
-
# asking for a collection that does not exist, or trying to create a
|
40
|
-
# collection that already exists, raises an error.
|
41
|
-
#
|
42
|
-
# Strict mode is disabled by default, but enabled (+true+) at any time.
|
43
|
-
#
|
44
|
-
# @deprecated Support for strict will be removed in version 2.0 of the driver.
|
45
|
-
def strict=(value)
|
46
|
-
unless ENV['TEST_MODE']
|
47
|
-
warn "Support for strict mode has been deprecated and will be " +
|
48
|
-
"removed in version 2.0 of the driver."
|
49
|
-
end
|
50
|
-
@strict = value
|
51
|
-
end
|
52
|
-
|
53
|
-
# Returns the value of the +strict+ flag.
|
54
|
-
#
|
55
|
-
# @deprecated Support for strict will be removed in version 2.0 of the driver.
|
56
|
-
def strict?
|
57
|
-
@strict
|
58
|
-
end
|
59
|
-
|
60
|
-
# The name of the database and the local write concern options.
|
61
|
-
attr_reader :name, :write_concern
|
62
|
-
|
63
|
-
# The Mongo::MongoClient instance connecting to the MongoDB server.
|
64
|
-
attr_reader :client
|
65
|
-
|
66
|
-
# for backward compatibility
|
67
|
-
alias_method :connection, :client
|
68
|
-
|
69
|
-
# The length of time that Collection.ensure_index should cache index calls
|
70
|
-
attr_accessor :cache_time
|
71
|
-
|
72
|
-
# Read Preference
|
73
|
-
attr_accessor :read, :tag_sets, :acceptable_latency
|
74
|
-
|
75
|
-
# Instances of DB are normally obtained by calling Mongo#db.
|
76
|
-
#
|
77
|
-
# @param [String] name the database name.
|
78
|
-
# @param [Mongo::MongoClient] client a connection object pointing to MongoDB. Note
|
79
|
-
# that databases are usually instantiated via the MongoClient class. See the examples below.
|
80
|
-
#
|
81
|
-
# @option opts [Boolean] :strict (False) [DEPRECATED] If true, collections existence checks are
|
82
|
-
# performed during a number of relevant operations. See DB#collection, DB#create_collection and
|
83
|
-
# DB#drop_collection.
|
84
|
-
#
|
85
|
-
# @option opts [Object, #create_pk(doc)] :pk (BSON::ObjectId) A primary key factory object,
|
86
|
-
# which should take a hash and return a hash which merges the original hash with any primary key
|
87
|
-
# fields the factory wishes to inject. (NOTE: if the object already has a primary key,
|
88
|
-
# the factory should not inject a new key).
|
89
|
-
#
|
90
|
-
# @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
|
91
|
-
# should be acknowledged.
|
92
|
-
# @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
|
93
|
-
# @option opts [Boolean] :j (false) If true, block until write operations have been committed
|
94
|
-
# to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
|
95
|
-
# ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
|
96
|
-
# fail with an exception if this option is used when the server is running without journaling.
|
97
|
-
# @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
|
98
|
-
# the server has synced all data files to disk. If the server is running with journaling, this acts the same as
|
99
|
-
# the 'j' option, blocking until write operations have been committed to the journal.
|
100
|
-
# Cannot be used in combination with 'j'.
|
101
|
-
#
|
102
|
-
# Notes on write concern:
|
103
|
-
# These write concern options are propagated to Collection objects instantiated off of this DB. If no
|
104
|
-
# options are provided, the default write concern set on this instance's MongoClient object will be used. This
|
105
|
-
# default can be overridden upon instantiation of any collection by explicitly setting write concern options
|
106
|
-
# on initialization or at the time of an operation.
|
107
|
-
#
|
108
|
-
# @option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.
|
109
|
-
|
110
|
-
def initialize(name, client, opts={})
|
111
|
-
# A database name of '$external' is permitted for some auth types
|
112
|
-
Support.validate_db_name(name) unless name == '$external'
|
113
|
-
|
114
|
-
@name = name
|
115
|
-
@client = client
|
116
|
-
@strict = opts[:strict]
|
117
|
-
@pk_factory = opts[:pk]
|
118
|
-
|
119
|
-
@write_concern = get_write_concern(opts, client)
|
120
|
-
|
121
|
-
@read = opts[:read] || @client.read
|
122
|
-
ReadPreference::validate(@read)
|
123
|
-
|
124
|
-
@tag_sets = opts.fetch(:tag_sets, @client.tag_sets)
|
125
|
-
@acceptable_latency = opts.fetch(:acceptable_latency,
|
126
|
-
@client.acceptable_latency)
|
127
|
-
|
128
|
-
@cache_time = opts[:cache_time] || 300 #5 minutes.
|
129
|
-
end
|
130
|
-
|
131
|
-
# Authenticate with the given username and password.
|
132
|
-
#
|
133
|
-
# @param username [String] The username.
|
134
|
-
# @param password [String] The user's password. This is not required for
|
135
|
-
# some authentication mechanisms.
|
136
|
-
# @param save_auth [Boolean]
|
137
|
-
# Save this authentication to the client object using
|
138
|
-
# MongoClient#add_auth. This will ensure that the authentication will
|
139
|
-
# be applied to all sockets and upon database reconnect.
|
140
|
-
# @param source [String] Database with user credentials. This should be
|
141
|
-
# used to authenticate against a database when the credentials exist
|
142
|
-
# elsewhere.
|
143
|
-
# @param mechanism [String] The authentication mechanism to be used.
|
144
|
-
# @param extra [Hash] A optional hash of extra options to be stored with
|
145
|
-
# the credential set.
|
146
|
-
#
|
147
|
-
# @note The ability to disable the save_auth option has been deprecated.
|
148
|
-
# With save_auth=false specified, driver authentication behavior during
|
149
|
-
# failovers and reconnections becomes unreliable. This option still
|
150
|
-
# exists for API compatibility, but it no longer has any effect if
|
151
|
-
# disabled and now always uses the default behavior (safe_auth=true).
|
152
|
-
#
|
153
|
-
# @raise [AuthenticationError] Raised if authentication fails.
|
154
|
-
# @return [Boolean] The result of the authentication operation.
|
155
|
-
def authenticate(username, password=nil, save_auth=nil, source=nil, mechanism=nil, extra=nil)
|
156
|
-
warn "[DEPRECATED] Disabling the 'save_auth' option no longer has " +
|
157
|
-
"any effect. Please see the API documentation for more details " +
|
158
|
-
"on this change." unless save_auth.nil?
|
159
|
-
@client.add_auth(self.name, username, password, source, mechanism, extra)
|
160
|
-
true
|
161
|
-
end
|
162
|
-
|
163
|
-
# Deauthorizes use for this database for this client connection. Also removes
|
164
|
-
# the saved authentication in the MongoClient class associated with this
|
165
|
-
# database.
|
166
|
-
#
|
167
|
-
# @return [Boolean]
|
168
|
-
def logout(opts={})
|
169
|
-
@client.remove_auth(self.name)
|
170
|
-
true
|
171
|
-
end
|
172
|
-
|
173
|
-
# Adds a stored Javascript function to the database which can executed
|
174
|
-
# server-side in map_reduce, db.eval and $where clauses.
|
175
|
-
#
|
176
|
-
# @param [String] function_name
|
177
|
-
# @param [String] code
|
178
|
-
#
|
179
|
-
# @return [String] the function name saved to the database
|
180
|
-
def add_stored_function(function_name, code)
|
181
|
-
self[SYSTEM_JS_COLLECTION].save(
|
182
|
-
{
|
183
|
-
"_id" => function_name,
|
184
|
-
:value => BSON::Code.new(code)
|
185
|
-
}
|
186
|
-
)
|
187
|
-
end
|
188
|
-
|
189
|
-
# Removes stored Javascript function from the database. Returns
|
190
|
-
# false if the function does not exist
|
191
|
-
#
|
192
|
-
# @param [String] function_name
|
193
|
-
#
|
194
|
-
# @return [Boolean]
|
195
|
-
def remove_stored_function(function_name)
|
196
|
-
return false unless self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
|
197
|
-
self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :w => 1)
|
198
|
-
end
|
199
|
-
|
200
|
-
# Adds a user to this database for use with authentication. If the user already
|
201
|
-
# exists in the system, the password and any additional fields provided in opts
|
202
|
-
# will be updated.
|
203
|
-
#
|
204
|
-
# @param [String] username
|
205
|
-
# @param [String] password
|
206
|
-
# @param [Boolean] read_only
|
207
|
-
# Create a read-only user.
|
208
|
-
#
|
209
|
-
# @param [Hash] opts
|
210
|
-
# Optional fields for the user document (e.g. +userSource+, or +roles+)
|
211
|
-
#
|
212
|
-
# See {http://docs.mongodb.org/manual/reference/privilege-documents}
|
213
|
-
# for more information.
|
214
|
-
#
|
215
|
-
# @note The use of the opts argument to provide or update additional fields
|
216
|
-
# on the user document requires MongoDB >= 2.4.0
|
217
|
-
#
|
218
|
-
# @return [Hash] an object representing the user.
|
219
|
-
def add_user(username, password=nil, read_only=false, opts={})
|
220
|
-
user_info = command(:usersInfo => username)
|
221
|
-
if user_info.key?('users') && !user_info['users'].empty?
|
222
|
-
create_or_update_user(:updateUser, username, password, read_only, opts)
|
223
|
-
else
|
224
|
-
create_or_update_user(:createUser, username, password, read_only, opts)
|
225
|
-
end
|
226
|
-
# MongoDB >= 2.5.3 requires the use of commands to manage users.
|
227
|
-
# "Command not found" error didn't return an error code (59) before
|
228
|
-
# MongoDB 2.4.7 so we assume that a nil error code means the usersInfo
|
229
|
-
# command doesn't exist and we should fall back to the legacy add user code.
|
230
|
-
rescue OperationFailure => ex
|
231
|
-
if Mongo::ErrorCode::COMMAND_NOT_FOUND_CODES.include?(ex.error_code)
|
232
|
-
legacy_add_user(username, password, read_only, opts)
|
233
|
-
elsif ex.error_code == Mongo::ErrorCode::UNAUTHORIZED
|
234
|
-
# In MongoDB > 2.7 the localhost exception was narrowed, and the usersInfo
|
235
|
-
# command is no longer allowed. In this case, add the first user.
|
236
|
-
create_or_update_user(:createUser, username, password, read_only, opts)
|
237
|
-
else
|
238
|
-
raise ex
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
# Remove the given user from this database. Returns false if the user
|
243
|
-
# doesn't exist in the system.
|
244
|
-
#
|
245
|
-
# @param [String] username
|
246
|
-
#
|
247
|
-
# @return [Boolean]
|
248
|
-
def remove_user(username)
|
249
|
-
begin
|
250
|
-
command(:dropUser => username)
|
251
|
-
rescue OperationFailure => ex
|
252
|
-
raise ex unless Mongo::ErrorCode::COMMAND_NOT_FOUND_CODES.include?(ex.error_code)
|
253
|
-
response = self[SYSTEM_USER_COLLECTION].remove({:user => username}, :w => 1)
|
254
|
-
response.key?('n') && response['n'] > 0 ? response : false
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
# Get an array of collection names in this database.
|
259
|
-
#
|
260
|
-
# @return [Array]
|
261
|
-
def collection_names
|
262
|
-
if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
|
263
|
-
names = collections_info.collect { |doc| doc['name'] || '' }
|
264
|
-
names.delete_if do |name|
|
265
|
-
name.index('$')
|
266
|
-
end
|
267
|
-
else
|
268
|
-
legacy_collection_names
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
# Get an array of Collection instances, one for each collection in this database.
|
273
|
-
#
|
274
|
-
# @return [Array<Mongo::Collection>]
|
275
|
-
def collections
|
276
|
-
collection_names.map do |name|
|
277
|
-
Collection.new(name, self)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
# Get info on system namespaces (collections). This method returns
|
282
|
-
# a cursor which can be iterated over. For each collection, a hash
|
283
|
-
# will be yielded containing a 'name' string and, optionally, an 'options' hash.
|
284
|
-
#
|
285
|
-
# @param [String] coll_name return info for the specified collection only.
|
286
|
-
#
|
287
|
-
# @return [Array] List of collection info.
|
288
|
-
def collections_info(coll_name=nil)
|
289
|
-
if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
|
290
|
-
cmd = BSON::OrderedHash[:listCollections, 1]
|
291
|
-
cmd.merge!(:filter => { :name => coll_name }) if coll_name
|
292
|
-
result = self.command(cmd, :cursor => {})
|
293
|
-
if result.key?('cursor')
|
294
|
-
cursor_info = result['cursor']
|
295
|
-
pinned_pool = @client.pinned_pool
|
296
|
-
pinned_pool = pinned_pool[:pool] if pinned_pool.respond_to?(:keys)
|
297
|
-
|
298
|
-
seed = {
|
299
|
-
:cursor_id => cursor_info['id'],
|
300
|
-
:first_batch => cursor_info['firstBatch'],
|
301
|
-
:pool => pinned_pool,
|
302
|
-
:ns => cursor_info['ns']
|
303
|
-
}
|
304
|
-
|
305
|
-
Cursor.new(Collection.new('$cmd', self), seed).to_a
|
306
|
-
else
|
307
|
-
result['collections']
|
308
|
-
end
|
309
|
-
else
|
310
|
-
legacy_collections_info(coll_name).to_a
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
# Create a collection.
|
315
|
-
#
|
316
|
-
# new collection. If +strict+ is true, will raise an error if
|
317
|
-
# collection +name+ already exists.
|
318
|
-
#
|
319
|
-
# @param [String, Symbol] name the name of the new collection.
|
320
|
-
#
|
321
|
-
# @option opts [Boolean] :capped (False) created a capped collection.
|
322
|
-
#
|
323
|
-
# @option opts [Integer] :size (Nil) If +capped+ is +true+,
|
324
|
-
# specifies the maximum number of bytes for the capped collection.
|
325
|
-
# If +false+, specifies the number of bytes allocated
|
326
|
-
# for the initial extent of the collection.
|
327
|
-
#
|
328
|
-
# @option opts [Integer] :max (Nil) If +capped+ is +true+, indicates
|
329
|
-
# the maximum number of records in a capped collection.
|
330
|
-
#
|
331
|
-
# @raise [MongoDBError] raised under two conditions:
|
332
|
-
# either we're in +strict+ mode and the collection
|
333
|
-
# already exists or collection creation fails on the server.
|
334
|
-
#
|
335
|
-
# @note Note that the options listed may be subset of those available.
|
336
|
-
# Please see the MongoDB documentation for a full list of supported options by server version.
|
337
|
-
#
|
338
|
-
# @return [Mongo::Collection]
|
339
|
-
def create_collection(name, opts={})
|
340
|
-
name = name.to_s
|
341
|
-
if strict? && collection_names.include?(name)
|
342
|
-
raise MongoDBError, "Collection '#{name}' already exists. (strict=true)"
|
343
|
-
end
|
344
|
-
|
345
|
-
begin
|
346
|
-
cmd = BSON::OrderedHash.new
|
347
|
-
cmd[:create] = name
|
348
|
-
doc = command(cmd.merge(opts || {}))
|
349
|
-
return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
|
350
|
-
rescue OperationFailure => e
|
351
|
-
return Collection.new(name, self, :pk => @pk_factory) if e.message =~ /exists/
|
352
|
-
raise e
|
353
|
-
end
|
354
|
-
raise MongoDBError, "Error creating collection: #{doc.inspect}"
|
355
|
-
end
|
356
|
-
|
357
|
-
# Get a collection by name.
|
358
|
-
#
|
359
|
-
# @param [String, Symbol] name the collection name.
|
360
|
-
# @param [Hash] opts any valid options that can be passed to Collection#new.
|
361
|
-
#
|
362
|
-
# @raise [MongoDBError] if collection does not already exist and we're in
|
363
|
-
# +strict+ mode.
|
364
|
-
#
|
365
|
-
# @return [Mongo::Collection]
|
366
|
-
def collection(name, opts={})
|
367
|
-
if strict? && !collection_names.include?(name.to_s)
|
368
|
-
raise MongoDBError, "Collection '#{name}' doesn't exist. (strict=true)"
|
369
|
-
else
|
370
|
-
opts = opts.dup
|
371
|
-
opts.merge!(:pk => @pk_factory) unless opts[:pk]
|
372
|
-
Collection.new(name, self, opts)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
alias_method :[], :collection
|
376
|
-
|
377
|
-
# Drop a collection by +name+.
|
378
|
-
#
|
379
|
-
# @param [String, Symbol] name
|
380
|
-
#
|
381
|
-
# @return [Boolean] +true+ on success or +false+ if the collection name doesn't exist.
|
382
|
-
def drop_collection(name)
|
383
|
-
return false if strict? && !collection_names.include?(name.to_s)
|
384
|
-
begin
|
385
|
-
ok?(command(:drop => name))
|
386
|
-
rescue OperationFailure
|
387
|
-
false
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
# Run the getlasterror command with the specified replication options.
|
392
|
-
#
|
393
|
-
# @option opts [Boolean] :fsync (false)
|
394
|
-
# @option opts [Integer] :w (nil)
|
395
|
-
# @option opts [Integer] :wtimeout (nil)
|
396
|
-
# @option opts [Boolean] :j (false)
|
397
|
-
#
|
398
|
-
# @return [Hash] the entire response to getlasterror.
|
399
|
-
#
|
400
|
-
# @raise [MongoDBError] if the operation fails.
|
401
|
-
def get_last_error(opts={})
|
402
|
-
cmd = BSON::OrderedHash.new
|
403
|
-
cmd[:getlasterror] = 1
|
404
|
-
cmd.merge!(opts)
|
405
|
-
doc = command(cmd, :check_response => false)
|
406
|
-
raise MongoDBError, "Error retrieving last error: #{doc.inspect}" unless ok?(doc)
|
407
|
-
doc
|
408
|
-
end
|
409
|
-
|
410
|
-
# Return +true+ if an error was caused by the most recently executed
|
411
|
-
# database operation.
|
412
|
-
#
|
413
|
-
# @return [Boolean]
|
414
|
-
def error?
|
415
|
-
get_last_error['err'] != nil
|
416
|
-
end
|
417
|
-
|
418
|
-
# Get the most recent error to have occurred on this database.
|
419
|
-
#
|
420
|
-
# This command only returns errors that have occurred since the last call to
|
421
|
-
# DB#reset_error_history - returns +nil+ if there is no such error.
|
422
|
-
#
|
423
|
-
# @return [String, Nil] the text of the error or +nil+ if no error has occurred.
|
424
|
-
def previous_error
|
425
|
-
error = command(:getpreverror => 1)
|
426
|
-
error["err"] ? error : nil
|
427
|
-
end
|
428
|
-
|
429
|
-
# Reset the error history of this database
|
430
|
-
#
|
431
|
-
# Calls to DB#previous_error will only return errors that have occurred
|
432
|
-
# since the most recent call to this method.
|
433
|
-
#
|
434
|
-
# @return [Hash]
|
435
|
-
def reset_error_history
|
436
|
-
command(:reseterror => 1)
|
437
|
-
end
|
438
|
-
|
439
|
-
# Dereference a DBRef, returning the document it points to.
|
440
|
-
#
|
441
|
-
# @param [Mongo::DBRef] dbref
|
442
|
-
#
|
443
|
-
# @return [Hash] the document indicated by the db reference.
|
444
|
-
#
|
445
|
-
# @see http://www.mongodb.org/display/DOCS/DB+Ref MongoDB DBRef spec.
|
446
|
-
def dereference(dbref)
|
447
|
-
collection(dbref.namespace).find_one("_id" => dbref.object_id)
|
448
|
-
end
|
449
|
-
|
450
|
-
# Evaluate a JavaScript expression in MongoDB.
|
451
|
-
#
|
452
|
-
# @param [String, Code] code a JavaScript expression to evaluate server-side.
|
453
|
-
# @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when
|
454
|
-
# it's run on the server.
|
455
|
-
#
|
456
|
-
# @note the eval command is deprecated in MongoDB 3.0 and will be removed in a future server version.
|
457
|
-
#
|
458
|
-
# @return [String] the return value of the function.
|
459
|
-
def eval(code, *args)
|
460
|
-
unless code.is_a?(BSON::Code)
|
461
|
-
code = BSON::Code.new(code)
|
462
|
-
end
|
463
|
-
|
464
|
-
cmd = BSON::OrderedHash.new
|
465
|
-
cmd[:$eval] = code
|
466
|
-
cmd.merge!(args.pop) if args.last.respond_to?(:keys) && args.last.key?(:nolock)
|
467
|
-
cmd[:args] = args
|
468
|
-
doc = command(cmd)
|
469
|
-
doc['retval']
|
470
|
-
end
|
471
|
-
|
472
|
-
# Rename a collection.
|
473
|
-
#
|
474
|
-
# @param [String] from original collection name.
|
475
|
-
# @param [String] to new collection name.
|
476
|
-
#
|
477
|
-
# @return [True] returns +true+ on success.
|
478
|
-
#
|
479
|
-
# @raise MongoDBError if there's an error renaming the collection.
|
480
|
-
def rename_collection(from, to)
|
481
|
-
cmd = BSON::OrderedHash.new
|
482
|
-
cmd[:renameCollection] = "#{@name}.#{from}"
|
483
|
-
cmd[:to] = "#{@name}.#{to}"
|
484
|
-
doc = DB.new('admin', @client).command(cmd, :check_response => false)
|
485
|
-
ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
|
486
|
-
end
|
487
|
-
|
488
|
-
# Drop an index from a given collection. Normally called from
|
489
|
-
# Collection#drop_index or Collection#drop_indexes.
|
490
|
-
#
|
491
|
-
# @param [String] collection_name
|
492
|
-
# @param [String] index_name
|
493
|
-
#
|
494
|
-
# @return [True] returns +true+ on success.
|
495
|
-
#
|
496
|
-
# @raise MongoDBError if there's an error dropping the index.
|
497
|
-
def drop_index(collection_name, index_name)
|
498
|
-
cmd = BSON::OrderedHash.new
|
499
|
-
cmd[:deleteIndexes] = collection_name
|
500
|
-
cmd[:index] = index_name.to_s
|
501
|
-
doc = command(cmd, :check_response => false)
|
502
|
-
ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
|
503
|
-
end
|
504
|
-
|
505
|
-
# Get information on the indexes for the given collection.
|
506
|
-
# Normally called by Collection#index_information.
|
507
|
-
#
|
508
|
-
# @param [String] collection_name
|
509
|
-
#
|
510
|
-
# @return [Hash] keys are index names and the values are lists of [key, type] pairs
|
511
|
-
# defining the index.
|
512
|
-
def index_information(collection_name)
|
513
|
-
if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
|
514
|
-
result = self.command({ :listIndexes => collection_name }, :cursor => {})
|
515
|
-
if result.key?('cursor')
|
516
|
-
cursor_info = result['cursor']
|
517
|
-
pinned_pool = @client.pinned_pool
|
518
|
-
pinned_pool = pinned_pool[:pool] if pinned_pool.respond_to?(:keys)
|
519
|
-
|
520
|
-
seed = {
|
521
|
-
:cursor_id => cursor_info['id'],
|
522
|
-
:first_batch => cursor_info['firstBatch'],
|
523
|
-
:pool => pinned_pool,
|
524
|
-
:ns => cursor_info['ns']
|
525
|
-
}
|
526
|
-
|
527
|
-
indexes = Cursor.new(Collection.new('$cmd', self), seed).to_a
|
528
|
-
else
|
529
|
-
indexes = result['indexes']
|
530
|
-
end
|
531
|
-
else
|
532
|
-
indexes = legacy_list_indexes(collection_name)
|
533
|
-
end
|
534
|
-
indexes.reduce({}) do |info, index|
|
535
|
-
info.merge!(index['name'] => index)
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
|
-
# Return stats on this database. Uses MongoDB's dbstats command.
|
540
|
-
#
|
541
|
-
# @return [Hash]
|
542
|
-
def stats
|
543
|
-
self.command(:dbstats => 1)
|
544
|
-
end
|
545
|
-
|
546
|
-
# Return +true+ if the supplied +doc+ contains an 'ok' field with the value 1.
|
547
|
-
#
|
548
|
-
# @param [Hash] doc
|
549
|
-
#
|
550
|
-
# @return [Boolean]
|
551
|
-
def ok?(doc)
|
552
|
-
Mongo::Support.ok?(doc)
|
553
|
-
end
|
554
|
-
|
555
|
-
# Send a command to the database.
|
556
|
-
#
|
557
|
-
# Note: DB commands must start with the "command" key. For this reason,
|
558
|
-
# any selector containing more than one key must be an OrderedHash.
|
559
|
-
#
|
560
|
-
# Note also that a command in MongoDB is just a kind of query
|
561
|
-
# that occurs on the system command collection ($cmd). Examine this method's implementation
|
562
|
-
# to see how it works.
|
563
|
-
#
|
564
|
-
# @param [OrderedHash, Hash] selector an OrderedHash, or a standard Hash with just one
|
565
|
-
# key, specifying the command to be performed. In Ruby 1.9 and above, OrderedHash isn't necessary
|
566
|
-
# because hashes are ordered by default.
|
567
|
-
#
|
568
|
-
# @option opts [Boolean] :check_response (true) If +true+, raises an exception if the
|
569
|
-
# command fails.
|
570
|
-
# @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
|
571
|
-
# @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
|
572
|
-
# more details.
|
573
|
-
# @option opts [String] :comment (nil) a comment to include in profiling logs
|
574
|
-
# @option opts [Boolean] :compile_regex (true) whether BSON regex objects should be compiled into Ruby regexes.
|
575
|
-
# If false, a BSON::Regex object will be returned instead.
|
576
|
-
#
|
577
|
-
# @return [Hash]
|
578
|
-
def command(selector, opts={})
|
579
|
-
raise MongoArgumentError, "Command must be given a selector" unless selector.respond_to?(:keys) && !selector.empty?
|
580
|
-
|
581
|
-
opts = opts.dup
|
582
|
-
# deletes :check_response and returns the value, if nil defaults to the block result
|
583
|
-
check_response = opts.delete(:check_response) { true }
|
584
|
-
|
585
|
-
# build up the command hash
|
586
|
-
command = opts.key?(:socket) ? { :socket => opts.delete(:socket) } : {}
|
587
|
-
command.merge!(:comment => opts.delete(:comment)) if opts.key?(:comment)
|
588
|
-
command.merge!(:compile_regex => opts.delete(:compile_regex)) if opts.key?(:compile_regex)
|
589
|
-
command[:limit] = -1
|
590
|
-
command[:read] = Mongo::ReadPreference::cmd_read_pref(opts.delete(:read), selector) if opts.key?(:read)
|
591
|
-
|
592
|
-
if RUBY_VERSION < '1.9' && selector.class != BSON::OrderedHash
|
593
|
-
if selector.keys.length > 1
|
594
|
-
raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
|
595
|
-
end
|
596
|
-
if opts.keys.size > 0
|
597
|
-
# extra opts will be merged into the selector, so make sure it's an OH in versions < 1.9
|
598
|
-
selector = selector.dup
|
599
|
-
selector = BSON::OrderedHash.new.merge!(selector)
|
600
|
-
end
|
601
|
-
end
|
602
|
-
|
603
|
-
# arbitrary opts are merged into the selector
|
604
|
-
command[:selector] = selector.merge!(opts)
|
605
|
-
|
606
|
-
begin
|
607
|
-
result = Cursor.new(system_command_collection, command).next_document
|
608
|
-
rescue OperationFailure => ex
|
609
|
-
if check_response
|
610
|
-
raise ex.class.new("Database command '#{selector.keys.first}' failed: #{ex.message}", ex.error_code, ex.result)
|
611
|
-
else
|
612
|
-
result = ex.result
|
613
|
-
end
|
614
|
-
end
|
615
|
-
|
616
|
-
raise OperationFailure,
|
617
|
-
"Database command '#{selector.keys.first}' failed: returned null." unless result
|
618
|
-
|
619
|
-
if check_response && (!ok?(result) || result['writeErrors'] || result['writeConcernError'])
|
620
|
-
message = "Database command '#{selector.keys.first}' failed: ("
|
621
|
-
message << result.map do |key, value|
|
622
|
-
"#{key}: '#{value}'"
|
623
|
-
end.join('; ')
|
624
|
-
message << ').'
|
625
|
-
code = result['code'] || result['assertionCode']
|
626
|
-
if result['writeErrors']
|
627
|
-
code = result['writeErrors'].first['code']
|
628
|
-
end
|
629
|
-
raise ExecutionTimeout.new(message, code, result) if code == MAX_TIME_MS_CODE
|
630
|
-
raise OperationFailure.new(message, code, result)
|
631
|
-
end
|
632
|
-
|
633
|
-
result
|
634
|
-
end
|
635
|
-
|
636
|
-
# A shortcut returning db plus dot plus collection name.
|
637
|
-
#
|
638
|
-
# @param [String] collection_name
|
639
|
-
#
|
640
|
-
# @return [String]
|
641
|
-
def full_collection_name(collection_name)
|
642
|
-
"#{@name}.#{collection_name}"
|
643
|
-
end
|
644
|
-
|
645
|
-
# The primary key factory object (or +nil+).
|
646
|
-
#
|
647
|
-
# @return [Object, Nil]
|
648
|
-
def pk_factory
|
649
|
-
@pk_factory
|
650
|
-
end
|
651
|
-
|
652
|
-
# Specify a primary key factory if not already set.
|
653
|
-
#
|
654
|
-
# @raise [MongoArgumentError] if the primary key factory has already been set.
|
655
|
-
def pk_factory=(pk_factory)
|
656
|
-
raise MongoArgumentError,
|
657
|
-
"Cannot change primary key factory once it's been set" if @pk_factory
|
658
|
-
|
659
|
-
@pk_factory = pk_factory
|
660
|
-
end
|
661
|
-
|
662
|
-
# Return the current database profiling level. If profiling is enabled, you can
|
663
|
-
# get the results using DB#profiling_info.
|
664
|
-
#
|
665
|
-
# @return [Symbol] :off, :slow_only, or :all
|
666
|
-
def profiling_level
|
667
|
-
cmd = BSON::OrderedHash.new
|
668
|
-
cmd[:profile] = -1
|
669
|
-
doc = command(cmd, :check_response => false)
|
670
|
-
|
671
|
-
raise "Error with profile command: #{doc.inspect}" unless ok?(doc)
|
672
|
-
|
673
|
-
level_sym = PROFILE_LEVEL.invert[doc['was'].to_i]
|
674
|
-
raise "Error: illegal profiling level value #{doc['was']}" unless level_sym
|
675
|
-
level_sym
|
676
|
-
end
|
677
|
-
|
678
|
-
# Set this database's profiling level. If profiling is enabled, you can
|
679
|
-
# get the results using DB#profiling_info.
|
680
|
-
#
|
681
|
-
# @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
|
682
|
-
def profiling_level=(level)
|
683
|
-
cmd = BSON::OrderedHash.new
|
684
|
-
cmd[:profile] = PROFILE_LEVEL[level]
|
685
|
-
doc = command(cmd, :check_response => false)
|
686
|
-
ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
|
687
|
-
end
|
688
|
-
|
689
|
-
# Get the current profiling information.
|
690
|
-
#
|
691
|
-
# @return [Array] a list of documents containing profiling information.
|
692
|
-
def profiling_info
|
693
|
-
Cursor.new(Collection.new(SYSTEM_PROFILE_COLLECTION, self), :selector => {}).to_a
|
694
|
-
end
|
695
|
-
|
696
|
-
# Validate a named collection.
|
697
|
-
#
|
698
|
-
# @param [String] name the collection name.
|
699
|
-
#
|
700
|
-
# @return [Hash] validation information.
|
701
|
-
#
|
702
|
-
# @raise [MongoDBError] if the command fails or there's a problem with the validation
|
703
|
-
# data, or if the collection is invalid.
|
704
|
-
def validate_collection(name)
|
705
|
-
cmd = BSON::OrderedHash.new
|
706
|
-
cmd[:validate] = name
|
707
|
-
cmd[:full] = true
|
708
|
-
doc = command(cmd, :check_response => false)
|
709
|
-
|
710
|
-
raise MongoDBError, "Error with validate command: #{doc.inspect}" unless ok?(doc)
|
711
|
-
|
712
|
-
if (doc.has_key?('valid') && !doc['valid']) || (doc['result'] =~ /\b(exception|corrupt)\b/i)
|
713
|
-
raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
|
714
|
-
end
|
715
|
-
doc
|
716
|
-
end
|
717
|
-
|
718
|
-
private
|
719
|
-
|
720
|
-
def system_command_collection
|
721
|
-
Collection.new(SYSTEM_COMMAND_COLLECTION, self)
|
722
|
-
end
|
723
|
-
|
724
|
-
# Create a new user.
|
725
|
-
#
|
726
|
-
# @param username [String] The username.
|
727
|
-
# @param password [String] The user's password.
|
728
|
-
# @param read_only [Boolean] Create a read-only user (deprecated in MongoDB >= 2.6)
|
729
|
-
# @param opts [Hash]
|
730
|
-
#
|
731
|
-
# @private
|
732
|
-
def create_or_update_user(command, username, password, read_only, opts)
|
733
|
-
if read_only || !opts.key?(:roles)
|
734
|
-
warn "Creating a user with the read_only option or without roles is " +
|
735
|
-
"deprecated in MongoDB >= 2.6"
|
736
|
-
end
|
737
|
-
|
738
|
-
# The password is always salted and hashed by the driver.
|
739
|
-
if opts.key?(:digestPassword)
|
740
|
-
raise MongoArgumentError,
|
741
|
-
"The digestPassword option is not available via DB#add_user. " +
|
742
|
-
"Use DB#command(:createUser => ...) instead for this option."
|
743
|
-
end
|
744
|
-
|
745
|
-
opts = opts.dup
|
746
|
-
pwd = Mongo::Authentication.hash_password(username, password) if password
|
747
|
-
cmd_opts = pwd ? { :pwd => pwd } : {}
|
748
|
-
# specify that the server shouldn't digest the password because the driver does
|
749
|
-
cmd_opts[:digestPassword] = false
|
750
|
-
unless opts.key?(:roles)
|
751
|
-
if name == 'admin'
|
752
|
-
roles = read_only ? ['readAnyDatabase'] : ['root']
|
753
|
-
else
|
754
|
-
roles = read_only ? ['read'] : ["dbOwner"]
|
755
|
-
end
|
756
|
-
cmd_opts[:roles] = roles
|
757
|
-
end
|
758
|
-
cmd_opts[:writeConcern] =
|
759
|
-
opts.key?(:writeConcern) ? opts.delete(:writeConcern) : { :w => 1 }
|
760
|
-
cmd_opts.merge!(opts)
|
761
|
-
command({ command => username }, cmd_opts)
|
762
|
-
end
|
763
|
-
|
764
|
-
# Create a user in MongoDB versions < 2.5.3.
|
765
|
-
# Called by #add_user if the 'usersInfo' command fails.
|
766
|
-
#
|
767
|
-
# @param username [String] The username.
|
768
|
-
# @param password [String] (nil) The user's password.
|
769
|
-
# @param read_only [Boolean] (false) Create a read-only user.
|
770
|
-
# @param opts [Hash]
|
771
|
-
#
|
772
|
-
# @private
|
773
|
-
def legacy_add_user(username, password=nil, read_only=false, opts={})
|
774
|
-
users = self[SYSTEM_USER_COLLECTION]
|
775
|
-
user = users.find_one(:user => username) || {:user => username}
|
776
|
-
user['pwd'] =
|
777
|
-
Mongo::Authentication.hash_password(username, password) if password
|
778
|
-
user['readOnly'] = true if read_only
|
779
|
-
user.merge!(opts)
|
780
|
-
begin
|
781
|
-
users.save(user)
|
782
|
-
rescue OperationFailure => ex
|
783
|
-
# adding first admin user fails GLE in MongoDB 2.2
|
784
|
-
raise ex unless ex.message =~ /login/
|
785
|
-
end
|
786
|
-
user
|
787
|
-
end
|
788
|
-
|
789
|
-
def legacy_list_indexes(collection_name)
|
790
|
-
sel = {:ns => full_collection_name(collection_name)}
|
791
|
-
Cursor.new(Collection.new(SYSTEM_INDEX_COLLECTION, self), :selector => sel)
|
792
|
-
end
|
793
|
-
|
794
|
-
def legacy_collections_info(coll_name=nil)
|
795
|
-
selector = {}
|
796
|
-
selector[:name] = full_collection_name(coll_name) if coll_name
|
797
|
-
Cursor.new(Collection.new(SYSTEM_NAMESPACE_COLLECTION, self), :selector => selector)
|
798
|
-
end
|
799
|
-
|
800
|
-
def legacy_collection_names
|
801
|
-
names = legacy_collections_info.collect { |doc| doc['name'] || '' }
|
802
|
-
names = names.delete_if do |name|
|
803
|
-
name.index(@name).nil? || name.index('$')
|
804
|
-
end
|
805
|
-
names.map {|name| name.sub(@name + '.', '')}
|
806
|
-
end
|
807
|
-
end
|
808
|
-
end
|