#50 - advanced tests (tests 5,6)
authorFedor Yudanov <fedwiz@academ.org>
Wed, 3 Apr 2013 11:32:43 +0000 (18:32 +0700)
committerFedor Yudanov <fedwiz@academ.org>
Wed, 3 Apr 2013 11:32:43 +0000 (18:32 +0700)
rbejdb/src/rbbson.c
rbejdb/src/rbejdb.c
rbejdb/test/t2.rb

index 7713b8c..e0af287 100644 (file)
@@ -62,6 +62,25 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) {
 
     switch (TYPE(val)) {
         case T_OBJECT:
+            if (0 == strcmp(rb_obj_classname(val), "EJDBBinary")) {
+                VALUE bdata = rb_iv_get(val, "@data");
+                Check_Type(bdata, T_ARRAY);
+
+                int length = NUM2INT(rb_funcall(bdata, rb_intern("length"), 0));
+                char* buf = (char*) malloc(sizeof(char) * length);
+                int i;
+
+                for (i = 0; i < length; i++) {
+                    VALUE byte = rb_ary_entry(bdata, i);
+                    buf[i] = (char) NUM2INT(byte);
+                }
+
+                bson_append_binary(b, attrName, BSON_BIN_BINARY, buf, length);
+
+                free(buf);
+                break;
+            }
+            //else same as hash :)
         case T_HASH:
             ruby_to_bson(val, &subbson, rbbson->flags);
             bson_append_bson(b, attrName, subbson);
@@ -72,7 +91,12 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) {
             bson_append_finish_array(b);
             break;
         case T_STRING:
-            bson_append_string(b, attrName, StringValuePtr(val));
+            if (0 != strcmp("_id", attrName)) {
+                bson_append_string(b, attrName, StringValuePtr(val));
+            } else {
+                bson_oid_t oid = ruby_to_bson_oid(val);
+                bson_append_oid(b, attrName, &oid);
+            }
             break;
         case T_FIXNUM:
             bson_append_int(b, attrName, FIX2INT(val));
@@ -81,7 +105,7 @@ int iterate_key_values_callback(VALUE key, VALUE val, VALUE bsonWrap) {
             if (0 == strcmp(rb_obj_classname(val), "Time")) {
                 bson_append_date(b, attrName, ruby_time_to_bson_internal(val));
             } else {
-                rb_raise(rb_eRuntimeError, "Cannot convert ruby data object to bson");
+                rb_raise(rb_eRuntimeError, "Cannot convert ruby data object to bson: %s", rb_obj_classname(val));
             }
             break;
         case T_REGEXP: {
@@ -200,6 +224,19 @@ VALUE bson_iterator_to_ruby(bson_iterator* it, bson_type t) {
         case BSON_ARRAY:
             val = bson_array_to_ruby(it);
             break;
+        case BSON_BINDATA: {
+                const char* buf = bson_iterator_bin_data(it);
+                int length = bson_iterator_bin_len(it);
+
+                VALUE bdata = rb_ary_new();
+                int i;
+                for (i = 0; i < length; i++) {
+                    rb_ary_push(bdata, INT2NUM(buf[i]));
+                }
+
+                val = rb_funcall(rb_path2class("EJDBBinary"), rb_intern("new"), 1, bdata);
+            }
+            break;
         case BSON_NULL:
             val = Qnil;
             break;
index dd3ffd0..57d3e72 100644 (file)
@@ -35,6 +35,7 @@ VALUE create_EJDB_query_results(TCLIST* qres);
 
 VALUE ejdbClass;
 VALUE ejdbResultsClass;
+VALUE ejdbBinaryClass;
 
 
 VALUE get_hash_option(VALUE hash, const char* opt) {
@@ -349,6 +350,36 @@ void EJDB_results_close(VALUE self) {
 }
 
 
+VALUE EJDB_binary_init(VALUE self, VALUE bdata) {
+    Check_Type(bdata, T_ARRAY);
+
+    int length = NUM2INT(rb_funcall(bdata, rb_intern("length"), 0));
+    int i;
+    for (i = 0; i < length; i++) {
+        VALUE byte = rb_ary_entry(bdata, i);
+        if (NUM2INT(byte) > 255 || NUM2INT(byte) < 0) {
+            rb_raise(rb_eRuntimeError, "Invalid value in binary array for EJDBBinary");
+        }
+    }
+
+    rb_iv_set(self, "@data", rb_ary_dup(bdata));
+}
+
+
+static VALUE EJDB_block_proxy_context(VALUE yielded_object, VALUE context, int argc, VALUE argv[]){
+    VALUE block = context;
+    return rb_funcall(block, rb_intern("call"), 1, yielded_object);
+}
+
+void EJDB_binary_each(VALUE self) {
+    VALUE bdata = rb_iv_get(self, "@data");
+    Check_Type(bdata, T_ARRAY);
+
+    VALUE block = rb_block_proc();
+    rb_block_call(bdata, rb_intern("each"), 0, NULL, RUBY_METHOD_FUNC(EJDB_block_proxy_context), block);
+}
+
+
 Init_rbejdb() {
     init_ruby_to_bson();
 
@@ -377,4 +408,10 @@ Init_rbejdb() {
     rb_include_module(ejdbResultsClass, rb_mEnumerable);
     rb_define_method(ejdbResultsClass, "each", RUBY_METHOD_FUNC(EJDB_results_each), 0);
     rb_define_method(ejdbResultsClass, "close", RUBY_METHOD_FUNC(EJDB_results_close), 0);
+
+
+    ejdbBinaryClass = rb_define_class("EJDBBinary", rb_cObject);
+    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);
 }
\ No newline at end of file
index 707834e..75f9592 100644 (file)
@@ -40,6 +40,8 @@ class EJDBTestUnit < Test::Unit::TestCase
     assert_not_nil obj
     assert_equal(parrot2["_id"], obj["_id"])
     assert_equal("Bounty", obj["name"])
+
+    puts "test_ejdb1_save_load has passed successfull"
   end
 
 
@@ -86,10 +88,12 @@ class EJDBTestUnit < Test::Unit::TestCase
     results = $jb.find("parrots")
     assert_not_nil results
     assert_equal(2, results.to_a.length)
+
+    puts "test_ejdb2_query1 has passed successfull"
   end
 
 
-  def test_ejdb3_test_query2
+  def test_ejdb3_query2
     assert_not_nil $jb
     assert $jb.is_open?
 
@@ -108,11 +112,12 @@ class EJDBTestUnit < Test::Unit::TestCase
         assert_equal("sugar cane", rv["likes"].join(","))
       end
     }
-  end
 
+    puts "test_ejdb3_query2 has passed successfull"
+  end
 
-  def test_ejdb4_test_query3
 
+  def test_ejdb4_query3
     assert_not_nil $jb
     assert $jb.is_open?
 
@@ -132,7 +137,6 @@ class EJDBTestUnit < Test::Unit::TestCase
       end
     }
 
-
     assert_equal(2, results.to_a.length)
 
     # testing force close
@@ -141,6 +145,80 @@ class EJDBTestUnit < Test::Unit::TestCase
     assert_raise(RuntimeError) {
       results.to_a.length
     }
+
+    puts "test_ejdb4_query3 has passed successfull"
+  end
+
+
+=begin
+  test is written but this functionality is rather special an has low priority...
+
+  def test_ejdb5_circular
+    assert_not_nil $jb
+    assert $jb.is_open?
+
+    #Circular query object
+    cir_query = {}
+    cir_query["cq"] = cir_query
+
+    err = nil
+    begin
+      $jb.find("parrots", cir_query)
+    rescue Exception => e
+      err = e
+    end
+
+    assert_not_nil err
+    assert_equal(err.message, "Converting circular structure to JSON")
+
+    err = nil
+    begin
+      $jb.find("parrots", [cir_query])
+    rescue Exception => e
+      err = e
+    end
+
+    assert_not_nil err
+    assert_equal(err.message, "Converting circular structure to JSON")
+
+    puts "test_ejdb5_circular has passed successfull"
+  end
+=end
+
+  def test_ejdb6_save_load_buffer
+    assert_not_nil $jb
+    assert $jb.is_open?
+
+    sally = {
+        "name" => "Sally",
+        "mood" => "Angry",
+        "secret" => EJDBBinary.new("Some binary secrect".encode("utf-8").bytes.to_a)
+    }
+
+    molly = {
+        "name" => "Molly",
+        "mood" => "Very angry",
+        "secret" => nil
+    }
+
+    sally_oid = $jb.save("birds", sally)
+
+    assert_not_nil sally_oid
+    assert_not_nil sally["_id"]
+
+    obj = $jb.load("birds", sally_oid)
+
+    assert(obj["secret"].is_a? EJDBBinary)
+    assert_equal("Some binary secrect", obj["secret"].to_a.pack("U*"))
+
+    oids = $jb.save("birds", sally, molly)
+
+    assert_not_nil oids
+    assert_not_nil oids.find { |oid|
+      oid == sally_oid
+    }
+
+    puts "test_ejdb6_save_load_buffer has passed successfull"
   end
 
 end