7 nodejs_db::Binding::Binding() : nodejs_db::EventEmitter()
16 nodejs_db::Binding::~Binding() {
17 if (this->cbConnect != NULL) {
18 node::cb_destroy(this->cbConnect);
22 #if NODE_VERSION_AT_LEAST(0, 7, 8)
23 uv_async_t nodejs_db::Binding::g_async;
31 void nodejs_db::Binding::Init(v8::Handle<v8::Object> target
32 , v8::Persistent<v8::FunctionTemplate> constructorTemplate
34 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_STRING,
35 nodejs_db::Result::Column::STRING);
36 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_TEXT,
37 nodejs_db::Result::Column::TEXT);
38 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_INT,
39 nodejs_db::Result::Column::INT);
40 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_NUMBER,
41 nodejs_db::Result::Column::NUMBER);
42 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_MONEY,
43 nodejs_db::Result::Column::MONEY);
44 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_DATE,
45 nodejs_db::Result::Column::DATE);
46 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_TIME,
47 nodejs_db::Result::Column::TIME);
48 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_INTERVAL,
49 nodejs_db::Result::Column::INTERVAL);
50 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_DATETIME,
51 nodejs_db::Result::Column::DATETIME);
52 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_BOOL,
53 nodejs_db::Result::Column::BOOL);
54 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_BLOB,
55 nodejs_db::Result::Column::BLOB);
56 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_SET,
57 nodejs_db::Result::Column::SET);
58 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_ROW,
59 nodejs_db::Result::Column::ROW);
60 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_COLLECTION,
61 nodejs_db::Result::Column::COLLECTION);
62 NODE_ADD_CONSTANT(constructorTemplate, COLUMN_TYPE_CONSTRUCTED,
63 nodejs_db::Result::Column::CONSTRUCTED);
65 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"connect", Connect);
66 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"disconnect", Disconnect);
67 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"isConnected", IsConnected);
68 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"escape", Escape);
69 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"name", Name);
70 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"query", Query);
78 nodejs_db::Binding::Connect(
const v8::Arguments& args) {
79 v8::HandleScope scope;
82 node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
86 int optionsIndex = -1,
89 if (args.Length() > 0) {
90 if (args.Length() > 1) {
91 ARG_CHECK_OBJECT(0, options);
92 ARG_CHECK_FUNCTION(1, callback);
95 }
else if (args[0]->IsFunction()) {
96 ARG_CHECK_FUNCTION(0, callback);
99 ARG_CHECK_OBJECT(0, options);
103 if (optionsIndex >= 0) {
104 v8::Local<v8::Object> options = args[optionsIndex]->ToObject();
106 v8::Handle<v8::Value>
set = binding->set(options);
107 if (!
set.IsEmpty()) {
108 return scope.Close(
set);
111 ARG_CHECK_OBJECT_ATTR_OPTIONAL_BOOL(options, async);
113 if (options->Has(async_key) && options->Get(async_key)->IsFalse()) {
118 if (callbackIndex >= 0) {
119 binding->cbConnect = node::cb_persist(args[callbackIndex]);
123 connect_request_t* request =
new connect_request_t();
124 if (request == NULL) {
125 THROW_EXCEPTION(
"Could not create UV request")
128 request->context = v8::Persistent<v8::Object>::New(args.This());
129 request->binding = binding;
130 request->error = NULL;
133 request->binding->Ref();
135 uv_work_t* req =
new uv_work_t();
137 uv_queue_work(uv_default_loop(), req, uvConnect, (uv_after_work_cb)uvConnectFinished);
139 #if NODE_VERSION_AT_LEAST(0, 7, 9)
140 uv_ref((uv_handle_t *)&g_async);
142 uv_ref(uv_default_loop());
143 #endif // NODE_VERSION_AT_LEAST(0, 7, 9)
147 connectFinished(request);
150 return scope.Close(v8::Undefined());
157 void nodejs_db::Binding::connect(connect_request_t* request) {
159 request->binding->connection->open();
161 request->error = exception.what();
169 void nodejs_db::Binding::connectFinished(connect_request_t* request) {
170 bool connected = request->binding->connection->isAlive();
171 v8::Local<v8::Value> argv[2];
174 v8::Local<v8::Object> server = v8::Object::New();
175 server->Set(v8::String::New(
"version"), v8::String::New(request->binding->connection->version().c_str()));
176 server->Set(v8::String::New(
"hostname"), v8::String::New(request->binding->connection->getHostname().c_str()));
177 server->Set(v8::String::New(
"user"), v8::String::New(request->binding->connection->getUser().c_str()));
178 server->Set(v8::String::New(
"database"), v8::String::New(request->binding->connection->getDatabase().c_str()));
180 argv[0] = v8::Local<v8::Value>::New(v8::Null());
183 request->binding->Emit(
"ready", 1, &argv[1]);
185 argv[0] = v8::String::New(request->error != NULL ? request->error :
"(unknown error)");
187 request->binding->Emit(
"error", 1, argv);
190 if (request->binding->cbConnect != NULL && !request->binding->cbConnect->IsEmpty()) {
191 v8::TryCatch tryCatch;
192 (*(request->binding->cbConnect))->Call(request->context, connected ? 2 : 1, argv);
193 if (tryCatch.HasCaught()) {
194 node::FatalException(tryCatch);
198 request->context.Dispose();
207 void nodejs_db::Binding::uvConnect(uv_work_t* uvRequest) {
208 connect_request_t* request =
static_cast<connect_request_t*
>(uvRequest->data);
211 request->binding->connection->lock();
213 request->binding->connection->unlock();
220 void nodejs_db::Binding::uvConnectFinished(uv_work_t* uvRequest,
int status) {
221 v8::HandleScope scope;
223 connect_request_t* request =
static_cast<connect_request_t*
>(uvRequest->data);
226 #if NODE_VERSION_AT_LEAST(0, 7, 9)
227 uv_unref((uv_handle_t *)&g_async);
229 uv_unref(uv_default_loop());
232 request->binding->Unref();
234 connectFinished(request);
241 v8::Handle<v8::Value> nodejs_db::Binding::Disconnect(
const v8::Arguments& args) {
242 v8::HandleScope scope;
244 nodejs_db::Binding* binding = node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
248 binding->connection->lock();
249 binding->connection->close();
250 binding->connection->unlock();
252 binding->connection->unlock();
255 return scope.Close(v8::Undefined());
262 v8::Handle<v8::Value> nodejs_db::Binding::IsConnected(
const v8::Arguments& args) {
263 v8::HandleScope scope;
265 nodejs_db::Binding* binding = node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
268 return scope.Close(binding->connection->isAlive() ? v8::True() : v8::False());
275 v8::Handle<v8::Value> nodejs_db::Binding::Escape(
const v8::Arguments& args) {
276 v8::HandleScope scope;
278 ARG_CHECK_STRING(0,
string);
280 nodejs_db::Binding* binding = node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
286 v8::String::Utf8Value string(args[0]->ToString());
287 std::string unescaped(*
string);
288 escaped = binding->connection->escape(unescaped);
290 THROW_EXCEPTION(exception.what())
293 return scope.Close(v8::String::New(escaped.c_str()));
300 v8::Handle<v8::Value>
301 nodejs_db::Binding::Name(
const v8::Arguments& args) {
302 v8::HandleScope scope;
304 ARG_CHECK_STRING(0, table);
306 nodejs_db::Binding* binding = node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
309 std::ostringstream escaped;
312 v8::String::Utf8Value string(args[0]->ToString());
313 std::string unescaped(*
string);
314 escaped << binding->connection->
escapeName(unescaped);
316 THROW_EXCEPTION(exception.what())
319 return scope.Close(v8::String::New(escaped.str().c_str()));
326 v8::Handle<v8::Value>
328 v8::HandleScope scope;
331 node::ObjectWrap::Unwrap<nodejs_db::Binding>(args.This());
335 v8::Persistent<v8::Object> query = binding->createQuery();
336 if (query.IsEmpty()) {
337 THROW_EXCEPTION(
"Could not create query");
341 node::ObjectWrap::Unwrap<nodejs_db::Query>(query);
342 queryInstance->setConnection(binding->connection);
344 v8::Handle<v8::Value>
set = queryInstance->set(args);
345 if (!
set.IsEmpty()) {
346 return scope.Close(
set);
349 return scope.Close(query);