Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2ec4ae7

Browse filesBrowse files
tniessenRafaelGSS
authored andcommitted
sqlite: add readOnly option
Allow opening existing SQLite databases with SQLITE_OPEN_READONLY set. PR-URL: #55567 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 4676184 commit 2ec4ae7
Copy full SHA for 2ec4ae7

File tree

Expand file treeCollapse file tree

4 files changed

+59
-1
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+59
-1
lines changed
Open diff view settings
Collapse file

‎doc/api/sqlite.md‎

Copy file name to clipboardExpand all lines: doc/api/sqlite.md
+2Lines changed: 2 additions & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ added: v22.5.0
107107
* `open` {boolean} If `true`, the database is opened by the constructor. When
108108
this value is `false`, the database must be opened via the `open()` method.
109109
**Default:** `true`.
110+
* `readOnly` {boolean} If `true`, the database is opened in read-only mode.
111+
If the database does not exist, opening it will fail. **Default:** `false`.
110112
* `enableForeignKeyConstraints` {boolean} If `true`, foreign key constraints
111113
are enabled. This is recommended but can be disabled for compatibility with
112114
legacy database schemas. The enforcement of foreign key constraints can be
Collapse file

‎src/node_sqlite.cc‎

Copy file name to clipboardExpand all lines: src/node_sqlite.cc
+19-1Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ bool DatabaseSync::Open() {
126126
}
127127

128128
// TODO(cjihrig): Support additional flags.
129-
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
129+
int flags = open_config_.get_read_only()
130+
? SQLITE_OPEN_READONLY
131+
: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
130132
int r = sqlite3_open_v2(
131133
open_config_.location().c_str(), &connection_, flags, nullptr);
132134
CHECK_ERROR_OR_THROW(env()->isolate(), connection_, r, SQLITE_OK, false);
@@ -219,6 +221,22 @@ void DatabaseSync::New(const FunctionCallbackInfo<Value>& args) {
219221
open = open_v.As<Boolean>()->Value();
220222
}
221223

224+
Local<String> read_only_string =
225+
FIXED_ONE_BYTE_STRING(env->isolate(), "readOnly");
226+
Local<Value> read_only_v;
227+
if (!options->Get(env->context(), read_only_string).ToLocal(&read_only_v)) {
228+
return;
229+
}
230+
if (!read_only_v->IsUndefined()) {
231+
if (!read_only_v->IsBoolean()) {
232+
node::THROW_ERR_INVALID_ARG_TYPE(
233+
env->isolate(),
234+
"The \"options.readOnly\" argument must be a boolean.");
235+
return;
236+
}
237+
open_config.set_read_only(read_only_v.As<Boolean>()->Value());
238+
}
239+
222240
Local<String> enable_foreign_keys_string =
223241
FIXED_ONE_BYTE_STRING(env->isolate(), "enableForeignKeyConstraints");
224242
Local<Value> enable_foreign_keys_v;
Collapse file

‎src/node_sqlite.h‎

Copy file name to clipboardExpand all lines: src/node_sqlite.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ class DatabaseOpenConfiguration {
2121

2222
inline const std::string& location() const { return location_; }
2323

24+
inline bool get_read_only() const { return read_only_; }
25+
26+
inline void set_read_only(bool flag) { read_only_ = flag; }
27+
2428
inline bool get_enable_foreign_keys() const { return enable_foreign_keys_; }
2529

2630
inline void set_enable_foreign_keys(bool flag) {
@@ -33,6 +37,7 @@ class DatabaseOpenConfiguration {
3337

3438
private:
3539
std::string location_;
40+
bool read_only_ = false;
3641
bool enable_foreign_keys_ = true;
3742
bool enable_dqs_ = false;
3843
};
Collapse file

‎test/parallel/test-sqlite-database-sync.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-sqlite-database-sync.js
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,39 @@ suite('DatabaseSync() constructor', () => {
5151
});
5252
});
5353

54+
test('throws if options.readOnly is provided but is not a boolean', (t) => {
55+
t.assert.throws(() => {
56+
new DatabaseSync('foo', { readOnly: 5 });
57+
}, {
58+
code: 'ERR_INVALID_ARG_TYPE',
59+
message: /The "options\.readOnly" argument must be a boolean/,
60+
});
61+
});
62+
63+
test('is not read-only by default', (t) => {
64+
const dbPath = nextDb();
65+
const db = new DatabaseSync(dbPath);
66+
db.exec('CREATE TABLE foo (id INTEGER PRIMARY KEY)');
67+
});
68+
69+
test('is read-only if readOnly is set', (t) => {
70+
const dbPath = nextDb();
71+
{
72+
const db = new DatabaseSync(dbPath);
73+
db.exec('CREATE TABLE foo (id INTEGER PRIMARY KEY)');
74+
db.close();
75+
}
76+
{
77+
const db = new DatabaseSync(dbPath, { readOnly: true });
78+
t.assert.throws(() => {
79+
db.exec('CREATE TABLE bar (id INTEGER PRIMARY KEY)');
80+
}, {
81+
code: 'ERR_SQLITE_ERROR',
82+
message: /attempt to write a readonly database/,
83+
});
84+
}
85+
});
86+
5487
test('throws if options.enableForeignKeyConstraints is provided but is not a boolean', (t) => {
5588
t.assert.throws(() => {
5689
new DatabaseSync('foo', { enableForeignKeyConstraints: 5 });

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.