@@ -1378,6 +1378,7 @@ StatementSync::StatementSync(Environment* env,
13781378 statement_ = stmt;
13791379 // In the future, some of these options could be set at the database
13801380 // connection level and inherited by statements to reduce boilerplate.
1381+ return_arrays_ = false ;
13811382 use_big_ints_ = false ;
13821383 allow_bare_named_params_ = true ;
13831384 allow_unknown_named_params_ = false ;
@@ -1577,28 +1578,45 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
15771578 auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
15781579 int num_cols = sqlite3_column_count (stmt->statement_ );
15791580 LocalVector<Value> rows (isolate);
1580- LocalVector<Name> row_keys (isolate);
1581- while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1582- if (row_keys.size () == 0 ) {
1583- row_keys.reserve (num_cols);
1581+
1582+ if (stmt->return_arrays_ ) {
1583+ while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1584+ LocalVector<Value> array_values (isolate);
1585+ array_values.reserve (num_cols);
15841586 for (int i = 0 ; i < num_cols; ++i) {
1585- Local<Name> key ;
1586- if (!stmt->ColumnNameToName (i).ToLocal (&key )) return ;
1587- row_keys .emplace_back (key );
1587+ Local<Value> val ;
1588+ if (!stmt->ColumnToValue (i).ToLocal (&val )) return ;
1589+ array_values .emplace_back (val );
15881590 }
1591+ Local<Array> row_array =
1592+ Array::New (isolate, array_values.data (), array_values.size ());
1593+ rows.emplace_back (row_array);
15891594 }
1595+ } else {
1596+ LocalVector<Name> row_keys (isolate);
1597+
1598+ while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1599+ if (row_keys.size () == 0 ) {
1600+ row_keys.reserve (num_cols);
1601+ for (int i = 0 ; i < num_cols; ++i) {
1602+ Local<Name> key;
1603+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1604+ row_keys.emplace_back (key);
1605+ }
1606+ }
15901607
1591- LocalVector<Value> row_values (isolate);
1592- row_values.reserve (num_cols);
1593- for (int i = 0 ; i < num_cols; ++i) {
1594- Local<Value> val;
1595- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1596- row_values.emplace_back (val);
1597- }
1608+ LocalVector<Value> row_values (isolate);
1609+ row_values.reserve (num_cols);
1610+ for (int i = 0 ; i < num_cols; ++i) {
1611+ Local<Value> val;
1612+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1613+ row_values.emplace_back (val);
1614+ }
15981615
1599- Local<Object> row = Object::New (
1600- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1601- rows.emplace_back (row);
1616+ Local<Object> row_obj = Object::New (
1617+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1618+ rows.emplace_back (row_obj);
1619+ }
16021620 }
16031621
16041622 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1611,9 +1629,10 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
16111629 Environment* env = Environment::GetCurrent (args);
16121630 THROW_AND_RETURN_ON_BAD_STATE (
16131631 env, stmt->IsFinalized (), " statement has been finalized" );
1632+ auto isolate = env->isolate ();
16141633 auto context = env->context ();
16151634 int r = sqlite3_reset (stmt->statement_ );
1616- CHECK_ERROR_OR_THROW (env-> isolate () , stmt->db_ .get (), r, SQLITE_OK, void ());
1635+ CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_OK, void ());
16171636
16181637 if (!stmt->BindParams (args)) {
16191638 return ;
@@ -1633,13 +1652,15 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
16331652
16341653 BaseObjectPtr<StatementSyncIterator> iter =
16351654 StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>(stmt));
1655+
16361656 if (iter->object ()
16371657 ->GetPrototype ()
16381658 .As <Object>()
16391659 ->SetPrototype (context, js_iterator_prototype)
16401660 .IsNothing ()) {
16411661 return ;
16421662 }
1663+
16431664 args.GetReturnValue ().Set (iter->object ());
16441665}
16451666
@@ -1670,24 +1691,37 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
16701691 return ;
16711692 }
16721693
1673- LocalVector<Name> keys (isolate);
1674- keys.reserve (num_cols);
1675- LocalVector<Value> values (isolate);
1676- values.reserve (num_cols);
1694+ if (stmt->return_arrays_ ) {
1695+ LocalVector<Value> array_values (isolate);
1696+ array_values.reserve (num_cols);
1697+ for (int i = 0 ; i < num_cols; ++i) {
1698+ Local<Value> val;
1699+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1700+ array_values.emplace_back (val);
1701+ }
1702+ Local<Array> result =
1703+ Array::New (isolate, array_values.data (), array_values.size ());
1704+ args.GetReturnValue ().Set (result);
1705+ } else {
1706+ LocalVector<Name> keys (isolate);
1707+ keys.reserve (num_cols);
1708+ LocalVector<Value> values (isolate);
1709+ values.reserve (num_cols);
16771710
1678- for (int i = 0 ; i < num_cols; ++i) {
1679- Local<Name> key;
1680- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1681- Local<Value> val;
1682- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1683- keys.emplace_back (key);
1684- values.emplace_back (val);
1685- }
1711+ for (int i = 0 ; i < num_cols; ++i) {
1712+ Local<Name> key;
1713+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1714+ Local<Value> val;
1715+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1716+ keys.emplace_back (key);
1717+ values.emplace_back (val);
1718+ }
16861719
1687- Local<Object> result =
1688- Object::New ( isolate, Null (isolate), keys.data (), values.data (), num_cols);
1720+ Local<Object> result = Object::New (
1721+ isolate, Null (isolate), keys.data (), values.data (), num_cols);
16891722
1690- args.GetReturnValue ().Set (result);
1723+ args.GetReturnValue ().Set (result);
1724+ }
16911725}
16921726
16931727void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -1887,6 +1921,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
18871921 stmt->use_big_ints_ = args[0 ]->IsTrue ();
18881922}
18891923
1924+ void StatementSync::SetReturnArrays (const FunctionCallbackInfo<Value>& args) {
1925+ StatementSync* stmt;
1926+ ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
1927+ Environment* env = Environment::GetCurrent (args);
1928+ THROW_AND_RETURN_ON_BAD_STATE (
1929+ env, stmt->IsFinalized (), " statement has been finalized" );
1930+
1931+ if (!args[0 ]->IsBoolean ()) {
1932+ THROW_ERR_INVALID_ARG_TYPE (
1933+ env->isolate (), " The \" returnArrays\" argument must be a boolean." );
1934+ return ;
1935+ }
1936+
1937+ stmt->return_arrays_ = args[0 ]->IsTrue ();
1938+ }
1939+
18901940void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
18911941 THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
18921942}
@@ -1942,6 +1992,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
19421992 StatementSync::SetAllowUnknownNamedParameters);
19431993 SetProtoMethod (
19441994 isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
1995+ SetProtoMethod (
1996+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
19451997 env->set_sqlite_statement_sync_constructor_template (tmpl);
19461998 }
19471999 return tmpl;
@@ -2033,22 +2085,36 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
20332085 }
20342086
20352087 int num_cols = sqlite3_column_count (iter->stmt_ ->statement_ );
2036- LocalVector<Name> row_keys (isolate);
2037- LocalVector<Value> row_values (isolate);
2038- row_keys.reserve (num_cols);
2039- row_values.reserve (num_cols);
2040- for (int i = 0 ; i < num_cols; ++i) {
2041- Local<Name> key;
2042- if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2043- Local<Value> val;
2044- if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2045- row_keys.emplace_back (key);
2046- row_values.emplace_back (val);
2088+ Local<Value> row_value;
2089+
2090+ if (iter->stmt_ ->return_arrays_ ) {
2091+ LocalVector<Value> array_values (isolate);
2092+ array_values.reserve (num_cols);
2093+ for (int i = 0 ; i < num_cols; ++i) {
2094+ Local<Value> val;
2095+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2096+ array_values.emplace_back (val);
2097+ }
2098+ row_value = Array::New (isolate, array_values.data (), array_values.size ());
2099+ } else {
2100+ LocalVector<Name> row_keys (isolate);
2101+ LocalVector<Value> row_values (isolate);
2102+ row_keys.reserve (num_cols);
2103+ row_values.reserve (num_cols);
2104+ for (int i = 0 ; i < num_cols; ++i) {
2105+ Local<Name> key;
2106+ if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2107+ Local<Value> val;
2108+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2109+ row_keys.emplace_back (key);
2110+ row_values.emplace_back (val);
2111+ }
2112+
2113+ row_value = Object::New (
2114+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
20472115 }
20482116
2049- Local<Object> row = Object::New (
2050- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
2051- LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
2117+ LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row_value});
20522118 Local<Object> result = Object::New (
20532119 isolate, Null (isolate), keys.data (), values.data (), keys.size ());
20542120 args.GetReturnValue ().Set (result);
0 commit comments