faststep 0.0.1 → 0.0.2
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.
- data/LICENSE +22 -0
- data/README.markdown +84 -0
- data/ext/faststep/bson_ruby_conversion.c +34 -8
- data/ext/faststep/bson_ruby_conversion.h +8 -5
- data/ext/faststep/collection.c +56 -13
- data/ext/faststep/collection.h +14 -12
- data/ext/faststep/connection.c +13 -7
- data/ext/faststep/connection.h +7 -6
- data/ext/faststep/cursor.c +86 -23
- data/ext/faststep/cursor.h +9 -4
- data/ext/faststep/exceptions.c +2 -2
- data/ext/faststep/faststep.c +11 -3
- data/ext/faststep/faststep_defines.h +4 -2
- data/lib/faststep/connection.rb +1 -7
- data/lib/faststep/version.rb +1 -1
- data/lib/faststep.rb +0 -1
- data/spec/collection_spec.rb +6 -0
- data/spec/cursor_spec.rb +60 -6
- metadata +5 -35
- data/lib/faststep/collection.rb +0 -21
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011 Josh Clayton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Faststep
|
2
|
+
|
3
|
+
## Mongo on Speed
|
4
|
+
|
5
|
+
### Install
|
6
|
+
|
7
|
+
Add to your Gemfile and `bundle`; otherwise,
|
8
|
+
|
9
|
+
gem install faststep
|
10
|
+
|
11
|
+
### Usage
|
12
|
+
|
13
|
+
Connect to mongo:
|
14
|
+
|
15
|
+
>> conn = Faststep::Connection.new("127.0.0.1", 27017)
|
16
|
+
|
17
|
+
Pick a database:
|
18
|
+
|
19
|
+
>> db = conn.db("awesome_development")
|
20
|
+
|
21
|
+
Have some fun!
|
22
|
+
|
23
|
+
>> db["users"].count
|
24
|
+
=> 0
|
25
|
+
>> db["users"].insert(10000.times.map {|i| { :name => "Person #{i}" } }
|
26
|
+
=> true
|
27
|
+
>> db["users"].count
|
28
|
+
=> 10000
|
29
|
+
>> db["users"].count(:name => /0$/)
|
30
|
+
=> 1000
|
31
|
+
>> db["users"].find(:name => /0$/).to_a
|
32
|
+
=> [{"_id"=>BSON::ObjectId('4d83c53555ca381d572c1cf7'), "name"=>"Person 0"}, {"_id"=>BSON::ObjectId('4d83c53555ca381d572c1d01'), "name"=>"Person 10"}, ...]
|
33
|
+
>> db["users"].remove(:name => /0$/)
|
34
|
+
=> nil
|
35
|
+
>> db["users"].count(:name => /0$/)
|
36
|
+
=> 0
|
37
|
+
>> db["users"].count
|
38
|
+
=> 9000
|
39
|
+
>> db["users"].drop
|
40
|
+
=> true
|
41
|
+
>> db.drop
|
42
|
+
=> true
|
43
|
+
|
44
|
+
### Caveats
|
45
|
+
|
46
|
+
This is under heavy development (what gem isn't?) but there's a lot of stuff to be implemented still. Some methods return nil (remove, for example) when they shouldn't.
|
47
|
+
It's not nearly as smart as the mongo Ruby driver and it doesn't handle errors that well.
|
48
|
+
|
49
|
+
### Todo
|
50
|
+
|
51
|
+
* Connection pooling
|
52
|
+
* Safe mode
|
53
|
+
* Allow updates to *not* be multi (currently unconfigurable)
|
54
|
+
* Master/slave
|
55
|
+
* Replica sets
|
56
|
+
|
57
|
+
Basically, most of http://www.mongodb.org/display/DOCS/Feature+Checklist+for+Mongo+Drivers
|
58
|
+
|
59
|
+
### About
|
60
|
+
|
61
|
+
This is a C extension that uses the [Mongo C driver](https://github.com/mongodb/mongo-c-driver).
|
62
|
+
As of right now, I haven't modified any of the code provided in that driver in here.
|
63
|
+
That code's Apache license still applies, and since it's not a derivative work (I haven't
|
64
|
+
changed any of the source), I'm using an MIT license for Faststep.
|
65
|
+
|
66
|
+
I've basically copied the benchmark from the [Mongo Ruby driver](https://github.com/mongodb/mongo-ruby-driver)
|
67
|
+
to test Faststep's speed, and all operations are anywhere between 10% (finding ranges on large docs)
|
68
|
+
and 120% faster (inserting small/medium indexed documents and inserting small/medium documents in batches).
|
69
|
+
See https://gist.github.com/870297 for benchmarks.
|
70
|
+
|
71
|
+
I started writing this driver for a project I'm working on called [Crowdtap](http://crowdtap.com),
|
72
|
+
which uses Mongo as its primary data store. I'd dabbled in C extensions before and
|
73
|
+
figured I could leverage this knowledge to speed up certain operations we were doing.
|
74
|
+
If it wasn't for them and their belief that I could get something usable in a short time,
|
75
|
+
this project probably wouldn't exist; thanks guys!
|
76
|
+
|
77
|
+
### License
|
78
|
+
|
79
|
+
The Mongo C driver code has retained its Apache license; I've released faststep under an MIT license (see
|
80
|
+
LICENSE for details).
|
81
|
+
|
82
|
+
### Author
|
83
|
+
|
84
|
+
Written 2011 by Josh Clayton.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#include "bson_ruby_conversion.h"
|
2
2
|
#include "faststep_defines.h"
|
3
3
|
|
4
|
-
bson* create_bson_from_ruby_hash(VALUE hash) {
|
4
|
+
bson* create_bson_from_ruby_hash(const VALUE hash) {
|
5
5
|
bson* document = bson_malloc(sizeof(bson));
|
6
6
|
|
7
7
|
if(NIL_P(hash)) {
|
@@ -18,27 +18,53 @@ bson* create_bson_from_ruby_hash(VALUE hash) {
|
|
18
18
|
return document;
|
19
19
|
}
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
bson* bson_from_ruby_array(const VALUE array) {
|
22
|
+
VALUE hash = rb_hash_new();
|
23
|
+
|
24
|
+
if(RTEST(array)) {
|
25
|
+
int iterator;
|
26
|
+
for(iterator = 0; iterator < RARRAY_LEN(array); iterator++) {
|
27
|
+
rb_hash_aset(hash, rb_ary_entry(array, iterator), INT2NUM(1));
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
create_bson_from_ruby_hash(hash);
|
32
|
+
}
|
33
|
+
|
34
|
+
VALUE ruby_array_to_bson_ordered_hash(const VALUE array) {
|
35
|
+
VALUE order_as_ordered_hash = rb_funcall(rb_cBsonOrderedHash, rb_intern("new"), 0);
|
36
|
+
rb_iterate(rb_each, array, _map_assoc_ary_to_key_value_pair, order_as_ordered_hash);
|
37
|
+
|
38
|
+
return order_as_ordered_hash;
|
23
39
|
}
|
24
40
|
|
25
|
-
VALUE ruby_hash_from_bson(bson* bson) {
|
41
|
+
VALUE ruby_hash_from_bson(const bson* bson) {
|
26
42
|
VALUE bson_buf = rb_str_new(bson->data, bson_size(bson));
|
27
43
|
|
28
44
|
return rb_funcall(rb_mBson, rb_intern("deserialize"), 1, bson_buf);
|
29
45
|
}
|
30
46
|
|
31
|
-
VALUE
|
47
|
+
VALUE bool_to_ruby(const bson_bool_t result) {
|
48
|
+
return result ? Qtrue : Qfalse;
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
VALUE ensure_document_ok(const VALUE document) {
|
32
53
|
if(rb_funcall(rb_mFaststepSupport, rb_intern("ok?"), 1, document) == Qfalse) {
|
33
|
-
rb_raise(
|
54
|
+
rb_raise(rb_eFaststepOperationFailure, _invalid_command_description(document));
|
34
55
|
}
|
35
56
|
}
|
36
57
|
|
37
|
-
static char* _invalid_command_description(VALUE document) {
|
58
|
+
static char* _invalid_command_description(const VALUE document) {
|
38
59
|
VALUE message = rb_str_new2("Invalid command (");
|
39
|
-
rb_str_concat(message,
|
60
|
+
rb_str_concat(message, rb_inspect(rb_hash_aref(document, rb_str_new2("bad cmd"))));
|
40
61
|
rb_str_concat(message, rb_str_new2("): "));
|
41
62
|
rb_str_concat(message, rb_hash_aref(document, rb_str_new2("errmsg")));
|
42
63
|
|
43
64
|
return RSTRING_PTR(message);
|
44
65
|
}
|
66
|
+
|
67
|
+
static VALUE _map_assoc_ary_to_key_value_pair(const VALUE item, VALUE hash) {
|
68
|
+
rb_hash_aset(hash, rb_ary_entry(item, 0), rb_ary_entry(item, 1));
|
69
|
+
return hash;
|
70
|
+
}
|
@@ -2,9 +2,12 @@
|
|
2
2
|
#include <ruby.h>
|
3
3
|
#include "bson.h"
|
4
4
|
#define BSON_RUBY_CONVERSION_H
|
5
|
-
bson* create_bson_from_ruby_hash(VALUE);
|
6
|
-
|
7
|
-
VALUE
|
8
|
-
VALUE
|
9
|
-
|
5
|
+
bson* create_bson_from_ruby_hash(const VALUE);
|
6
|
+
bson* bson_from_ruby_array(const VALUE);
|
7
|
+
VALUE ruby_array_to_bson_ordered_hash(const VALUE);
|
8
|
+
VALUE ruby_hash_from_bson(const bson*);
|
9
|
+
VALUE bool_to_ruby(const bson_bool_t);
|
10
|
+
VALUE ensure_document_ok(const VALUE);
|
11
|
+
static char* _invalid_command_description(const VALUE);
|
12
|
+
static VALUE _map_assoc_ary_to_key_value_pair(const VALUE, VALUE);
|
10
13
|
#endif
|
data/ext/faststep/collection.c
CHANGED
@@ -11,6 +11,8 @@ void faststep_collection_main() {
|
|
11
11
|
|
12
12
|
rb_define_method(rb_cFaststepCollection, "initialize", faststep_collection_init, 2);
|
13
13
|
rb_define_method(rb_cFaststepCollection, "ns", faststep_collection_ns, 0);
|
14
|
+
rb_define_method(rb_cFaststepCollection, "find", faststep_collection_find, -1);
|
15
|
+
rb_define_method(rb_cFaststepCollection, "find_one", faststep_collection_find_one, -1);
|
14
16
|
rb_define_method(rb_cFaststepCollection, "count", faststep_collection_count, -1);
|
15
17
|
rb_define_method(rb_cFaststepCollection, "insert", faststep_collection_insert, 1);
|
16
18
|
rb_define_method(rb_cFaststepCollection, "update", faststep_collection_update, 2);
|
@@ -20,14 +22,14 @@ void faststep_collection_main() {
|
|
20
22
|
return;
|
21
23
|
}
|
22
24
|
|
23
|
-
static VALUE faststep_collection_init(VALUE self, VALUE name, VALUE database) {
|
25
|
+
static VALUE faststep_collection_init(VALUE self, const VALUE name, const VALUE database) {
|
24
26
|
rb_iv_set(self, "@name", name);
|
25
27
|
rb_iv_set(self, "@db", database);
|
26
28
|
|
27
29
|
return self;
|
28
30
|
}
|
29
31
|
|
30
|
-
VALUE faststep_collection_ns(VALUE self) {
|
32
|
+
VALUE faststep_collection_ns(const VALUE self) {
|
31
33
|
VALUE db = rb_iv_get(self, "@db");
|
32
34
|
|
33
35
|
char ns[255] = "";
|
@@ -51,7 +53,48 @@ static VALUE faststep_collection_count(int argc, VALUE* argv, VALUE self) {
|
|
51
53
|
return ULL2NUM(count);
|
52
54
|
}
|
53
55
|
|
54
|
-
|
56
|
+
static VALUE faststep_collection_find(int argc, VALUE* argv, VALUE self) {
|
57
|
+
VALUE selector, options;
|
58
|
+
rb_scan_args(argc, argv, "02", &selector, &options);
|
59
|
+
if(!RTEST(selector)) { selector = rb_hash_new(); }
|
60
|
+
if(!RTEST(options)) { options = rb_hash_new(); }
|
61
|
+
|
62
|
+
VALUE full_query = rb_hash_new();
|
63
|
+
rb_hash_aset(full_query, rb_str_new2("selector"), selector);
|
64
|
+
rb_funcall(full_query, rb_intern("merge"), 1, options);
|
65
|
+
|
66
|
+
return rb_funcall(rb_cFaststepCursor, rb_intern("new"), 2, self, full_query);
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE faststep_collection_find_one(int argc, VALUE* argv, VALUE self) {
|
70
|
+
VALUE selector, options;
|
71
|
+
rb_scan_args(argc, argv, "02", &selector, &options);
|
72
|
+
|
73
|
+
if(!RTEST(options)) { options = rb_hash_new(); }
|
74
|
+
|
75
|
+
VALUE full_query = rb_hash_new();
|
76
|
+
|
77
|
+
if(RTEST(rb_funcall(selector, rb_intern("is_a?"), 1, rb_cBsonObjectId))) {
|
78
|
+
rb_hash_aset(full_query, rb_str_new2("_id"), selector);
|
79
|
+
} else {
|
80
|
+
switch(TYPE(selector)) {
|
81
|
+
case T_NIL:
|
82
|
+
break;
|
83
|
+
case T_HASH:
|
84
|
+
full_query = selector;
|
85
|
+
break;
|
86
|
+
default:
|
87
|
+
rb_raise(rb_eTypeError, "selector must be an instance of BSON::ObjectId, Hash, or nil");
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
rb_hash_aset(options, rb_str_new2("limit"), INT2NUM(-1));
|
92
|
+
|
93
|
+
VALUE result = rb_funcall(self, rb_intern("find"), 2, full_query, options);
|
94
|
+
return rb_funcall(result, rb_intern("first"), 0);
|
95
|
+
}
|
96
|
+
|
97
|
+
void build_collection_ns(char* ns, const char* database, const char* collection) {
|
55
98
|
strcat(ns, database);
|
56
99
|
strcat(ns, ".");
|
57
100
|
strcat(ns, collection);
|
@@ -59,7 +102,7 @@ void build_collection_ns(char* ns, char* database, char* collection) {
|
|
59
102
|
return;
|
60
103
|
}
|
61
104
|
|
62
|
-
static VALUE faststep_collection_insert(VALUE self, VALUE documents) {
|
105
|
+
static VALUE faststep_collection_insert(const VALUE self, const VALUE documents) {
|
63
106
|
mongo_connection* conn = GetFaststepConnectionForCollection(self);
|
64
107
|
|
65
108
|
VALUE ns = faststep_collection_ns(self);
|
@@ -73,7 +116,7 @@ static VALUE faststep_collection_insert(VALUE self, VALUE documents) {
|
|
73
116
|
return Qtrue;
|
74
117
|
}
|
75
118
|
|
76
|
-
static VALUE faststep_collection_update(VALUE self, VALUE query, VALUE operations) {
|
119
|
+
static VALUE faststep_collection_update(const VALUE self, const VALUE query, const VALUE operations) {
|
77
120
|
bson* bson_query = create_bson_from_ruby_hash(query);
|
78
121
|
bson* bson_operations = create_bson_from_ruby_hash(operations);
|
79
122
|
|
@@ -102,7 +145,7 @@ static VALUE faststep_collection_remove(int argc, VALUE* argv, VALUE self) {
|
|
102
145
|
return Qnil;
|
103
146
|
}
|
104
147
|
|
105
|
-
static VALUE faststep_collection_drop(VALUE self) {
|
148
|
+
static VALUE faststep_collection_drop(const VALUE self) {
|
106
149
|
bson_bool_t result = mongo_cmd_drop_collection(GetFaststepConnectionForCollection(self),
|
107
150
|
_ivar_name(rb_iv_get(self, "@db")),
|
108
151
|
_ivar_name(self),
|
@@ -111,7 +154,7 @@ static VALUE faststep_collection_drop(VALUE self) {
|
|
111
154
|
return bool_to_ruby(result);
|
112
155
|
}
|
113
156
|
|
114
|
-
static VALUE faststep_collection_create_index(VALUE self, VALUE indexes) {
|
157
|
+
static VALUE faststep_collection_create_index(const VALUE self, const VALUE indexes) {
|
115
158
|
bson* bson_indexes = create_bson_from_ruby_hash(indexes);
|
116
159
|
|
117
160
|
bson_bool_t result = mongo_create_index(GetFaststepConnectionForCollection(self),
|
@@ -124,13 +167,13 @@ static VALUE faststep_collection_create_index(VALUE self, VALUE indexes) {
|
|
124
167
|
return bool_to_ruby(result);
|
125
168
|
}
|
126
169
|
|
127
|
-
static void _faststep_collection_insert_one(mongo_connection* conn, char* ns, VALUE document) {
|
170
|
+
static void _faststep_collection_insert_one(mongo_connection* conn, const char* ns, const VALUE document) {
|
128
171
|
bson* bson_document = create_bson_from_ruby_hash(document);
|
129
172
|
mongo_insert(conn, ns, bson_document);
|
130
173
|
bson_destroy(bson_document);
|
131
174
|
}
|
132
175
|
|
133
|
-
static void _faststep_collection_insert_batch(mongo_connection* conn, char* ns, VALUE documents) {
|
176
|
+
static void _faststep_collection_insert_batch(mongo_connection* conn, const char* ns, const VALUE documents) {
|
134
177
|
int total_document_count = RARRAY_LEN(documents);
|
135
178
|
bson** bson_documents = (bson**)malloc(sizeof(bson*) * total_document_count);
|
136
179
|
|
@@ -167,7 +210,7 @@ static void _faststep_collection_insert_batch(mongo_connection* conn, char* ns,
|
|
167
210
|
}
|
168
211
|
}
|
169
212
|
|
170
|
-
static void _faststep_collection_destroy(bson** bson_documents, int document_count) {
|
213
|
+
static void _faststep_collection_destroy(bson** bson_documents, const int document_count) {
|
171
214
|
int iterator;
|
172
215
|
for(iterator = 0; iterator < document_count; iterator++) {
|
173
216
|
bson_destroy(bson_documents[iterator]);
|
@@ -175,11 +218,11 @@ static void _faststep_collection_destroy(bson** bson_documents, int document_cou
|
|
175
218
|
return;
|
176
219
|
}
|
177
220
|
|
178
|
-
static char* _ivar_name(VALUE
|
179
|
-
return RSTRING_PTR(rb_iv_get(
|
221
|
+
static char* _ivar_name(const VALUE object) {
|
222
|
+
return RSTRING_PTR(rb_iv_get(object, "@name"));
|
180
223
|
}
|
181
224
|
|
182
|
-
mongo_connection* GetFaststepConnectionForCollection(VALUE collection) {
|
225
|
+
mongo_connection* GetFaststepConnectionForCollection(const VALUE collection) {
|
183
226
|
VALUE db = rb_iv_get(collection, "@db");
|
184
227
|
VALUE connection = rb_iv_get(db, "@connection");
|
185
228
|
|
data/ext/faststep/collection.h
CHANGED
@@ -5,20 +5,22 @@
|
|
5
5
|
#define COLLECTION_H
|
6
6
|
|
7
7
|
void faststep_collection_main();
|
8
|
-
static VALUE faststep_collection_init(VALUE, VALUE, VALUE);
|
8
|
+
static VALUE faststep_collection_init(VALUE, const VALUE, const VALUE);
|
9
|
+
static VALUE faststep_collection_find(int, VALUE*, const VALUE);
|
10
|
+
static VALUE faststep_collection_find_one(int, VALUE*, const VALUE);
|
9
11
|
static VALUE faststep_collection_count(int, VALUE*, VALUE);
|
10
|
-
static VALUE faststep_collection_insert(VALUE, VALUE);
|
11
|
-
static VALUE faststep_collection_update(VALUE, VALUE, VALUE);
|
12
|
+
static VALUE faststep_collection_insert(const VALUE, const VALUE);
|
13
|
+
static VALUE faststep_collection_update(const VALUE, const VALUE, const VALUE);
|
12
14
|
static VALUE faststep_collection_remove(int, VALUE*, VALUE);
|
13
|
-
static VALUE faststep_collection_drop(VALUE);
|
14
|
-
static VALUE faststep_collection_create_index(VALUE, VALUE);
|
15
|
-
VALUE faststep_collection_ns(VALUE);
|
15
|
+
static VALUE faststep_collection_drop(const VALUE);
|
16
|
+
static VALUE faststep_collection_create_index(const VALUE, const VALUE);
|
17
|
+
VALUE faststep_collection_ns(const VALUE);
|
16
18
|
|
17
|
-
static void _faststep_collection_insert_one(mongo_connection*, char*, VALUE);
|
18
|
-
static void _faststep_collection_insert_batch(mongo_connection*, char*, VALUE);
|
19
|
-
mongo_connection* GetFaststepConnectionForCollection(VALUE);
|
20
|
-
static void _faststep_collection_destroy(bson**, int);
|
19
|
+
static void _faststep_collection_insert_one(mongo_connection*, const char*, const VALUE);
|
20
|
+
static void _faststep_collection_insert_batch(mongo_connection*, const char*, const VALUE);
|
21
|
+
mongo_connection* GetFaststepConnectionForCollection(const VALUE);
|
22
|
+
static void _faststep_collection_destroy(bson**, const int);
|
21
23
|
|
22
|
-
void build_collection_ns(char*, char*, char*);
|
23
|
-
static char* _ivar_name(VALUE);
|
24
|
+
void build_collection_ns(char*, const char*, const char*);
|
25
|
+
static char* _ivar_name(const VALUE);
|
24
26
|
#endif
|
data/ext/faststep/connection.c
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
void faststep_connection_main() {
|
6
6
|
rb_cFaststepConnection = rb_define_class_under(rb_mFaststep, "Connection", rb_cObject);
|
7
|
+
rb_define_const(rb_cFaststepConnection, "DEFAULT_PORT", INT2FIX(27017));
|
7
8
|
|
8
9
|
rb_define_attr(rb_cFaststepConnection, "host", 1, 0);
|
9
10
|
rb_define_attr(rb_cFaststepConnection, "port", 1, 0);
|
@@ -15,11 +16,12 @@ void faststep_connection_main() {
|
|
15
16
|
rb_define_method(rb_cFaststepConnection, "disconnect!", faststep_connection_disconnect, 0);
|
16
17
|
rb_define_method(rb_cFaststepConnection, "connected?", faststep_connection_connected, 0);
|
17
18
|
rb_define_method(rb_cFaststepConnection, "master?", faststep_connection_master, 0);
|
19
|
+
rb_define_method(rb_cFaststepConnection, "db", faststep_connection_db, 1);
|
18
20
|
|
19
21
|
return;
|
20
22
|
}
|
21
23
|
|
22
|
-
static VALUE faststep_connection_init(VALUE self, VALUE host, VALUE port) {
|
24
|
+
static VALUE faststep_connection_init(VALUE self, const VALUE host, const VALUE port) {
|
23
25
|
rb_iv_set(self, "@host", host);
|
24
26
|
rb_iv_set(self, "@port", port);
|
25
27
|
|
@@ -28,7 +30,7 @@ static VALUE faststep_connection_init(VALUE self, VALUE host, VALUE port) {
|
|
28
30
|
return self;
|
29
31
|
}
|
30
32
|
|
31
|
-
static VALUE faststep_connection_new(VALUE class, VALUE host, VALUE port) {
|
33
|
+
static VALUE faststep_connection_new(VALUE class, const VALUE host, const VALUE port) {
|
32
34
|
mongo_connection* conn = bson_malloc(sizeof(mongo_connection));
|
33
35
|
|
34
36
|
VALUE tdata = Data_Wrap_Struct(class, NULL, mongo_destroy, conn);
|
@@ -53,32 +55,36 @@ static VALUE faststep_connection_connect(VALUE self) {
|
|
53
55
|
return Qnil;
|
54
56
|
}
|
55
57
|
|
56
|
-
static VALUE faststep_connection_disconnect(VALUE self) {
|
58
|
+
static VALUE faststep_connection_disconnect(const VALUE self) {
|
57
59
|
mongo_disconnect(GetFaststepConnection(self));
|
58
60
|
|
59
61
|
return Qnil;
|
60
62
|
}
|
61
63
|
|
62
|
-
static VALUE faststep_connection_connected(VALUE self) {
|
64
|
+
static VALUE faststep_connection_connected(const VALUE self) {
|
63
65
|
return bool_to_ruby(GetFaststepConnection(self)->connected);
|
64
66
|
}
|
65
67
|
|
66
|
-
static VALUE faststep_connection_master(VALUE self) {
|
68
|
+
static VALUE faststep_connection_master(const VALUE self) {
|
67
69
|
return bool_to_ruby(mongo_cmd_ismaster(GetFaststepConnection(self), NULL));
|
68
70
|
}
|
69
71
|
|
72
|
+
static VALUE faststep_connection_db(const VALUE self, const VALUE database_name) {
|
73
|
+
return rb_funcall(rb_cFaststepDb, rb_intern("new"), 2, database_name, self);
|
74
|
+
}
|
75
|
+
|
70
76
|
static void _faststep_connect_or_raise(mongo_connection* conn, mongo_connection_options* options) {
|
71
77
|
mongo_connect(conn, options);
|
72
78
|
|
73
79
|
if(conn->connected == 0) {
|
74
80
|
mongo_destroy(conn);
|
75
|
-
rb_raise(
|
81
|
+
rb_raise(rb_eFaststepConnectionFailure, "unable to connect to Mongo");
|
76
82
|
}
|
77
83
|
|
78
84
|
return;
|
79
85
|
}
|
80
86
|
|
81
|
-
mongo_connection* GetFaststepConnection(VALUE object) {
|
87
|
+
mongo_connection* GetFaststepConnection(const VALUE object) {
|
82
88
|
mongo_connection* conn;
|
83
89
|
Data_Get_Struct(object, mongo_connection, conn);
|
84
90
|
return conn;
|
data/ext/faststep/connection.h
CHANGED
@@ -4,14 +4,15 @@
|
|
4
4
|
#define CONNECTION_H
|
5
5
|
void faststep_connection_main();
|
6
6
|
|
7
|
-
static VALUE faststep_connection_init(VALUE, VALUE, VALUE);
|
8
|
-
static VALUE faststep_connection_new(VALUE, VALUE, VALUE);
|
7
|
+
static VALUE faststep_connection_init(VALUE, const VALUE, const VALUE);
|
8
|
+
static VALUE faststep_connection_new(VALUE, const VALUE, const VALUE);
|
9
9
|
static VALUE faststep_connection_connect(VALUE);
|
10
|
-
static VALUE faststep_connection_disconnect(VALUE);
|
11
|
-
static VALUE faststep_connection_connected(VALUE);
|
12
|
-
static VALUE faststep_connection_master(VALUE);
|
10
|
+
static VALUE faststep_connection_disconnect(const VALUE);
|
11
|
+
static VALUE faststep_connection_connected(const VALUE);
|
12
|
+
static VALUE faststep_connection_master(const VALUE);
|
13
|
+
static VALUE faststep_connection_db(const VALUE, const VALUE);
|
13
14
|
|
14
|
-
mongo_connection* GetFaststepConnection(VALUE);
|
15
|
+
mongo_connection* GetFaststepConnection(const VALUE);
|
15
16
|
|
16
17
|
static void _faststep_connect_or_raise(mongo_connection*, mongo_connection_options*);
|
17
18
|
#endif
|
data/ext/faststep/cursor.c
CHANGED
@@ -9,53 +9,116 @@ void faststep_cursor_main() {
|
|
9
9
|
rb_define_attr(rb_cFaststepCursor, "collection", 1, 0);
|
10
10
|
rb_include_module(rb_cFaststepCursor, rb_mEnumerable);
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
rb_define_method(rb_cFaststepCursor, "
|
15
|
-
rb_define_method(rb_cFaststepCursor, "
|
12
|
+
rb_define_method(rb_cFaststepCursor, "initialize", faststep_cursor_init, -1);
|
13
|
+
rb_define_method(rb_cFaststepCursor, "explain", faststep_cursor_explain, 0);
|
14
|
+
rb_define_method(rb_cFaststepCursor, "skip", faststep_cursor_skip, 1);
|
15
|
+
rb_define_method(rb_cFaststepCursor, "limit", faststep_cursor_limit, 1);
|
16
|
+
rb_define_method(rb_cFaststepCursor, "fields", faststep_cursor_fields, 1);
|
17
|
+
rb_define_method(rb_cFaststepCursor, "order", faststep_cursor_order, 1);
|
18
|
+
rb_define_method(rb_cFaststepCursor, "each", faststep_cursor_each, 0);
|
16
19
|
|
17
20
|
return;
|
18
21
|
}
|
19
22
|
|
20
|
-
static VALUE faststep_cursor_init(
|
23
|
+
static VALUE faststep_cursor_init(int argc, VALUE* argv, VALUE self) {
|
24
|
+
VALUE collection, options;
|
25
|
+
rb_scan_args(argc, argv, "11", &collection, &options);
|
26
|
+
|
21
27
|
rb_iv_set(self, "@collection", collection);
|
22
28
|
|
29
|
+
VALUE selector = rb_hash_aref(options, rb_str_new2("selector"));
|
30
|
+
if(NIL_P(selector)) { selector = rb_hash_new(); }
|
31
|
+
if(RTEST(rb_hash_aref(selector, rb_str_new2("$query")))) {
|
32
|
+
rb_iv_set(self, "@selector", rb_hash_aref(selector, rb_str_new2("$query")));
|
33
|
+
} else {
|
34
|
+
rb_iv_set(self, "@selector", selector);
|
35
|
+
}
|
36
|
+
|
37
|
+
rb_iv_set(self, "@explain", Qfalse);
|
38
|
+
rb_iv_set(self, "@fields", rb_hash_aref(options, rb_str_new2("fields")));
|
39
|
+
rb_iv_set(self, "@skip", rb_hash_aref(options, rb_str_new2("skip")));
|
40
|
+
rb_iv_set(self, "@limit", rb_hash_aref(options, rb_str_new2("limit")));
|
41
|
+
|
23
42
|
return self;
|
24
43
|
}
|
25
44
|
|
26
|
-
static VALUE
|
27
|
-
mongo_cursor* cursor = _faststep_build_mongo_cursor(
|
45
|
+
static VALUE faststep_cursor_each(const VALUE self) {
|
46
|
+
mongo_cursor* cursor = _faststep_build_mongo_cursor(self);
|
28
47
|
|
29
|
-
|
48
|
+
while(mongo_cursor_next(cursor)) {
|
49
|
+
rb_yield(ruby_hash_from_bson(&cursor->current));
|
50
|
+
}
|
51
|
+
}
|
30
52
|
|
31
|
-
|
32
|
-
|
33
|
-
argv[1] = options;
|
53
|
+
static VALUE faststep_cursor_explain(VALUE self) {
|
54
|
+
rb_iv_set(self, "@explain", Qtrue);
|
34
55
|
|
35
|
-
|
56
|
+
mongo_cursor* cursor = _faststep_build_mongo_cursor(self);
|
57
|
+
mongo_cursor_next(cursor);
|
36
58
|
|
37
|
-
|
59
|
+
VALUE result = ruby_hash_from_bson(&cursor->current);
|
60
|
+
mongo_cursor_destroy(cursor);
|
61
|
+
return result;
|
38
62
|
}
|
39
63
|
|
40
|
-
static VALUE
|
41
|
-
|
42
|
-
|
64
|
+
static VALUE faststep_cursor_skip(VALUE self, const VALUE skip_count) {
|
65
|
+
rb_iv_set(self, "@skip", skip_count);
|
66
|
+
return self;
|
67
|
+
}
|
43
68
|
|
44
|
-
|
45
|
-
|
46
|
-
|
69
|
+
static VALUE faststep_cursor_limit(VALUE self, const VALUE limit_count) {
|
70
|
+
rb_iv_set(self, "@limit", limit_count);
|
71
|
+
return self;
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE faststep_cursor_fields(VALUE self, const VALUE fields) {
|
75
|
+
rb_iv_set(self, "@fields", fields);
|
76
|
+
return self;
|
47
77
|
}
|
48
78
|
|
49
|
-
static
|
50
|
-
|
79
|
+
static VALUE faststep_cursor_order(VALUE self, const VALUE order) {
|
80
|
+
rb_iv_set(self, "@order", ruby_array_to_bson_ordered_hash(order));
|
81
|
+
return self;
|
82
|
+
}
|
83
|
+
|
84
|
+
static mongo_cursor* _faststep_build_mongo_cursor(VALUE self) {
|
85
|
+
bson* selector = create_bson_from_ruby_hash(_faststep_build_full_query(self));
|
86
|
+
bson* fields = bson_from_ruby_array(rb_iv_get(self, "@fields"));
|
87
|
+
|
88
|
+
int limit = 0;
|
89
|
+
if(RTEST(rb_iv_get(self, "@limit"))) {
|
90
|
+
limit = -1*FIX2INT(rb_iv_get(self, "@limit"));
|
91
|
+
}
|
92
|
+
|
93
|
+
int skip = 0;
|
94
|
+
if(RTEST(rb_iv_get(self, "@skip"))) {
|
95
|
+
skip = FIX2INT(rb_iv_get(self, "@skip"));
|
96
|
+
}
|
97
|
+
|
98
|
+
VALUE collection = rb_iv_get(self, "@collection");
|
51
99
|
|
52
100
|
mongo_cursor* result = mongo_find(GetFaststepConnectionForCollection(collection),
|
53
101
|
RSTRING_PTR(rb_funcall(collection, rb_intern("ns"), 0)),
|
54
102
|
selector,
|
55
|
-
|
56
|
-
|
103
|
+
fields,
|
104
|
+
limit, skip, 0);
|
57
105
|
|
58
106
|
bson_destroy(selector);
|
107
|
+
bson_destroy(fields);
|
59
108
|
|
60
109
|
return result;
|
61
110
|
}
|
111
|
+
|
112
|
+
static VALUE _faststep_build_full_query(VALUE self) {
|
113
|
+
if(RTEST(rb_iv_get(self, "@explain")) || RTEST(rb_iv_get(self, "@order"))) {
|
114
|
+
VALUE full_query = rb_hash_new();
|
115
|
+
rb_hash_aset(full_query, rb_str_new2("$query"), rb_iv_get(self, "@selector"));
|
116
|
+
rb_hash_aset(full_query, rb_str_new2("$explain"), rb_iv_get(self, "@explain"));
|
117
|
+
if(RTEST(rb_iv_get(self, "@order"))) {
|
118
|
+
rb_hash_aset(full_query, rb_str_new2("$orderby"), rb_iv_get(self, "@order"));
|
119
|
+
}
|
120
|
+
return full_query;
|
121
|
+
} else {
|
122
|
+
return rb_iv_get(self, "@selector");
|
123
|
+
}
|
124
|
+
}
|
data/ext/faststep/cursor.h
CHANGED
@@ -3,8 +3,13 @@
|
|
3
3
|
#include "mongo.h"
|
4
4
|
#define CURSOR_h
|
5
5
|
void faststep_cursor_main();
|
6
|
-
static VALUE faststep_cursor_init(
|
7
|
-
static VALUE
|
8
|
-
static VALUE
|
9
|
-
static
|
6
|
+
static VALUE faststep_cursor_init(int, VALUE*, VALUE);
|
7
|
+
static VALUE faststep_cursor_each(const VALUE);
|
8
|
+
static VALUE faststep_cursor_explain(VALUE);
|
9
|
+
static VALUE faststep_cursor_skip(VALUE, const VALUE);
|
10
|
+
static VALUE faststep_cursor_limit(VALUE, const VALUE);
|
11
|
+
static VALUE faststep_cursor_fields(VALUE, const VALUE);
|
12
|
+
static VALUE faststep_cursor_order(VALUE, const VALUE);
|
13
|
+
static mongo_cursor* _faststep_build_mongo_cursor(VALUE);
|
14
|
+
static VALUE _faststep_build_full_query(VALUE);
|
10
15
|
#endif
|
data/ext/faststep/exceptions.c
CHANGED
@@ -2,6 +2,6 @@
|
|
2
2
|
#include "faststep_defines.h"
|
3
3
|
|
4
4
|
void faststep_exceptions_main() {
|
5
|
-
|
6
|
-
|
5
|
+
rb_eFaststepConnectionFailure = rb_define_class_under(rb_mFaststep, "ConnectionFailure", rb_eStandardError);
|
6
|
+
rb_eFaststepOperationFailure = rb_define_class_under(rb_mFaststep, "OperationFailure", rb_eStandardError);
|
7
7
|
}
|
data/ext/faststep/faststep.c
CHANGED
@@ -7,6 +7,9 @@
|
|
7
7
|
#include "support.h"
|
8
8
|
|
9
9
|
VALUE rb_mBson;
|
10
|
+
VALUE rb_cBsonOrderedHash;
|
11
|
+
VALUE rb_cBsonObjectId;
|
12
|
+
|
10
13
|
VALUE rb_mFaststep;
|
11
14
|
VALUE rb_cFaststepConnection;
|
12
15
|
VALUE rb_cFaststepDb;
|
@@ -14,12 +17,17 @@ VALUE rb_cFaststepCollection;
|
|
14
17
|
VALUE rb_cFaststepCursor;
|
15
18
|
VALUE rb_mFaststepSupport;
|
16
19
|
|
17
|
-
VALUE
|
18
|
-
VALUE
|
20
|
+
VALUE rb_eFaststepConnectionFailure;
|
21
|
+
VALUE rb_eFaststepOperationFailure;
|
19
22
|
|
20
23
|
void Init_faststep() {
|
21
24
|
rb_mFaststep = rb_define_module("Faststep");
|
22
|
-
|
25
|
+
rb_define_const(rb_mFaststep, "DESCENDING", NUM2INT(-1));
|
26
|
+
rb_define_const(rb_mFaststep, "ASCENDING", NUM2INT(1));
|
27
|
+
|
28
|
+
rb_mBson = rb_const_get(rb_cObject, rb_intern("BSON"));
|
29
|
+
rb_cBsonOrderedHash = rb_const_get(rb_mBson, rb_intern("OrderedHash"));
|
30
|
+
rb_cBsonObjectId = rb_const_get(rb_mBson, rb_intern("ObjectId"));
|
23
31
|
|
24
32
|
faststep_connection_main();
|
25
33
|
faststep_db_main();
|
@@ -5,7 +5,9 @@ RUBY_EXTERN VALUE rb_cFaststepDb;
|
|
5
5
|
RUBY_EXTERN VALUE rb_cFaststepCollection;
|
6
6
|
RUBY_EXTERN VALUE rb_cFaststepCursor;
|
7
7
|
|
8
|
-
RUBY_EXTERN VALUE
|
9
|
-
RUBY_EXTERN VALUE
|
8
|
+
RUBY_EXTERN VALUE rb_eFaststepConnectionFailure;
|
9
|
+
RUBY_EXTERN VALUE rb_eFaststepOperationFailure;
|
10
10
|
|
11
11
|
RUBY_EXTERN VALUE rb_mBson;
|
12
|
+
RUBY_EXTERN VALUE rb_cBsonOrderedHash;
|
13
|
+
RUBY_EXTERN VALUE rb_cBsonObjectId;
|
data/lib/faststep/connection.rb
CHANGED
data/lib/faststep/version.rb
CHANGED
data/lib/faststep.rb
CHANGED
data/spec/collection_spec.rb
CHANGED
@@ -28,6 +28,12 @@ describe Faststep::Collection do
|
|
28
28
|
db["another.thing"].find({}).first["baz"].should == "qux"
|
29
29
|
end
|
30
30
|
|
31
|
+
it "finds single documents" do
|
32
|
+
10.times { db["something"].insert(:foo => "bar") }
|
33
|
+
db["something"].find_one({:foo => "bar"})["foo"].should == "bar"
|
34
|
+
db["something"].find_one(BSON::ObjectId.new).should be_nil
|
35
|
+
end
|
36
|
+
|
31
37
|
it "updates documents" do
|
32
38
|
db["something"].insert(:foo => "bar", :something => "fun")
|
33
39
|
db["something"].update({ :something => "fun" }, { "$set" => { :foo => "awesome" } })
|
data/spec/cursor_spec.rb
CHANGED
@@ -10,15 +10,69 @@ describe Faststep::Cursor do
|
|
10
10
|
cursor = Faststep::Cursor.new(collection, {})
|
11
11
|
cursor.to_a.length.should_not == 0
|
12
12
|
cursor.each do |doc|
|
13
|
-
doc[
|
13
|
+
doc["foo"].should == "bar"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
it "
|
18
|
-
|
17
|
+
it "finds specific fields for a document" do
|
18
|
+
collection.insert(:name => "John Doe", :age => 25, :gender => "Male", :postal_code => "02108")
|
19
|
+
collection.insert(:name => "Jane Doe", :age => 22, :gender => "Female", :postal_code => "02108")
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
documents = collection.find.fields(%w(name age)).to_a
|
22
|
+
|
23
|
+
documents.each do |document|
|
24
|
+
document.has_key?("name").should be_true
|
25
|
+
document.has_key?("age").should be_true
|
26
|
+
document.has_key?("_id").should be_true
|
27
|
+
document.has_key?("gender").should be_false
|
28
|
+
document.has_key?("postal_code").should be_false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "limits documents" do
|
33
|
+
10.times.map { |i| collection.insert(:name => "Person #{i}") }
|
34
|
+
|
35
|
+
documents = collection.find.limit(2).to_a
|
36
|
+
documents.map {|doc| doc["name"] }.should == ["Person 0", "Person 1"]
|
37
|
+
|
38
|
+
documents = collection.find({}).limit(1).to_a
|
39
|
+
documents.length.should == 1
|
40
|
+
documents.first["name"].should == "Person 0"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "skips documents" do
|
44
|
+
collection.insert(:name => "John Doe", :age => 25, :gender => "Male", :postal_code => "02108")
|
45
|
+
collection.insert(:name => "Jane Doe", :age => 22, :gender => "Female", :postal_code => "02108")
|
46
|
+
collection.insert(:name => "John Smith", :age => 40, :gender => "Male", :postal_code => "02108")
|
47
|
+
|
48
|
+
documents = collection.find.skip(1).to_a
|
49
|
+
documents.length.should == 2
|
50
|
+
documents[0]["name"].should == "Jane Doe"
|
51
|
+
documents[1]["name"].should == "John Smith"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "orders documents" do
|
55
|
+
10.times.map { |i| collection.insert(:name => "Person #{i}", :age => 24) }
|
56
|
+
collection.insert(:name => "Person 9", :age => 20)
|
57
|
+
collection.find.order([[:name, Faststep::DESCENDING], [:age, Faststep::ASCENDING]]).to_a.tap do |documents|
|
58
|
+
documents.first["name"].should == "Person 9"
|
59
|
+
documents.first["age"].should == 20
|
60
|
+
end
|
61
|
+
|
62
|
+
collection.find.order([[:age, Faststep::DESCENDING], [:name, Faststep::ASCENDING]]).to_a.tap do |documents|
|
63
|
+
documents.first["name"].should == "Person 0"
|
64
|
+
end
|
65
|
+
|
66
|
+
collection.find.order([[:age, Faststep::DESCENDING], [:name, Faststep::DESCENDING]]).to_a.tap do |documents|
|
67
|
+
documents.first["name"].should == "Person 9"
|
68
|
+
documents.first["age"].should == 24
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "explains queries" do
|
73
|
+
result = collection.find.explain
|
74
|
+
result.should have_key("cursor")
|
75
|
+
result.should have_key("nscanned")
|
76
|
+
result.should have_key("n")
|
23
77
|
end
|
24
78
|
end
|
metadata
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faststep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 29
|
5
4
|
prerelease:
|
6
|
-
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 1
|
10
|
-
version: 0.0.1
|
5
|
+
version: 0.0.2
|
11
6
|
platform: ruby
|
12
7
|
authors:
|
13
8
|
- Josh Clayton
|
@@ -15,7 +10,7 @@ autorequire:
|
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
12
|
|
18
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-20 00:00:00 -04:00
|
19
14
|
default_executable:
|
20
15
|
dependencies:
|
21
16
|
- !ruby/object:Gem::Dependency
|
@@ -26,11 +21,6 @@ dependencies:
|
|
26
21
|
requirements:
|
27
22
|
- - "="
|
28
23
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 15
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
- 7
|
33
|
-
- 6
|
34
24
|
version: 0.7.6
|
35
25
|
type: :runtime
|
36
26
|
version_requirements: *id001
|
@@ -42,11 +32,6 @@ dependencies:
|
|
42
32
|
requirements:
|
43
33
|
- - "="
|
44
34
|
- !ruby/object:Gem::Version
|
45
|
-
hash: 23
|
46
|
-
segments:
|
47
|
-
- 1
|
48
|
-
- 2
|
49
|
-
- 4
|
50
35
|
version: 1.2.4
|
51
36
|
type: :runtime
|
52
37
|
version_requirements: *id002
|
@@ -58,11 +43,6 @@ dependencies:
|
|
58
43
|
requirements:
|
59
44
|
- - "="
|
60
45
|
- !ruby/object:Gem::Version
|
61
|
-
hash: 23
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 2
|
65
|
-
- 4
|
66
46
|
version: 1.2.4
|
67
47
|
type: :runtime
|
68
48
|
version_requirements: *id003
|
@@ -74,11 +54,6 @@ dependencies:
|
|
74
54
|
requirements:
|
75
55
|
- - "="
|
76
56
|
- !ruby/object:Gem::Version
|
77
|
-
hash: 27
|
78
|
-
segments:
|
79
|
-
- 2
|
80
|
-
- 5
|
81
|
-
- 0
|
82
57
|
version: 2.5.0
|
83
58
|
type: :development
|
84
59
|
version_requirements: *id004
|
@@ -94,6 +69,8 @@ extra_rdoc_files: []
|
|
94
69
|
files:
|
95
70
|
- .gitignore
|
96
71
|
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- README.markdown
|
97
74
|
- Rakefile
|
98
75
|
- bench/standard_benchmark
|
99
76
|
- ext/faststep/bson.c
|
@@ -127,7 +104,6 @@ files:
|
|
127
104
|
- ext/faststep/support.h
|
128
105
|
- faststep.gemspec
|
129
106
|
- lib/faststep.rb
|
130
|
-
- lib/faststep/collection.rb
|
131
107
|
- lib/faststep/connection.rb
|
132
108
|
- lib/faststep/cursor.rb
|
133
109
|
- lib/faststep/db.rb
|
@@ -152,23 +128,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
128
|
requirements:
|
153
129
|
- - ">="
|
154
130
|
- !ruby/object:Gem::Version
|
155
|
-
hash: 3
|
156
|
-
segments:
|
157
|
-
- 0
|
158
131
|
version: "0"
|
159
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
133
|
none: false
|
161
134
|
requirements:
|
162
135
|
- - ">="
|
163
136
|
- !ruby/object:Gem::Version
|
164
|
-
hash: 3
|
165
|
-
segments:
|
166
|
-
- 0
|
167
137
|
version: "0"
|
168
138
|
requirements: []
|
169
139
|
|
170
140
|
rubyforge_project:
|
171
|
-
rubygems_version: 1.
|
141
|
+
rubygems_version: 1.6.2
|
172
142
|
signing_key:
|
173
143
|
specification_version: 3
|
174
144
|
summary: Mongo on Speed
|
data/lib/faststep/collection.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
module Faststep
|
2
|
-
class Collection
|
3
|
-
def find(selector = {}, options = {})
|
4
|
-
Cursor.new(self, "selector" => selector)
|
5
|
-
end
|
6
|
-
|
7
|
-
def find_one(spec_or_object_id=nil, opts={})
|
8
|
-
spec = case spec_or_object_id
|
9
|
-
when nil
|
10
|
-
{}
|
11
|
-
when BSON::ObjectId
|
12
|
-
{:_id => spec_or_object_id}
|
13
|
-
when Hash
|
14
|
-
spec_or_object_id
|
15
|
-
else
|
16
|
-
raise TypeError, "spec_or_object_id must be an instance of ObjectId or Hash, or nil"
|
17
|
-
end
|
18
|
-
find(spec, opts.merge(:limit => -1)).first
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|