@@ -25,7 +25,6 @@ using v8::ConstructorBehavior;
25
25
using v8::Context;
26
26
using v8::DontDelete;
27
27
using v8::Exception;
28
- using v8::External;
29
28
using v8::Function;
30
29
using v8::FunctionCallback;
31
30
using v8::FunctionCallbackInfo;
@@ -1630,142 +1629,12 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
1630
1629
args.GetReturnValue ().Set (Array::New (isolate, rows.data (), rows.size ()));
1631
1630
}
1632
1631
1633
- void StatementSync::IterateReturnCallback (
1634
- const FunctionCallbackInfo<Value>& args) {
1635
- Environment* env = Environment::GetCurrent (args);
1636
- auto isolate = env->isolate ();
1637
- auto context = isolate->GetCurrentContext ();
1638
-
1639
- auto self = args.This ();
1640
- // iterator has fetch all result or break, prevent next func to return result
1641
- if (self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1642
- .IsNothing ()) {
1643
- // An error will have been scheduled.
1644
- return ;
1645
- }
1646
-
1647
- Local<Value> val;
1648
- if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1649
- // An error will have been scheduled.
1650
- return ;
1651
- }
1652
- auto external_stmt = Local<External>::Cast (val);
1653
- auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1654
- if (!stmt->IsFinalized ()) {
1655
- sqlite3_reset (stmt->statement_ );
1656
- }
1657
-
1658
- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1659
- LocalVector<Value> values (isolate,
1660
- {Boolean::New (isolate, true ), Null (isolate)});
1661
-
1662
- DCHECK_EQ (keys.size (), values.size ());
1663
- Local<Object> result = Object::New (
1664
- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1665
- args.GetReturnValue ().Set (result);
1666
- }
1667
-
1668
- void StatementSync::IterateNextCallback (
1669
- const FunctionCallbackInfo<Value>& args) {
1670
- Environment* env = Environment::GetCurrent (args);
1671
- auto isolate = env->isolate ();
1672
- auto context = isolate->GetCurrentContext ();
1673
-
1674
- auto self = args.This ();
1675
-
1676
- Local<Value> val;
1677
- if (!self->Get (context, env->isfinished_string ()).ToLocal (&val)) {
1678
- // An error will have been scheduled.
1679
- return ;
1680
- }
1681
-
1682
- // skip iteration if is_finished
1683
- auto is_finished = Local<Boolean >::Cast (val);
1684
- if (is_finished->Value ()) {
1685
- Local<Name> keys[] = {env->done_string (), env->value_string ()};
1686
- Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1687
- static_assert (arraysize (keys) == arraysize (values));
1688
- Local<Object> result = Object::New (
1689
- isolate, Null (isolate), &keys[0 ], &values[0 ], arraysize (keys));
1690
- args.GetReturnValue ().Set (result);
1691
- return ;
1692
- }
1693
-
1694
- if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1695
- // An error will have been scheduled.
1696
- return ;
1697
- }
1698
-
1699
- auto external_stmt = Local<External>::Cast (val);
1700
- auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1701
-
1702
- if (!self->Get (context, env->num_cols_string ()).ToLocal (&val)) {
1703
- // An error will have been scheduled.
1704
- return ;
1705
- }
1706
-
1707
- auto num_cols = Local<Integer>::Cast (val)->Value ();
1708
-
1709
- THROW_AND_RETURN_ON_BAD_STATE (
1710
- env, stmt->IsFinalized (), " statement has been finalized" );
1711
-
1712
- int r = sqlite3_step (stmt->statement_ );
1713
- if (r != SQLITE_ROW) {
1714
- CHECK_ERROR_OR_THROW (
1715
- env->isolate (), stmt->db_ .get (), r, SQLITE_DONE, void ());
1716
-
1717
- // cleanup when no more rows to fetch
1718
- sqlite3_reset (stmt->statement_ );
1719
- if (self->Set (
1720
- context, env->isfinished_string (), Boolean::New (isolate, true ))
1721
- .IsNothing ()) {
1722
- // An error would have been scheduled
1723
- return ;
1724
- }
1725
-
1726
- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1727
- LocalVector<Value> values (isolate,
1728
- {Boolean::New (isolate, true ), Null (isolate)});
1729
-
1730
- DCHECK_EQ (keys.size (), values.size ());
1731
- Local<Object> result = Object::New (
1732
- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1733
- args.GetReturnValue ().Set (result);
1734
- return ;
1735
- }
1736
-
1737
- LocalVector<Name> row_keys (isolate);
1738
- row_keys.reserve (num_cols);
1739
- LocalVector<Value> row_values (isolate);
1740
- row_values.reserve (num_cols);
1741
- for (int i = 0 ; i < num_cols; ++i) {
1742
- Local<Name> key;
1743
- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1744
- Local<Value> val;
1745
- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1746
- row_keys.emplace_back (key);
1747
- row_values.emplace_back (val);
1748
- }
1749
-
1750
- Local<Object> row = Object::New (
1751
- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1752
-
1753
- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1754
- LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
1755
-
1756
- DCHECK_EQ (keys.size (), values.size ());
1757
- Local<Object> result = Object::New (
1758
- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1759
- args.GetReturnValue ().Set (result);
1760
- }
1761
-
1762
1632
void StatementSync::Iterate (const FunctionCallbackInfo<Value>& args) {
1763
1633
StatementSync* stmt;
1764
1634
ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
1765
1635
Environment* env = Environment::GetCurrent (args);
1766
1636
THROW_AND_RETURN_ON_BAD_STATE (
1767
1637
env, stmt->IsFinalized (), " statement has been finalized" );
1768
- auto isolate = env->isolate ();
1769
1638
auto context = env->context ();
1770
1639
int r = sqlite3_reset (stmt->statement_ );
1771
1640
CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
@@ -1774,67 +1643,28 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
1774
1643
return ;
1775
1644
}
1776
1645
1777
- Local<Function> next_func;
1778
- Local<Function> return_func;
1779
- if (!Function::New (context, StatementSync::IterateNextCallback)
1780
- .ToLocal (&next_func) ||
1781
- !Function::New (context, StatementSync::IterateReturnCallback)
1782
- .ToLocal (&return_func)) {
1783
- // An error will have been scheduled.
1784
- return ;
1785
- }
1786
-
1787
- Local<Name> keys[] = {env->next_string (), env->return_string ()};
1788
- Local<Value> values[] = {next_func, return_func};
1789
- static_assert (arraysize (keys) == arraysize (values));
1790
-
1791
1646
Local<Object> global = context->Global ();
1792
1647
Local<Value> js_iterator;
1793
1648
Local<Value> js_iterator_prototype;
1794
- if (!global->Get (context, env->iterator_string ()).ToLocal (&js_iterator))
1649
+ if (!global->Get (context, env->iterator_string ()).ToLocal (&js_iterator)) {
1795
1650
return ;
1651
+ }
1796
1652
if (!js_iterator.As <Object>()
1797
1653
->Get (context, env->prototype_string ())
1798
- .ToLocal (&js_iterator_prototype))
1799
- return ;
1800
-
1801
- Local<Object> iterable_iterator = Object::New (
1802
- isolate, js_iterator_prototype, &keys[0 ], &values[0 ], arraysize (keys));
1803
-
1804
- auto num_cols_pd = v8::PropertyDescriptor (
1805
- v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
1806
- num_cols_pd.set_enumerable (false );
1807
- num_cols_pd.set_configurable (false );
1808
- if (iterable_iterator
1809
- ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1810
- .IsNothing ()) {
1811
- // An error will have been scheduled.
1654
+ .ToLocal (&js_iterator_prototype)) {
1812
1655
return ;
1813
1656
}
1814
1657
1815
- auto stmt_pd =
1816
- v8::PropertyDescriptor ( v8::External::New (isolate, stmt), false );
1817
- stmt_pd. set_enumerable ( false );
1818
- stmt_pd. set_configurable ( false );
1819
- if (iterable_iterator
1820
- ->DefineProperty (context, env-> statement_string (), stmt_pd )
1658
+ BaseObjectPtr<StatementSyncIterator> iter =
1659
+ StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>( stmt));
1660
+ if (iter-> object ()
1661
+ -> GetPrototype ()
1662
+ . As <Object>()
1663
+ ->SetPrototype (context, js_iterator_prototype )
1821
1664
.IsNothing ()) {
1822
- // An error will have been scheduled.
1823
1665
return ;
1824
1666
}
1825
-
1826
- auto is_finished_pd =
1827
- v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
1828
- stmt_pd.set_enumerable (false );
1829
- stmt_pd.set_configurable (false );
1830
- if (iterable_iterator
1831
- ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1832
- .IsNothing ()) {
1833
- // An error will have been scheduled.
1834
- return ;
1835
- }
1836
-
1837
- args.GetReturnValue ().Set (iterable_iterator);
1667
+ args.GetReturnValue ().Set (iter->object ());
1838
1668
}
1839
1669
1840
1670
void StatementSync::Get (const FunctionCallbackInfo<Value>& args) {
@@ -2154,6 +1984,118 @@ BaseObjectPtr<StatementSync> StatementSync::Create(
2154
1984
return MakeBaseObject<StatementSync>(env, obj, std::move (db), stmt);
2155
1985
}
2156
1986
1987
+ StatementSyncIterator::StatementSyncIterator (Environment* env,
1988
+ Local<Object> object,
1989
+ BaseObjectPtr<StatementSync> stmt)
1990
+ : BaseObject(env, object), stmt_(std::move(stmt)) {
1991
+ MakeWeak ();
1992
+ done_ = false ;
1993
+ }
1994
+
1995
+ StatementSyncIterator::~StatementSyncIterator () {}
1996
+ void StatementSyncIterator::MemoryInfo (MemoryTracker* tracker) const {}
1997
+
1998
+ Local<FunctionTemplate> StatementSyncIterator::GetConstructorTemplate (
1999
+ Environment* env) {
2000
+ Local<FunctionTemplate> tmpl =
2001
+ env->sqlite_statement_sync_iterator_constructor_template ();
2002
+ if (tmpl.IsEmpty ()) {
2003
+ Isolate* isolate = env->isolate ();
2004
+ tmpl = NewFunctionTemplate (isolate, IllegalConstructor);
2005
+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " StatementSyncIterator" ));
2006
+ tmpl->InstanceTemplate ()->SetInternalFieldCount (
2007
+ StatementSync::kInternalFieldCount );
2008
+ SetProtoMethod (isolate, tmpl, " next" , StatementSyncIterator::Next);
2009
+ SetProtoMethod (isolate, tmpl, " return" , StatementSyncIterator::Return);
2010
+ env->set_sqlite_statement_sync_iterator_constructor_template (tmpl);
2011
+ }
2012
+ return tmpl;
2013
+ }
2014
+
2015
+ BaseObjectPtr<StatementSyncIterator> StatementSyncIterator::Create (
2016
+ Environment* env, BaseObjectPtr<StatementSync> stmt) {
2017
+ Local<Object> obj;
2018
+ if (!GetConstructorTemplate (env)
2019
+ ->InstanceTemplate ()
2020
+ ->NewInstance (env->context ())
2021
+ .ToLocal (&obj)) {
2022
+ return BaseObjectPtr<StatementSyncIterator>();
2023
+ }
2024
+
2025
+ return MakeBaseObject<StatementSyncIterator>(env, obj, std::move (stmt));
2026
+ }
2027
+
2028
+ void StatementSyncIterator::Next (const FunctionCallbackInfo<Value>& args) {
2029
+ StatementSyncIterator* iter;
2030
+ ASSIGN_OR_RETURN_UNWRAP (&iter, args.This ());
2031
+ Environment* env = Environment::GetCurrent (args);
2032
+ THROW_AND_RETURN_ON_BAD_STATE (
2033
+ env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
2034
+ Isolate* isolate = env->isolate ();
2035
+ LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2036
+
2037
+ if (iter->done_ ) {
2038
+ LocalVector<Value> values (isolate,
2039
+ {Boolean::New (isolate, true ), Null (isolate)});
2040
+ Local<Object> result = Object::New (
2041
+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2042
+ args.GetReturnValue ().Set (result);
2043
+ return ;
2044
+ }
2045
+
2046
+ int r = sqlite3_step (iter->stmt_ ->statement_ );
2047
+ if (r != SQLITE_ROW) {
2048
+ CHECK_ERROR_OR_THROW (
2049
+ env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE, void ());
2050
+ sqlite3_reset (iter->stmt_ ->statement_ );
2051
+ LocalVector<Value> values (isolate,
2052
+ {Boolean::New (isolate, true ), Null (isolate)});
2053
+ Local<Object> result = Object::New (
2054
+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2055
+ args.GetReturnValue ().Set (result);
2056
+ return ;
2057
+ }
2058
+
2059
+ int num_cols = sqlite3_column_count (iter->stmt_ ->statement_ );
2060
+ LocalVector<Name> row_keys (isolate);
2061
+ LocalVector<Value> row_values (isolate);
2062
+ row_keys.reserve (num_cols);
2063
+ row_values.reserve (num_cols);
2064
+ for (int i = 0 ; i < num_cols; ++i) {
2065
+ Local<Name> key;
2066
+ if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2067
+ Local<Value> val;
2068
+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2069
+ row_keys.emplace_back (key);
2070
+ row_values.emplace_back (val);
2071
+ }
2072
+
2073
+ Local<Object> row = Object::New (
2074
+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
2075
+ LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
2076
+ Local<Object> result = Object::New (
2077
+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2078
+ args.GetReturnValue ().Set (result);
2079
+ }
2080
+
2081
+ void StatementSyncIterator::Return (const FunctionCallbackInfo<Value>& args) {
2082
+ StatementSyncIterator* iter;
2083
+ ASSIGN_OR_RETURN_UNWRAP (&iter, args.This ());
2084
+ Environment* env = Environment::GetCurrent (args);
2085
+ THROW_AND_RETURN_ON_BAD_STATE (
2086
+ env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
2087
+ Isolate* isolate = env->isolate ();
2088
+
2089
+ sqlite3_reset (iter->stmt_ ->statement_ );
2090
+ iter->done_ = true ;
2091
+ LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2092
+ LocalVector<Value> values (isolate,
2093
+ {Boolean::New (isolate, true ), Null (isolate)});
2094
+ Local<Object> result = Object::New (
2095
+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2096
+ args.GetReturnValue ().Set (result);
2097
+ }
2098
+
2157
2099
Session::Session (Environment* env,
2158
2100
Local<Object> object,
2159
2101
BaseObjectWeakPtr<DatabaseSync> database,
0 commit comments