@@ -1582,27 +1582,38 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
15821582 int num_cols = sqlite3_column_count (stmt->statement_ );
15831583 LocalVector<Value> rows (isolate);
15841584 LocalVector<Name> row_keys (isolate);
1585+
15851586 while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1586- if (row_keys. size () == 0 ) {
1587- row_keys. reserve ( num_cols);
1587+ if (stmt-> return_arrays_ ) {
1588+ Local<Array> row = Array::New (isolate, num_cols);
15881589 for (int i = 0 ; i < num_cols; ++i) {
1589- Local<Name> key;
1590- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1591- row_keys.emplace_back (key);
1590+ Local<Value> val;
1591+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1592+ if (row->Set (env->context (), i, val).IsNothing ()) return ;
1593+ }
1594+ rows.emplace_back (row);
1595+ } else {
1596+ if (row_keys.size () == 0 ) {
1597+ row_keys.reserve (num_cols);
1598+ for (int i = 0 ; i < num_cols; ++i) {
1599+ Local<Name> key;
1600+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1601+ row_keys.emplace_back (key);
1602+ }
15921603 }
1593- }
15941604
1595- LocalVector<Value> row_values (isolate);
1596- row_values.reserve (num_cols);
1597- for (int i = 0 ; i < num_cols; ++i) {
1598- Local<Value> val;
1599- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1600- row_values.emplace_back (val);
1601- }
1605+ LocalVector<Value> row_values (isolate);
1606+ row_values.reserve (num_cols);
1607+ for (int i = 0 ; i < num_cols; ++i) {
1608+ Local<Value> val;
1609+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1610+ row_values.emplace_back (val);
1611+ }
16021612
1603- Local<Object> row = Object::New (
1604- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1605- rows.emplace_back (row);
1613+ Local<Object> row = Object::New (
1614+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1615+ rows.emplace_back (row);
1616+ }
16061617 }
16071618
16081619 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1645,7 +1656,7 @@ void StatementSync::IterateReturnCallback(
16451656}
16461657
16471658void StatementSync::IterateNextCallback (
1648- const FunctionCallbackInfo<Value>& args) {
1659+ const v8:: FunctionCallbackInfo<v8:: Value>& args) {
16491660 Environment* env = Environment::GetCurrent (args);
16501661 auto isolate = env->isolate ();
16511662 auto context = isolate->GetCurrentContext ();
@@ -1688,6 +1699,15 @@ void StatementSync::IterateNextCallback(
16881699 THROW_AND_RETURN_ON_BAD_STATE (
16891700 env, stmt->IsFinalized (), " statement has been finalized" );
16901701
1702+ // Get the return_arrays flag from the iterator object
1703+ Local<Value> return_arrays_val;
1704+ bool return_arrays = false ;
1705+ if (self->Get (context, FIXED_ONE_BYTE_STRING (isolate, " return_arrays" ))
1706+ .ToLocal (&return_arrays_val) &&
1707+ return_arrays_val->IsBoolean ()) {
1708+ return_arrays = return_arrays_val.As <Boolean>()->Value ();
1709+ }
1710+
16911711 int r = sqlite3_step (stmt->statement_ );
16921712 if (r != SQLITE_ROW) {
16931713 CHECK_ERROR_OR_THROW (
@@ -1702,39 +1722,47 @@ void StatementSync::IterateNextCallback(
17021722 return ;
17031723 }
17041724
1705- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1706- LocalVector<Value> values (isolate,
1707- {Boolean::New (isolate, true ), Null (isolate)});
1708-
1709- DCHECK_EQ (keys.size (), values.size ());
1725+ Local<Name> keys[] = {env->done_string (), env->value_string ()};
1726+ Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1727+ static_assert (arraysize (keys) == arraysize (values));
17101728 Local<Object> result = Object::New (
1711- isolate, Null (isolate), keys. data (), values. data (), keys. size ( ));
1729+ isolate, Null (isolate), & keys[ 0 ], & values[ 0 ], arraysize (keys ));
17121730 args.GetReturnValue ().Set (result);
17131731 return ;
17141732 }
17151733
1716- LocalVector<Name> row_keys (isolate);
1717- row_keys.reserve (num_cols);
1718- LocalVector<Value> row_values (isolate);
1719- row_values.reserve (num_cols);
1720- for (int i = 0 ; i < num_cols; ++i) {
1721- Local<Name> key;
1722- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1723- Local<Value> val;
1724- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1725- row_keys.emplace_back (key);
1726- row_values.emplace_back (val);
1727- }
1728-
1729- Local<Object> row = Object::New (
1730- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1734+ Local<Value> row;
1735+ if (return_arrays) {
1736+ Local<Array> array_row = Array::New (isolate, num_cols);
1737+ for (int i = 0 ; i < num_cols; ++i) {
1738+ Local<Value> val;
1739+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1740+ if (array_row->Set (env->context (), i, val).IsNothing ()) return ;
1741+ }
1742+ row = array_row;
1743+ } else {
1744+ LocalVector<Name> row_keys (isolate);
1745+ row_keys.reserve (num_cols);
1746+ LocalVector<Value> row_values (isolate);
1747+ row_values.reserve (num_cols);
1748+ for (int i = 0 ; i < num_cols; ++i) {
1749+ Local<Name> key;
1750+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1751+ Local<Value> val;
1752+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1753+ row_keys.emplace_back (key);
1754+ row_values.emplace_back (val);
1755+ }
17311756
1732- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1733- LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
1757+ row = Object::New (
1758+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1759+ }
17341760
1735- DCHECK_EQ (keys.size (), values.size ());
1761+ Local<Name> keys[] = {env->done_string (), env->value_string ()};
1762+ Local<Value> values[] = {Boolean::New (isolate, false ), row};
1763+ static_assert (arraysize (keys) == arraysize (values));
17361764 Local<Object> result = Object::New (
1737- isolate, Null (isolate), keys. data (), values. data (), keys. size ( ));
1765+ isolate, Null (isolate), & keys[ 0 ], & values[ 0 ], arraysize (keys ));
17381766 args.GetReturnValue ().Set (result);
17391767}
17401768
@@ -1804,15 +1832,30 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
18041832
18051833 auto is_finished_pd =
18061834 v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
1807- stmt_pd .set_enumerable (false );
1808- stmt_pd .set_configurable (false );
1835+ is_finished_pd .set_enumerable (false );
1836+ is_finished_pd .set_configurable (false );
18091837 if (iterable_iterator
18101838 ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
18111839 .IsNothing ()) {
18121840 // An error will have been scheduled.
18131841 return ;
18141842 }
18151843
1844+ // Add the return_arrays flag to the iterator
1845+ auto return_arrays_pd =
1846+ v8::PropertyDescriptor (v8::Boolean::New (
1847+ isolate, stmt->return_arrays_ ), false );
1848+ return_arrays_pd.set_enumerable (false );
1849+ return_arrays_pd.set_configurable (false );
1850+ if (iterable_iterator
1851+ ->DefineProperty (
1852+ context, FIXED_ONE_BYTE_STRING (
1853+ isolate, " return_arrays" ), return_arrays_pd)
1854+ .IsNothing ()) {
1855+ // An error will have been scheduled.
1856+ return ;
1857+ }
1858+
18161859 args.GetReturnValue ().Set (iterable_iterator);
18171860}
18181861
@@ -1843,24 +1886,35 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
18431886 return ;
18441887 }
18451888
1846- LocalVector<Name> keys (isolate);
1847- keys.reserve (num_cols);
1848- LocalVector<Value> values (isolate);
1849- values.reserve (num_cols);
1889+ if (stmt->return_arrays_ ) {
1890+ Local<Array> result = Array::New (isolate, num_cols);
1891+ for (int i = 0 ; i < num_cols; ++i) {
1892+ Local<Value> val;
1893+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1894+ if (result->Set (env->context (), i, val).IsNothing ()) return ;
1895+ }
1896+ args.GetReturnValue ().Set (result);
1897+ } else {
1898+ LocalVector<Name> keys (isolate);
1899+ keys.reserve (num_cols);
1900+ LocalVector<Value> values (isolate);
1901+ values.reserve (num_cols);
18501902
1851- for (int i = 0 ; i < num_cols; ++i) {
1852- Local<Name> key;
1853- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1854- Local<Value> val;
1855- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1856- keys.emplace_back (key);
1857- values.emplace_back (val);
1858- }
1903+ for (int i = 0 ; i < num_cols; ++i) {
1904+ Local<Name> key;
1905+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1906+ Local<Value> val;
1907+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1908+ keys.emplace_back (key);
1909+ values.emplace_back (val);
1910+ }
18591911
1860- Local<Object> result =
1861- Object::New (isolate, Null (isolate), keys.data (), values.data (), num_cols);
1912+ Local<Object> result =
1913+ Object::New (
1914+ isolate, Null (isolate), keys.data (), values.data (), num_cols);
18621915
1863- args.GetReturnValue ().Set (result);
1916+ args.GetReturnValue ().Set (result);
1917+ }
18641918}
18651919
18661920void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -2043,6 +2097,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
20432097 stmt->use_big_ints_ = args[0 ]->IsTrue ();
20442098}
20452099
2100+ void StatementSync::SetReturnArrays (const FunctionCallbackInfo<Value>& args) {
2101+ StatementSync* stmt;
2102+ ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
2103+ Environment* env = Environment::GetCurrent (args);
2104+ THROW_AND_RETURN_ON_BAD_STATE (
2105+ env, stmt->IsFinalized (), " statement has been finalized" );
2106+
2107+ if (!args[0 ]->IsBoolean ()) {
2108+ THROW_ERR_INVALID_ARG_TYPE (
2109+ env->isolate (), " The \" returnArrays\" argument must be a boolean." );
2110+ return ;
2111+ }
2112+
2113+ stmt->return_arrays_ = args[0 ]->IsTrue ();
2114+ }
2115+
20462116void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
20472117 THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
20482118}
@@ -2094,6 +2164,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
20942164 StatementSync::SetAllowBareNamedParameters);
20952165 SetProtoMethod (
20962166 isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
2167+ SetProtoMethod (
2168+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
20972169 env->set_sqlite_statement_sync_constructor_template (tmpl);
20982170 }
20992171 return tmpl;
0 commit comments