@@ -67,6 +67,63 @@ using v8::Value;
6767 } \
6868 } while (0 )
6969
70+ #define SQLITE_VALUE_TO_JS ( \
71+ from, unreachable_message, isolate, use_big_int_args, ...) \
72+ switch (sqlite3_##from##_type(__VA_ARGS__)) { \
73+ case SQLITE_INTEGER: { \
74+ sqlite3_int64 val = sqlite3_##from##_int64 (__VA_ARGS__); \
75+ if (use_big_int_args) { \
76+ return BigInt::New (isolate, val); \
77+ } else if (std::abs (val) <= kMaxSafeJsInteger ) { \
78+ return Number::New (isolate, val); \
79+ } else { \
80+ return MaybeLocal<Value>(); \
81+ } \
82+ break ; \
83+ } \
84+ case SQLITE_FLOAT: { \
85+ return Number::New (isolate, sqlite3_##from##_double (__VA_ARGS__)); \
86+ break ; \
87+ } \
88+ case SQLITE_TEXT: { \
89+ const char * v = \
90+ reinterpret_cast <const char *>(sqlite3_##from##_text (__VA_ARGS__)); \
91+ return String::NewFromUtf8 (isolate, v).As <Value>(); \
92+ } \
93+ case SQLITE_NULL: \
94+ return Null (isolate); \
95+ case SQLITE_BLOB: { \
96+ size_t size = static_cast <size_t >(sqlite3_##from##_bytes (__VA_ARGS__)); \
97+ auto data = reinterpret_cast <const uint8_t *>( \
98+ sqlite3_##from##_blob (__VA_ARGS__)); \
99+ auto store = ArrayBuffer::NewBackingStore (isolate, size); \
100+ memcpy (store->Data (), data, size); \
101+ auto ab = ArrayBuffer::New (isolate, std::move (store)); \
102+ return Uint8Array::New (ab, 0 , size); \
103+ } \
104+ default : \
105+ UNREACHABLE (unreachable_message); \
106+ }
107+
108+ MaybeLocal<Value> SQLiteValueToJS (Isolate* isolate,
109+ bool use_big_int_args,
110+ sqlite3_value* sqlite_value) {
111+ SQLITE_VALUE_TO_JS (
112+ value, " Bad SQLite value" , isolate, use_big_int_args, sqlite_value);
113+ }
114+
115+ MaybeLocal<Value> SQLiteValueToJS (Isolate* isolate,
116+ bool use_big_int_args,
117+ sqlite3_stmt* stmt,
118+ int column) {
119+ SQLITE_VALUE_TO_JS (column,
120+ " Bad SQLite column type" ,
121+ isolate,
122+ use_big_int_args,
123+ stmt,
124+ column);
125+ }
126+
70127inline MaybeLocal<Object> CreateSQLiteError (Isolate* isolate,
71128 const char * message) {
72129 Local<String> js_msg;
@@ -356,51 +413,18 @@ void UserDefinedFunction::xFunc(sqlite3_context* ctx,
356413
357414 for (int i = 0 ; i < argc; ++i) {
358415 sqlite3_value* value = argv[i];
359- MaybeLocal<Value> js_val;
360-
361- switch (sqlite3_value_type (value)) {
362- case SQLITE_INTEGER: {
363- sqlite3_int64 val = sqlite3_value_int64 (value);
364- if (self->use_bigint_args_ ) {
365- js_val = BigInt::New (isolate, val);
366- } else if (std::abs (val) <= kMaxSafeJsInteger ) {
367- js_val = Number::New (isolate, val);
368- } else {
369- // Ignore the SQLite error because a JavaScript exception is being
370- // thrown.
371- self->db_ ->SetIgnoreNextSQLiteError (true );
372- sqlite3_result_error (ctx, " " , 0 );
373- THROW_ERR_OUT_OF_RANGE (isolate,
374- " Value is too large to be represented as a "
375- " JavaScript number: %" PRId64,
376- val);
377- return ;
378- }
379- break ;
380- }
381- case SQLITE_FLOAT:
382- js_val = Number::New (isolate, sqlite3_value_double (value));
383- break ;
384- case SQLITE_TEXT: {
385- const char * v =
386- reinterpret_cast <const char *>(sqlite3_value_text (value));
387- js_val = String::NewFromUtf8 (isolate, v).As <Value>();
388- break ;
389- }
390- case SQLITE_NULL:
391- js_val = Null (isolate);
392- break ;
393- case SQLITE_BLOB: {
394- size_t size = static_cast <size_t >(sqlite3_value_bytes (value));
395- auto data = reinterpret_cast <const uint8_t *>(sqlite3_value_blob (value));
396- auto store = ArrayBuffer::NewBackingStore (isolate, size);
397- memcpy (store->Data (), data, size);
398- auto ab = ArrayBuffer::New (isolate, std::move (store));
399- js_val = Uint8Array::New (ab, 0 , size);
400- break ;
401- }
402- default :
403- UNREACHABLE (" Bad SQLite value" );
416+ MaybeLocal<Value> js_val =
417+ SQLiteValueToJS (isolate, self->use_bigint_args_ , value);
418+
419+ if (js_val.IsEmpty ()) {
420+ // Ignore the SQLite error because a JavaScript exception is pending.
421+ self->db_ ->SetIgnoreNextSQLiteError (true );
422+ sqlite3_result_error (ctx, " " , 0 );
423+ THROW_ERR_OUT_OF_RANGE (isolate,
424+ " Value is too large to be represented as a "
425+ " JavaScript number: %" PRId64,
426+ sqlite3_value_int64 (value));
427+ return ;
404428 }
405429
406430 Local<Value> local;
@@ -1511,45 +1535,20 @@ bool StatementSync::BindValue(const Local<Value>& value, const int index) {
15111535}
15121536
15131537MaybeLocal<Value> StatementSync::ColumnToValue (const int column) {
1514- switch (sqlite3_column_type (statement_, column)) {
1515- case SQLITE_INTEGER: {
1516- sqlite3_int64 value = sqlite3_column_int64 (statement_, column);
1517- if (use_big_ints_) {
1518- return BigInt::New (env ()->isolate (), value);
1519- } else if (std::abs (value) <= kMaxSafeJsInteger ) {
1520- return Number::New (env ()->isolate (), value);
1521- } else {
1522- THROW_ERR_OUT_OF_RANGE (env ()->isolate (),
1523- " The value of column %d is too large to be "
1524- " represented as a JavaScript number: %" PRId64,
1525- column,
1526- value);
1527- return MaybeLocal<Value>();
1528- }
1529- }
1530- case SQLITE_FLOAT:
1531- return Number::New (env ()->isolate (),
1532- sqlite3_column_double (statement_, column));
1533- case SQLITE_TEXT: {
1534- const char * value = reinterpret_cast <const char *>(
1535- sqlite3_column_text (statement_, column));
1536- return String::NewFromUtf8 (env ()->isolate (), value).As <Value>();
1537- }
1538- case SQLITE_NULL:
1539- return Null (env ()->isolate ());
1540- case SQLITE_BLOB: {
1541- size_t size =
1542- static_cast <size_t >(sqlite3_column_bytes (statement_, column));
1543- auto data = reinterpret_cast <const uint8_t *>(
1544- sqlite3_column_blob (statement_, column));
1545- auto store = ArrayBuffer::NewBackingStore (env ()->isolate (), size);
1546- memcpy (store->Data (), data, size);
1547- auto ab = ArrayBuffer::New (env ()->isolate (), std::move (store));
1548- return Uint8Array::New (ab, 0 , size);
1549- }
1550- default :
1551- UNREACHABLE (" Bad SQLite column type" );
1538+ Isolate* isolate = env ()->isolate ();
1539+ MaybeLocal<Value> js_val =
1540+ SQLiteValueToJS (isolate, use_big_ints_, statement_, column);
1541+
1542+ if (js_val.IsEmpty ()) {
1543+ THROW_ERR_OUT_OF_RANGE (isolate,
1544+ " The value of column %d is too large to be "
1545+ " represented as a JavaScript number: %" PRId64,
1546+ column,
1547+ sqlite3_column_int64 (statement_, column));
1548+ return MaybeLocal<Value>();
15521549 }
1550+
1551+ return js_val;
15531552}
15541553
15551554MaybeLocal<Name> StatementSync::ColumnNameToName (const int column) {
0 commit comments