faststep 0.0.1

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.
Files changed (47) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +15 -0
  4. data/bench/standard_benchmark +178 -0
  5. data/ext/faststep/bson.c +687 -0
  6. data/ext/faststep/bson.h +225 -0
  7. data/ext/faststep/bson_ruby_conversion.c +44 -0
  8. data/ext/faststep/bson_ruby_conversion.h +10 -0
  9. data/ext/faststep/collection.c +187 -0
  10. data/ext/faststep/collection.h +24 -0
  11. data/ext/faststep/connection.c +85 -0
  12. data/ext/faststep/connection.h +17 -0
  13. data/ext/faststep/cursor.c +61 -0
  14. data/ext/faststep/cursor.h +10 -0
  15. data/ext/faststep/db.c +56 -0
  16. data/ext/faststep/db.h +8 -0
  17. data/ext/faststep/exceptions.c +7 -0
  18. data/ext/faststep/exceptions.h +5 -0
  19. data/ext/faststep/extconf.rb +3 -0
  20. data/ext/faststep/faststep.c +30 -0
  21. data/ext/faststep/faststep.h +4 -0
  22. data/ext/faststep/faststep_defines.h +11 -0
  23. data/ext/faststep/gridfs.c +799 -0
  24. data/ext/faststep/gridfs.h +278 -0
  25. data/ext/faststep/md5.c +381 -0
  26. data/ext/faststep/md5.h +91 -0
  27. data/ext/faststep/mongo.c +801 -0
  28. data/ext/faststep/mongo.h +188 -0
  29. data/ext/faststep/mongo_except.h +143 -0
  30. data/ext/faststep/numbers.c +127 -0
  31. data/ext/faststep/platform_hacks.h +93 -0
  32. data/ext/faststep/support.c +21 -0
  33. data/ext/faststep/support.h +6 -0
  34. data/faststep.gemspec +26 -0
  35. data/lib/faststep/collection.rb +21 -0
  36. data/lib/faststep/connection.rb +13 -0
  37. data/lib/faststep/cursor.rb +7 -0
  38. data/lib/faststep/db.rb +25 -0
  39. data/lib/faststep/version.rb +3 -0
  40. data/lib/faststep.rb +10 -0
  41. data/spec/collection_spec.rb +116 -0
  42. data/spec/connection_spec.rb +34 -0
  43. data/spec/cursor_spec.rb +24 -0
  44. data/spec/db_spec.rb +28 -0
  45. data/spec/spec_helper.rb +13 -0
  46. data/spec/support_spec.rb +14 -0
  47. metadata +181 -0
