moped 1.0.0.rc → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of moped might be problematic. Click here for more details.
- data/CHANGELOG.md +11 -0
- data/README.md +32 -467
- data/lib/moped.rb +0 -1
- data/lib/moped/bson.rb +3 -0
- data/lib/moped/bson/binary.rb +4 -4
- data/lib/moped/bson/code.rb +12 -10
- data/lib/moped/bson/extensions.rb +64 -54
- data/lib/moped/bson/extensions/array.rb +9 -6
- data/lib/moped/bson/extensions/boolean.rb +1 -1
- data/lib/moped/bson/extensions/false_class.rb +5 -2
- data/lib/moped/bson/extensions/float.rb +1 -2
- data/lib/moped/bson/extensions/hash.rb +4 -5
- data/lib/moped/bson/extensions/integer.rb +2 -4
- data/lib/moped/bson/extensions/nil_class.rb +1 -2
- data/lib/moped/bson/extensions/object.rb +13 -0
- data/lib/moped/bson/extensions/regexp.rb +5 -6
- data/lib/moped/bson/extensions/string.rb +24 -13
- data/lib/moped/bson/extensions/symbol.rb +12 -14
- data/lib/moped/bson/extensions/time.rb +4 -4
- data/lib/moped/bson/extensions/true_class.rb +5 -2
- data/lib/moped/bson/max_key.rb +1 -2
- data/lib/moped/bson/min_key.rb +1 -2
- data/lib/moped/bson/object_id.rb +44 -4
- data/lib/moped/bson/types.rb +1 -1
- data/lib/moped/cluster.rb +13 -5
- data/lib/moped/collection.rb +5 -1
- data/lib/moped/connection.rb +4 -4
- data/lib/moped/database.rb +58 -29
- data/lib/moped/logging.rb +3 -3
- data/lib/moped/node.rb +35 -6
- data/lib/moped/protocol/command.rb +1 -4
- data/lib/moped/protocol/delete.rb +2 -0
- data/lib/moped/protocol/get_more.rb +16 -1
- data/lib/moped/protocol/insert.rb +2 -0
- data/lib/moped/protocol/kill_cursors.rb +2 -0
- data/lib/moped/protocol/message.rb +31 -12
- data/lib/moped/protocol/query.rb +15 -3
- data/lib/moped/protocol/reply.rb +6 -4
- data/lib/moped/protocol/update.rb +2 -0
- data/lib/moped/query.rb +60 -5
- data/lib/moped/session.rb +53 -17
- data/lib/moped/session/context.rb +17 -7
- data/lib/moped/threaded.rb +2 -1
- data/lib/moped/version.rb +1 -1
- metadata +11 -6
@@ -13,16 +13,13 @@ module Moped
|
|
13
13
|
# @param [Hash] command the command to run
|
14
14
|
# @param [Hash] additional query options
|
15
15
|
def initialize(database, command, options = {})
|
16
|
-
super database,
|
16
|
+
super database, '$cmd', command, options.merge(limit: -1)
|
17
17
|
end
|
18
18
|
|
19
19
|
def log_inspect
|
20
20
|
type = "COMMAND"
|
21
|
-
|
22
21
|
"%-12s database=%s command=%s" % [type, database, selector.inspect]
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
25
|
end
|
@@ -43,6 +43,8 @@ module Moped
|
|
43
43
|
# @return [Number] the id of the cursor to get more documents from
|
44
44
|
int64 :cursor_id
|
45
45
|
|
46
|
+
finalize
|
47
|
+
|
46
48
|
undef op_code
|
47
49
|
# @return [Number] OP_GETMORE operation code (2005)
|
48
50
|
def op_code
|
@@ -72,9 +74,22 @@ module Moped
|
|
72
74
|
|
73
75
|
def log_inspect
|
74
76
|
type = "GET_MORE"
|
75
|
-
|
76
77
|
"%-12s database=%s collection=%s limit=%s cursor_id=%s" % [type, database, collection, limit, cursor_id]
|
77
78
|
end
|
79
|
+
|
80
|
+
# Receive replies to the message.
|
81
|
+
#
|
82
|
+
# @example Receive replies.
|
83
|
+
# message.receive_replies(connection)
|
84
|
+
#
|
85
|
+
# @param [ Connection ] connection The connection.
|
86
|
+
#
|
87
|
+
# @return [ Protocol::Reply ] The reply.
|
88
|
+
#
|
89
|
+
# @since 1.0.0
|
90
|
+
def receive_replies(connection)
|
91
|
+
connection.read
|
92
|
+
end
|
78
93
|
end
|
79
94
|
end
|
80
95
|
end
|
@@ -271,6 +271,23 @@ module Moped
|
|
271
271
|
fields << name
|
272
272
|
end
|
273
273
|
|
274
|
+
# Declares the message class as complete, and defines its serialization
|
275
|
+
# method from the declared fields.
|
276
|
+
def finalize
|
277
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
278
|
+
def serialize(buffer = "")
|
279
|
+
start = buffer.bytesize
|
280
|
+
|
281
|
+
#{fields.map { |f| "serialize_#{f}(buffer)" }.join("\n")}
|
282
|
+
|
283
|
+
self.length = buffer.bytesize - start
|
284
|
+
buffer[start, 4] = serialize_length ""
|
285
|
+
buffer
|
286
|
+
end
|
287
|
+
alias to_s serialize
|
288
|
+
EOS
|
289
|
+
end
|
290
|
+
|
274
291
|
private
|
275
292
|
|
276
293
|
# This ensures that subclasses of the primary wire message classes have
|
@@ -283,25 +300,27 @@ module Moped
|
|
283
300
|
|
284
301
|
end
|
285
302
|
|
303
|
+
# Default implementation for a message is to do nothing when receiving
|
304
|
+
# replies.
|
305
|
+
#
|
306
|
+
# @example Receive replies.
|
307
|
+
# message.receive_replies(connection)
|
308
|
+
#
|
309
|
+
# @param [ Connection ] connection The connection.
|
310
|
+
#
|
311
|
+
# @since 1.0.0
|
312
|
+
#
|
313
|
+
# @return [ nil ] nil.
|
314
|
+
def receive_replies(connection); end
|
315
|
+
|
286
316
|
# Serializes the message and all of its fields to a new buffer or to the
|
287
317
|
# provided buffer.
|
288
318
|
#
|
289
319
|
# @param [String] buffer a buffer to serialize to
|
290
320
|
# @return [String] the result of serliazing this message
|
291
321
|
def serialize(buffer = "")
|
292
|
-
|
293
|
-
start = buffer.length
|
294
|
-
|
295
|
-
self.class.fields.each do |field|
|
296
|
-
__send__ :"serialize_#{field}", buffer
|
297
|
-
end
|
298
|
-
|
299
|
-
self.length = buffer.length - start
|
300
|
-
|
301
|
-
buffer[start, 4] = serialize_length("")
|
302
|
-
end
|
322
|
+
raise NotImplementedError, "This method is generated after calling #finalize on a message class"
|
303
323
|
end
|
304
|
-
|
305
324
|
alias to_s serialize
|
306
325
|
|
307
326
|
# @return [String] the nicely formatted version of the message
|
data/lib/moped/protocol/query.rb
CHANGED
@@ -64,6 +64,8 @@ module Moped
|
|
64
64
|
# @return [Hash, nil] the fields to include in the reply
|
65
65
|
document :fields, :optional => true
|
66
66
|
|
67
|
+
finalize
|
68
|
+
|
67
69
|
undef op_code
|
68
70
|
# @return [Number] OP_QUERY operation code (2004)
|
69
71
|
def op_code
|
@@ -111,7 +113,6 @@ module Moped
|
|
111
113
|
|
112
114
|
def log_inspect
|
113
115
|
type = "QUERY"
|
114
|
-
|
115
116
|
fields = []
|
116
117
|
fields << ["%-12s", type]
|
117
118
|
fields << ["database=%s", database]
|
@@ -121,12 +122,23 @@ module Moped
|
|
121
122
|
fields << ["limit=%s", limit.inspect]
|
122
123
|
fields << ["skip=%s", skip.inspect]
|
123
124
|
fields << ["fields=%s", self.fields.inspect]
|
124
|
-
|
125
125
|
f, v = fields.transpose
|
126
|
-
|
127
126
|
f.join(" ") % v
|
128
127
|
end
|
129
128
|
|
129
|
+
# Receive replies to the message.
|
130
|
+
#
|
131
|
+
# @example Receive replies.
|
132
|
+
# message.receive_replies(connection)
|
133
|
+
#
|
134
|
+
# @param [ Connection ] connection The connection.
|
135
|
+
#
|
136
|
+
# @return [ Protocol::Reply ] The reply.
|
137
|
+
#
|
138
|
+
# @since 1.0.0
|
139
|
+
def receive_replies(connection)
|
140
|
+
connection.read
|
141
|
+
end
|
130
142
|
end
|
131
143
|
end
|
132
144
|
end
|
data/lib/moped/protocol/reply.rb
CHANGED
@@ -51,6 +51,8 @@ module Moped
|
|
51
51
|
# @return [Array] the returned documents
|
52
52
|
document :documents, type: :array
|
53
53
|
|
54
|
+
finalize
|
55
|
+
|
54
56
|
class << self
|
55
57
|
|
56
58
|
# Consumes a buffer, returning the deserialized Reply message.
|
@@ -65,11 +67,11 @@ module Moped
|
|
65
67
|
# reply from.
|
66
68
|
# @return [Reply] the deserialized reply
|
67
69
|
def deserialize(buffer)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
70
|
+
reply = allocate
|
71
|
+
fields.each do |field|
|
72
|
+
reply.__send__ :"deserialize_#{field}", buffer
|
72
73
|
end
|
74
|
+
reply
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
data/lib/moped/query.rb
CHANGED
@@ -73,11 +73,11 @@ module Moped
|
|
73
73
|
# @yieldparam [ Hash ] document each matching document
|
74
74
|
def each
|
75
75
|
cursor = Cursor.new(session, operation)
|
76
|
-
cursor.to_enum
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
enum = cursor.to_enum
|
77
|
+
enum.each do |document|
|
78
|
+
yield document
|
79
|
+
end if block_given?
|
80
|
+
enum
|
81
81
|
end
|
82
82
|
|
83
83
|
# Explain the current query.
|
@@ -118,6 +118,22 @@ module Moped
|
|
118
118
|
end
|
119
119
|
alias :one :first
|
120
120
|
|
121
|
+
# Apply an index hint to the query.
|
122
|
+
#
|
123
|
+
# @example Apply an index hint.
|
124
|
+
# db[:people].find.hint("$natural" => 1)
|
125
|
+
#
|
126
|
+
# @param [ Hash ] hint The index hint.
|
127
|
+
#
|
128
|
+
# @return [ Query ] self
|
129
|
+
#
|
130
|
+
# @since 1.0.0
|
131
|
+
def hint(hint)
|
132
|
+
operation.selector = { "$query" => selector } unless operation.selector["$query"]
|
133
|
+
operation.selector["$hint"] = hint
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
121
137
|
# Initialize the query.
|
122
138
|
#
|
123
139
|
# @example Initialize the query.
|
@@ -151,6 +167,45 @@ module Moped
|
|
151
167
|
self
|
152
168
|
end
|
153
169
|
|
170
|
+
# Execute a $findAndModify on the query.
|
171
|
+
#
|
172
|
+
# @example Find and modify a document, returning the original.
|
173
|
+
# db[:bands].find.modify({ "$inc" => { likes: 1 }})
|
174
|
+
#
|
175
|
+
# @example Find and modify a document, returning the updated document.
|
176
|
+
# db[:bands].find.modify({ "$inc" => { likes: 1 }}, new: true)
|
177
|
+
#
|
178
|
+
# @example Find and return a document, removing it from the database.
|
179
|
+
# db[:bands].find.modify({}, remove: true)
|
180
|
+
#
|
181
|
+
# @example Find and return a document, upserting if no match found.
|
182
|
+
# db[:bands].find.modify({}, upsert: true, new: true)
|
183
|
+
#
|
184
|
+
# @param [ Hash ] change The changes to make to the document.
|
185
|
+
# @param [ Hash ] options The options.
|
186
|
+
#
|
187
|
+
# @option options :new Set to true if you want to return the updated document.
|
188
|
+
# @option options :remove Set to true if the document should be deleted.
|
189
|
+
# @option options :upsert Set to true if you want to upsert
|
190
|
+
#
|
191
|
+
# @return [ Hash ] The document.
|
192
|
+
#
|
193
|
+
# @since 1.0.0
|
194
|
+
def modify(change, options = {})
|
195
|
+
command = {
|
196
|
+
findAndModify: collection.name,
|
197
|
+
query: selector
|
198
|
+
}.merge(options)
|
199
|
+
|
200
|
+
command[:sort] = operation.selector["$orderby"] if operation.selector["$orderby"]
|
201
|
+
command[:fields] = operation.fields if operation.fields
|
202
|
+
command[:update] = change unless options[:remove]
|
203
|
+
|
204
|
+
session.with(consistency: :strong) do |sess|
|
205
|
+
sess.command(command)["value"]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
154
209
|
# Remove a single document matching the query's selector.
|
155
210
|
#
|
156
211
|
# @example Remove a single document.
|
data/lib/moped/session.rb
CHANGED
@@ -28,47 +28,88 @@ module Moped
|
|
28
28
|
# session.with(database: "admin").login("admin", "s3cr3t")
|
29
29
|
#
|
30
30
|
class Session
|
31
|
-
extend Forwardable
|
32
31
|
|
33
32
|
# @attribute [r] cluster The session cluster.
|
34
33
|
# @attribute [r] context The session context.
|
35
34
|
# @attribute [r] options The session options.
|
36
35
|
attr_reader :cluster, :context, :options
|
37
36
|
|
38
|
-
# @method [](collection)
|
39
37
|
# Return +collection+ from the current database.
|
40
38
|
#
|
41
39
|
# @param (see Moped::Database#[])
|
40
|
+
#
|
42
41
|
# @return (see Moped::Database#[])
|
43
|
-
|
42
|
+
#
|
43
|
+
# @since 1.0.0
|
44
|
+
def [](name)
|
45
|
+
current_database[name]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return non system collection name from the current database.
|
49
|
+
#
|
50
|
+
# @param (see Moped::Database#collection_names)
|
51
|
+
#
|
52
|
+
# @return (see Moped::Database#collection_names)
|
53
|
+
#
|
54
|
+
# @since 1.0.0
|
55
|
+
def collection_names
|
56
|
+
current_database.collection_names
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return non system collection name from the current database.
|
60
|
+
#
|
61
|
+
# @param (see Moped::Database#collections)
|
62
|
+
#
|
63
|
+
# @return (see Moped::Database#collections)
|
64
|
+
#
|
65
|
+
# @since 1.0.0
|
66
|
+
def collections
|
67
|
+
current_database.collections
|
68
|
+
end
|
44
69
|
|
45
|
-
# @method command(command)
|
46
70
|
# Run +command+ on the current database.
|
47
71
|
#
|
48
72
|
# @param (see Moped::Database#command)
|
73
|
+
#
|
49
74
|
# @return (see Moped::Database#command)
|
50
|
-
|
75
|
+
#
|
76
|
+
# @since 1.0.0
|
77
|
+
def command(op)
|
78
|
+
current_database.command(op)
|
79
|
+
end
|
51
80
|
|
52
|
-
# @method drop
|
53
81
|
# Drop the current database.
|
54
82
|
#
|
55
83
|
# @param (see Moped::Database#drop)
|
84
|
+
#
|
56
85
|
# @return (see Moped::Database#drop)
|
57
|
-
|
86
|
+
#
|
87
|
+
# @since 1.0.0
|
88
|
+
def drop
|
89
|
+
current_database.drop
|
90
|
+
end
|
58
91
|
|
59
|
-
# @method login(username, password)
|
60
92
|
# Log in with +username+ and +password+ on the current database.
|
61
93
|
#
|
62
94
|
# @param (see Moped::Database#login)
|
95
|
+
#
|
63
96
|
# @raise (see Moped::Database#login)
|
64
|
-
|
97
|
+
#
|
98
|
+
# @since 1.0.0
|
99
|
+
def login(username, password)
|
100
|
+
current_database.login(username, password)
|
101
|
+
end
|
65
102
|
|
66
|
-
# @method logout
|
67
103
|
# Log out from the current database.
|
68
104
|
#
|
69
105
|
# @param (see Moped::Database#logout)
|
106
|
+
#
|
70
107
|
# @raise (see Moped::Database#login)
|
71
|
-
|
108
|
+
#
|
109
|
+
# @since 1.0.0
|
110
|
+
def logout
|
111
|
+
current_database.logout
|
112
|
+
end
|
72
113
|
|
73
114
|
# Get the session's consistency.
|
74
115
|
#
|
@@ -168,12 +209,7 @@ module Moped
|
|
168
209
|
#
|
169
210
|
# @since 1.0.0
|
170
211
|
def safety
|
171
|
-
|
172
|
-
case safe
|
173
|
-
when false then false
|
174
|
-
when true then { safe: true }
|
175
|
-
else safe
|
176
|
-
end
|
212
|
+
options[:safe].__safe_options__
|
177
213
|
end
|
178
214
|
|
179
215
|
# Switch the session's current database.
|
@@ -3,16 +3,28 @@ module Moped
|
|
3
3
|
|
4
4
|
# @api private
|
5
5
|
class Context
|
6
|
-
|
6
|
+
|
7
|
+
attr_reader :session
|
7
8
|
|
8
9
|
def initialize(session)
|
9
10
|
@session = session
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
def safety
|
14
|
+
session.safety
|
15
|
+
end
|
16
|
+
|
17
|
+
def safe?
|
18
|
+
session.safe?
|
19
|
+
end
|
20
|
+
|
21
|
+
def consistency
|
22
|
+
session.consistency
|
23
|
+
end
|
24
|
+
|
25
|
+
def cluster
|
26
|
+
session.cluster
|
27
|
+
end
|
16
28
|
|
17
29
|
def login(database, username, password)
|
18
30
|
cluster.auth[database.to_s] = [username, password]
|
@@ -98,8 +110,6 @@ module Moped
|
|
98
110
|
end
|
99
111
|
end
|
100
112
|
end
|
101
|
-
|
102
113
|
end
|
103
|
-
|
104
114
|
end
|
105
115
|
end
|