Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for file open flags for sqlite3 #4446

Merged
merged 6 commits into from Apr 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions lib/dialects/sqlite3/index.js
Expand Up @@ -62,8 +62,24 @@ class Client_SQLite3 extends Client {
// Get a raw connection from the database, returning a promise with the connection object.
acquireRawConnection() {
return new Promise((resolve, reject) => {
// the default mode for sqlite3
let flags = this.driver.OPEN_READWRITE | this.driver.OPEN_CREATE;

if (this.connectionSettings.flags) {
if (!Array.isArray(this.connectionSettings.flags)) {
throw new Error(`flags must be an array of strings`);
}
this.connectionSettings.flags.forEach((_flag) => {
if (!_flag.startsWith('OPEN_') || !this.driver[_flag]) {
throw new Error(`flag ${_flag} not supported by node-sqlite3`);
}
flags = flags | this.driver[_flag];
});
}

const db = new this.driver.Database(
this.connectionSettings.filename,
flags,
(err) => {
if (err) {
return reject(err);
Expand Down
Empty file added memdb-test
Empty file.
69 changes: 69 additions & 0 deletions test/tape/knex.js
Expand Up @@ -2,6 +2,7 @@

const knex = require('../../lib/index');
const test = require('tape');
const fs = require('fs');

test('it should parse the connection string', function (t) {
t.plan(1);
Expand Down Expand Up @@ -66,6 +67,74 @@ test('it should use knex supported dialect', function (t) {
knexObj.destroy();
});

test('it should support open flags selection for sqlite3', function (t) {
t.plan(1);
const knexObj = knex({
client: 'sqlite3',
connection: {
filename: 'file:memdb-test?mode=memory',
// allow the filename to be interpreted as a URI
flags: ['OPEN_URI'],
},
});
// run a query so a connection is created
knexObj
.select(knexObj.raw('"0"'))
.then(() => {
// if the filename was interpreted as a URI, no file should have been created
t.equal(fs.existsSync('./file:memdb-test?mode=memory'), false);
})
.finally(() => {
knexObj.destroy();
});
});

test('it should error when invalid open flags are selected for sqlite3', function (t) {
t.plan(2);

// Test invalid flags
let knexObj = knex({
client: 'sqlite3',
connection: {
filename: ':memory:',
flags: ['NON_EXISTING'],
},
});
// run a query so a connection is created
knexObj
.select(knexObj.raw('"0"'))
.then(() => {
t.fail('Should not get here');
})
.catch((err) => {
t.equal(err.message, 'flag NON_EXISTING not supported by node-sqlite3');
})
.finally(() => {
knexObj.destroy();
});

// test invalid config
knexObj = knex({
client: 'sqlite3',
connection: {
filename: ':memory:',
flags: 'OPEN_URI',
},
});
// run a query so a connection is created
knexObj
.select(knexObj.raw('"0"'))
.then(() => {
t.fail('Should not get here');
})
.catch((err) => {
t.equal(err.message, 'flags must be an array of strings');
})
.finally(() => {
knexObj.destroy();
});
});

test('it should throw error if client is omitted in config', function (t) {
t.plan(1);
try {
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Expand Up @@ -2263,6 +2263,7 @@ interface MsSqlConnectionConfigBase {
/** Used with SQLite3 adapter */
interface Sqlite3ConnectionConfig {
filename: string;
flags?: string[];
debug?: boolean;
expirationChecker?(): boolean;
}
Expand Down