4 bool nodejs_db::Query::gmtDeltaLoaded =
false;
5 int nodejs_db::Query::gmtDelta;
7 #if NODE_VERSION_AT_LEAST(0, 7, 8)
8 uv_async_t nodejs_db::Query::g_async;
12 nodejs_db::Query::Init(v8::Handle<v8::Object> target
13 , v8::Persistent<v8::FunctionTemplate> constructorTemplate
15 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"select", Select);
16 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"skip",
Skip);
17 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"limit",
Limit);
18 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"first",
First);
19 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"from", From);
20 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"join", Join);
21 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"where", Where);
22 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"and", And);
23 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"or", Or);
24 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"orderby", OrderBy);
25 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"add", Add);
26 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"insert", Insert);
27 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"into", Into);
28 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"values", Values);
29 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"update", Update);
30 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"set", Set);
31 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"delete", Delete);
32 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"sql", Sql);
33 NODE_ADD_PROTOTYPE_METHOD(constructorTemplate,
"execute",
Execute);
36 nodejs_db::Query::Query(): nodejs_db::EventEmitter(),
47 nodejs_db::Query::~Query() {
48 for (std::vector< v8::Persistent<v8::Value> >::iterator iterator = this->values.begin(),
49 end = this->values.end();
50 iterator != end; ++iterator
55 if (this->cbStart != NULL) {
56 node::cb_destroy(this->cbStart);
58 if (this->cbExecute != NULL) {
59 node::cb_destroy(this->cbExecute);
61 if (this->cbFinish != NULL) {
62 node::cb_destroy(this->cbFinish);
70 v8::Handle<v8::Value> nodejs_db::Query::Select(
const v8::Arguments& args) {
71 v8::HandleScope scope;
73 if (args.Length() > 0) {
74 if (args[0]->IsArray()) {
75 ARG_CHECK_ARRAY(0, fields);
76 }
else if (args[0]->IsObject()) {
77 ARG_CHECK_OBJECT(0, fields);
79 ARG_CHECK_STRING(0, fields);
82 ARG_CHECK_STRING(0, fields);
85 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
88 query->sql <<
"SELECT ";
89 query->sqlType = Query::SELECT;
91 if (args[0]->IsArray()) {
92 v8::Local<v8::Array> fields = v8::Array::Cast(*args[0]);
93 if (fields->Length() == 0) {
94 THROW_EXCEPTION(
"No fields specified in select")
97 for (uint32_t i = 0, limiti = fields->Length(); i < limiti; i++) {
103 query->sql << query->fieldName(fields->Get(i));
105 THROW_EXCEPTION(exception.what())
108 }
else if (args[0]->IsObject()) {
110 query->sql << query->fieldName(args[0]);
112 THROW_EXCEPTION(exception.what())
115 v8::String::Utf8Value fields(args[0]->ToString());
116 query->sql << *fields;
119 return scope.Close(args.This());
122 v8::Handle<v8::Value> nodejs_db::Query::From(
const v8::Arguments& args) {
123 v8::HandleScope scope;
125 if (args.Length() > 0) {
126 if (args[0]->IsArray()) {
127 ARG_CHECK_ARRAY(0, fields);
128 }
else if (args[0]->IsObject()) {
129 ARG_CHECK_OBJECT(0, tables);
131 ARG_CHECK_STRING(0, tables);
134 ARG_CHECK_STRING(0, tables);
137 ARG_CHECK_OPTIONAL_BOOL(1, escape);
139 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
143 if (args.Length() > 1) {
144 escape = args[1]->IsTrue();
147 query->sql <<
" FROM ";
150 query->sql << query->tableName(args[0], escape);
152 THROW_EXCEPTION(exception.what());
155 return scope.Close(args.This());
158 v8::Handle<v8::Value> nodejs_db::Query::Join(
const v8::Arguments& args) {
159 v8::HandleScope scope;
161 ARG_CHECK_OBJECT(0, join);
162 ARG_CHECK_OPTIONAL_ARRAY(1, values);
164 v8::Local<v8::Object> join = args[0]->ToObject();
166 ARG_CHECK_OBJECT_ATTR_OPTIONAL_STRING(join, type);
167 ARG_CHECK_OBJECT_ATTR_STRING(join, table);
168 ARG_CHECK_OBJECT_ATTR_OPTIONAL_STRING(join, alias);
169 ARG_CHECK_OBJECT_ATTR_OPTIONAL_STRING(join, conditions);
170 ARG_CHECK_OBJECT_ATTR_OPTIONAL_BOOL(join, escape);
172 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
175 std::string type =
"INNER";
178 if (join->Has(type_key)) {
179 v8::String::Utf8Value currentType(join->Get(type_key)->ToString());
181 std::transform(type.begin(), type.end(), type.begin(), toupper);
184 if (join->Has(escape_key)) {
185 escape = join->Get(escape_key)->IsTrue();
188 v8::String::Utf8Value table(join->Get(table_key)->ToString());
190 query->sql <<
" " << type <<
" JOIN ";
191 query->sql << (escape ? query->connection->
escapeName(*table) : *table);
193 if (join->Has(alias_key)) {
194 v8::String::Utf8Value alias(join->Get(alias_key)->ToString());
195 query->sql <<
" AS ";
196 query->sql << (escape ? query->connection->
escapeName(*alias) : *alias);
199 if (join->Has(conditions_key)) {
200 v8::String::Utf8Value conditions(join->Get(conditions_key)->ToObject());
201 std::string currentConditions = *conditions;
202 if (args.Length() > 1) {
203 v8::Local<v8::Array> currentValues = v8::Array::Cast(*args[1]);
204 for (uint32_t i = 0, limiti = currentValues->Length(); i < limiti; i++) {
205 query->values.push_back(v8::Persistent<v8::Value>::New(currentValues->Get(i)));
209 query->sql <<
" ON (" << currentConditions <<
")";
212 return scope.Close(args.This());
215 v8::Handle<v8::Value> nodejs_db::Query::Where(
const v8::Arguments& args) {
216 v8::HandleScope scope;
218 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
221 return scope.Close(query->addCondition(args,
"WHERE"));
224 v8::Handle<v8::Value> nodejs_db::Query::And(
const v8::Arguments& args) {
225 v8::HandleScope scope;
227 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
230 return scope.Close(query->addCondition(args,
"AND"));
233 v8::Handle<v8::Value> nodejs_db::Query::Or(
const v8::Arguments& args) {
234 v8::HandleScope scope;
236 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
239 return scope.Close(query->addCondition(args,
"OR"));
242 v8::Handle<v8::Value> nodejs_db::Query::OrderBy(
const v8::Arguments& args) {
243 v8::HandleScope scope;
245 if (args.Length() > 0 && args[0]->IsObject()) {
246 ARG_CHECK_OBJECT(0, fields);
248 ARG_CHECK_STRING(0, fields);
251 ARG_CHECK_OPTIONAL_BOOL(1, escape);
253 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
257 if (args.Length() > 1) {
258 escape = args[1]->IsTrue();
261 query->sql <<
" ORDER BY ";
263 if (args[0]->IsObject()) {
264 v8::Local<v8::Object> fields = args[0]->ToObject();
265 v8::Local<v8::Array> properties = fields->GetPropertyNames();
266 if (properties->Length() == 0) {
267 THROW_EXCEPTION(
"Non empty objects should be used for fields in order");
270 for (uint32_t i = 0, limiti = properties->Length(); i < limiti; i++) {
271 v8::Local<v8::Value> propertyName = properties->Get(i);
272 v8::String::Utf8Value fieldName(propertyName);
273 v8::Local<v8::Value> currentValue = fields->Get(propertyName);
279 bool innerEscape = escape;
280 v8::Local<v8::Value> order;
281 if (currentValue->IsObject()) {
282 v8::Local<v8::Object> currentObject = currentValue->ToObject();
283 v8::Local<v8::String> escapeKey = v8::String::New(
"escape");
284 v8::Local<v8::String> orderKey = v8::String::New(
"order");
285 v8::Local<v8::Value> optionValue;
287 if (!currentObject->Has(orderKey)) {
288 THROW_EXCEPTION(
"The \"order\" option for the order field object must be specified");
291 order = currentObject->Get(orderKey);
293 if (currentObject->Has(escapeKey)) {
294 optionValue = currentObject->Get(escapeKey);
295 if (!optionValue->IsBoolean()) {
296 THROW_EXCEPTION(
"Specify a valid boolean value for the \"escape\" option in the order field object");
298 innerEscape = optionValue->IsTrue();
301 order = currentValue;
304 query->sql << (innerEscape ? query->connection->
escapeName(*fieldName) : *fieldName);
307 if (order->IsBoolean()) {
308 query->sql << (order->IsTrue() ?
"ASC" :
"DESC");
309 }
else if (order->IsString()) {
310 v8::String::Utf8Value currentOrder(order->ToString());
311 query->sql << *currentOrder;
313 THROW_EXCEPTION(
"Invalid value specified for \"order\" property in order field");
317 v8::String::Utf8Value sql(args[0]->ToString());
321 return scope.Close(args.This());
333 v8::Handle<v8::Value>
335 v8::HandleScope scope;
337 if (args.Length() < 1) {
338 THROW_EXCEPTION(
"LIMIT requires at-least one integer argument");
341 if (args.Length() >= 2) {
342 ARG_CHECK_UINT32(0, skip);
343 ARG_CHECK_UINT32(1, rows);
345 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
348 query->projection.skip.flag =
true;
349 query->projection.skip.arg = args[0]->ToInt32()->Value();
351 query->projection.first.flag =
false;
352 query->projection.first.arg = 0;
354 query->projection.limit.flag =
true;
355 query->projection.limit.arg = args[1]->ToInt32()->Value();
357 ARG_CHECK_UINT32(0, rows);
359 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
362 query->projection.first.flag =
false;
363 query->projection.first.arg = 0;
365 query->projection.limit.flag =
true;
366 query->projection.limit.arg = args[0]->ToInt32()->Value();
369 return scope.Close(args.This());
382 v8::HandleScope scope;
384 if (args.Length() < 1) {
385 THROW_EXCEPTION(
"FIRST clause requires at-least one integer argument");
388 ARG_CHECK_UINT32(0, rows);
390 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
393 query->projection.first.flag =
true;
394 query->projection.first.arg = args[0]->ToInt32()->Value();
396 query->projection.limit.flag =
false;
397 query->projection.limit.arg = 0;
399 return scope.Close(args.This());
412 v8::HandleScope scope;
414 if (args.Length() < 1) {
415 THROW_EXCEPTION(
"SKIP clause requires at-least one integer argument");
418 ARG_CHECK_UINT32(0, rows);
420 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
423 query->projection.skip.flag =
true;
424 query->projection.skip.arg = args[0]->ToInt32()->Value();
426 return scope.Close(args.This());
431 v8::Handle<v8::Value> nodejs_db::Query::Add(
const v8::Arguments& args) {
432 v8::HandleScope scope;
436 if (args.Length() > 0 && args[0]->IsObject()) {
437 v8::Local<v8::Object>
object = args[0]->ToObject();
438 v8::Handle<v8::String> key = v8::String::New(
"sql");
439 if (!object->Has(key) || !
object->Get(key)->IsFunction()) {
440 ARG_CHECK_STRING(0, sql);
443 innerQuery = node::ObjectWrap::Unwrap<nodejs_db::Query>(object);
446 ARG_CHECK_STRING(0, sql);
449 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
452 if (innerQuery != NULL) {
453 query->sql << innerQuery->sql.str();
455 v8::String::Utf8Value sql(args[0]->ToString());
459 return scope.Close(args.This());
464 v8::Handle<v8::Value> nodejs_db::Query::Delete(
const v8::Arguments& args) {
465 v8::HandleScope scope;
467 if (args.Length() > 0) {
468 if (args[0]->IsArray()) {
469 ARG_CHECK_ARRAY(0, tables);
470 }
else if (args[0]->IsObject()) {
471 ARG_CHECK_OBJECT(0, tables);
473 ARG_CHECK_STRING(0, tables);
475 ARG_CHECK_OPTIONAL_BOOL(1, escape);
478 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
482 if (args.Length() > 1) {
483 escape = args[1]->IsTrue();
486 query->sql <<
"DELETE";
487 query->sqlType = Query::DELETE;
489 if (args.Length() > 0) {
491 query->sql <<
" " << query->tableName(args[0], escape);
493 THROW_EXCEPTION(exception.what());
497 return scope.Close(args.This());
502 v8::Handle<v8::Value> nodejs_db::Query::Insert(
const v8::Arguments& args) {
503 v8::HandleScope scope;
504 uint32_t argsLength = (uint32_t)args.Length();
506 int fieldsIndex = -1, valuesIndex = -1;
508 if (argsLength > 0) {
509 ARG_CHECK_STRING(0, table);
511 if (argsLength > 2) {
512 if (args[1]->IsArray()) {
513 ARG_CHECK_ARRAY(1, fields);
514 }
else if (args[1]->IsObject()) {
515 ARG_CHECK_OBJECT(1, fields);
516 }
else if (!args[1]->IsFalse()) {
517 ARG_CHECK_STRING(1, fields);
521 if (!args[2]->IsFalse()) {
523 ARG_CHECK_ARRAY(2, values);
526 ARG_CHECK_OPTIONAL_BOOL(3, escape);
527 }
else if (argsLength > 1) {
528 ARG_CHECK_ARRAY(1, values);
532 ARG_CHECK_STRING(0, table);
535 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
539 if (argsLength > 3) {
540 escape = args[3]->IsTrue();
544 query->sql <<
"INSERT INTO " << query->tableName(args[0], escape);
546 THROW_EXCEPTION(exception.what());
549 query->sqlType = Query::INSERT;
551 if (argsLength > 1) {
552 if (fieldsIndex != -1) {
554 if (args[fieldsIndex]->IsArray()) {
555 v8::Local<v8::Array> fields = v8::Array::Cast(*args[fieldsIndex]);
556 if (fields->Length() == 0) {
557 THROW_EXCEPTION(
"No fields specified in insert")
560 for (uint32_t i = 0, limiti = fields->Length(); i < limiti; i++) {
566 query->sql << query->fieldName(fields->Get(i));
568 THROW_EXCEPTION(exception.what())
572 v8::String::Utf8Value fields(args[fieldsIndex]->ToString());
573 query->sql << *fields;
580 if (valuesIndex != -1) {
581 v8::Local<v8::Array> values = v8::Array::Cast(*args[valuesIndex]);
582 uint32_t valuesLength = values->Length();
583 if (valuesLength > 0) {
584 bool multipleRecords = values->Get(0)->IsArray();
586 query->sql <<
"VALUES ";
587 if (!multipleRecords) {
591 for (uint32_t i = 0; i < valuesLength; i++) {
595 query->sql << query->value(values->Get(i));
598 if (!multipleRecords) {
607 return scope.Close(args.This());
610 v8::Handle<v8::Value> nodejs_db::Query::Into(
const v8::Arguments& args) {
611 v8::HandleScope scope;
613 if (args.Length() < 1) {
614 THROW_EXCEPTION(
"INTO clause requires at-least one string argument");
617 ARG_CHECK_STRING(0, table);
619 ARG_CHECK_OPTIONAL_BOOL(1, escape);
621 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
624 return scope.Close(args.This());
627 v8::Handle<v8::Value> nodejs_db::Query::Values(
const v8::Arguments& args) {
628 v8::HandleScope scope;
629 return scope.Close(args.This());
632 v8::Handle<v8::Value> nodejs_db::Query::Update(
const v8::Arguments& args) {
633 v8::HandleScope scope;
635 if (args.Length() > 0) {
636 if (args[0]->IsArray()) {
637 ARG_CHECK_ARRAY(0, tables);
638 }
else if (args[0]->IsObject()) {
639 ARG_CHECK_OBJECT(0, tables);
641 ARG_CHECK_STRING(0, tables);
644 ARG_CHECK_STRING(0, tables);
647 ARG_CHECK_OPTIONAL_BOOL(1, escape);
649 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
653 if (args.Length() > 1) {
654 escape = args[1]->IsTrue();
657 query->sql <<
"UPDATE ";
658 query->sqlType = Query::UPDATE;
661 query->sql << query->tableName(args[0], escape);
663 THROW_EXCEPTION(exception.what());
666 return scope.Close(args.This());
669 v8::Handle<v8::Value> nodejs_db::Query::Set(
const v8::Arguments& args) {
670 v8::HandleScope scope;
672 ARG_CHECK_OBJECT(0, values);
673 ARG_CHECK_OPTIONAL_BOOL(1, escape);
675 nodejs_db::Query *query = node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
679 if (args.Length() > 1) {
680 escape = args[1]->IsTrue();
683 query->sql <<
" SET ";
685 v8::Local<v8::Object> values = args[0]->ToObject();
686 v8::Local<v8::Array> valueProperties = values->GetPropertyNames();
687 if (valueProperties->Length() == 0) {
688 THROW_EXCEPTION(
"Non empty objects should be used for values in set");
691 for (uint32_t j = 0, max_j = valueProperties->Length(); j < max_j; j++) {
692 v8::Local<v8::Value> propertyName = valueProperties->Get(j);
693 v8::String::Utf8Value fieldName(propertyName);
694 v8::Local<v8::Value> currentValue = values->Get(propertyName);
705 query->sql << query->value(currentValue);
708 return scope.Close(args.This());
711 v8::Handle<v8::Value> nodejs_db::Query::Sql(
const v8::Arguments& args) {
712 v8::HandleScope scope;
715 node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
718 return scope.Close(v8::String::New(query->sql.str().c_str()));
727 v8::Handle<v8::Value>
730 v8::HandleScope scope;
733 node::ObjectWrap::Unwrap<nodejs_db::Query>(args.This());
736 if (args.Length() > 0) {
737 v8::Handle<v8::Value>
set = query->set(args);
738 if (!
set.IsEmpty()) {
739 return scope.Close(
set);
746 THROW_EXCEPTION(exception.what());
754 THROW_EXCEPTION(exception.what())
758 if (query->cbStart != NULL && !query->cbStart->IsEmpty()) {
759 v8::Local<v8::Value> argv[1];
760 argv[0] = v8::String::New(sql.c_str());
762 v8::TryCatch tryCatch;
763 v8::Handle<v8::Value> result =
764 (*(query->cbStart))->Call(
765 v8::Context::GetCurrent()->Global()
768 if (tryCatch.HasCaught()) {
769 node::FatalException(tryCatch);
772 if (!result->IsUndefined()) {
773 if (result->IsFalse()) {
774 return scope.Close(v8::Undefined());
775 }
else if (result->IsString()) {
776 v8::String::Utf8Value modifiedQuery(result->ToString());
777 sql = *modifiedQuery;
782 if (!query->connection->isAlive(
false)) {
783 THROW_EXCEPTION(
"Can't execute a query without being connected")
787 if (request == NULL) {
788 THROW_EXCEPTION(
"Could not create request")
796 std::cout <<
"SQL: " << sql << std::endl;
799 request->context = v8::Persistent<v8::Object>::New(args.This());
800 request->query = query;
801 request->buffered =
false;
802 request->result = NULL;
803 request->rows = NULL;
804 request->error = NULL;
807 request->query->Ref();
808 uv_work_t* req =
new uv_work_t();
809 req->data =
static_cast<void *
>(request);
820 , (uv_after_work_cb)uvExecuteFinished);
822 #if NODE_VERSION_AT_LEAST(0, 7, 9)
823 uv_ref((uv_handle_t *)&g_async);
825 uv_run(uv_default_loop(), UV_RUN_DEFAULT);
826 #endif // NODE_VERSION_AT_LEAST(0, 7, 9)
829 request->query->executeAsync(request);
832 return scope.Close(v8::Undefined());
850 || request->query == NULL
851 || request->query->connection == NULL
852 || !request->query->connection->isAlive()
857 request->query->connection->lock();
858 request->result = request->query->
execute();
861 std::cout <<
"Result is ";
863 if ((request->result != NULL) && !request->result->isEmpty()) {
865 std::cout <<
"not empty or null ";
869 request->rows =
new std::vector<row_t*>();
870 if (request->rows == NULL) {
875 request->buffered = request->result->isBuffered();
876 request->columnCount = request->result->columnCount();
878 while (request->result->hasNext()) {
879 unsigned long* columnLengths = request->result->columnLengths();
880 assert(columnLengths);
882 std::vector<std::string> *currentRow = request->result->next();
893 "Could not create buffer for row");
896 if (request->buffered) {
897 row->columns = currentRow;
898 row->columnLengths = columnLengths;
901 new unsigned long[request->columnCount];
903 if (row->columnLengths == NULL) {
905 "Could not create buffer for column lengths");
911 new std::vector<std::string>(
912 size_t(request->columnCount));
914 if (row->columns == NULL) {
916 "Could not create buffer for columns");
920 std::cout << std::endl;
922 for (uint16_t i = 0; i < request->columnCount; ++i) {
926 <<
" Length: " << columnLengths[i]
927 <<
" Value: " << currentRow->at(i)
930 row->columnLengths[i] = columnLengths[i];
931 row->columns->push_back(currentRow->at(i));
935 request->rows->push_back(row);
947 if (!request->result->isBuffered()) {
948 request->result->release();
951 std::cout << std::endl;
955 request->query->connection->unlock();
957 request->query->connection->unlock();
958 Query::freeRequest(request,
false);
959 request->error =
new std::string(exception.what());
962 #if !NODE_VERSION_AT_LEAST(0, 5, 0)
968 #if NODE_VERSION_AT_LEAST(0, 7, 8)
969 void nodejs_db::Query::uvEmitResults(uv_async_t* uvAsync,
int status) {
971 v8::HandleScope scope;
973 query_async_t* cr =
static_cast<query_async_t *
>(uvAsync->data);
976 execute_request_t* request = cr->request;
982 v8::Local<v8::Object> row = request->query->row(request->result, r);
983 v8::Local<v8::Value> eachArgv[1];
987 request->query->Emit(
"each", 1, eachArgv);
991 scope.Close(v8::Undefined());
996 void nodejs_db::Query::uvExecuteFinished(uv_work_t* uvRequest,
int status) {
998 v8::HandleScope scope;
1000 execute_request_t *request =
1001 static_cast<execute_request_t *
>(uvRequest->data);
1006 std::cout <<
"result ";
1009 if (request->error == NULL && request->result != NULL) {
1012 std::cout <<
"is not null";
1015 v8::Local<v8::Value> argv[3];
1016 argv[0] = v8::Local<v8::Value>::New(v8::Null());
1018 bool isEmpty = request->result->isEmpty();
1021 std::cout <<
", is not empty";
1024 assert(request->rows);
1026 size_t totalRows = request->rows->size();
1027 v8::Local<v8::Array> rows = v8::Array::New(totalRows);
1030 for (std::vector<row_t*>::iterator iterator =
1031 request->rows->begin(), end = request->rows->end();
1033 ++iterator, index++)
1035 row_t* currentRow = *iterator;
1036 v8::Local<v8::Object> row =
1037 request->query->row(request->result, currentRow);
1038 v8::Local<v8::Value> eachArgv[3];
1041 eachArgv[1] = v8::Number::New(index);
1042 eachArgv[2] = v8::Local<v8::Value>::New(
1043 (index == totalRows - 1)
1047 request->query->Emit(
"each", 3, eachArgv);
1049 rows->Set(index, row);
1052 v8::Local<v8::Array> columns = v8::Array::New(request->columnCount);
1053 for (uint16_t j = 0; j < request->columnCount; j++) {
1056 v8::Local<v8::Object> column = v8::Object::New();
1057 column->Set(v8::String::New(
"name"), v8::String::New(currentColumn->getName().c_str()));
1058 column->Set(v8::String::New(
"type"), NODE_CONSTANT(currentColumn->getType()));
1060 columns->Set(j, column);
1066 v8::Local<v8::Object> result = v8::Object::New();
1067 result->Set(v8::String::New(
"id"), v8::Number::New(request->result->insertId()));
1068 result->Set(v8::String::New(
"affected"), v8::Number::New(request->result->affectedCount()));
1069 result->Set(v8::String::New(
"warning"), v8::Number::New(request->result->warningCount()));
1073 request->query->Emit(
"success", !isEmpty ? 2 : 1, &argv[1]);
1075 if (request->query->cbExecute != NULL && !request->query->cbExecute->IsEmpty()) {
1076 v8::TryCatch tryCatch;
1077 (*(request->query->cbExecute))->Call(request->context, !isEmpty ? 3 : 2, argv);
1078 if (tryCatch.HasCaught()) {
1079 node::FatalException(tryCatch);
1083 v8::Local<v8::Value> argv[1];
1084 argv[0] = v8::String::New(request->error != NULL ? request->error->c_str() :
"(unknown error)");
1086 request->query->Emit(
"error", 1, argv);
1088 if (request->query->cbExecute != NULL && !request->query->cbExecute->IsEmpty()) {
1089 v8::TryCatch tryCatch;
1090 (*(request->query->cbExecute))->Call(request->context, 1, argv);
1091 if (tryCatch.HasCaught()) {
1092 node::FatalException(tryCatch);
1098 if (request->query->cbFinish != NULL && !request->query->cbFinish->IsEmpty()) {
1099 v8::TryCatch tryCatch;
1100 (*(request->query->cbFinish))->Call(v8::Context::GetCurrent()->Global(), 0, NULL);
1101 if (tryCatch.HasCaught()) {
1102 node::FatalException(tryCatch);
1106 #if NODE_VERSION_AT_LEAST(0, 7, 9)
1107 uv_unref((uv_handle_t *)&g_async);
1109 #else // NODE_VERSION_AT_LEAST(0, 7, 9)
1110 uv_unref(uv_default_loop());
1113 request->query->Unref();
1115 Query::freeRequest(request,
true);
1118 std::cout << std::endl;
1121 #if !NODE_VERSION_AT_LEAST(0, 7, 8)
1122 return scope.Close(v8::Undefined());
1124 scope.Close(v8::Undefined());
1133 void nodejs_db::Query::executeAsync(execute_request_t* request) {
1136 bool freeAll =
true;
1139 this->connection->lock();
1140 request->result = this->execute();
1141 this->connection->unlock();
1144 std::cout <<
"result: ";
1147 if (request->result != NULL) {
1149 std::cout <<
" is not null ";
1151 v8::Local<v8::Value> argv[3];
1152 argv[0] = v8::Local<v8::Value>::New(v8::Null());
1154 bool isEmpty = request->result->isEmpty();
1157 std::cout <<
", is not empty ";
1159 request->columnCount = request->result->columnCount();
1161 v8::Local<v8::Array> columns =
1162 v8::Array::New(request->columnCount);
1163 v8::Local<v8::Array> rows;
1166 rows = v8::Array::New(request->result->count());
1168 rows = v8::Array::New();
1172 std::cout <<
", columnCount "
1173 << request->columnCount << std::endl;
1176 for (uint16_t i = 0; i < request->columnCount; i++) {
1178 request->result->column(i);
1182 <<
" Name: " << currentColumn->getName()
1183 <<
" Type: " << currentColumn->getType()
1184 <<
" IsBinary: " << currentColumn->isBinary()
1188 v8::Local<v8::Object> column = v8::Object::New();
1189 column->Set(v8::String::New(
"name")
1191 currentColumn->getName().c_str()));
1192 column->Set(v8::String::New(
"type")
1193 , NODE_CONSTANT(currentColumn->getType()));
1195 columns->Set(i, column);
1203 std::cout <<
"Rows" << std::endl;
1205 while (request->result->hasNext()) {
1207 std::cout <<
"Row: " << index;
1211 static_cast<unsigned long*
>(
1212 request->result->columnLengths());
1213 row.columns = request->result->next();
1218 <<
", Columns: " << row.columns->size()
1223 v8::Local<v8::Object> jsRow = this->row(request->result, &row);
1224 v8::Local<v8::Value> eachArgv[3];
1226 eachArgv[0] = jsRow;
1227 eachArgv[1] = v8::Number::New(index);
1228 eachArgv[2] = v8::Local<v8::Value>::New(request->result->hasNext() ? v8::True() : v8::False());
1230 this->Emit(
"each", 3, eachArgv);
1232 rows->Set(index++, jsRow);
1235 if (!request->result->isBuffered()) {
1236 request->result->release();
1243 std::cout <<
", is empty";
1245 v8::Local<v8::Object> result = v8::Object::New();
1246 result->Set(v8::String::New(
"id"), v8::Number::New(request->result->insertId()));
1247 result->Set(v8::String::New(
"affected"), v8::Number::New(request->result->affectedCount()));
1248 result->Set(v8::String::New(
"warning"), v8::Number::New(request->result->warningCount()));
1253 std::cout << std::endl;
1256 this->Emit(
"success", !isEmpty ? 2 : 1, &argv[1]);
1258 if (this->cbExecute != NULL && !this->cbExecute->IsEmpty()) {
1259 v8::TryCatch tryCatch;
1260 (*(this->cbExecute))->Call(request->context, !isEmpty ? 3 : 2, argv);
1261 if (tryCatch.HasCaught()) {
1262 node::FatalException(tryCatch);
1267 this->connection->unlock();
1269 v8::Local<v8::Value> argv[1];
1270 argv[0] = v8::String::New(exception.what());
1272 this->Emit(
"error", 1, argv);
1274 if (this->cbExecute != NULL && !this->cbExecute->IsEmpty()) {
1275 v8::TryCatch tryCatch;
1276 (*(this->cbExecute))->Call(request->context, 1, argv);
1277 if (tryCatch.HasCaught()) {
1278 node::FatalException(tryCatch);
1285 Query::freeRequest(request, freeAll);
1308 if (this->sqlType == Query::NONE
1309 || this->sqlType == Query::SELECT
1311 return this->connection->query(this->sql.str());
1314 if (this->sqlType != Query::SELECT) {
1315 return this->connection->query_x(this->sql.str());
1318 return this->connection->query(this->sql.str());
1323 void nodejs_db::Query::freeRequest(execute_request_t* request,
bool freeAll) {
1347 if (request->error != NULL) {
1348 delete request->error;
1356 if (request->result != NULL) {
delete request->result; }
1358 request->context.Dispose();
1368 v8::Handle<v8::Value>
1369 nodejs_db::Query::set(
const v8::Arguments& args) {
1372 if (!this->connection) {
1373 THROW_EXCEPTION(
"No connection. Did you attempt to create new query "
1374 "without connection?");
1377 if (args.Length() == 0) {
1378 return v8::Handle<v8::Value>();
1381 int queryIndex = -1, optionsIndex = -1, valuesIndex = -1, callbackIndex = -1;
1383 if (args.Length() > 3) {
1384 ARG_CHECK_STRING(0, query);
1385 ARG_CHECK_ARRAY(1, values);
1386 ARG_CHECK_FUNCTION(2, callback);
1387 ARG_CHECK_OBJECT(3, options);
1392 }
else if (args.Length() == 3) {
1393 ARG_CHECK_STRING(0, query);
1395 if (args[2]->IsFunction()) {
1396 ARG_CHECK_FUNCTION(2, callback);
1397 if (args[1]->IsArray()) {
1398 ARG_CHECK_ARRAY(1, values);
1401 ARG_CHECK_OBJECT(1, options);
1406 ARG_CHECK_ARRAY(1, values);
1407 ARG_CHECK_OBJECT(2, options);
1411 }
else if (args.Length() == 2) {
1412 if (args[1]->IsFunction()) {
1413 ARG_CHECK_FUNCTION(1, callback);
1415 }
else if (args[1]->IsArray()) {
1416 ARG_CHECK_ARRAY(1, values);
1419 ARG_CHECK_OBJECT(1, options);
1423 if (args[0]->IsFunction() && callbackIndex == -1) {
1424 ARG_CHECK_FUNCTION(0, callback);
1427 ARG_CHECK_STRING(0, query);
1430 }
else if (args.Length() == 1) {
1431 if (args[0]->IsString()) {
1432 ARG_CHECK_STRING(0, query);
1434 }
else if (args[0]->IsFunction()) {
1435 ARG_CHECK_FUNCTION(0, callback);
1437 }
else if (args[0]->IsArray()) {
1438 ARG_CHECK_ARRAY(0, values);
1441 ARG_CHECK_OBJECT(0, options);
1446 if (queryIndex >= 0) {
1447 v8::String::Utf8Value initialSql(args[queryIndex]->ToString());
1450 this->sql << *initialSql;
1453 if (optionsIndex >= 0) {
1454 v8::Local<v8::Object> options = args[optionsIndex]->ToObject();
1456 ARG_CHECK_OBJECT_ATTR_OPTIONAL_BOOL(options, async);
1457 ARG_CHECK_OBJECT_ATTR_OPTIONAL_BOOL(options, cast);
1458 ARG_CHECK_OBJECT_ATTR_OPTIONAL_BOOL(options, bufferText);
1459 ARG_CHECK_OBJECT_ATTR_OPTIONAL_FUNCTION(options, start);
1460 ARG_CHECK_OBJECT_ATTR_OPTIONAL_FUNCTION(options, finish);
1462 if (options->Has(async_key)) {
1463 this->async = options->Get(async_key)->IsTrue();
1466 if (options->Has(cast_key)) {
1467 this->cast = options->Get(cast_key)->IsTrue();
1470 if (options->Has(bufferText_key)) {
1471 this->bufferText = options->Get(bufferText_key)->IsTrue();
1474 if (options->Has(start_key)) {
1475 if (this->cbStart != NULL) {
1476 node::cb_destroy(this->cbStart);
1478 this->cbStart = node::cb_persist(options->Get(start_key));
1481 if (options->Has(finish_key)) {
1482 if (this->cbFinish != NULL) {
1483 node::cb_destroy(this->cbFinish);
1485 this->cbFinish = node::cb_persist(options->Get(finish_key));
1489 if (valuesIndex >= 0) {
1490 v8::Local<v8::Array> v= v8::Array::Cast(*args[valuesIndex]);
1491 for (uint32_t i = 0, limiti = v->Length(); i < limiti; i++) {
1492 this->values.push_back(v8::Persistent<v8::Value>::New(v->Get(i)));
1496 if (callbackIndex >= 0) {
1497 this->cbExecute = node::cb_persist(args[callbackIndex]);
1500 return v8::Handle<v8::Value>();
1504 nodejs_db::Query::fieldName(v8::Local<v8::Value> v)
1509 if (v->IsObject()) {
1510 v8::Local<v8::Object> valueObject = v->ToObject();
1511 v8::Local<v8::Array> valueProperties = valueObject->GetPropertyNames();
1512 if (valueProperties->Length() == 0) {
1516 for (uint32_t j = 0, max_j = valueProperties->Length(); j < max_j; j++) {
1517 v8::Local<v8::Value> propertyName = valueProperties->Get(j);
1518 v8::String::Utf8Value fn(propertyName);
1520 v8::Local<v8::Value> currentValue = valueObject->Get(propertyName);
1521 if (currentValue->IsObject() && !currentValue->IsArray() && !currentValue->IsFunction() && !currentValue->IsDate()) {
1522 v8::Local<v8::Object> currentObject = currentValue->ToObject();
1523 v8::Local<v8::String> escapeKey = v8::String::New(
"escape");
1524 v8::Local<v8::String> valueKey = v8::String::New(
"value");
1525 v8::Local<v8::String> precisionKey = v8::String::New(
"precision");
1526 v8::Local<v8::Value> optionValue;
1527 bool escape =
false;
1530 if (!currentObject->Has(valueKey)) {
1531 throw nodejs_db::Exception(
"The \"value\" option for the select field object must be specified");
1534 if (currentObject->Has(escapeKey)) {
1535 optionValue = currentObject->Get(escapeKey);
1536 if (!optionValue->IsBoolean()) {
1537 throw nodejs_db::Exception(
"Specify a valid boolean value for the \"escape\" option in the select field object");
1539 escape = optionValue->IsTrue();
1542 if (currentObject->Has(precisionKey)) {
1543 optionValue = currentObject->Get(precisionKey);
1544 if (!optionValue->IsNumber() || optionValue->IntegerValue() < 0) {
1547 precision = optionValue->IntegerValue();
1554 buffer += this->value(currentObject->Get(valueKey),
false, escape, precision);
1560 buffer += this->value(currentValue,
false, currentValue->IsString() ?
false :
true);
1564 buffer += this->connection->escapeName(*fn);
1566 }
else if (v->IsString()) {
1567 v8::String::Utf8Value fn(v->ToString());
1578 nodejs_db::Query::tableName(
1579 v8::Local<v8::Value> value
1585 if (value->IsArray()) {
1586 v8::Local<v8::Array> tables = v8::Array::Cast(*value);
1587 if (tables->Length() == 0) {
1591 for (uint32_t i = 0, limiti = tables->Length(); i < limiti; i++) {
1596 buffer += this->tableName(tables->Get(i), escape);
1598 }
else if (value->IsObject()) {
1599 v8::Local<v8::Object> valueObject = value->ToObject();
1600 v8::Local<v8::Array> valueProperties = valueObject->GetPropertyNames();
1601 if (valueProperties->Length() == 0) {
1605 v8::Local<v8::Value> propertyName = valueProperties->Get(0);
1606 v8::Local<v8::Value> propertyValue = valueObject->Get(propertyName);
1608 if (!propertyName->IsString() || !propertyValue->IsString()) {
1612 v8::String::Utf8Value table(propertyValue);
1613 v8::String::Utf8Value alias(propertyName);
1615 buffer += (escape ? this->connection->escapeName(*table) : *table);
1617 buffer += (escape ? this->connection->escapeName(*alias) : *alias);
1619 v8::String::Utf8Value tables(value->ToString());
1621 buffer += (escape ? this->connection->escapeName(*tables) : *tables);
1628 v8::Handle<v8::Value>
1629 nodejs_db::Query::addCondition(
1630 const v8::Arguments& args
1631 ,
const char* separator
1634 ARG_CHECK_STRING(0, conditions);
1635 ARG_CHECK_OPTIONAL_ARRAY(1, values);
1637 v8::String::Utf8Value conditions(args[0]->ToString());
1638 std::string currentConditions = *conditions;
1639 if (args.Length() > 1) {
1640 v8::Local<v8::Array> currentValues = v8::Array::Cast(*args[1]);
1641 for (uint32_t i = 0, limiti = currentValues->Length(); i < limiti; i++) {
1642 this->values.push_back(v8::Persistent<v8::Value>::New(currentValues->Get(i)));
1646 this->sql <<
" " << separator <<
" ";
1647 this->sql << currentConditions;
1653 v8::Local<v8::Object>
1654 nodejs_db::Query::row(
1666 v8::Local<v8::Object> row = v8::Object::New();
1668 for (uint16_t j = 0, max_j = result->columnCount(); j < max_j; ++j) {
1670 v8::Local<v8::Value> v;
1675 <<
", Name: " << currentColumn->getName().c_str();
1678 if (currentRow->columns->at(j).c_str() != NULL) {
1679 const char* currentValue = currentRow->columns->at(j).c_str();
1680 unsigned long currentLength = currentRow->columnLengths[j];
1683 <<
", Value: " << currentValue
1684 <<
", length: " << currentLength
1690 nodejs_db::Result::Column::type_t columnType = currentColumn->getType();
1694 <<
", columnType: " << columnType;
1697 switch (columnType) {
1698 case nodejs_db::Result::Column::BOOL:
1699 v = v8::Local<v8::Value>::New(currentValue == NULL || currentLength == 0 || currentValue[0] !=
'0' ? v8::True() : v8::False());
1701 case nodejs_db::Result::Column::INT:
1702 v = v8::String::New(currentValue, currentLength)->ToInteger();
1704 case nodejs_db::Result::Column::NUMBER:
1705 v = v8::String::New(currentValue, currentLength)->ToNumber();
1707 case nodejs_db::Result::Column::TIME:
1710 sscanf(currentValue,
"%d:%d:%d", &hour, &min, &sec);
1711 v = v8::Date::New(static_cast<uint64_t>((hour*60*60 + min*60 + sec) * 1000));
1714 case nodejs_db::Result::Column::DATE:
1715 case nodejs_db::Result::Column::DATETIME:
1718 int day = 0, month = 0, year = 0, hour = 0, min = 0, sec = 0;
1722 if (columnType == nodejs_db::Result::Column::DATETIME) {
1723 sscanf(currentValue,
"%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &min, &sec);
1725 sscanf(currentValue,
"%d-%d-%d", &year, &month, &day);
1729 if (!localtime_r(&rawtime, &timeinfo)) {
1733 if (!Query::gmtDeltaLoaded) {
1734 int localHour, gmtHour, localMin, gmtMin;
1736 localHour = timeinfo.tm_hour - (timeinfo.tm_isdst > 0 ? 1 : 0);
1737 localMin = timeinfo.tm_min;
1739 if (!gmtime_r(&rawtime, &timeinfo)) {
1742 gmtHour = timeinfo.tm_hour;
1743 gmtMin = timeinfo.tm_min;
1745 Query::gmtDelta = ((localHour - gmtHour) * 60 + (localMin - gmtMin)) * 60;
1746 if (Query::gmtDelta <= -(12 * 60 * 60)) {
1747 Query::gmtDelta += 24 * 60 * 60;
1748 }
else if (Query::gmtDelta > (12 * 60 * 60)) {
1749 Query::gmtDelta -= 24 * 60 * 60;
1751 Query::gmtDeltaLoaded =
true;
1754 timeinfo.tm_year = year - 1900;
1755 timeinfo.tm_mon = month - 1;
1756 timeinfo.tm_mday = day;
1757 timeinfo.tm_hour = hour;
1758 timeinfo.tm_min = min;
1759 timeinfo.tm_sec = sec;
1761 v = v8::Date::New(static_cast<double>(mktime(&timeinfo) + Query::gmtDelta) * 1000);
1763 v = v8::String::New(currentValue, currentLength);
1766 case nodejs_db::Result::Column::SET:
1768 v8::Local<v8::Array> vs = v8::Array::New();
1769 std::istringstream stream(currentValue);
1772 while (std::getline(stream, item,
',')) {
1773 if (!item.empty()) {
1774 vs->Set(v8::Integer::New(index++), v8::String::New(item.c_str()));
1780 case nodejs_db::Result::Column::STRING:
1782 v = v8::String::New(currentValue, currentLength);
1785 case nodejs_db::Result::Column::TEXT:
1786 if (this->bufferText || currentColumn->isBinary()) {
1787 v = v8::Local<v8::Value>::New(node::Buffer::New(v8::String::New(currentValue, currentLength)));
1789 v = v8::String::New(currentValue, currentLength);
1793 v = v8::String::New(currentValue, currentLength);
1797 v = v8::String::New(currentValue, currentLength);
1801 std::cout <<
" is Null";
1803 v = v8::Local<v8::Value>::New(v8::Null());
1806 std::cout << std::endl;
1808 row->Set(v8::String::New(currentColumn->getName().c_str()), v);
1818 std::vector<std::string::size_type>
1823 std::string query = this->sql.str();
1824 std::vector<std::string::size_type> positions;
1826 bool escaped =
false;
1832 for (std::string::size_type i = 0, limiti = query.length()
1836 char currentChar = query[i];
1838 if (currentChar ==
'?') {
1839 parsed->replace(i - 1 - delta, 1,
"");
1843 }
else if (currentChar ==
'\\') {
1845 }
else if (quote && currentChar == quote) {
1847 }
else if (!quote && (currentChar == this->connection->quoteString)) {
1848 quote = currentChar;
1849 }
else if (!quote && currentChar ==
'?') {
1850 positions.push_back(i - delta);
1854 if (positions.size() != this->values.size()) {
1875 std::string s = this->sql.str();
1877 std::ostringstream ss;
1878 std::string select =
"SELECT";
1879 size_t pos = s.find(select);
1880 if (pos == std::string::npos) {
1885 if (this->projection.skip.flag) {
1887 std::string skipStr =
" SKIP ";
1889 ss << skipStr << this->projection.skip.arg;
1892 if (this->projection.limit.flag) {
1893 const std::string limitStr =
" LIMIT ";
1895 ss << limitStr << this->projection.limit.arg;
1896 }
else if (this->projection.first.flag) {
1897 const std::string firstStr =
" FIRST ";
1899 ss << firstStr << this->projection.first.arg;
1902 s.insert(pos + select.length(), ss.str());
1905 this->sql.seekp(s.length(), std::ios_base::beg);
1920 std::vector<std::string::size_type> p
1921 = this->placeholders(&parsed);
1923 uint32_t index = 0, delta = 0;
1924 for (std::vector<std::string::size_type>::iterator iterator = p.begin()
1930 std::string v = this->value(*(this->values[index]));
1934 "Internal error, attempting to replace with zero length\
1938 parsed.replace(*iterator + delta, 1, v);
1939 delta += (v.length() - 1);
1948 nodejs_db::Query::value(
1949 v8::Local<v8::Value> v,
1955 std::ostringstream currentStream;
1958 currentStream <<
"NULL";
1959 }
else if (v->IsArray()) {
1960 v8::Local<v8::Array> array = v8::Array::Cast(*v);
1962 currentStream <<
'(';
1964 for (uint32_t i = 0, limiti = array->Length(); i < limiti; i++) {
1965 v8::Local<v8::Value> child = array->Get(i);
1966 if (child->IsArray() && i > 0) {
1967 currentStream <<
"),(";
1969 currentStream <<
',';
1972 currentStream << this->value(child,
true, escape);
1975 currentStream <<
')';
1977 }
else if (v->IsDate()) {
1979 << this->connection->quoteString
1980 << this->fromDate(v8::Date::Cast(*v)->NumberValue())
1981 << this->connection->quoteString;
1982 }
else if (v->IsObject()) {
1983 v8::Local<v8::Object>
object = v->ToObject();
1984 v8::Handle<v8::String> valueKey = v8::String::New(
"value");
1985 v8::Handle<v8::String> escapeKey = v8::String::New(
"escape");
1987 if (object->Has(valueKey)) {
1988 v8::Handle<v8::String> precisionKey = v8::String::New(
"precision");
1992 if (object->Has(precisionKey)) {
1993 v8::Local<v8::Value> optionValue =
object->Get(precisionKey);
1994 if (!optionValue->IsNumber()
1995 || optionValue->IntegerValue() < 0
1998 "Specify a number equal or greater than 0 for\
2001 p = optionValue->IntegerValue();
2004 bool innerEscape =
true;
2005 if (object->Has(escapeKey)) {
2006 v8::Local<v8::Value> escapeValue =
object->Get(escapeKey);
2007 if (!escapeValue->IsBoolean()) {
2009 "Specify a valid boolean value for the \"escape\"\
2010 option in the select field object");
2012 innerEscape = escapeValue->IsTrue();
2015 << this->value(object->Get(valueKey),
false, innerEscape, p);
2017 v8::Handle<v8::String> sqlKey = v8::String::New(
"sql");
2018 if (!object->Has(sqlKey) || !
object->Get(sqlKey)->IsFunction()) {
2020 "Objects can't be converted to a SQL value");
2024 node::ObjectWrap::Unwrap<nodejs_db::Query>(object);
2027 currentStream <<
"(";
2029 currentStream << query->sql.str();
2031 currentStream <<
")";
2034 }
else if (v->IsBoolean()) {
2035 currentStream << (v->IsTrue() ?
'1' :
'0');
2039 || (v->IsNumber() && v->NumberValue() == v->IntegerValue())
2041 currentStream << v->IntegerValue();
2042 }
else if (v->IsNumber()) {
2043 if (precision == -1) {
2044 v8::String::Utf8Value currentString(v->ToString());
2045 currentStream << *currentString;
2049 << std::setprecision(precision)
2050 << v->NumberValue();
2052 }
else if (v->IsString()) {
2053 v8::String::Utf8Value currentString(v->ToString());
2054 std::string s = *currentString;
2058 << this->connection->quoteString
2059 << this->connection->escape(s)
2060 << this->connection->quoteString;
2063 << this->connection->quoteString
2065 << this->connection->quoteString;
2071 v8::String::Utf8Value currentString(v->ToString());
2072 std::string s = *currentString;
2074 "Unknown type for to convert to SQL, converting `" + s +
"'");
2077 return currentStream.str();
2083 nodejs_db::Query::fromDate(
2084 const double timeStamp
2086 char* buffer =
new char[20];
2087 if (buffer == NULL) {
2089 "Can\'t create buffer to write parsed date");
2094 time_t rawtime = (time_t) (timeStamp / 1000);
2095 if (!localtime_r(&rawtime, &timeinfo)) {
2099 strftime(buffer, 20,
"%Y-%m-%d %H:%M:%S", &timeinfo);
2101 std::string date(buffer);