Skip to main content
Glama
statement-iterator.cpp3.34 kB
StatementIterator::StatementIterator(Statement* stmt, bool bound) : node::ObjectWrap(), stmt(stmt), handle(stmt->handle), db_state(stmt->db->GetState()), bound(bound), safe_ints(stmt->safe_ints), mode(stmt->mode), alive(true), logged(!db_state->has_logger) { assert(stmt != NULL); assert(handle != NULL); assert(stmt->bound == bound); assert(stmt->alive == true); assert(stmt->locked == false); assert(db_state->iterators < USHRT_MAX); stmt->locked = true; db_state->iterators += 1; } // The ~Statement destructor currently covers any state this object creates. // Additionally, we actually DON'T want to revert stmt->locked or db_state // ->iterators in this destructor, to ensure deterministic database access. StatementIterator::~StatementIterator() {} void StatementIterator::Next(NODE_ARGUMENTS info) { assert(alive == true); db_state->busy = true; if (!logged) { logged = true; if (stmt->db->Log(OnlyIsolate, handle)) { db_state->busy = false; Throw(); return; } } int status = sqlite3_step(handle); db_state->busy = false; if (status == SQLITE_ROW) { UseIsolate; UseContext; info.GetReturnValue().Set( NewRecord(isolate, ctx, Data::GetRowJS(isolate, ctx, handle, safe_ints, mode), db_state->addon, false) ); } else { if (status == SQLITE_DONE) Return(info); else Throw(); } } void StatementIterator::Return(NODE_ARGUMENTS info) { Cleanup(); STATEMENT_RETURN_LOGIC(DoneRecord(OnlyIsolate, db_state->addon)); } void StatementIterator::Throw() { Cleanup(); Database* db = stmt->db; STATEMENT_THROW_LOGIC(); } void StatementIterator::Cleanup() { assert(alive == true); alive = false; stmt->locked = false; db_state->iterators -= 1; sqlite3_reset(handle); } INIT(StatementIterator::Init) { v8::Local<v8::FunctionTemplate> t = NewConstructorTemplate(isolate, data, JS_new, "StatementIterator"); SetPrototypeMethod(isolate, data, t, "next", JS_next); SetPrototypeMethod(isolate, data, t, "return", JS_return); SetPrototypeSymbolMethod(isolate, data, t, v8::Symbol::GetIterator(isolate), JS_symbolIterator); return t->GetFunction(OnlyContext).ToLocalChecked(); } NODE_METHOD(StatementIterator::JS_new) { UseAddon; if (!addon->privileged_info) return ThrowTypeError("Disabled constructor"); assert(info.IsConstructCall()); StatementIterator* iter; { NODE_ARGUMENTS info = *addon->privileged_info; STATEMENT_START_LOGIC(REQUIRE_STATEMENT_RETURNS_DATA, DOES_ADD_ITERATOR); iter = new StatementIterator(stmt, bound); } UseIsolate; UseContext; iter->Wrap(info.This()); SetFrozen(isolate, ctx, info.This(), addon->cs.statement, addon->privileged_info->This()); info.GetReturnValue().Set(info.This()); } NODE_METHOD(StatementIterator::JS_next) { StatementIterator* iter = Unwrap<StatementIterator>(info.This()); REQUIRE_DATABASE_NOT_BUSY(iter->db_state); if (iter->alive) iter->Next(info); else info.GetReturnValue().Set(DoneRecord(OnlyIsolate, iter->db_state->addon)); } NODE_METHOD(StatementIterator::JS_return) { StatementIterator* iter = Unwrap<StatementIterator>(info.This()); REQUIRE_DATABASE_NOT_BUSY(iter->db_state); if (iter->alive) iter->Return(info); else info.GetReturnValue().Set(DoneRecord(OnlyIsolate, iter->db_state->addon)); } NODE_METHOD(StatementIterator::JS_symbolIterator) { info.GetReturnValue().Set(info.This()); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/mnehmos.synch.mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server