@@ -1368,6 +1368,7 @@ StatementSync::StatementSync(Environment* env,
13681368 statement_ = stmt;
13691369 // In the future, some of these options could be set at the database
13701370 // connection level and inherited by statements to reduce boilerplate.
1371+ return_arrays_ = false ;
13711372 use_big_ints_ = false ;
13721373 allow_bare_named_params_ = true ;
13731374 allow_unknown_named_params_ = false ;
@@ -1567,28 +1568,45 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
15671568 auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
15681569 int num_cols = sqlite3_column_count (stmt->statement_ );
15691570 LocalVector<Value> rows (isolate);
1570- LocalVector<Name> row_keys (isolate);
1571- while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1572- if (row_keys.size () == 0 ) {
1573- row_keys.reserve (num_cols);
1571+
1572+ if (stmt->return_arrays_ ) {
1573+ while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1574+ LocalVector<Value> array_values (isolate);
1575+ array_values.reserve (num_cols);
15741576 for (int i = 0 ; i < num_cols; ++i) {
1575- Local<Name> key ;
1576- if (!stmt->ColumnNameToName (i).ToLocal (&key )) return ;
1577- row_keys .emplace_back (key );
1577+ Local<Value> val ;
1578+ if (!stmt->ColumnToValue (i).ToLocal (&val )) return ;
1579+ array_values .emplace_back (val );
15781580 }
1581+ Local<Array> row_array =
1582+ Array::New (isolate, array_values.data (), array_values.size ());
1583+ rows.emplace_back (row_array);
15791584 }
1585+ } else {
1586+ LocalVector<Name> row_keys (isolate);
1587+
1588+ while ((r = sqlite3_step (stmt->statement_ )) == SQLITE_ROW) {
1589+ if (row_keys.size () == 0 ) {
1590+ row_keys.reserve (num_cols);
1591+ for (int i = 0 ; i < num_cols; ++i) {
1592+ Local<Name> key;
1593+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1594+ row_keys.emplace_back (key);
1595+ }
1596+ }
15801597
1581- LocalVector<Value> row_values (isolate);
1582- row_values.reserve (num_cols);
1583- for (int i = 0 ; i < num_cols; ++i) {
1584- Local<Value> val;
1585- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1586- row_values.emplace_back (val);
1587- }
1598+ LocalVector<Value> row_values (isolate);
1599+ row_values.reserve (num_cols);
1600+ for (int i = 0 ; i < num_cols; ++i) {
1601+ Local<Value> val;
1602+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1603+ row_values.emplace_back (val);
1604+ }
15881605
1589- Local<Object> row = Object::New (
1590- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1591- rows.emplace_back (row);
1606+ Local<Object> row_obj = Object::New (
1607+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1608+ rows.emplace_back (row_obj);
1609+ }
15921610 }
15931611
15941612 CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1601,9 +1619,10 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
16011619 Environment* env = Environment::GetCurrent (args);
16021620 THROW_AND_RETURN_ON_BAD_STATE (
16031621 env, stmt->IsFinalized (), " statement has been finalized" );
1622+ auto isolate = env->isolate ();
16041623 auto context = env->context ();
16051624 int r = sqlite3_reset (stmt->statement_ );
1606- CHECK_ERROR_OR_THROW (env-> isolate () , stmt->db_ .get (), r, SQLITE_OK, void ());
1625+ CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_OK, void ());
16071626
16081627 if (!stmt->BindParams (args)) {
16091628 return ;
@@ -1623,13 +1642,15 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
16231642
16241643 BaseObjectPtr<StatementSyncIterator> iter =
16251644 StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>(stmt));
1645+
16261646 if (iter->object ()
16271647 ->GetPrototype ()
16281648 .As <Object>()
16291649 ->SetPrototype (context, js_iterator_prototype)
16301650 .IsNothing ()) {
16311651 return ;
16321652 }
1653+
16331654 args.GetReturnValue ().Set (iter->object ());
16341655}
16351656
@@ -1660,24 +1681,37 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
16601681 return ;
16611682 }
16621683
1663- LocalVector<Name> keys (isolate);
1664- keys.reserve (num_cols);
1665- LocalVector<Value> values (isolate);
1666- values.reserve (num_cols);
1684+ if (stmt->return_arrays_ ) {
1685+ LocalVector<Value> array_values (isolate);
1686+ array_values.reserve (num_cols);
1687+ for (int i = 0 ; i < num_cols; ++i) {
1688+ Local<Value> val;
1689+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1690+ array_values.emplace_back (val);
1691+ }
1692+ Local<Array> result =
1693+ Array::New (isolate, array_values.data (), array_values.size ());
1694+ args.GetReturnValue ().Set (result);
1695+ } else {
1696+ LocalVector<Name> keys (isolate);
1697+ keys.reserve (num_cols);
1698+ LocalVector<Value> values (isolate);
1699+ values.reserve (num_cols);
16671700
1668- for (int i = 0 ; i < num_cols; ++i) {
1669- Local<Name> key;
1670- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1671- Local<Value> val;
1672- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1673- keys.emplace_back (key);
1674- values.emplace_back (val);
1675- }
1701+ for (int i = 0 ; i < num_cols; ++i) {
1702+ Local<Name> key;
1703+ if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1704+ Local<Value> val;
1705+ if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1706+ keys.emplace_back (key);
1707+ values.emplace_back (val);
1708+ }
16761709
1677- Local<Object> result =
1678- Object::New ( isolate, Null (isolate), keys.data (), values.data (), num_cols);
1710+ Local<Object> result = Object::New (
1711+ isolate, Null (isolate), keys.data (), values.data (), num_cols);
16791712
1680- args.GetReturnValue ().Set (result);
1713+ args.GetReturnValue ().Set (result);
1714+ }
16811715}
16821716
16831717void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -1877,6 +1911,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
18771911 stmt->use_big_ints_ = args[0 ]->IsTrue ();
18781912}
18791913
1914+ void StatementSync::SetReturnArrays (const FunctionCallbackInfo<Value>& args) {
1915+ StatementSync* stmt;
1916+ ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
1917+ Environment* env = Environment::GetCurrent (args);
1918+ THROW_AND_RETURN_ON_BAD_STATE (
1919+ env, stmt->IsFinalized (), " statement has been finalized" );
1920+
1921+ if (!args[0 ]->IsBoolean ()) {
1922+ THROW_ERR_INVALID_ARG_TYPE (
1923+ env->isolate (), " The \" returnArrays\" argument must be a boolean." );
1924+ return ;
1925+ }
1926+
1927+ stmt->return_arrays_ = args[0 ]->IsTrue ();
1928+ }
1929+
18801930void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
18811931 THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
18821932}
@@ -1932,6 +1982,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
19321982 StatementSync::SetAllowUnknownNamedParameters);
19331983 SetProtoMethod (
19341984 isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
1985+ SetProtoMethod (
1986+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
19351987 env->set_sqlite_statement_sync_constructor_template (tmpl);
19361988 }
19371989 return tmpl;
@@ -2023,22 +2075,36 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
20232075 }
20242076
20252077 int num_cols = sqlite3_column_count (iter->stmt_ ->statement_ );
2026- LocalVector<Name> row_keys (isolate);
2027- LocalVector<Value> row_values (isolate);
2028- row_keys.reserve (num_cols);
2029- row_values.reserve (num_cols);
2030- for (int i = 0 ; i < num_cols; ++i) {
2031- Local<Name> key;
2032- if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2033- Local<Value> val;
2034- if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2035- row_keys.emplace_back (key);
2036- row_values.emplace_back (val);
2078+ Local<Value> row_value;
2079+
2080+ if (iter->stmt_ ->return_arrays_ ) {
2081+ LocalVector<Value> array_values (isolate);
2082+ array_values.reserve (num_cols);
2083+ for (int i = 0 ; i < num_cols; ++i) {
2084+ Local<Value> val;
2085+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2086+ array_values.emplace_back (val);
2087+ }
2088+ row_value = Array::New (isolate, array_values.data (), array_values.size ());
2089+ } else {
2090+ LocalVector<Name> row_keys (isolate);
2091+ LocalVector<Value> row_values (isolate);
2092+ row_keys.reserve (num_cols);
2093+ row_values.reserve (num_cols);
2094+ for (int i = 0 ; i < num_cols; ++i) {
2095+ Local<Name> key;
2096+ if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2097+ Local<Value> val;
2098+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2099+ row_keys.emplace_back (key);
2100+ row_values.emplace_back (val);
2101+ }
2102+
2103+ row_value = Object::New (
2104+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
20372105 }
20382106
2039- Local<Object> row = Object::New (
2040- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
2041- LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
2107+ LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row_value});
20422108 Local<Object> result = Object::New (
20432109 isolate, Null (isolate), keys.data (), values.data (), keys.size ());
20442110 args.GetReturnValue ().Set (result);
0 commit comments