summaryrefslogtreecommitdiff
path: root/rbejdb
diff options
context:
space:
mode:
authorFedor Yudanov <fedwiz@academ.org>2013-04-09 13:36:00 +0700
committerFedor Yudanov <fedwiz@academ.org>2013-04-09 13:36:00 +0700
commitab780afda10e739205b818c7d3722776859d3063 (patch)
treed81cc3c16ba56d680f55b4b0311652a29d0bcc66 /rbejdb
parent9bc718c4c86d2d48c3fa1cf818d1795fad934969 (diff)
downloadejdb-ab780afda10e739205b818c7d3722776859d3063.tar.gz
ejdb-ab780afda10e739205b818c7d3722776859d3063.tar.bz2
ejdb-ab780afda10e739205b818c7d3722776859d3063.zip
#50 - advanced tests (some hacks test) + gc memory free for query
Diffstat (limited to 'rbejdb')
-rw-r--r--rbejdb/src/rbejdb.c74
-rw-r--r--rbejdb/test/t2.rb8
2 files changed, 65 insertions, 17 deletions
diff --git a/rbejdb/src/rbejdb.c b/rbejdb/src/rbejdb.c
index ed6651a..440e72e 100644
--- a/rbejdb/src/rbejdb.c
+++ b/rbejdb/src/rbejdb.c
@@ -30,6 +30,13 @@ typedef struct {
TCXSTR* log;
} RBEJDB_RESULTS;
+typedef struct {
+ bson* qbson;
+ bson* hintsbson;
+ int orarrlng;
+ bson* orarrbson;
+} RBEJDB_QUERY;
+
VALUE create_EJDB_query_results(TCLIST* qres, TCXSTR *log);
@@ -37,6 +44,7 @@ VALUE create_EJDB_query_results(TCLIST* qres, TCXSTR *log);
VALUE ejdbClass;
VALUE ejdbResultsClass;
VALUE ejdbBinaryClass;
+VALUE ejdbQueryClass;
VALUE get_hash_option(VALUE hash, const char* opt) {
@@ -259,6 +267,23 @@ VALUE prepare_query_hints(VALUE hints) {
return res;
}
+VALUE EJDB_query_free(RBEJDB_QUERY* rbquery) {
+ if (rbquery->qbson) {
+ bson_destroy(rbquery->qbson);
+ }
+ if (rbquery->hintsbson) {
+ bson_destroy(rbquery->hintsbson);
+ }
+ if (rbquery->orarrbson) {
+ int i;
+ for (i = 0; i < rbquery->orarrlng; i++) {
+ bson_destroy(rbquery->orarrbson + i);
+ }
+ free(rbquery->orarrbson);
+ }
+ ruby_xfree(rbquery);
+}
+
VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
VALUE collName;
VALUE q;
@@ -279,41 +304,54 @@ VALUE EJDB_find(int argc, VALUE* argv, VALUE self) {
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);
+
+ VALUE orarrlng = rb_funcall(orarr, rb_intern("length"), 0);
+ rbquery->qbson = NULL;
+ rbquery->hintsbson = NULL;
+ rbquery->orarrbson = NUM2INT(orarrlng) ? (bson*) tcmalloc(rbquery->orarrlng * sizeof(bson)) : NULL;
+ rbquery->orarrlng;
+
+ ruby_to_bson(q, &(rbquery->qbson), RUBY_TO_BSON_AS_QUERY);
+
+ bool onlycount = RTEST(get_hash_option(hints, "onlycount"));
+ bool explain = RTEST(get_hash_option(hints, "explain"));
+
EJDB* ejdb = getEJDB(self);
- EJCOLL *coll = ejdbcreatecoll(ejdb, StringValuePtr(collName), NULL);
+ EJCOLL *coll = ejdbgetcoll(ejdb, StringValuePtr(collName));
if (!coll) {
- raise_ejdb_error(ejdb);
+ bson_iterator it;
+ if (bson_find(&it, rbquery->qbson, "$upsert") == BSON_OBJECT) {
+ coll = ejdbcreatecoll(ejdb, StringValuePtr(collName), NULL);
+ }
+ if (!coll) {
+ return !onlycount ? create_EJDB_query_results(tclistnew2(1), NULL) : INT2NUM(0);
+ }
}
- bson* qbson;
- ruby_to_bson(q, &qbson, RUBY_TO_BSON_AS_QUERY);
-
- VALUE orarrlng = rb_funcall(orarr, rb_intern("length"), 0);
- bson* orarrbson = (bson*) malloc(sizeof(bson) * NUM2INT(orarrlng));
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);
- orarrbson[i++] = *orqbson;
+ bson_copy(rbquery->orarrbson + (i++), orqbson);
+ bson_destroy(orqbson);
+ rbquery->orarrlng++;
}
- bson* hintsbson = NULL;
- ruby_to_bson(prepare_query_hints(hints), &hintsbson, RUBY_TO_BSON_AS_QUERY);
+ ruby_to_bson(prepare_query_hints(hints), &(rbquery->hintsbson), RUBY_TO_BSON_AS_QUERY);
- EJQ *ejq = ejdbcreatequery(ejdb, qbson, orarrbson, NUM2INT(orarrlng), hintsbson);
+ EJQ *ejq = ejdbcreatequery(ejdb, rbquery->qbson, rbquery->orarrbson, NUM2INT(orarrlng), rbquery->hintsbson);
int count;
- int qflags = 0;
- bool onlycount = RTEST(get_hash_option(hints, "onlycount"));
- bool explain = RTEST(get_hash_option(hints, "explain"));
- qflags |= onlycount ? EJQONLYCOUNT : 0;
-
+ int qflags = onlycount ? EJQONLYCOUNT : 0;
TCXSTR *log = explain ? tcxstrnew() : NULL;
+
TCLIST* qres = ejdbqryexecute(coll, ejq, &count, qflags, log);
- free(orarrbson);
return !onlycount ? create_EJDB_query_results(qres, log) : INT2NUM(count);
}
@@ -705,4 +743,6 @@ Init_rbejdb() {
rb_include_module(ejdbBinaryClass, rb_mEnumerable);
rb_define_private_method(ejdbBinaryClass, "initialize", RUBY_METHOD_FUNC(EJDB_binary_init), 1);
rb_define_method(ejdbBinaryClass, "each", RUBY_METHOD_FUNC(EJDB_binary_each), 0);
+
+ ejdbQueryClass = rb_define_class("EJDBQuery", rb_cObject);
} \ No newline at end of file
diff --git a/rbejdb/test/t2.rb b/rbejdb/test/t2.rb
index a44db85..ff055e1 100644
--- a/rbejdb/test/t2.rb
+++ b/rbejdb/test/t2.rb
@@ -470,6 +470,7 @@ class EJDBTestUnit < Test::Unit::TestCase
$jb.load("parrots", "", "sldslk")
}
+
assert_raise(ArgumentError) {
$jb.save
}
@@ -505,6 +506,13 @@ 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
+ }
+
+ assert_equal(0, $jb.find("dsldajsdlkjasl").count)
+
puts __method__.inspect + " has passed successfull"
end