From c36a4775c4989503ebe261cb12a95c0018d407f8 Mon Sep 17 00:00:00 2001 From: Fedor Yudanov Date: Tue, 9 Apr 2013 15:07:40 +0700 Subject: [PATCH] #50 - query free with rb_ensure --- rbejdb/src/rbejdb.c | 109 +++++++++++++++++++++++++++++++++++----------------- rbejdb/test/t2.rb | 1 - 2 files changed, 74 insertions(+), 36 deletions(-) diff --git a/rbejdb/src/rbejdb.c b/rbejdb/src/rbejdb.c index 440e72e..edbf60a 100644 --- a/rbejdb/src/rbejdb.c +++ b/rbejdb/src/rbejdb.c @@ -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; } diff --git a/rbejdb/test/t2.rb b/rbejdb/test/t2.rb index ff055e1..264e850 100644 --- a/rbejdb/test/t2.rb +++ b/rbejdb/test/t2.rb @@ -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 } -- 2.7.4