@@ -66,6 +66,54 @@ using v8::Value; |
66 | 66 | } \ |
67 | 67 | } while (0) |
68 | 68 |
|
| 69 | +#define SQLITE_VALUE_TO_JS(from, isolate, use_big_int_args, result, ...) \ |
| 70 | + do { \ |
| 71 | + switch (sqlite3_##from##_type(__VA_ARGS__)) { \ |
| 72 | + case SQLITE_INTEGER: { \ |
| 73 | + sqlite3_int64 val = sqlite3_##from##_int64(__VA_ARGS__); \ |
| 74 | + if ((use_big_int_args)) { \ |
| 75 | + (result) = BigInt::New((isolate), val); \ |
| 76 | + } else if (std::abs(val) <= kMaxSafeJsInteger) { \ |
| 77 | + (result) = Number::New((isolate), val); \ |
| 78 | + } else { \ |
| 79 | + THROW_ERR_OUT_OF_RANGE((isolate), \ |
| 80 | + "Value is too large to be represented as a " \ |
| 81 | + "JavaScript number: %" PRId64, \ |
| 82 | + val); \ |
| 83 | + } \ |
| 84 | + break; \ |
| 85 | + } \ |
| 86 | + case SQLITE_FLOAT: { \ |
| 87 | + (result) = \ |
| 88 | + Number::New((isolate), sqlite3_##from##_double(__VA_ARGS__)); \ |
| 89 | + break; \ |
| 90 | + } \ |
| 91 | + case SQLITE_TEXT: { \ |
| 92 | + const char* v = \ |
| 93 | + reinterpret_cast<const char*>(sqlite3_##from##_text(__VA_ARGS__)); \ |
| 94 | + (result) = String::NewFromUtf8((isolate), v).As<Value>(); \ |
| 95 | + break; \ |
| 96 | + } \ |
| 97 | + case SQLITE_NULL: { \ |
| 98 | + (result) = Null((isolate)); \ |
| 99 | + break; \ |
| 100 | + } \ |
| 101 | + case SQLITE_BLOB: { \ |
| 102 | + size_t size = \ |
| 103 | + static_cast<size_t>(sqlite3_##from##_bytes(__VA_ARGS__)); \ |
| 104 | + auto data = reinterpret_cast<const uint8_t*>( \ |
| 105 | + sqlite3_##from##_blob(__VA_ARGS__)); \ |
| 106 | + auto store = ArrayBuffer::NewBackingStore((isolate), size); \ |
| 107 | + memcpy(store->Data(), data, size); \ |
| 108 | + auto ab = ArrayBuffer::New((isolate), std::move(store)); \ |
| 109 | + (result) = Uint8Array::New(ab, 0, size); \ |
| 110 | + break; \ |
| 111 | + } \ |
| 112 | + default: \ |
| 113 | + UNREACHABLE("Bad SQLite value"); \ |
| 114 | + } \ |
| 115 | + } while (0) |
| 116 | + |
69 | 117 | inline MaybeLocal<Object> CreateSQLiteError(Isolate* isolate, |
70 | 118 | const char* message) { |
71 | 119 | Local<String> js_msg; |
@@ -355,51 +403,13 @@ void UserDefinedFunction::xFunc(sqlite3_context* ctx, |
355 | 403 |
|
356 | 404 | for (int i = 0; i < argc; ++i) { |
357 | 405 | sqlite3_value* value = argv[i]; |
358 | | - MaybeLocal<Value> js_val; |
359 | | - |
360 | | - switch (sqlite3_value_type(value)) { |
361 | | - case SQLITE_INTEGER: { |
362 | | - sqlite3_int64 val = sqlite3_value_int64(value); |
363 | | - if (self->use_bigint_args_) { |
364 | | - js_val = BigInt::New(isolate, val); |
365 | | - } else if (std::abs(val) <= kMaxSafeJsInteger) { |
366 | | - js_val = Number::New(isolate, val); |
367 | | - } else { |
368 | | - // Ignore the SQLite error because a JavaScript exception is being |
369 | | - // thrown. |
370 | | - self->db_->SetIgnoreNextSQLiteError(true); |
371 | | - sqlite3_result_error(ctx, "", 0); |
372 | | - THROW_ERR_OUT_OF_RANGE(isolate, |
373 | | - "Value is too large to be represented as a " |
374 | | - "JavaScript number: %" PRId64, |
375 | | - val); |
376 | | - return; |
377 | | - } |
378 | | - break; |
379 | | - } |
380 | | - case SQLITE_FLOAT: |
381 | | - js_val = Number::New(isolate, sqlite3_value_double(value)); |
382 | | - break; |
383 | | - case SQLITE_TEXT: { |
384 | | - const char* v = |
385 | | - reinterpret_cast<const char*>(sqlite3_value_text(value)); |
386 | | - js_val = String::NewFromUtf8(isolate, v).As<Value>(); |
387 | | - break; |
388 | | - } |
389 | | - case SQLITE_NULL: |
390 | | - js_val = Null(isolate); |
391 | | - break; |
392 | | - case SQLITE_BLOB: { |
393 | | - size_t size = static_cast<size_t>(sqlite3_value_bytes(value)); |
394 | | - auto data = reinterpret_cast<const uint8_t*>(sqlite3_value_blob(value)); |
395 | | - auto store = ArrayBuffer::NewBackingStore(isolate, size); |
396 | | - memcpy(store->Data(), data, size); |
397 | | - auto ab = ArrayBuffer::New(isolate, std::move(store)); |
398 | | - js_val = Uint8Array::New(ab, 0, size); |
399 | | - break; |
400 | | - } |
401 | | - default: |
402 | | - UNREACHABLE("Bad SQLite value"); |
| 406 | + MaybeLocal<Value> js_val = MaybeLocal<Value>(); |
| 407 | + SQLITE_VALUE_TO_JS(value, isolate, self->use_bigint_args_, js_val, value); |
| 408 | + if (js_val.IsEmpty()) { |
| 409 | + // Ignore the SQLite error because a JavaScript exception is pending. |
| 410 | + self->db_->SetIgnoreNextSQLiteError(true); |
| 411 | + sqlite3_result_error(ctx, "", 0); |
| 412 | + return; |
403 | 413 | } |
404 | 414 |
|
405 | 415 | Local<Value> local; |
@@ -1521,45 +1531,11 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) { |
1521 | 1531 | } |
1522 | 1532 |
|
1523 | 1533 | MaybeLocal<Value> StatementSync::ColumnToValue(const int column) { |
1524 | | - switch (sqlite3_column_type(statement_, column)) { |
1525 | | - case SQLITE_INTEGER: { |
1526 | | - sqlite3_int64 value = sqlite3_column_int64(statement_, column); |
1527 | | - if (use_big_ints_) { |
1528 | | - return BigInt::New(env()->isolate(), value); |
1529 | | - } else if (std::abs(value) <= kMaxSafeJsInteger) { |
1530 | | - return Number::New(env()->isolate(), value); |
1531 | | - } else { |
1532 | | - THROW_ERR_OUT_OF_RANGE(env()->isolate(), |
1533 | | - "The value of column %d is too large to be " |
1534 | | - "represented as a JavaScript number: %" PRId64, |
1535 | | - column, |
1536 | | - value); |
1537 | | - return MaybeLocal<Value>(); |
1538 | | - } |
1539 | | - } |
1540 | | - case SQLITE_FLOAT: |
1541 | | - return Number::New(env()->isolate(), |
1542 | | - sqlite3_column_double(statement_, column)); |
1543 | | - case SQLITE_TEXT: { |
1544 | | - const char* value = reinterpret_cast<const char*>( |
1545 | | - sqlite3_column_text(statement_, column)); |
1546 | | - return String::NewFromUtf8(env()->isolate(), value).As<Value>(); |
1547 | | - } |
1548 | | - case SQLITE_NULL: |
1549 | | - return Null(env()->isolate()); |
1550 | | - case SQLITE_BLOB: { |
1551 | | - size_t size = |
1552 | | - static_cast<size_t>(sqlite3_column_bytes(statement_, column)); |
1553 | | - auto data = reinterpret_cast<const uint8_t*>( |
1554 | | - sqlite3_column_blob(statement_, column)); |
1555 | | - auto store = ArrayBuffer::NewBackingStore(env()->isolate(), size); |
1556 | | - memcpy(store->Data(), data, size); |
1557 | | - auto ab = ArrayBuffer::New(env()->isolate(), std::move(store)); |
1558 | | - return Uint8Array::New(ab, 0, size); |
1559 | | - } |
1560 | | - default: |
1561 | | - UNREACHABLE("Bad SQLite column type"); |
1562 | | - } |
| 1534 | + Isolate* isolate = env()->isolate(); |
| 1535 | + MaybeLocal<Value> js_val = MaybeLocal<Value>(); |
| 1536 | + SQLITE_VALUE_TO_JS( |
| 1537 | + column, isolate, use_big_ints_, js_val, statement_, column); |
| 1538 | + return js_val; |
1563 | 1539 | } |
1564 | 1540 |
|
1565 | 1541 | MaybeLocal<Name> StatementSync::ColumnNameToName(const int column) { |
|