@@ -1582,27 +1582,38 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
1582
1582
int num_cols = sqlite3_column_count (stmt->statement_ );
1583
1583
LocalVector<Value> rows (isolate);
1584
1584
LocalVector<Name> row_keys (isolate);
1585
+
1585
1586
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);
1588
1589
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
+ }
1592
1603
}
1593
- }
1594
1604
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
+ }
1602
1612
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
+ }
1606
1617
}
1607
1618
1608
1619
CHECK_ERROR_OR_THROW (isolate, stmt->db_ .get (), r, SQLITE_DONE, void ());
@@ -1645,7 +1656,7 @@ void StatementSync::IterateReturnCallback(
1645
1656
}
1646
1657
1647
1658
void StatementSync::IterateNextCallback (
1648
- const FunctionCallbackInfo<Value>& args) {
1659
+ const v8:: FunctionCallbackInfo<v8:: Value>& args) {
1649
1660
Environment* env = Environment::GetCurrent (args);
1650
1661
auto isolate = env->isolate ();
1651
1662
auto context = isolate->GetCurrentContext ();
@@ -1688,6 +1699,15 @@ void StatementSync::IterateNextCallback(
1688
1699
THROW_AND_RETURN_ON_BAD_STATE (
1689
1700
env, stmt->IsFinalized (), " statement has been finalized" );
1690
1701
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
+
1691
1711
int r = sqlite3_step (stmt->statement_ );
1692
1712
if (r != SQLITE_ROW) {
1693
1713
CHECK_ERROR_OR_THROW (
@@ -1702,39 +1722,47 @@ void StatementSync::IterateNextCallback(
1702
1722
return ;
1703
1723
}
1704
1724
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));
1710
1728
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 ));
1712
1730
args.GetReturnValue ().Set (result);
1713
1731
return ;
1714
1732
}
1715
1733
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
+ }
1731
1756
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
+ }
1734
1760
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));
1736
1764
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 ));
1738
1766
args.GetReturnValue ().Set (result);
1739
1767
}
1740
1768
@@ -1804,15 +1832,30 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1804
1832
1805
1833
auto is_finished_pd =
1806
1834
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 );
1809
1837
if (iterable_iterator
1810
1838
->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1811
1839
.IsNothing ()) {
1812
1840
// An error will have been scheduled.
1813
1841
return ;
1814
1842
}
1815
1843
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
+
1816
1859
args.GetReturnValue ().Set (iterable_iterator);
1817
1860
}
1818
1861
@@ -1843,24 +1886,35 @@ void StatementSync::Get(const FunctionCallbackInfo<Value>& args) {
1843
1886
return ;
1844
1887
}
1845
1888
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);
1850
1902
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
+ }
1859
1911
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);
1862
1915
1863
- args.GetReturnValue ().Set (result);
1916
+ args.GetReturnValue ().Set (result);
1917
+ }
1864
1918
}
1865
1919
1866
1920
void StatementSync::Run (const FunctionCallbackInfo<Value>& args) {
@@ -2043,6 +2097,22 @@ void StatementSync::SetReadBigInts(const FunctionCallbackInfo<Value>& args) {
2043
2097
stmt->use_big_ints_ = args[0 ]->IsTrue ();
2044
2098
}
2045
2099
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
+
2046
2116
void IllegalConstructor (const FunctionCallbackInfo<Value>& args) {
2047
2117
THROW_ERR_ILLEGAL_CONSTRUCTOR (Environment::GetCurrent (args));
2048
2118
}
@@ -2094,6 +2164,8 @@ Local<FunctionTemplate> StatementSync::GetConstructorTemplate(
2094
2164
StatementSync::SetAllowBareNamedParameters);
2095
2165
SetProtoMethod (
2096
2166
isolate, tmpl, " setReadBigInts" , StatementSync::SetReadBigInts);
2167
+ SetProtoMethod (
2168
+ isolate, tmpl, " setReturnArrays" , StatementSync::SetReturnArrays);
2097
2169
env->set_sqlite_statement_sync_constructor_template (tmpl);
2098
2170
}
2099
2171
return tmpl;
0 commit comments