faststep 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|