diff --git a/src/statement.cc b/src/statement.cc index fc49b90f..604292a7 100644 --- a/src/statement.cc +++ b/src/statement.cc @@ -587,8 +587,9 @@ void Statement::Work_AfterAll(napi_env e, napi_status status, void* data) { Napi::Array result(Napi::Array::New(env, baton->rows.size())); auto it = static_cast(baton->rows.begin()); decltype(it) end = baton->rows.end(); + std::vector js_names; for (int i = 0; it < end; ++it, i++) { - (result).Set(i, RowToJS(env, it->get())); + (result).Set(i, RowToJS(env, it->get(), &js_names)); } Napi::Value argv[] = { env.Null(), result }; @@ -711,8 +712,9 @@ void Statement::AsyncEach(uv_async_t* handle) { Napi::Value argv[2]; argv[0] = env.Null(); + std::vector js_names; for(auto& row : rows) { - argv[1] = RowToJS(env,row.get()); + argv[1] = RowToJS(env, row.get(), &js_names); async->retrieved++; TRY_CATCH_CALL(async->stmt->Value(), cb, 2, argv); } @@ -787,11 +789,19 @@ void Statement::Work_AfterReset(napi_env e, napi_status status, void* data) { STATEMENT_END(); } -Napi::Value Statement::RowToJS(Napi::Env env, Row* row) { +Napi::Value Statement::RowToJS(Napi::Env env, Row* row, std::vector* js_names) { + // Must fill this array if empty before we enter the escapable handle scope below. + if (js_names != nullptr && js_names->empty()) { + for (auto& field : *row) { + js_names->push_back(Napi::String::New(env, field->name)); + } + } + Napi::EscapableHandleScope scope(env); auto result = Napi::Object::New(env); + size_t js_name_idx = 0; for (auto& field : *row) { Napi::Value value; @@ -816,7 +826,10 @@ Napi::Value Statement::RowToJS(Napi::Env env, Row* row) { } break; } - result.Set(field->name, value); + napi_value field_name = js_names && js_names->empty() + ? Napi::String::New(env, field->name) + : (*js_names)[js_name_idx++]; + result.Set(field_name, value); } return scope.Escape(result); diff --git a/src/statement.h b/src/statement.h index c522c0fd..91891840 100644 --- a/src/statement.h +++ b/src/statement.h @@ -220,7 +220,7 @@ class Statement : public Napi::ObjectWrap { bool Bind(const Parameters ¶meters); static void GetRow(Row* row, sqlite3_stmt* stmt); - static Napi::Value RowToJS(Napi::Env env, Row* row); + static Napi::Value RowToJS(Napi::Env env, Row* row, std::vector* js_names = nullptr); void Schedule(Work_Callback callback, Baton* baton); void Process(); void CleanQueue();