@@ -1368,6 +1368,7 @@ StatementSync::StatementSync(Environment* env,
1368
1368
statement_ = stmt;
1369
1369
// In the future, some of these options could be set at the database
1370
1370
// connection level and inherited by statements to reduce boilerplate.
1371
+ return_arrays_ = false ;
1371
1372
use_big_ints_ = false ;
1372
1373
allow_bare_named_params_ = true ;
1373
1374
allow_unknown_named_params_ = false ;
@@ -1567,28 +1568,45 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
1567
1568
auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
1568
1569
int num_cols = sqlite3_column_count (stmt->statement_ );
1569
1570
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);
1574
1576
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 );
1578
1580
}
1581
+ Local<Array> row_array =
1582
+ Array::New (isolate, array_values.data (), array_values.size ());
1583
+ rows.emplace_back (row_array);
1579
1584
}
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
+ }
1580
1597
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
+ }
1588
1605
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
+ }
1592
1610
}
1593
1611
1594
1612
CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1601,9 +1619,10 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1601
1619
Environment* env = Environment::GetCurrent (args);
1602
1620
THROW_AND_RETURN_ON_BAD_STATE (
1603
1621
env, stmt->IsFinalized (), " statement has been finalized" );
1622
+ auto isolate = env->isolate ();
1604
1623
auto context = env->context ();
1605
1624
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 ());
1607
1626
1608
1627
if (!stmt->BindParams (args)) {
1609
1628
return ;
@@ -1623,13 +1642,15 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1623
1642
1624
1643
BaseObjectPtr<StatementSyncIterator> iter =
1625
1644
StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>(stmt));
1645
+
1626
1646
if (iter->object ()
1627
1647
->GetPrototype ()
1628
1648
.As <Object>()
1629
1649
->SetPrototype (context, js_iterator_prototype)
1630
1650
.IsNothing ()) {
1631
1651
return ;
1632
1652
}
1653
+
1633
1654
args.GetReturnValue ().Set (iter->object ());
1634
1655
}
1635
1656
@@ -1660,24 +1681,37 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
1660
1681
return ;
1661
1682
}
1662
1683
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);
1667
1700
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
+ }
1676
1709
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);
1679
1712
1680
- args.GetReturnValue ().Set (result);
1713
+ args.GetReturnValue ().Set (result);
1714
+ }
1681
1715
}
1682
1716
1683
1717
void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -1877,6 +1911,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
1877
1911
stmt->use_big_ints_ = args[0 ]->IsTrue ();
1878
1912
}
1879
1913
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
+
1880
1930
void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
1881
1931
THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
1882
1932
}
@@ -1932,6 +1982,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
1932
1982
StatementSync::SetAllowUnknownNamedParameters);
1933
1983
SetProtoMethod (
1934
1984
isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
1985
+ SetProtoMethod (
1986
+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
1935
1987
env->set_sqlite_statement_sync_constructor_template (tmpl);
1936
1988
}
1937
1989
return tmpl;
@@ -2023,22 +2075,36 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
2023
2075
}
2024
2076
2025
2077
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);
2037
2105
}
2038
2106
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});
2042
2108
Local<Object> result = Object::New (
2043
2109
isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2044
2110
args.GetReturnValue ().Set (result);
0 commit comments