@@ -25,7 +25,6 @@ using v8::ConstructorBehavior;
2525using v8::Context;
2626using v8::DontDelete;
2727using v8::Exception;
28- using v8::External;
2928using v8::Function;
3029using v8::FunctionCallback;
3130using v8::FunctionCallbackInfo;
@@ -1615,142 +1614,12 @@ void StatementSync::All(const FunctionCallbackInfo<Value>& args) {
16151614 args.GetReturnValue ().Set (Array::New (isolate, rows.data (), rows.size ()));
16161615}
16171616
1618- void StatementSync::IterateReturnCallback (
1619- const FunctionCallbackInfo<Value>& args) {
1620- Environment* env = Environment::GetCurrent (args);
1621- auto isolate = env->isolate ();
1622- auto context = isolate->GetCurrentContext ();
1623-
1624- auto self = args.This ();
1625- // iterator has fetch all result or break, prevent next func to return result
1626- if (self->Set (context, env->isfinished_string (), Boolean::New (isolate, true ))
1627- .IsNothing ()) {
1628- // An error will have been scheduled.
1629- return ;
1630- }
1631-
1632- Local<Value> val;
1633- if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1634- // An error will have been scheduled.
1635- return ;
1636- }
1637- auto external_stmt = Local<External>::Cast (val);
1638- auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1639- if (!stmt->IsFinalized ()) {
1640- sqlite3_reset (stmt->statement_ );
1641- }
1642-
1643- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1644- LocalVector<Value> values (isolate,
1645- {Boolean::New (isolate, true ), Null (isolate)});
1646-
1647- DCHECK_EQ (keys.size (), values.size ());
1648- Local<Object> result = Object::New (
1649- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1650- args.GetReturnValue ().Set (result);
1651- }
1652-
1653- void StatementSync::IterateNextCallback (
1654- const FunctionCallbackInfo<Value>& args) {
1655- Environment* env = Environment::GetCurrent (args);
1656- auto isolate = env->isolate ();
1657- auto context = isolate->GetCurrentContext ();
1658-
1659- auto self = args.This ();
1660-
1661- Local<Value> val;
1662- if (!self->Get (context, env->isfinished_string ()).ToLocal (&val)) {
1663- // An error will have been scheduled.
1664- return ;
1665- }
1666-
1667- // skip iteration if is_finished
1668- auto is_finished = Local<Boolean>::Cast (val);
1669- if (is_finished->Value ()) {
1670- Local<Name> keys[] = {env->done_string (), env->value_string ()};
1671- Local<Value> values[] = {Boolean::New (isolate, true ), Null (isolate)};
1672- static_assert (arraysize (keys) == arraysize (values));
1673- Local<Object> result = Object::New (
1674- isolate, Null (isolate), &keys[0 ], &values[0 ], arraysize (keys));
1675- args.GetReturnValue ().Set (result);
1676- return ;
1677- }
1678-
1679- if (!self->Get (context, env->statement_string ()).ToLocal (&val)) {
1680- // An error will have been scheduled.
1681- return ;
1682- }
1683-
1684- auto external_stmt = Local<External>::Cast (val);
1685- auto stmt = static_cast <StatementSync*>(external_stmt->Value ());
1686-
1687- if (!self->Get (context, env->num_cols_string ()).ToLocal (&val)) {
1688- // An error will have been scheduled.
1689- return ;
1690- }
1691-
1692- auto num_cols = Local<Integer>::Cast (val)->Value ();
1693-
1694- THROW_AND_RETURN_ON_BAD_STATE (
1695- env, stmt->IsFinalized (), " statement has been finalized" );
1696-
1697- int r = sqlite3_step (stmt->statement_ );
1698- if (r != SQLITE_ROW) {
1699- CHECK_ERROR_OR_THROW (
1700- env->isolate (), stmt->db_ .get (), r, SQLITE_DONE, void ());
1701-
1702- // cleanup when no more rows to fetch
1703- sqlite3_reset (stmt->statement_ );
1704- if (self->Set (
1705- context, env->isfinished_string (), Boolean::New (isolate, true ))
1706- .IsNothing ()) {
1707- // An error would have been scheduled
1708- return ;
1709- }
1710-
1711- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1712- LocalVector<Value> values (isolate,
1713- {Boolean::New (isolate, true ), Null (isolate)});
1714-
1715- DCHECK_EQ (keys.size (), values.size ());
1716- Local<Object> result = Object::New (
1717- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1718- args.GetReturnValue ().Set (result);
1719- return ;
1720- }
1721-
1722- LocalVector<Name> row_keys (isolate);
1723- row_keys.reserve (num_cols);
1724- LocalVector<Value> row_values (isolate);
1725- row_values.reserve (num_cols);
1726- for (int i = 0 ; i < num_cols; ++i) {
1727- Local<Name> key;
1728- if (!stmt->ColumnNameToName (i).ToLocal (&key)) return ;
1729- Local<Value> val;
1730- if (!stmt->ColumnToValue (i).ToLocal (&val)) return ;
1731- row_keys.emplace_back (key);
1732- row_values.emplace_back (val);
1733- }
1734-
1735- Local<Object> row = Object::New (
1736- isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
1737-
1738- LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
1739- LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
1740-
1741- DCHECK_EQ (keys.size (), values.size ());
1742- Local<Object> result = Object::New (
1743- isolate, Null (isolate), keys.data (), values.data (), keys.size ());
1744- args.GetReturnValue ().Set (result);
1745- }
1746-
17471617void StatementSync::Iterate (const FunctionCallbackInfo<Value>& args) {
17481618 StatementSync* stmt;
17491619 ASSIGN_OR_RETURN_UNWRAP (&stmt, args.This ());
17501620 Environment* env = Environment::GetCurrent (args);
17511621 THROW_AND_RETURN_ON_BAD_STATE (
17521622 env, stmt->IsFinalized (), " statement has been finalized" );
1753- auto isolate = env->isolate ();
17541623 auto context = env->context ();
17551624 int r = sqlite3_reset (stmt->statement_ );
17561625 CHECK_ERROR_OR_THROW (env->isolate (), stmt->db_ .get (), r, SQLITE_OK, void ());
@@ -1759,67 +1628,28 @@ void StatementSync::Iterate(const FunctionCallbackInfo<Value>& args) {
17591628 return ;
17601629 }
17611630
1762- Local<Function> next_func;
1763- Local<Function> return_func;
1764- if (!Function::New (context, StatementSync::IterateNextCallback)
1765- .ToLocal (&next_func) ||
1766- !Function::New (context, StatementSync::IterateReturnCallback)
1767- .ToLocal (&return_func)) {
1768- // An error will have been scheduled.
1769- return ;
1770- }
1771-
1772- Local<Name> keys[] = {env->next_string (), env->return_string ()};
1773- Local<Value> values[] = {next_func, return_func};
1774- static_assert (arraysize (keys) == arraysize (values));
1775-
17761631 Local<Object> global = context->Global ();
17771632 Local<Value> js_iterator;
17781633 Local<Value> js_iterator_prototype;
1779- if (!global->Get (context, env->iterator_string ()).ToLocal (&js_iterator))
1634+ if (!global->Get (context, env->iterator_string ()).ToLocal (&js_iterator)) {
17801635 return ;
1636+ }
17811637 if (!js_iterator.As <Object>()
17821638 ->Get (context, env->prototype_string ())
1783- .ToLocal (&js_iterator_prototype))
1784- return ;
1785-
1786- Local<Object> iterable_iterator = Object::New (
1787- isolate, js_iterator_prototype, &keys[0 ], &values[0 ], arraysize (keys));
1788-
1789- auto num_cols_pd = v8::PropertyDescriptor (
1790- v8::Integer::New (isolate, sqlite3_column_count (stmt->statement_ )), false );
1791- num_cols_pd.set_enumerable (false );
1792- num_cols_pd.set_configurable (false );
1793- if (iterable_iterator
1794- ->DefineProperty (context, env->num_cols_string (), num_cols_pd)
1795- .IsNothing ()) {
1796- // An error will have been scheduled.
1639+ .ToLocal (&js_iterator_prototype)) {
17971640 return ;
17981641 }
17991642
1800- auto stmt_pd =
1801- v8::PropertyDescriptor ( v8::External::New (isolate, stmt), false );
1802- stmt_pd. set_enumerable ( false );
1803- stmt_pd. set_configurable ( false );
1804- if (iterable_iterator
1805- ->DefineProperty (context, env-> statement_string (), stmt_pd )
1643+ BaseObjectPtr<StatementSyncIterator> iter =
1644+ StatementSyncIterator::Create (env, BaseObjectPtr<StatementSync>( stmt));
1645+ if (iter-> object ()
1646+ -> GetPrototype ()
1647+ . As <Object>()
1648+ ->SetPrototype (context, js_iterator_prototype )
18061649 .IsNothing ()) {
1807- // An error will have been scheduled.
18081650 return ;
18091651 }
1810-
1811- auto is_finished_pd =
1812- v8::PropertyDescriptor (v8::Boolean::New (isolate, false ), true );
1813- stmt_pd.set_enumerable (false );
1814- stmt_pd.set_configurable (false );
1815- if (iterable_iterator
1816- ->DefineProperty (context, env->isfinished_string (), is_finished_pd)
1817- .IsNothing ()) {
1818- // An error will have been scheduled.
1819- return ;
1820- }
1821-
1822- args.GetReturnValue ().Set (iterable_iterator);
1652+ args.GetReturnValue ().Set (iter->object ());
18231653}
18241654
18251655void StatementSync::Get (const FunctionCallbackInfo<Value>& args) {
@@ -2118,6 +1948,118 @@ BaseObjectPtr<StatementSync> StatementSync::Create(
21181948 return MakeBaseObject<StatementSync>(env, obj, std::move (db), stmt);
21191949}
21201950
1951+ StatementSyncIterator::StatementSyncIterator (Environment* env,
1952+ Local<Object> object,
1953+ BaseObjectPtr<StatementSync> stmt)
1954+ : BaseObject(env, object), stmt_(std::move(stmt)) {
1955+ MakeWeak ();
1956+ done_ = false ;
1957+ }
1958+
1959+ StatementSyncIterator::~StatementSyncIterator () {}
1960+ void StatementSyncIterator::MemoryInfo (MemoryTracker* tracker) const {}
1961+
1962+ Local<FunctionTemplate> StatementSyncIterator::GetConstructorTemplate (
1963+ Environment* env) {
1964+ Local<FunctionTemplate> tmpl =
1965+ env->sqlite_statement_sync_iterator_constructor_template ();
1966+ if (tmpl.IsEmpty ()) {
1967+ Isolate* isolate = env->isolate ();
1968+ tmpl = NewFunctionTemplate (isolate, IllegalConstructor);
1969+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " StatementSyncIterator" ));
1970+ tmpl->InstanceTemplate ()->SetInternalFieldCount (
1971+ StatementSync::kInternalFieldCount );
1972+ SetProtoMethod (isolate, tmpl, " next" , StatementSyncIterator::Next);
1973+ SetProtoMethod (isolate, tmpl, " return" , StatementSyncIterator::Return);
1974+ env->set_sqlite_statement_sync_iterator_constructor_template (tmpl);
1975+ }
1976+ return tmpl;
1977+ }
1978+
1979+ BaseObjectPtr<StatementSyncIterator> StatementSyncIterator::Create (
1980+ Environment* env, BaseObjectPtr<StatementSync> stmt) {
1981+ Local<Object> obj;
1982+ if (!GetConstructorTemplate (env)
1983+ ->InstanceTemplate ()
1984+ ->NewInstance (env->context ())
1985+ .ToLocal (&obj)) {
1986+ return BaseObjectPtr<StatementSyncIterator>();
1987+ }
1988+
1989+ return MakeBaseObject<StatementSyncIterator>(env, obj, std::move (stmt));
1990+ }
1991+
1992+ void StatementSyncIterator::Next (const FunctionCallbackInfo<Value>& args) {
1993+ StatementSyncIterator* iter;
1994+ ASSIGN_OR_RETURN_UNWRAP (&iter, args.This ());
1995+ Environment* env = Environment::GetCurrent (args);
1996+ THROW_AND_RETURN_ON_BAD_STATE (
1997+ env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
1998+ Isolate* isolate = env->isolate ();
1999+ LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2000+
2001+ if (iter->done_ ) {
2002+ LocalVector<Value> values (isolate,
2003+ {Boolean::New (isolate, true ), Null (isolate)});
2004+ Local<Object> result = Object::New (
2005+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2006+ args.GetReturnValue ().Set (result);
2007+ return ;
2008+ }
2009+
2010+ int r = sqlite3_step (iter->stmt_ ->statement_ );
2011+ if (r != SQLITE_ROW) {
2012+ CHECK_ERROR_OR_THROW (
2013+ env->isolate (), iter->stmt_ ->db_ .get (), r, SQLITE_DONE, void ());
2014+ sqlite3_reset (iter->stmt_ ->statement_ );
2015+ LocalVector<Value> values (isolate,
2016+ {Boolean::New (isolate, true ), Null (isolate)});
2017+ Local<Object> result = Object::New (
2018+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2019+ args.GetReturnValue ().Set (result);
2020+ return ;
2021+ }
2022+
2023+ int num_cols = sqlite3_column_count (iter->stmt_ ->statement_ );
2024+ LocalVector<Name> row_keys (isolate);
2025+ LocalVector<Value> row_values (isolate);
2026+ row_keys.reserve (num_cols);
2027+ row_values.reserve (num_cols);
2028+ for (int i = 0 ; i < num_cols; ++i) {
2029+ Local<Name> key;
2030+ if (!iter->stmt_ ->ColumnNameToName (i).ToLocal (&key)) return ;
2031+ Local<Value> val;
2032+ if (!iter->stmt_ ->ColumnToValue (i).ToLocal (&val)) return ;
2033+ row_keys.emplace_back (key);
2034+ row_values.emplace_back (val);
2035+ }
2036+
2037+ Local<Object> row = Object::New (
2038+ isolate, Null (isolate), row_keys.data (), row_values.data (), num_cols);
2039+ LocalVector<Value> values (isolate, {Boolean::New (isolate, false ), row});
2040+ Local<Object> result = Object::New (
2041+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2042+ args.GetReturnValue ().Set (result);
2043+ }
2044+
2045+ void StatementSyncIterator::Return (const FunctionCallbackInfo<Value>& args) {
2046+ StatementSyncIterator* iter;
2047+ ASSIGN_OR_RETURN_UNWRAP (&iter, args.This ());
2048+ Environment* env = Environment::GetCurrent (args);
2049+ THROW_AND_RETURN_ON_BAD_STATE (
2050+ env, iter->stmt_ ->IsFinalized (), " statement has been finalized" );
2051+ Isolate* isolate = env->isolate ();
2052+
2053+ sqlite3_reset (iter->stmt_ ->statement_ );
2054+ iter->done_ = true ;
2055+ LocalVector<Name> keys (isolate, {env->done_string (), env->value_string ()});
2056+ LocalVector<Value> values (isolate,
2057+ {Boolean::New (isolate, true ), Null (isolate)});
2058+ Local<Object> result = Object::New (
2059+ isolate, Null (isolate), keys.data (), values.data (), keys.size ());
2060+ args.GetReturnValue ().Set (result);
2061+ }
2062+
21212063Session::Session (Environment* env,
21222064 Local<Object> object,
21232065 BaseObjectWeakPtr<DatabaseSync> database,
0 commit comments