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);
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));
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: {
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;
VALUE ejdbClass;
VALUE ejdbResultsClass;
+VALUE ejdbBinaryClass;
VALUE get_hash_option(VALUE hash, const char* opt) {
}
+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();
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
assert_not_nil obj
assert_equal(parrot2["_id"], obj["_id"])
assert_equal("Bounty", obj["name"])
+
+ puts "test_ejdb1_save_load has passed successfull"
end
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?
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?
end
}
-
assert_equal(2, results.to_a.length)
# testing force close
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