@@ -0,0 +1,225 @@
1
+ /* bson.h */
2
+
3
+ /* Copyright 2009, 2010 10gen Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _BSON_H_
19
+ #define _BSON_H_
20
+
21
+ #include "platform_hacks.h"
22
+ #include <time.h>
23
+
24
+ MONGO_EXTERN_C_START
25
+
26
+ typedef enum {
27
+ bson_eoo=0 ,
28
+ bson_double=1,
29
+ bson_string=2,
30
+ bson_object=3,
31
+ bson_array=4,
32
+ bson_bindata=5,
33
+ bson_undefined=6,
34
+ bson_oid=7,
35
+ bson_bool=8,
36
+ bson_date=9,
37
+ bson_null=10,
38
+ bson_regex=11,
39
+ bson_dbref=12, /* deprecated */
40
+ bson_code=13,
41
+ bson_symbol=14,
42
+ bson_codewscope=15,
43
+ bson_int = 16,
44
+ bson_timestamp = 17,
45
+ bson_long = 18
46
+ } bson_type;
47
+
48
+ typedef int bson_bool_t;
49
+
50
+ typedef struct {
51
+ char * data;
52
+ bson_bool_t owned;
53
+ } bson;
54
+
55
+ typedef struct {
56
+ const char * cur;
57
+ bson_bool_t first;
58
+ } bson_iterator;
59
+
60
+ typedef struct {
61
+ char * buf;
62
+ char * cur;
63
+ int bufSize;
64
+ bson_bool_t finished;
65
+ int stack[32];
66
+ int stackPos;
67
+ } bson_buffer;
68
+
69
+ #pragma pack(1)
70
+ typedef union{
71
+ char bytes[12];
72
+ int ints[3];
73
+ } bson_oid_t;
74
+ #pragma pack()
75
+
76
+ typedef int64_t bson_date_t; /* milliseconds since epoch UTC */
77
+
78
+ typedef struct {
79
+ int i; /* increment */
80
+ int t; /* time in seconds */
81
+ } bson_timestamp_t;
82
+
83
+ /* ----------------------------
84
+ READING
85
+ ------------------------------ */
86
+
87
+ bson * bson_empty(bson * obj); /* returns pointer to static empty bson object */
88
+ void bson_copy(bson* out, const bson* in); /* puts data in new buffer. NOOP if out==NULL */
89
+ bson * bson_from_buffer(bson * b, bson_buffer * buf);
90
+ bson * bson_init( bson * b , char * data , bson_bool_t mine );
91
+ int bson_size(const bson * b );
92
+ void bson_destroy( bson * b );
93
+
94
+ void bson_print( bson * b );
95
+ void bson_print_raw( const char * bson , int depth );
96
+
97
+ /* advances iterator to named field */
98
+ /* returns bson_eoo (which is false) if field not found */
99
+ bson_type bson_find(bson_iterator* it, const bson* obj, const char* name);
100
+
101
+ void bson_iterator_init( bson_iterator * i , const char * bson );
102
+
103
+ /* more returns true for eoo. best to loop with bson_iterator_next(&it) */
104
+ bson_bool_t bson_iterator_more( const bson_iterator * i );
105
+ bson_type bson_iterator_next( bson_iterator * i );
106
+
107
+ bson_type bson_iterator_type( const bson_iterator * i );
108
+ const char * bson_iterator_key( const bson_iterator * i );
109
+ const char * bson_iterator_value( const bson_iterator * i );
110
+
111
+ /* these convert to the right type (return 0 if non-numeric) */
112
+ double bson_iterator_double( const bson_iterator * i );
113
+ int bson_iterator_int( const bson_iterator * i );
114
+ int64_t bson_iterator_long( const bson_iterator * i );
115
+
116
+ /* return the bson timestamp as a whole or in parts */
117
+ bson_timestamp_t bson_iterator_timestamp( const bson_iterator * i );
118
+
119
+ /* false: boolean false, 0 in any type, or null */
120
+ /* true: anything else (even empty strings and objects) */
121
+ bson_bool_t bson_iterator_bool( const bson_iterator * i );
122
+
123
+ /* these assume you are using the right type */
124
+ double bson_iterator_double_raw( const bson_iterator * i );
125
+ int bson_iterator_int_raw( const bson_iterator * i );
126
+ int64_t bson_iterator_long_raw( const bson_iterator * i );
127
+ bson_bool_t bson_iterator_bool_raw( const bson_iterator * i );
128
+ bson_oid_t* bson_iterator_oid( const bson_iterator * i );
129
+
130
+ /* these can also be used with bson_code and bson_symbol*/
131
+ const char * bson_iterator_string( const bson_iterator * i );
132
+ int bson_iterator_string_len( const bson_iterator * i );
133
+
134
+ /* works with bson_code, bson_codewscope, and bson_string */
135
+ /* returns NULL for everything else */
136
+ const char * bson_iterator_code(const bson_iterator * i);
137
+
138
+ /* calls bson_empty on scope if not a bson_codewscope */
139
+ void bson_iterator_code_scope(const bson_iterator * i, bson * scope);
140
+
141
+ /* both of these only work with bson_date */
142
+ bson_date_t bson_iterator_date(const bson_iterator * i);
143
+ time_t bson_iterator_time_t(const bson_iterator * i);
144
+
145
+ int bson_iterator_bin_len( const bson_iterator * i );
146
+ char bson_iterator_bin_type( const bson_iterator * i );
147
+ const char * bson_iterator_bin_data( const bson_iterator * i );
148
+
149
+ const char * bson_iterator_regex( const bson_iterator * i );
150
+ const char * bson_iterator_regex_opts( const bson_iterator * i );
151
+
152
+ /* these work with bson_object and bson_array */
153
+ void bson_iterator_subobject(const bson_iterator * i, bson * sub);
154
+ void bson_iterator_subiterator(const bson_iterator * i, bson_iterator * sub);
155
+
156
+ /* str must be at least 24 hex chars + null byte */
157
+ void bson_oid_from_string(bson_oid_t* oid, const char* str);
158
+ void bson_oid_to_string(const bson_oid_t* oid, char* str);
159
+ void bson_oid_gen(bson_oid_t* oid);
160
+
161
+ time_t bson_oid_generated_time(bson_oid_t* oid); /* Gives the time the OID was created */
162
+
163
+ /* ----------------------------
164
+ BUILDING
165
+ ------------------------------ */
166
+
167
+ bson_buffer * bson_buffer_init( bson_buffer * b );
168
+ bson_buffer * bson_ensure_space( bson_buffer * b , const int bytesNeeded );
169
+
170
+ /**
171
+ * @return the raw data. you either should free this OR call bson_destroy not both
172
+ */
173
+ char * bson_buffer_finish( bson_buffer * b );
174
+ void bson_buffer_destroy( bson_buffer * b );
175
+
176
+ bson_buffer * bson_append_oid( bson_buffer * b , const char * name , const bson_oid_t* oid );
177
+ bson_buffer * bson_append_new_oid( bson_buffer * b , const char * name );
178
+ bson_buffer * bson_append_int( bson_buffer * b , const char * name , const int i );
179
+ bson_buffer * bson_append_long( bson_buffer * b , const char * name , const int64_t i );
180
+ bson_buffer * bson_append_double( bson_buffer * b , const char * name , const double d );
181
+ bson_buffer * bson_append_string( bson_buffer * b , const char * name , const char * str );
182
+ bson_buffer * bson_append_symbol( bson_buffer * b , const char * name , const char * str );
183
+ bson_buffer * bson_append_code( bson_buffer * b , const char * name , const char * str );
184
+ bson_buffer * bson_append_code_w_scope( bson_buffer * b , const char * name , const char * code , const bson * scope);
185
+ bson_buffer * bson_append_binary( bson_buffer * b, const char * name, char type, const char * str, int len );
186
+ bson_buffer * bson_append_bool( bson_buffer * b , const char * name , const bson_bool_t v );
187
+ bson_buffer * bson_append_null( bson_buffer * b , const char * name );
188
+ bson_buffer * bson_append_undefined( bson_buffer * b , const char * name );
189
+ bson_buffer * bson_append_regex( bson_buffer * b , const char * name , const char * pattern, const char * opts );
190
+ bson_buffer * bson_append_bson( bson_buffer * b , const char * name , const bson* bson);
191
+ bson_buffer * bson_append_element( bson_buffer * b, const char * name_or_null, const bson_iterator* elem);
192
+ bson_buffer * bson_append_timestamp( bson_buffer * b, const char * name, bson_timestamp_t * ts );
193
+
194
+ /* these both append a bson_date */
195
+ bson_buffer * bson_append_date(bson_buffer * b, const char * name, bson_date_t millis);
196
+ bson_buffer * bson_append_time_t(bson_buffer * b, const char * name, time_t secs);
197
+
198
+ bson_buffer * bson_append_start_object( bson_buffer * b , const char * name );
199
+ bson_buffer * bson_append_start_array( bson_buffer * b , const char * name );
200
+ bson_buffer * bson_append_finish_object( bson_buffer * b );
201
+
202
+ void bson_numstr(char* str, int i);
203
+ void bson_incnumstr(char* str);
204
+
205
+
206
+ /* ------------------------------
207
+ ERROR HANDLING - also used in mongo code
208
+ ------------------------------ */
209
+
210
+ void * bson_malloc(int size); /* checks return value */
211
+ void * bson_realloc(void * ptr, int size); /* checks return value */
212
+
213
+ /* bson_err_handlers shouldn't return!!! */
214
+ typedef void(*bson_err_handler)(const char* errmsg);
215
+
216
+ /* returns old handler or NULL */
217
+ /* default handler prints error then exits with failure*/
218
+ bson_err_handler set_bson_err_handler(bson_err_handler func);
219
+
220
+ /* does nothing is ok != 0 */
221
+ void bson_fatal( int ok );
222
+ void bson_fatal_msg( int ok, const char* msg );
223
+
224
+ MONGO_EXTERN_C_END
225
+ #endif
@@ -0,0 +1,44 @@
1
+ #include "bson_ruby_conversion.h"
2
+ #include "faststep_defines.h"
3
+
4
+ bson* create_bson_from_ruby_hash(VALUE hash) {
5
+ bson* document = bson_malloc(sizeof(bson));
6
+
7
+ if(NIL_P(hash)) {
8
+ bson_empty(document);
9
+ } else {
10
+ VALUE byte_buffer = rb_funcall(rb_mBson, rb_intern("serialize"), 3, hash, Qfalse, Qfalse);
11
+ VALUE query = rb_funcall(byte_buffer, rb_intern("to_s"), 0);
12
+ bson* temp_bson = bson_malloc(sizeof(bson));
13
+ bson_init(temp_bson, RSTRING_PTR(query), 0);
14
+ bson_copy(document, temp_bson);
15
+ bson_destroy(temp_bson);
16
+ }
17
+
18
+ return document;
19
+ }
20
+
21
+ VALUE bool_to_ruby(bson_bool_t result) {
22
+ return result ? Qtrue : Qfalse;
23
+ }
24
+
25
+ VALUE ruby_hash_from_bson(bson* bson) {
26
+ VALUE bson_buf = rb_str_new(bson->data, bson_size(bson));
27
+
28
+ return rb_funcall(rb_mBson, rb_intern("deserialize"), 1, bson_buf);
29
+ }
30
+
31
+ VALUE ensure_document_ok(VALUE document) {
32
+ if(rb_funcall(rb_mFaststepSupport, rb_intern("ok?"), 1, document) == Qfalse) {
33
+ rb_raise(rb_cFaststepOperationFailure, _invalid_command_description(document));
34
+ }
35
+ }
36
+
37
+ static char* _invalid_command_description(VALUE document) {
38
+ VALUE message = rb_str_new2("Invalid command (");
39
+ rb_str_concat(message, rb_funcall(rb_hash_aref(document, rb_str_new2("bad cmd")), rb_intern("inspect"), 0));
40
+ rb_str_concat(message, rb_str_new2("): "));
41
+ rb_str_concat(message, rb_hash_aref(document, rb_str_new2("errmsg")));
42
+
43
+ return RSTRING_PTR(message);
44
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef BSON_RUBY_CONVERSION_H
2
+ #include <ruby.h>
3
+ #include "bson.h"
4
+ #define BSON_RUBY_CONVERSION_H
5
+ bson* create_bson_from_ruby_hash(VALUE);
6
+ VALUE ruby_hash_from_bson(bson*);
7
+ VALUE ensure_document_ok(VALUE);
8
+ VALUE bool_to_ruby(bson_bool_t);
9
+ static char* _invalid_command_description(VALUE);
10
+ #endif
@@ -0,0 +1,187 @@
1
+ #include "collection.h"
2
+ #include "connection.h"
3
+ #include "bson_ruby_conversion.h"
4
+ #include "faststep_defines.h"
5
+ #include <string.h>
6
+
7
+ void faststep_collection_main() {
8
+ rb_cFaststepCollection = rb_define_class_under(rb_mFaststep, "Collection", rb_cObject);
9
+
10
+ rb_define_attr(rb_cFaststepCollection, "name", 1, 0);
11
+
12
+ rb_define_method(rb_cFaststepCollection, "initialize", faststep_collection_init, 2);
13
+ rb_define_method(rb_cFaststepCollection, "ns", faststep_collection_ns, 0);
14
+ rb_define_method(rb_cFaststepCollection, "count", faststep_collection_count, -1);
15
+ rb_define_method(rb_cFaststepCollection, "insert", faststep_collection_insert, 1);
16
+ rb_define_method(rb_cFaststepCollection, "update", faststep_collection_update, 2);
17
+ rb_define_method(rb_cFaststepCollection, "remove", faststep_collection_remove, -1);
18
+ rb_define_method(rb_cFaststepCollection, "drop", faststep_collection_drop, 0);
19
+ rb_define_method(rb_cFaststepCollection, "create_index", faststep_collection_create_index, 1);
20
+ return;
21
+ }
22
+
23
+ static VALUE faststep_collection_init(VALUE self, VALUE name, VALUE database) {
24
+ rb_iv_set(self, "@name", name);
25
+ rb_iv_set(self, "@db", database);
26
+
27
+ return self;
28
+ }
29
+
30
+ VALUE faststep_collection_ns(VALUE self) {
31
+ VALUE db = rb_iv_get(self, "@db");
32
+
33
+ char ns[255] = "";
34
+ build_collection_ns(ns, _ivar_name(db), _ivar_name(self));
35
+
36
+ return rb_str_new2(ns);
37
+ }
38
+
39
+ static VALUE faststep_collection_count(int argc, VALUE* argv, VALUE self) {
40
+ VALUE query;
41
+ rb_scan_args(argc, argv, "01", &query);
42
+
43
+ bson* bson_query = create_bson_from_ruby_hash(query);
44
+
45
+ int64_t count = mongo_count(GetFaststepConnectionForCollection(self),
46
+ _ivar_name(rb_iv_get(self, "@db")),
47
+ _ivar_name(self),
48
+ bson_query);
49
+
50
+ bson_destroy(bson_query);
51
+ return ULL2NUM(count);
52
+ }
53
+
54
+ void build_collection_ns(char* ns, char* database, char* collection) {
55
+ strcat(ns, database);
56
+ strcat(ns, ".");
57
+ strcat(ns, collection);
58
+
59
+ return;
60
+ }
61
+
62
+ static VALUE faststep_collection_insert(VALUE self, VALUE documents) {
63
+ mongo_connection* conn = GetFaststepConnectionForCollection(self);
64
+
65
+ VALUE ns = faststep_collection_ns(self);
66
+
67
+ if(TYPE(documents) == T_ARRAY) {
68
+ _faststep_collection_insert_batch(conn, RSTRING_PTR(ns), documents);
69
+ } else {
70
+ _faststep_collection_insert_one(conn, RSTRING_PTR(ns), documents);
71
+ }
72
+
73
+ return Qtrue;
74
+ }
75
+
76
+ static VALUE faststep_collection_update(VALUE self, VALUE query, VALUE operations) {
77
+ bson* bson_query = create_bson_from_ruby_hash(query);
78
+ bson* bson_operations = create_bson_from_ruby_hash(operations);
79
+
80
+ mongo_update(GetFaststepConnectionForCollection(self),
81
+ RSTRING_PTR(faststep_collection_ns(self)),
82
+ bson_query,
83
+ bson_operations,
84
+ MONGO_UPDATE_MULTI);
85
+
86
+ bson_destroy(bson_query);
87
+ bson_destroy(bson_operations);
88
+
89
+ return Qtrue;
90
+ }
91
+
92
+ static VALUE faststep_collection_remove(int argc, VALUE* argv, VALUE self) {
93
+ VALUE query;
94
+ rb_scan_args(argc, argv, "01", &query);
95
+
96
+ bson* bson_query = create_bson_from_ruby_hash(query);
97
+
98
+ mongo_remove(GetFaststepConnectionForCollection(self),
99
+ RSTRING_PTR(faststep_collection_ns(self)),
100
+ bson_query);
101
+ bson_destroy(bson_query);
102
+ return Qnil;
103
+ }
104
+
105
+ static VALUE faststep_collection_drop(VALUE self) {
106
+ bson_bool_t result = mongo_cmd_drop_collection(GetFaststepConnectionForCollection(self),
107
+ _ivar_name(rb_iv_get(self, "@db")),
108
+ _ivar_name(self),
109
+ NULL);
110
+
111
+ return bool_to_ruby(result);
112
+ }
113
+
114
+ static VALUE faststep_collection_create_index(VALUE self, VALUE indexes) {
115
+ bson* bson_indexes = create_bson_from_ruby_hash(indexes);
116
+
117
+ bson_bool_t result = mongo_create_index(GetFaststepConnectionForCollection(self),
118
+ RSTRING_PTR(faststep_collection_ns(self)),
119
+ bson_indexes,
120
+ 0,
121
+ NULL);
122
+ bson_destroy(bson_indexes);
123
+
124
+ return bool_to_ruby(result);
125
+ }
126
+
127
+ static void _faststep_collection_insert_one(mongo_connection* conn, char* ns, VALUE document) {
128
+ bson* bson_document = create_bson_from_ruby_hash(document);
129
+ mongo_insert(conn, ns, bson_document);
130
+ bson_destroy(bson_document);
131
+ }
132
+
133
+ static void _faststep_collection_insert_batch(mongo_connection* conn, char* ns, VALUE documents) {
134
+ int total_document_count = RARRAY_LEN(documents);
135
+ bson** bson_documents = (bson**)malloc(sizeof(bson*) * total_document_count);
136
+
137
+ int chunk_size = 1024*1024*16;
138
+ int sent_document_count = 0,
139
+ current_bson_size = 0,
140
+ current_document_count = 0,
141
+ iterator;
142
+
143
+ for(iterator = 0; iterator < total_document_count; iterator++) {
144
+ int current_document_array_index = sent_document_count + current_document_count;
145
+ bson* document = create_bson_from_ruby_hash(rb_ary_entry(documents, current_document_array_index));
146
+
147
+ if(bson_size(document) + current_bson_size > chunk_size) {
148
+ mongo_insert_batch(conn, ns, bson_documents, current_document_count);
149
+ _faststep_collection_destroy(bson_documents, current_document_count);
150
+
151
+ sent_document_count += current_document_count;
152
+ total_document_count -= current_document_count;
153
+
154
+ current_bson_size = 0;
155
+ current_document_count = 0;
156
+ iterator = 0;
157
+ }
158
+
159
+ bson_documents[iterator] = document;
160
+ current_document_count += 1;
161
+ current_bson_size += bson_size(document);
162
+ }
163
+
164
+ if(current_document_count > 0) {
165
+ mongo_insert_batch(conn, ns, bson_documents, current_document_count);
166
+ _faststep_collection_destroy(bson_documents, current_document_count);
167
+ }
168
+ }
169
+
170
+ static void _faststep_collection_destroy(bson** bson_documents, int document_count) {
171
+ int iterator;
172
+ for(iterator = 0; iterator < document_count; iterator++) {
173
+ bson_destroy(bson_documents[iterator]);
174
+ }
175
+ return;
176
+ }
177
+
178
+ static char* _ivar_name(VALUE obj) {
179
+ return RSTRING_PTR(rb_iv_get(obj, "@name"));
180
+ }
181
+
182
+ mongo_connection* GetFaststepConnectionForCollection(VALUE collection) {
183
+ VALUE db = rb_iv_get(collection, "@db");
184
+ VALUE connection = rb_iv_get(db, "@connection");
185
+
186
+ return GetFaststepConnection(connection);
187
+ }
@@ -0,0 +1,24 @@
1
+ #ifndef COLLECTION_H
2
+ #include <ruby.h>
3
+ #include "mongo.h"
4
+ #include "bson.h"
5
+ #define COLLECTION_H
6
+
7
+ void faststep_collection_main();
8
+ static VALUE faststep_collection_init(VALUE, VALUE, VALUE);
9
+ 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_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);
16
+
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);
21
+
22
+ void build_collection_ns(char*, char*, char*);
23
+ static char* _ivar_name(VALUE);
24
+ #endif
@@ -0,0 +1,85 @@
1
+ #include "connection.h"
2
+ #include "faststep_defines.h"
3
+ #include "bson_ruby_conversion.h"
4
+
5
+ void faststep_connection_main() {
6
+ rb_cFaststepConnection = rb_define_class_under(rb_mFaststep, "Connection", rb_cObject);
7
+
8
+ rb_define_attr(rb_cFaststepConnection, "host", 1, 0);
9
+ rb_define_attr(rb_cFaststepConnection, "port", 1, 0);
10
+
11
+ rb_define_singleton_method(rb_cFaststepConnection, "new", faststep_connection_new, 2);
12
+
13
+ rb_define_method(rb_cFaststepConnection, "initialize", faststep_connection_init, 2);
14
+ rb_define_method(rb_cFaststepConnection, "connect!", faststep_connection_connect, 0);
15
+ rb_define_method(rb_cFaststepConnection, "disconnect!", faststep_connection_disconnect, 0);
16
+ rb_define_method(rb_cFaststepConnection, "connected?", faststep_connection_connected, 0);
17
+ rb_define_method(rb_cFaststepConnection, "master?", faststep_connection_master, 0);
18
+
19
+ return;
20
+ }
21
+
22
+ static VALUE faststep_connection_init(VALUE self, VALUE host, VALUE port) {
23
+ rb_iv_set(self, "@host", host);
24
+ rb_iv_set(self, "@port", port);
25
+
26
+ faststep_connection_connect(self);
27
+
28
+ return self;
29
+ }
30
+
31
+ static VALUE faststep_connection_new(VALUE class, VALUE host, VALUE port) {
32
+ mongo_connection* conn = bson_malloc(sizeof(mongo_connection));
33
+
34
+ VALUE tdata = Data_Wrap_Struct(class, NULL, mongo_destroy, conn);
35
+
36
+ VALUE argv[2];
37
+ argv[0] = host;
38
+ argv[1] = port;
39
+
40
+ rb_obj_call_init(tdata, 2, argv);
41
+
42
+ return tdata;
43
+ }
44
+
45
+ static VALUE faststep_connection_connect(VALUE self) {
46
+ mongo_connection_options* options = bson_malloc(sizeof(mongo_connection_options));
47
+
48
+ strcpy(options->host, RSTRING_PTR(rb_iv_get(self, "@host")));
49
+ options->port = NUM2INT(rb_iv_get(self, "@port"));
50
+
51
+ _faststep_connect_or_raise(GetFaststepConnection(self), options);
52
+
53
+ return Qnil;
54
+ }
55
+
56
+ static VALUE faststep_connection_disconnect(VALUE self) {
57
+ mongo_disconnect(GetFaststepConnection(self));
58
+
59
+ return Qnil;
60
+ }
61
+
62
+ static VALUE faststep_connection_connected(VALUE self) {
63
+ return bool_to_ruby(GetFaststepConnection(self)->connected);
64
+ }
65
+
66
+ static VALUE faststep_connection_master(VALUE self) {
67
+ return bool_to_ruby(mongo_cmd_ismaster(GetFaststepConnection(self), NULL));
68
+ }
69
+
70
+ static void _faststep_connect_or_raise(mongo_connection* conn, mongo_connection_options* options) {
71
+ mongo_connect(conn, options);
72
+
73
+ if(conn->connected == 0) {
74
+ mongo_destroy(conn);
75
+ rb_raise(rb_cFaststepConnectionFailure, "unable to connect to Mongo");
76
+ }
77
+
78
+ return;
79
+ }
80
+
81
+ mongo_connection* GetFaststepConnection(VALUE object) {
82
+ mongo_connection* conn;
83
+ Data_Get_Struct(object, mongo_connection, conn);
84
+ return conn;
85
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef CONNECTION_H
2
+ #include <ruby.h>
3
+ #include "mongo.h"
4
+ #define CONNECTION_H
5
+ void faststep_connection_main();
6
+
7
+ static VALUE faststep_connection_init(VALUE, VALUE, VALUE);
8
+ static VALUE faststep_connection_new(VALUE, VALUE, VALUE);
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);
13
+
14
+ mongo_connection* GetFaststepConnection(VALUE);
15
+
16
+ static void _faststep_connect_or_raise(mongo_connection*, mongo_connection_options*);
17
+ #endif
@@ -0,0 +1,61 @@
1
+ #include "cursor.h"
2
+ #include "bson_ruby_conversion.h"
3
+ #include "collection.h"
4
+ #include "faststep_defines.h"
5
+
6
+ void faststep_cursor_main() {
7
+ rb_cFaststepCursor = rb_define_class_under(rb_mFaststep, "Cursor", rb_cObject);
8
+
9
+ rb_define_attr(rb_cFaststepCursor, "collection", 1, 0);
10
+ rb_include_module(rb_cFaststepCursor, rb_mEnumerable);
11
+
12
+ rb_define_singleton_method(rb_cFaststepCursor, "new", faststep_cursor_new, 2);
13
+
14
+ rb_define_method(rb_cFaststepCursor, "initialize", faststep_cursor_init, 2);
15
+ rb_define_method(rb_cFaststepCursor, "each", faststep_cursor_each, 0);
16
+
17
+ return;
18
+ }
19
+
20
+ static VALUE faststep_cursor_init(VALUE self, VALUE collection, VALUE options) {
21
+ rb_iv_set(self, "@collection", collection);
22
+
23
+ return self;
24
+ }
25
+
26
+ static VALUE faststep_cursor_new(VALUE class, VALUE collection, VALUE options) {
27
+ mongo_cursor* cursor = _faststep_build_mongo_cursor(collection, options);
28
+
29
+ VALUE tdata = Data_Wrap_Struct(class, NULL, mongo_cursor_destroy, cursor);
30
+
31
+ VALUE argv[2];
32
+ argv[0] = collection;
33
+ argv[1] = options;
34
+
35
+ rb_obj_call_init(tdata, 2, argv);
36
+
37
+ return tdata;
38
+ }
39
+
40
+ static VALUE faststep_cursor_each(VALUE self) {
41
+ mongo_cursor* cursor;
42
+ Data_Get_Struct(self, mongo_cursor, cursor);
43
+
44
+ while(mongo_cursor_next(cursor)) {
45
+ rb_yield(ruby_hash_from_bson(&cursor->current));
46
+ }
47
+ }
48
+
49
+ static mongo_cursor* _faststep_build_mongo_cursor(VALUE collection, VALUE options) {
50
+ bson* selector = create_bson_from_ruby_hash(rb_hash_aref(options, rb_str_new2("selector")));
51
+
52
+ mongo_cursor* result = mongo_find(GetFaststepConnectionForCollection(collection),
53
+ RSTRING_PTR(rb_funcall(collection, rb_intern("ns"), 0)),
54
+ selector,
55
+ NULL,
56
+ 0, 0, 0);
57
+
58
+ bson_destroy(selector);
59
+
60
+ return result;
61
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef CURSOR_H
2
+ #include <ruby.h>
3
+ #include "mongo.h"
4
+ #define CURSOR_h
5
+ void faststep_cursor_main();
6
+ static VALUE faststep_cursor_init(VALUE, VALUE, VALUE);
7
+ static VALUE faststep_cursor_new(VALUE, VALUE, VALUE);
8
+ static VALUE faststep_cursor_each(VALUE);
9
+ static mongo_cursor* _faststep_build_mongo_cursor(VALUE, VALUE);
10
+ #endif