#50 - query free with rb_ensure
authorFedor Yudanov <fedwiz@academ.org>
Tue, 9 Apr 2013 08:07:40 +0000 (15:07 +0700)
committerFedor Yudanov <fedwiz@academ.org>
Tue, 9 Apr 2013 08:07:40 +0000 (15:07 +0700)
rbejdb/src/rbejdb.c
rbejdb/test/t2.rb

index 440e72e..edbf60a 100644 (file)
@@ -252,6 +252,7 @@ VALUE EJDB_load(VALUE self, VALUE collName, VALUE rboid) {
     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)) {
@@ -267,12 +268,14 @@ VALUE prepare_query_hints(VALUE hints) {
     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;
@@ -280,31 +283,16 @@ VALUE EJDB_query_free(RBEJDB_QUERY* rbquery) {
             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);
 
@@ -312,10 +300,22 @@ VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
     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"));
 
@@ -332,18 +332,6 @@ VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
         }
     }
 
-    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;
@@ -355,6 +343,57 @@ VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
     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;
 }
index ff055e1..264e850 100644 (file)
@@ -506,7 +506,6 @@ class EJDBTestUnit < Test::Unit::TestCase
     #puts $jb.find("monsters").to_a.to_s
     assert_equal(6, $jb.find("monsters").count)
 
-
     assert_raise(ArgumentError) {
       $jb.find
     }