Remove loadExtension method

This commit is contained in:
Fedor Indutny 2024-10-16 09:23:33 -07:00
parent 89ff55bf0b
commit 28d1929af0
8 changed files with 1 additions and 158 deletions

View File

@ -29,10 +29,5 @@
}],
],
},
{
'target_name': 'test_extension',
'dependencies': ['deps/sqlite3.gyp:sqlite3'],
'conditions': [['sqlite3 == ""', { 'sources': ['deps/test_extension.c'] }]],
},
],
}

1
index.d.ts vendored
View File

@ -88,7 +88,6 @@ declare namespace BetterSqlite3 {
function(name: string, cb: (...params: any[]) => any): this;
function(name: string, options: Database.RegistrationOptions, cb: (...params: any[]) => any): this;
aggregate(name: string, options: Database.AggregateOptions): this;
loadExtension(path: string, entryPoint?: string): this;
close(): this;
defaultSafeIntegers(toggleState?: boolean): this;
backup(destinationFile: string, options?: Database.BackupOptions): Promise<Database.BackupMetadata>;

View File

@ -85,7 +85,6 @@ Database.prototype.function = require('./methods/function');
Database.prototype.aggregate = require('./methods/aggregate');
Database.prototype.table = require('./methods/table');
Database.prototype.createFTS5Tokenizer = require('./methods/createFTS5Tokenizer');
Database.prototype.loadExtension = wrappers.loadExtension;
Database.prototype.exec = wrappers.exec;
Database.prototype.close = wrappers.close;
Database.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;

View File

@ -15,11 +15,6 @@ exports.close = function close() {
return this;
};
exports.loadExtension = function loadExtension(...args) {
this[cppdb].loadExtension(...args);
return this;
};
exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
this[cppdb].defaultSafeIntegers(...args);
return this;

View File

@ -314,7 +314,6 @@ v8::Local<v8 ::Function> Database::Init(v8::Isolate* isolate,
SetPrototypeMethod(isolate, data, t, "function", JS_function);
SetPrototypeMethod(isolate, data, t, "aggregate", JS_aggregate);
SetPrototypeMethod(isolate, data, t, "table", JS_table);
SetPrototypeMethod(isolate, data, t, "loadExtension", JS_loadExtension);
SetPrototypeMethod(isolate, data, t, "close", JS_close);
SetPrototypeMethod(isolate, data, t, "defaultSafeIntegers",
JS_defaultSafeIntegers);
@ -519,10 +518,7 @@ void Database::JS_new(v8::FunctionCallbackInfo<v8 ::Value> const& info) {
db_handle, SQLITE_LIMIT_LENGTH,
MAX_BUFFER_SIZE < MAX_STRING_SIZE ? MAX_BUFFER_SIZE : MAX_STRING_SIZE);
sqlite3_limit(db_handle, SQLITE_LIMIT_SQL_LENGTH, MAX_STRING_SIZE);
int status = sqlite3_db_config(
db_handle, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
assert(status == SQLITE_OK);
status = sqlite3_db_config(db_handle, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
int status = sqlite3_db_config(db_handle, SQLITE_DBCONFIG_DEFENSIVE, 1, NULL);
assert(status == SQLITE_OK);
if (node::Buffer::HasInstance(buffer) &&
@ -919,43 +915,6 @@ void Database::JS_table(v8::FunctionCallbackInfo<v8 ::Value> const& info) {
}
db->busy = false;
}
void Database::JS_loadExtension(
v8::FunctionCallbackInfo<v8 ::Value> const& info) {
Database* db = node ::ObjectWrap ::Unwrap<Database>(info.This());
v8::Local<v8::String> entryPoint;
if (info.Length() <= (0) || !info[0]->IsString())
return ThrowTypeError(
"Expected "
"first"
" argument to be "
"a string");
v8 ::Local<v8 ::String> filename = (info[0].As<v8 ::String>());
if (info.Length() > 1) {
if (info.Length() <= (1) || !info[1]->IsString())
return ThrowTypeError(
"Expected "
"second"
" argument to be "
"a string");
entryPoint = (info[1].As<v8 ::String>());
}
if (!db->open)
return ThrowTypeError("The database connection is not open");
if (db->busy)
return ThrowTypeError("This database connection is busy executing a query");
if (db->iterators)
return ThrowTypeError("This database connection is busy executing a query");
v8 ::Isolate* isolate = info.GetIsolate();
char* error;
int status = sqlite3_load_extension(
db->db_handle, *v8::String::Utf8Value(isolate, filename),
entryPoint.IsEmpty() ? NULL : *v8::String::Utf8Value(isolate, entryPoint),
&error);
if (status != SQLITE_OK) {
ThrowSqliteError(db->addon, error, status);
}
sqlite3_free(error);
}
void Database::JS_close(v8::FunctionCallbackInfo<v8 ::Value> const& info) {
Database* db = node ::ObjectWrap ::Unwrap<Database>(info.This());
if (db->open) {

View File

@ -192,8 +192,6 @@ class Database : public node::ObjectWrap {
static void JS_function(v8::FunctionCallbackInfo<v8 ::Value> const& info);
static void JS_aggregate(v8::FunctionCallbackInfo<v8 ::Value> const& info);
static void JS_table(v8::FunctionCallbackInfo<v8 ::Value> const& info);
static void JS_loadExtension(
v8::FunctionCallbackInfo<v8 ::Value> const& info);
static void JS_close(v8::FunctionCallbackInfo<v8 ::Value> const& info);
static void JS_defaultSafeIntegers(
v8::FunctionCallbackInfo<v8 ::Value> const& info);

View File

@ -1,75 +0,0 @@
'use strict';
const fs = require('fs');
const path = require('path');
const Database = require('../.');
describe('Database#loadExtension()', function () {
let filepath;
before(function () {
const releaseFilepath = path.join(__dirname, '..', 'build', 'Release', 'test_extension.node');
const debugFilepath = path.join(__dirname, '..', 'build', 'Debug', 'test_extension.node');
try {
fs.accessSync(releaseFilepath);
filepath = releaseFilepath;
} catch (_) {
fs.accessSync(debugFilepath);
filepath = debugFilepath;
}
});
beforeEach(function () {
this.db = new Database(util.next());
});
afterEach(function () {
this.db.close();
});
it('should throw an exception if a string argument is not given', function () {
expect(() => this.db.loadExtension()).to.throw(TypeError);
expect(() => this.db.loadExtension(undefined)).to.throw(TypeError);
expect(() => this.db.loadExtension(null)).to.throw(TypeError);
expect(() => this.db.loadExtension(123)).to.throw(TypeError);
expect(() => this.db.loadExtension(new String(filepath))).to.throw(TypeError);
expect(() => this.db.loadExtension([filepath])).to.throw(TypeError);
});
it('should throw an exception if the database is busy', function () {
let invoked = false;
for (const value of this.db.prepare('select 555').pluck().iterate()) {
expect(value).to.equal(555);
expect(() => this.db.loadExtension(filepath)).to.throw(TypeError);
invoked = true;
}
expect(invoked).to.be.true;
});
it('should throw an exception if the extension is not found', function () {
try {
this.db.loadExtension(filepath + 'x');
} catch (err) {
expect(err).to.be.an.instanceof(Database.SqliteError);
expect(err.message).to.be.a('string');
expect(err.message.length).to.be.above(0);
expect(err.message).to.not.equal('not an error');
expect(err.code).to.equal('SQLITE_ERROR');
return;
}
throw new Error('This code should not have been reached');
});
it('should register the specified extension', function () {
expect(this.db.loadExtension(filepath)).to.equal(this.db);
expect(this.db.prepare('SELECT testExtensionFunction(NULL, 123, 99, 2)').pluck().get()).to.equal(4);
expect(this.db.prepare('SELECT testExtensionFunction(NULL, 2)').pluck().get()).to.equal(2);
});
it('should not allow registering extensions with SQL', function () {
expect(() => this.db.prepare('SELECT load_extension(?)').get(filepath)).to.throw(Database.SqliteError);
expect(this.db.loadExtension(filepath)).to.equal(this.db);
expect(() => this.db.prepare('SELECT load_extension(?)').get(filepath)).to.throw(Database.SqliteError);
this.db.close();
this.db = new Database(util.next());
try {
this.db.loadExtension(filepath + 'x');
} catch (err) {
expect(() => this.db.prepare('SELECT load_extension(?)').get(filepath)).to.throw(Database.SqliteError);
return;
}
throw new Error('This code should not have been reached');
});
});

View File

@ -187,33 +187,6 @@ describe('integrity checks', function () {
});
});
describe('Database#loadExtension()', function () {
let filepath;
before(function () {
const releaseFilepath = path.join(__dirname, '..', 'build', 'Release', 'test_extension.node');
const debugFilepath = path.join(__dirname, '..', 'build', 'Debug', 'test_extension.node');
try {
fs.accessSync(releaseFilepath);
filepath = releaseFilepath;
} catch (_) {
fs.accessSync(debugFilepath);
filepath = debugFilepath;
}
});
specify('while iterating (blocked)', function () {
whileIterating(this, blocked(() => this.db.loadExtension(filepath)));
normally(allowed(() => this.db.loadExtension(filepath)));
});
specify('while busy (blocked)', function () {
whileBusy(this, blocked(() => this.db.loadExtension(filepath)));
normally(allowed(() => this.db.loadExtension(filepath)));
});
specify('while closed (blocked)', function () {
whileClosed(this, blocked(() => this.db.loadExtension(filepath)));
});
});
describe('Database#close()', function () {
specify('while iterating (blocked)', function () {
whileIterating(this, blocked(() => this.db.close()));