static_cast<v8::PropertyAttribute>( \
v8::ReadOnly|v8::DontDelete))
+static Persistent<String> sym_close;
+static Persistent<String> sym_save;
+static Persistent<String> sym_load;
+static Persistent<String> sym_query;
+
namespace ejdb {
+ /** Convert V8 object into binary json instance. After using it must be freed by bson_del() */
+ static bson* toBSON(const Handle<Object>& obj) {
+ assert(obj->IsObject());
+ bson *bs = bson_create();
+ bson_init(bs);
+ Local<Array> pnames = obj->GetOwnPropertyNames();
+ for (uint32_t i = 0; i < pnames->Length(); ++i) {
+ Local<Value> pn = pnames->Get(i);
+ String::Utf8Value spn(pn);
+ Local<Value> pv = obj->Get(pn);
+ if (pv->IsString()) {
+ String::Utf8Value val(pv);
+ bson_append_string(bs, *spn, *val);
+ } else if (pv->IsUint32()) {
+ bson_append_long(bs, *spn, pv->Uint32Value());
+ } else if (pv->IsInt32()) {
+ bson_append_int(bs, *spn, pv->Int32Value());
+ } else if (pv->IsNumber()) {
+ bson_append_double(bs, *spn, pv->NumberValue());
+ } else if (pv->IsNull()) {
+ bson_append_null(bs, *spn);
+ } else if (pv->IsUndefined()) {
+ bson_append_undefined(bs, *spn);
+ } else if (pv->IsBoolean()) {
+ bson_append_bool(bs, *spn, pv->BooleanValue());
+ } else if (pv->IsDate()) {
+ bson_append_long(bs, *spn, Handle<Date>::Cast(pv)->IntegerValue());
+ } else if (pv->IsRegExp()) {
+ Handle<RegExp> regexp = Handle<RegExp>::Cast(pv);
+ int flags = regexp->GetFlags();
+ String::Utf8Value sr(regexp->GetSource());
+ std::string sf;
+ if (flags & RegExp::kIgnoreCase) {
+ sf.append("i");
+ }
+ if (flags & RegExp::kGlobal) {
+ sf.append("g");
+ }
+ if (flags & RegExp::kMultiline) {
+ sf.append("m");
+ }
+ bson_append_regex(bs, *spn, *sr, sf.c_str());
+ }
+ //TODO
+ }
+ return bs;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Main NodeEJDB //
+ ///////////////////////////////////////////////////////////////////////////
+
class NodeEJDB : public ObjectWrap {
typedef EIOCmdTask<NodeEJDB> EJTask;
HandleScope scope;
REQ_STR_ARG(0, dbPath);
REQ_INT32_ARG(1, mode);
- NodeEJDB *nejdb = new NodeEJDB();
- if (!nejdb->open(*dbPath, mode)) {
+ NodeEJDB *njb = new NodeEJDB();
+ if (!njb->open(*dbPath, mode)) {
std::ostringstream os;
- os << "Unable to open database: " << (*dbPath) << " error: " << nejdb->jb_error_msg();
- EJ_LOG_ERROR(os.str().c_str());
- delete nejdb;
+ os << "Unable to open database: " << (*dbPath) << " error: " << njb->jb_error_msg();
+ EJ_LOG_ERROR("%s", os.str().c_str());
+ delete njb;
return scope.Close(ThrowException(Exception::Error(String::New(os.str().c_str()))));
}
- nejdb->Wrap(args.This());
+ njb->Wrap(args.This());
+ return scope.Close(args.This());
+ }
+
+ static Handle<Value> s_close(const Arguments& args) {
+ HandleScope scope;
+ NodeEJDB *njb = ObjectWrap::Unwrap< NodeEJDB > (args.This());
+ assert(njb);
+ if (!njb->close()) {
+ return scope.Close(ThrowException(Exception::Error(String::New(njb->jb_error_msg()))));
+ }
+ return scope.Close(args.This());
+ }
+
+ static Handle<Value> s_save(const Arguments& args) {
+ HandleScope scope;
+ REQ_OBJ_ARG(0, obj);
+ bson *bs = toBSON(obj);
+ if (bs->err) {
+ Local<String> msg = String::New(bs->errstr ? bs->errstr : "bson creation failed");
+ bson_del(bs);
+ return scope.Close(ThrowException(Exception::Error(msg)));
+ }
+
+
return scope.Close(args.This());
}
}
bool close() {
- if (m_jb) {
- return ejdbclose(m_jb);
- }
+ return m_jb ? ejdbclose(m_jb) : false;
}
const char* jb_error_msg() {
- return m_jb ? ejdberrmsg(ejdbecode(m_jb)) : "unknown";
+ return m_jb ? ejdberrmsg(ejdbecode(m_jb)) : "unknown error";
}
public:
//Misc
NODE_DEFINE_CONSTANT(target, JBQRYCOUNT);
+ //Symbols
+ sym_close = NODE_PSYMBOL("close");
+ sym_save = NODE_PSYMBOL("save");
+ sym_load = NODE_PSYMBOL("load");
+ sym_query = NODE_PSYMBOL("query");
+
target->Set(v8::String::NewSymbol("NodeEJDB"), constructor_template->GetFunction());
+
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "close", s_close);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "save", s_save);
}
void Ref() {
ObjectWrap::Ref();
-
}
void Unref() {
}
// Register the module with node.
-NODE_MODULE(ejdb_native, ejdb::Init);
\ No newline at end of file
+NODE_MODULE(ejdb_native, ejdb::Init)
\ No newline at end of file
/* Efficiently copy an integer to a string. */
extern const char bson_numstrs[1000][4];
-EJDB_EXPORT void bson_numstr(char *str, long long int i) {
+EJDB_EXPORT void bson_numstr(char *str, int64_t i) {
if (i < 1000)
memcpy(str, bson_numstrs[i], 4);
else
- bson_sprintf(str, "%lld", i);
+ bson_sprintf(str, "%lld", (long long int) i);
}
-EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, long long int i) {
+EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, int64_t i) {
if (i < 1000 && maxbuf > 4) {
memcpy(str, bson_numstrs[i], 4);
return strlen(bson_numstrs[i]);
} else {
- return snprintf(str, maxbuf, "%lld", i);
+ return snprintf(str, maxbuf, "%lld", (long long int) i);
}
}