@@ -1378,6 +1378,7 @@ StatementSync::StatementSync(Environment* env,
1378
1378
statement_ = stmt;
1379
1379
// In the future, some of these options could be set at the database
1380
1380
// connection level and inherited by statements to reduce boilerplate.
1381
+ return_arrays_ = false ;
1381
1382
use_big_ints_ = false ;
1382
1383
allow_bare_named_params_ = true ;
1383
1384
allow_unknown_named_params_ = false ;
@@ -1577,28 +1578,45 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
1577
1578
auto reset = OnScopeLeave ([&]() { sqlite3_reset (stmt->statement_ ); });
1578
1579
int num_cols = sqlite3_column_count (stmt->statement_ );
1579
1580
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);
1584
1586
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 );
1588
1590
}
1591
+ Local<Array> row_array =
1592
+ Array::New (isolate, array_values.data (), array_values.size ());
1593
+ rows.emplace_back (row_array);
1589
1594
}
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
+ }
1590
1607
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
+ }
1598
1615
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
+ }
1602
1620
}
1603
1621
1604
1622
CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1611,9 +1629,10 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1611
1629
Environment* env = Environment::GetCurrent (args);
1612
1630
THROW_AND_RETURN_ON_BAD_STATE (
1613
1631
env, stmt->IsFinalized (), " statement has been finalized" );
1632
+ auto isolate = env->isolate ();
1614
1633
auto context = env->context ();
1615
1634
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 ());
1617
1636
1618
1637
if (!stmt->BindParams (args)) {
1619
1638
return ;
@@ -1633,13 +1652,15 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1633
1652
1634
1653
BaseObjectPtr<StatementSyncIterator> iter =
1635
1654
StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>(stmt));
1655
+
1636
1656
if (iter->object ()
1637
1657
->GetPrototype ()
1638
1658
.As <Object>()
1639
1659
->SetPrototype (context, js_iterator_prototype)
1640
1660
.IsNothing ()) {
1641
1661
return ;
1642
1662
}
1663
+
1643
1664
args.GetReturnValue ().Set (iter->object ());
1644
1665
}
1645
1666
@@ -1670,24 +1691,37 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
1670
1691
return ;
1671
1692
}
1672
1693
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);
1677
1710
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
+ }
1686
1719
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);
1689
1722
1690
- args.GetReturnValue ().Set (result);
1723
+ args.GetReturnValue ().Set (result);
1724
+ }
1691
1725
}
1692
1726
1693
1727
void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -1887,6 +1921,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
1887
1921
stmt->use_big_ints_ = args[0 ]->IsTrue ();
1888
1922
}
1889
1923
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
+
1890
1940
void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
1891
1941
THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
1892
1942
}
@@ -1942,6 +1992,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
1942
1992
StatementSync::SetAllowUnknownNamedParameters);
1943
1993
SetProtoMethod (
1944
1994
isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
1995
+ SetProtoMethod (
1996
+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
1945
1997
env->set_sqlite_statement_sync_constructor_template (tmpl);
1946
1998
}
1947
1999
return tmpl;
@@ -2033,22 +2085,36 @@ void StatementSyncIterator::Next(const FunctionCallbackInfo<Value>& args) {
2033
2085
}
2034
2086
2035
2087
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);
2047
2115
}
2048
2116
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});
2052
2118
Local<Object> result = Object::New (
2053
2119
isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2054
2120
args.GetReturnValue ().Set (result);
0 commit comments