Skip to content

Commit 9c5bba2

Browse files
committed
Consistent type casting in MysqlResult and MysqlStatement
@estliberitas, I'll bring back TINYINT casting, seea #143
1 parent 89ff92b commit 9c5bba2

File tree

2 files changed

+134
-83
lines changed

2 files changed

+134
-83
lines changed

src/mysql_bindings_result.cc

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,32 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field,
9090
Local<Value> js_field = Local<Value>::New(Null());
9191

9292
switch (field.type) {
93-
case MYSQL_TYPE_NULL: // NULL-type field
93+
case MYSQL_TYPE_NULL: // NULL-type field
9494
// Already null
9595
break;
96-
case MYSQL_TYPE_TINY: // TINYINT field
97-
case MYSQL_TYPE_BIT: // BIT field (MySQL 5.0.3 and up)
96+
case MYSQL_TYPE_TINY: // TINYINT field
9897
case MYSQL_TYPE_SHORT: // SMALLINT field
99-
case MYSQL_TYPE_LONG: // INTEGER field
98+
case MYSQL_TYPE_LONG: // INTEGER field
10099
case MYSQL_TYPE_INT24: // MEDIUMINT field
101-
case MYSQL_TYPE_YEAR: // YEAR field
100+
case MYSQL_TYPE_YEAR: // YEAR field
102101
if (field_value) {
103102
js_field = V8STR(field_value)->ToInteger();
104103
}
105104
break;
105+
case MYSQL_TYPE_BIT: // BIT field (MySQL 5.0.3 and up)
106106
case MYSQL_TYPE_LONGLONG: // BIGINT field
107107
// Return BIGINT as string, see #110
108108
if (field_value) {
109109
js_field = V8STR(field_value);
110110
}
111111
break;
112-
case MYSQL_TYPE_FLOAT: // FLOAT field
112+
case MYSQL_TYPE_FLOAT: // FLOAT field
113113
case MYSQL_TYPE_DOUBLE: // DOUBLE or REAL field
114114
if (field_value) {
115115
js_field = V8STR(field_value)->ToNumber();
116116
}
117117
break;
118-
case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
118+
case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
119119
case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field
120120
// Return DECIMAL/NUMERIC as string, see #110
121121
if (field_value) {
@@ -132,7 +132,7 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field,
132132
}
133133
break;
134134
case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
135-
case MYSQL_TYPE_DATETIME: // DATETIME field
135+
case MYSQL_TYPE_DATETIME: // DATETIME field
136136
if (field_value) {
137137
// First step is to get a handle to the global object:
138138
Local<v8::Object> globalObj = Context::GetCurrent()->Global();
@@ -148,8 +148,8 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field,
148148
js_field = dateConstructor->NewInstance(argc, argv);
149149
}
150150
break;
151-
case MYSQL_TYPE_DATE: // DATE field
152-
case MYSQL_TYPE_NEWDATE: // Newer const used > 5.0
151+
case MYSQL_TYPE_DATE: // DATE field
152+
case MYSQL_TYPE_NEWDATE: // Newer const used in MySQL > 5.0
153153
if (field_value) {
154154
// First step is to get a handle to the global object:
155155
Local<v8::Object> globalObj = Context::GetCurrent()->Global();
@@ -173,9 +173,6 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field,
173173
case MYSQL_TYPE_VAR_STRING:
174174
if (field_value) {
175175
if (field.flags & BINARY_FLAG) {
176-
// SlowBuffer
177-
// node::Buffer *bp = node::Buffer::New(field_value,
178-
// field_length);
179176
js_field = Local<Value>::New(
180177
node::Buffer::New(
181178
V8STR2(field_value, field_length)));
@@ -206,7 +203,7 @@ Local<Value> MysqlResult::GetFieldValue(MYSQL_FIELD field,
206203
js_field = V8STR(field_value);
207204
}
208205
break;
209-
case MYSQL_TYPE_GEOMETRY: // Spatial fielda
206+
case MYSQL_TYPE_GEOMETRY: // Spatial fields
210207
// See for information:
211208
// http://dev.mysql.com/doc/refman/5.1/en/spatial-extensions.html
212209
if (field_value) {

src/mysql_bindings_statement.cc

Lines changed: 123 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -477,9 +477,9 @@ Handle<Value> MysqlStatement::FetchAllSync(const Arguments& args) {
477477

478478
MYSQLSTMT_MUSTBE_INITIALIZED;
479479
MYSQLSTMT_MUSTBE_PREPARED;
480+
MYSQLSTMT_MUSTBE_STORED;
480481

481-
/* Get meta data for binding buffers */
482-
482+
// Get fields count for binding buffers
483483
unsigned int field_count = mysql_stmt_field_count(stmt->_stmt);
484484

485485
uint32_t i = 0, j = 0;
@@ -490,52 +490,84 @@ Handle<Value> MysqlStatement::FetchAllSync(const Arguments& args) {
490490
MYSQL_RES *meta;
491491
MYSQL_FIELD *fields;
492492

493-
/* Buffers */
493+
// Buffers
494494
int int_data[field_count];
495-
signed char tiny_data[field_count];
495+
my_ulonglong my_ulonglong_data[field_count];
496496
double double_data[field_count];
497497
char str_data[field_count][64];
498498
MYSQL_TIME date_data[field_count];
499499
memset(date_data, 0, sizeof(date_data));
500500

501501
memset(bind, 0, sizeof(bind));
502502

503+
// Get meta data for binding buffers
503504
meta = mysql_stmt_result_metadata(stmt->_stmt);
504505

505506
fields = meta->fields;
506507
while (i < field_count) {
507508
bind[i].buffer_type = fields[i].type;
508509

509510
switch (fields[i].type) {
510-
case MYSQL_TYPE_NULL:
511-
case MYSQL_TYPE_SHORT:
512-
case MYSQL_TYPE_LONG:
513-
case MYSQL_TYPE_LONGLONG:
514-
case MYSQL_TYPE_INT24:
511+
case MYSQL_TYPE_NULL: // NULL-type field
512+
// TODO: Implement this
513+
bind[i].buffer = &int_data[i];
514+
break;
515+
case MYSQL_TYPE_TINY: // TINYINT field
516+
case MYSQL_TYPE_SHORT: // SMALLINT field
517+
case MYSQL_TYPE_LONG: // INTEGER field
518+
case MYSQL_TYPE_INT24: // MEDIUMINT field
519+
case MYSQL_TYPE_YEAR: // YEAR field
515520
bind[i].buffer = &int_data[i];
516521
break;
517-
case MYSQL_TYPE_TINY:
518-
bind[i].buffer = &tiny_data[i];
522+
case MYSQL_TYPE_BIT: // BIT field (MySQL 5.0.3 and up)
523+
case MYSQL_TYPE_LONGLONG: // BIGINT field
524+
// Return BIGINT as string, see #110
525+
bind[i].buffer = &my_ulonglong_data[i];
519526
break;
520-
case MYSQL_TYPE_FLOAT:
521-
case MYSQL_TYPE_DOUBLE:
522-
case MYSQL_TYPE_DECIMAL:
523-
case MYSQL_TYPE_NEWDECIMAL:
527+
case MYSQL_TYPE_FLOAT: // FLOAT field
528+
case MYSQL_TYPE_DOUBLE: // DOUBLE or REAL field
524529
bind[i].buffer = &double_data[i];
525530
break;
531+
case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
532+
case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field
533+
// Return DECIMAL/NUMERIC as string, see #110
534+
bind[i].buffer = (char *) str_data[i];
535+
bind[i].buffer_length = fields[i].length;
536+
break;
537+
case MYSQL_TYPE_TIME: // TIME field
538+
case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
539+
case MYSQL_TYPE_DATETIME: // DATETIME field
540+
case MYSQL_TYPE_DATE: // DATE field
541+
case MYSQL_TYPE_NEWDATE: // Newer const used in MySQL > 5.0
542+
bind[i].buffer = (char *) &date_data[i];
543+
break;
544+
case MYSQL_TYPE_TINY_BLOB:
545+
case MYSQL_TYPE_MEDIUM_BLOB:
546+
case MYSQL_TYPE_LONG_BLOB:
547+
case MYSQL_TYPE_BLOB:
526548
case MYSQL_TYPE_STRING:
527549
case MYSQL_TYPE_VAR_STRING:
528-
case MYSQL_TYPE_VARCHAR:
529550
bind[i].buffer = (char *) str_data[i];
530551
bind[i].buffer_length = fields[i].length;
531552
break;
532-
case MYSQL_TYPE_YEAR:
533-
case MYSQL_TYPE_DATE:
534-
case MYSQL_TYPE_NEWDATE:
535-
case MYSQL_TYPE_TIME:
536-
case MYSQL_TYPE_DATETIME:
537-
case MYSQL_TYPE_TIMESTAMP:
538-
bind[i].buffer = (char *) &date_data[i];
553+
case MYSQL_TYPE_SET: // SET field
554+
// TODO: Implement this
555+
bind[i].buffer = (char *) str_data[i];
556+
bind[i].buffer_length = fields[i].length;
557+
break;
558+
case MYSQL_TYPE_ENUM: // ENUM field
559+
bind[i].buffer = (char *) str_data[i];
560+
bind[i].buffer_length = fields[i].length;
561+
break;
562+
case MYSQL_TYPE_GEOMETRY: // Spatial fields
563+
// See for information:
564+
// http://dev.mysql.com/doc/refman/5.1/en/spatial-extensions.html
565+
bind[i].buffer = (char *) str_data[i];
566+
bind[i].buffer_length = fields[i].length;
567+
break;
568+
default:
569+
bind[i].buffer = (char *) str_data[i];
570+
bind[i].buffer_length = fields[i].length;
539571
break;
540572
}
541573

@@ -554,15 +586,14 @@ Handle<Value> MysqlStatement::FetchAllSync(const Arguments& args) {
554586
return scope.Close(Null());
555587
}
556588

557-
Local<Array> js_result_rows = Array::New();
589+
Local<Array> js_result = Array::New();
558590
Local<Object> js_result_row;
559-
Handle<Value> js_result;
560591

561592
row_count = mysql_stmt_num_rows(stmt->_stmt);
562593

563594
/* If no rows, return empty array */
564-
if (!row_count) {
565-
return scope.Close(js_result_rows);
595+
if (row_count == 0) {
596+
return scope.Close(js_result);
566597
}
567598

568599
i = 0;
@@ -571,66 +602,89 @@ Handle<Value> MysqlStatement::FetchAllSync(const Arguments& args) {
571602

572603
j = 0;
573604
while (j < field_count) {
605+
Local<Value> js_field = Local<Value>::New(Null());
606+
574607
switch(fields[j].type) {
575-
case MYSQL_TYPE_NULL:
576-
case MYSQL_TYPE_SHORT:
577-
case MYSQL_TYPE_LONG:
578-
case MYSQL_TYPE_LONGLONG:
579-
case MYSQL_TYPE_INT24:
580-
js_result = Integer::New(int_data[j]);
608+
case MYSQL_TYPE_NULL: // NULL-type field
609+
// Already null
581610
break;
582-
case MYSQL_TYPE_TINY:
583-
if (length[j] == 1) {
584-
js_result = Boolean::New(tiny_data[j] != 0);
585-
} else {
586-
js_result = Integer::NewFromUnsigned(tiny_data[j]);
611+
case MYSQL_TYPE_TINY: // TINYINT field
612+
case MYSQL_TYPE_SHORT: // SMALLINT field
613+
case MYSQL_TYPE_LONG: // INTEGER field
614+
case MYSQL_TYPE_INT24: // MEDIUMINT field
615+
case MYSQL_TYPE_YEAR: // YEAR field
616+
if (!is_null[j]) {
617+
js_field = Integer::New(int_data[j]);
618+
}
619+
break;
620+
case MYSQL_TYPE_BIT: // BIT field (MySQL 5.0.3 and up)
621+
case MYSQL_TYPE_LONGLONG: // BIGINT field
622+
// Return BIGINT as string, see #110
623+
if (!is_null[j]) {
624+
js_field = V8STR2(str_data[j], length[j]);
625+
}
626+
break;
627+
case MYSQL_TYPE_FLOAT: // FLOAT field
628+
case MYSQL_TYPE_DOUBLE: // DOUBLE or REAL field
629+
if (!is_null[j]) {
630+
js_field = Number::New(double_data[j]);
587631
}
588632
break;
589-
case MYSQL_TYPE_FLOAT:
590-
case MYSQL_TYPE_DOUBLE:
591-
js_result = Number::New(double_data[j]);
633+
case MYSQL_TYPE_DECIMAL: // DECIMAL or NUMERIC field
634+
case MYSQL_TYPE_NEWDECIMAL: // Precision math DECIMAL or NUMERIC field
635+
// Return DECIMAL/NUMERIC as string, see #110
636+
if (!is_null[j]) {
637+
js_field = V8STR2(str_data[j], length[j]);
638+
}
592639
break;
593-
case MYSQL_TYPE_DECIMAL:
594-
case MYSQL_TYPE_NEWDECIMAL:
595-
js_result = Number::New(double_data[j])->ToString();
640+
case MYSQL_TYPE_TIME: // TIME field
641+
case MYSQL_TYPE_TIMESTAMP: // TIMESTAMP field
642+
case MYSQL_TYPE_DATETIME: // DATETIME field
643+
case MYSQL_TYPE_DATE: // DATE field
644+
case MYSQL_TYPE_NEWDATE: // Newer const used in MySQL > 5.0
645+
if (!is_null[j]) {
646+
MYSQL_TIME ts = date_data[j];
647+
time_t rawtime;
648+
struct tm * datetime;
649+
time(&rawtime);
650+
datetime = localtime(&rawtime);
651+
datetime->tm_year = ts.year - 1900;
652+
datetime->tm_mon = ts.month - 1;
653+
datetime->tm_mday = ts.day;
654+
datetime->tm_hour = ts.hour;
655+
datetime->tm_min = ts.minute;
656+
datetime->tm_sec = ts.second;
657+
time_t timestamp = mktime(datetime);
658+
659+
js_field = Date::New(1000 * (double) timestamp);
660+
}
596661
break;
662+
case MYSQL_TYPE_TINY_BLOB:
663+
case MYSQL_TYPE_MEDIUM_BLOB:
664+
case MYSQL_TYPE_LONG_BLOB:
665+
case MYSQL_TYPE_BLOB:
597666
case MYSQL_TYPE_STRING:
598667
case MYSQL_TYPE_VAR_STRING:
599-
case MYSQL_TYPE_VARCHAR:
600-
js_result = V8STR2(str_data[j], length[j]);
668+
if (!is_null[j]) {
669+
js_field = V8STR2(str_data[j], length[j]);
670+
}
601671
break;
602-
case MYSQL_TYPE_YEAR:
603-
case MYSQL_TYPE_DATE:
604-
case MYSQL_TYPE_NEWDATE:
605-
case MYSQL_TYPE_TIME:
606-
case MYSQL_TYPE_DATETIME:
607-
case MYSQL_TYPE_TIMESTAMP:
608-
MYSQL_TIME ts = date_data[j];
609-
time_t rawtime;
610-
struct tm * datetime;
611-
time(&rawtime);
612-
datetime = localtime(&rawtime);
613-
datetime->tm_year = ts.year - 1900;
614-
datetime->tm_mon = ts.month - 1;
615-
datetime->tm_mday = ts.day;
616-
datetime->tm_hour = ts.hour;
617-
datetime->tm_min = ts.minute;
618-
datetime->tm_sec = ts.second;
619-
time_t timestamp = mktime(datetime);
620-
621-
js_result = Date::New(1000 * (double) timestamp);
672+
default:
673+
if (!is_null[j]) {
674+
js_field = V8STR2(str_data[j], length[j]);
675+
}
622676
break;
623677
}
624678

625-
js_result_row->Set(V8STR(fields[j].name), js_result);
679+
js_result_row->Set(V8STR(fields[j].name), js_field);
626680
j++;
627681
}
628682

629-
js_result_rows->Set(Integer::NewFromUnsigned(i), js_result_row);
683+
js_result->Set(Integer::NewFromUnsigned(i), js_result_row);
630684
i++;
631685
}
632686

633-
return scope.Close(js_result_rows);
687+
return scope.Close(js_result);
634688
}
635689

636690
/**

0 commit comments

Comments
 (0)