return bs ? bson_to_ruby(bs) : nil_or_raise_ejdb_error(ejdb);
}
+
void prepare_query_hint(VALUE res, VALUE hints, char* hint) {
VALUE val = get_hash_option(hints, hint);
if (!NIL_P(val)) {
return res;
}
-VALUE EJDB_query_free(RBEJDB_QUERY* rbquery) {
+VALUE EJDB_remove_query_internal(RBEJDB_QUERY* rbquery) {
if (rbquery->qbson) {
bson_destroy(rbquery->qbson);
+ rbquery->qbson = NULL;
}
if (rbquery->hintsbson) {
bson_destroy(rbquery->hintsbson);
+ rbquery->hintsbson = NULL;
}
if (rbquery->orarrbson) {
int i;
bson_destroy(rbquery->orarrbson + i);
}
free(rbquery->orarrbson);
+ rbquery->orarrbson = NULL;
}
- ruby_xfree(rbquery);
}
-VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
- VALUE collName;
- VALUE q;
- VALUE orarr;
- VALUE hints;
-
- VALUE p3;
- VALUE p4;
-
- rb_scan_args(argc, argv, "13", &collName, &q, &p3, &p4);
-
- SafeStringValue(collName);
- q = !NIL_P(q) ? q :rb_hash_new();
- orarr = TYPE(p3) == T_ARRAY ? rb_ary_dup(p3) : rb_ary_new();
- hints = TYPE(p3) != T_ARRAY ? p3 : p4;
- hints = !NIL_P(hints) ? hints :rb_hash_new();
-
- Check_Type(q, T_HASH);
- Check_Type(hints, T_HASH);
+VALUE EJDB_query_free(RBEJDB_QUERY* rbquery) {
+ EJDB_remove_query_internal(rbquery);
+ ruby_xfree(rbquery);
+}
- VALUE queryWrap = Data_Wrap_Struct(ejdbQueryClass, NULL, EJDB_query_free, ruby_xmalloc(sizeof(RBEJDB_QUERY)));
+VALUE EJDB_find_internal(VALUE self, VALUE collName, VALUE queryWrap, VALUE q, VALUE orarr, VALUE hints) {
RBEJDB_QUERY* rbquery;
Data_Get_Struct(queryWrap, RBEJDB_QUERY, rbquery);
rbquery->qbson = NULL;
rbquery->hintsbson = NULL;
rbquery->orarrbson = NUM2INT(orarrlng) ? (bson*) tcmalloc(rbquery->orarrlng * sizeof(bson)) : NULL;
- rbquery->orarrlng;
+ rbquery->orarrlng = 0;
ruby_to_bson(q, &(rbquery->qbson), RUBY_TO_BSON_AS_QUERY);
+ int i;
+ while(!NIL_P(rb_ary_entry(orarr, 0))) {
+ VALUE orq = rb_ary_shift(orarr);
+ bson* orqbson;
+ ruby_to_bson(orq, &orqbson, RUBY_TO_BSON_AS_QUERY);
+ bson_copy(rbquery->orarrbson + (i++), orqbson);
+ bson_destroy(orqbson);
+ rbquery->orarrlng++;
+ }
+
+ ruby_to_bson(prepare_query_hints(hints), &(rbquery->hintsbson), RUBY_TO_BSON_AS_QUERY);
+
bool onlycount = RTEST(get_hash_option(hints, "onlycount"));
bool explain = RTEST(get_hash_option(hints, "explain"));
}
}
- int i;
- while(!NIL_P(rb_ary_entry(orarr, 0))) {
- VALUE orq = rb_ary_shift(orarr);
- bson* orqbson;
- ruby_to_bson(orq, &orqbson, RUBY_TO_BSON_AS_QUERY);
- bson_copy(rbquery->orarrbson + (i++), orqbson);
- bson_destroy(orqbson);
- rbquery->orarrlng++;
- }
-
- ruby_to_bson(prepare_query_hints(hints), &(rbquery->hintsbson), RUBY_TO_BSON_AS_QUERY);
-
EJQ *ejq = ejdbcreatequery(ejdb, rbquery->qbson, rbquery->orarrbson, NUM2INT(orarrlng), rbquery->hintsbson);
int count;
return !onlycount ? create_EJDB_query_results(qres, log) : INT2NUM(count);
}
+VALUE EJDB_find_internal_wrapper(VALUE args) {
+ return EJDB_find_internal(rb_ary_pop(args), rb_ary_pop(args), rb_ary_pop(args),
+ rb_ary_pop(args), rb_ary_pop(args), rb_ary_pop(args));
+}
+
+VALUE EJDB_find_ensure(VALUE queryWrap, VALUE exception) {
+ RBEJDB_QUERY* rbquery;
+ Data_Get_Struct(queryWrap, RBEJDB_QUERY, rbquery);
+ EJDB_remove_query_internal(rbquery);
+}
+
+VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
+ VALUE collName;
+ VALUE q;
+ VALUE orarr;
+ VALUE hints;
+
+ VALUE p3;
+ VALUE p4;
+
+ rb_scan_args(argc, argv, "13", &collName, &q, &p3, &p4);
+
+ SafeStringValue(collName);
+ q = !NIL_P(q) ? q :rb_hash_new();
+ orarr = TYPE(p3) == T_ARRAY ? rb_ary_dup(p3) : rb_ary_new();
+ hints = TYPE(p3) != T_ARRAY ? p3 : p4;
+ hints = !NIL_P(hints) ? hints :rb_hash_new();
+
+ Check_Type(q, T_HASH);
+ Check_Type(hints, T_HASH);
+
+ VALUE queryWrap = Data_Wrap_Struct(ejdbQueryClass, NULL, EJDB_query_free, ruby_xmalloc(sizeof(RBEJDB_QUERY)));
+ RBEJDB_QUERY* rbquery;
+ Data_Get_Struct(queryWrap, RBEJDB_QUERY, rbquery);
+ rbquery->qbson = NULL;
+ rbquery->hintsbson = NULL;
+ rbquery->orarrbson = NULL;
+ rbquery->orarrlng = 0;
+
+
+ VALUE params = rb_ary_new();
+ rb_ary_push(params, self);
+ rb_ary_push(params, collName);
+ rb_ary_push(params, queryWrap);
+ rb_ary_push(params, q);
+ rb_ary_push(params, orarr);
+ rb_ary_push(params, hints);
+
+ return rb_ensure(EJDB_find_internal_wrapper, params, EJDB_find_ensure, queryWrap);
+}
+
static VALUE EJDB_block_true(VALUE yielded_object, VALUE context, int argc, VALUE argv[]){
return Qtrue;
}