Repository: nodejs/node
Pull request: sqlite: aggregate constants in a single property

Refs: #56193
Closes: #56193

Changed files:
filename: doc/api/sqlite.md
patch: @@ -482,11 +482,19 @@ exception.
 | `TEXT`    | {string}             |
 | `BLOB`    | {Uint8Array}         |
 
-## SQLite constants
+## `sqlite.constants`
 
-The following constants are exported by the `node:sqlite` module.
+<!-- YAML
+added: REPLACEME
+-->
+
+* {Object}
+
+An object containing commonly used constants for SQLite operations.
+
+### SQLite constants
 
-### SQLite Session constants
+The following constants are exported by the `sqlite.constants` object.
 
 #### Conflict-resolution constants
 
@@ -507,7 +515,7 @@ The following constants are meant for use with [`database.applyChangeset()`](#da
   </tr>
   <tr>
     <td><code>SQLITE_CHANGESET_ABORT</code></td>
-    <td>Abort when a change encounters a conflict and roll back databsase.</td>
+    <td>Abort when a change encounters a conflict and roll back database.</td>
   </tr>
 </table>
 

filename: src/node_sqlite.cc
patch: @@ -1658,6 +1658,12 @@ void Session::Delete() {
   session_ = nullptr;
 }
 
+void DefineConstants(Local<Object> target) {
+  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_OMIT);
+  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_REPLACE);
+  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_ABORT);
+}
+
 static void Initialize(Local<Object> target,
                        Local<Value> unused,
                        Local<Context> context,
@@ -1668,6 +1674,9 @@ static void Initialize(Local<Object> target,
       NewFunctionTemplate(isolate, DatabaseSync::New);
   db_tmpl->InstanceTemplate()->SetInternalFieldCount(
       DatabaseSync::kInternalFieldCount);
+  Local<Object> constants = Object::New(isolate);
+
+  DefineConstants(constants);
 
   SetProtoMethod(isolate, db_tmpl, "open", DatabaseSync::Open);
   SetProtoMethod(isolate, db_tmpl, "close", DatabaseSync::Close);
@@ -1690,9 +1699,7 @@ static void Initialize(Local<Object> target,
                          "StatementSync",
                          StatementSync::GetConstructorTemplate(env));
 
-  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_OMIT);
-  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_REPLACE);
-  NODE_DEFINE_CONSTANT(target, SQLITE_CHANGESET_ABORT);
+  target->Set(context, OneByteString(isolate, "constants"), constants).Check();
 }
 
 }  // namespace sqlite

filename: test/parallel/test-sqlite-session.js
patch: @@ -3,9 +3,7 @@
 require('../common');
 const {
   DatabaseSync,
-  SQLITE_CHANGESET_OMIT,
-  SQLITE_CHANGESET_REPLACE,
-  SQLITE_CHANGESET_ABORT
+  constants,
 } = require('node:sqlite');
 const { test, suite } = require('node:test');
 
@@ -165,7 +163,7 @@ suite('conflict resolution', () => {
   test('database.applyChangeset() - conflict with SQLITE_CHANGESET_ABORT', (t) => {
     const { database2, changeset } = prepareConflict();
     const result = database2.applyChangeset(changeset, {
-      onConflict: SQLITE_CHANGESET_ABORT
+      onConflict: constants.SQLITE_CHANGESET_ABORT
     });
     // When changeset is aborted due to a conflict, applyChangeset should return false
     t.assert.strictEqual(result, false);
@@ -177,7 +175,7 @@ suite('conflict resolution', () => {
   test('database.applyChangeset() - conflict with SQLITE_CHANGESET_REPLACE', (t) => {
     const { database2, changeset } = prepareConflict();
     const result = database2.applyChangeset(changeset, {
-      onConflict: SQLITE_CHANGESET_REPLACE
+      onConflict: constants.SQLITE_CHANGESET_REPLACE
     });
     // Not aborted due to conflict, so should return true
     t.assert.strictEqual(result, true);
@@ -189,7 +187,7 @@ suite('conflict resolution', () => {
   test('database.applyChangeset() - conflict with SQLITE_CHANGESET_OMIT', (t) => {
     const { database2, changeset } = prepareConflict();
     const result = database2.applyChangeset(changeset, {
-      onConflict: SQLITE_CHANGESET_OMIT
+      onConflict: constants.SQLITE_CHANGESET_OMIT
     });
     // Not aborted due to conflict, so should return true
     t.assert.strictEqual(result, true);
@@ -199,12 +197,6 @@ suite('conflict resolution', () => {
   });
 });
 
-test('session related constants are defined', (t) => {
-  t.assert.strictEqual(SQLITE_CHANGESET_OMIT, 0);
-  t.assert.strictEqual(SQLITE_CHANGESET_REPLACE, 1);
-  t.assert.strictEqual(SQLITE_CHANGESET_ABORT, 2);
-});
-
 test('database.createSession() - filter changes', (t) => {
   const database1 = new DatabaseSync(':memory:');
   const database2 = new DatabaseSync(':memory:');

filename: test/parallel/test-sqlite.js
patch: @@ -2,7 +2,7 @@
 const { spawnPromisified } = require('../common');
 const tmpdir = require('../common/tmpdir');
 const { join } = require('node:path');
-const { DatabaseSync } = require('node:sqlite');
+const { DatabaseSync, constants } = require('node:sqlite');
 const { suite, test } = require('node:test');
 let cnt = 0;
 
@@ -85,6 +85,12 @@ test('in-memory databases are supported', (t) => {
   );
 });
 
+test('sqlite constants are defined', (t) => {
+  t.assert.strictEqual(constants.SQLITE_CHANGESET_OMIT, 0);
+  t.assert.strictEqual(constants.SQLITE_CHANGESET_REPLACE, 1);
+  t.assert.strictEqual(constants.SQLITE_CHANGESET_ABORT, 2);
+});
+
 test('PRAGMAs are supported', (t) => {
   const db = new DatabaseSync(nextDb());
   t.after(() => { db.close(); });

filename: typings/internalBinding/constants.d.ts
patch: @@ -130,6 +130,11 @@ export interface ConstantsBinding {
       PRIORITY_HIGHEST: -20;
     };
   };
+  sqlite: {
+    SQLITE_CHANGESET_OMIT: 0;
+    SQLITE_CHANGESET_REPLACE: 1;
+    SQLITE_CHANGESET_ABORT: 2;
+  };
   fs: {
     UV_FS_SYMLINK_DIR: 1;
     UV_FS_SYMLINK_JUNCTION: 2;