diff --git a/lib/index.ts b/lib/index.ts index aa18e9a..8b564b6 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -42,6 +42,7 @@ const addon = bindings<{ statementClose(stmt: NativeStatement): void; databaseOpen(path: string): NativeDatabase; + databaseInitTokenizer(db: NativeDatabase): void; databaseExec(db: NativeDatabase, query: string): void; databaseClose(db: NativeDatabase): void; @@ -350,6 +351,13 @@ export default class Database { this.#isCacheEnabled = cacheStatements === true; } + public initTokenizer(): void { + if (this.#native === undefined) { + throw new Error('Database closed'); + } + addon.databaseInitTokenizer(this.#native); + } + /** * Execute one or multiple SQL statements in a given `sql` string. * diff --git a/src/addon.cc b/src/addon.cc index e7cacb5..912af62 100644 --- a/src/addon.cc +++ b/src/addon.cc @@ -98,6 +98,8 @@ Napi::Error FormatError(Napi::Env env, const char* format, ...) { Napi::Object Database::Init(Napi::Env env, Napi::Object exports) { exports["databaseOpen"] = Napi::Function::New(env, &Database::Open); + exports["databaseInitTokenizer"] = + Napi::Function::New(env, &Database::InitTokenizer); exports["databaseClose"] = Napi::Function::New(env, &Database::Close); exports["databaseExec"] = Napi::Function::New(env, &Database::Exec); return exports; @@ -159,20 +161,32 @@ Napi::Value Database::Open(const Napi::CallbackInfo& info) { return db->ThrowSqliteError(env, r); } + return db->self_ref_.Value(); +} + +Napi::Value Database::InitTokenizer(const Napi::CallbackInfo& info) { + auto env = info.Env(); + + auto db = FromExternal(info[0]); + if (db == nullptr) { + return Napi::Value(); + } + fts5_api* fts5 = db->GetFTS5API(env); if (fts5 == nullptr) { return Napi::Value(); } SignalTokenizerModule* icu = new SignalTokenizerModule(); - r = fts5->xCreateTokenizer(fts5, "signal_tokenizer", icu, &icu->api_object, + int r = + fts5->xCreateTokenizer(fts5, "signal_tokenizer", icu, &icu->api_object, &SignalTokenizerModule::Destroy); if (r != SQLITE_OK) { delete icu; return db->ThrowSqliteError(env, r); } - return db->self_ref_.Value(); + return Napi::Value(); } Napi::Value Database::Close(const Napi::CallbackInfo& info) { diff --git a/src/addon.h b/src/addon.h index 425c259..54270b0 100644 --- a/src/addon.h +++ b/src/addon.h @@ -27,6 +27,7 @@ class Database { static Database* FromExternal(const Napi::Value value); static Napi::Value Open(const Napi::CallbackInfo& info); + static Napi::Value InitTokenizer(const Napi::CallbackInfo& info); static Napi::Value Close(const Napi::CallbackInfo& info); static Napi::Value Exec(const Napi::CallbackInfo& info); diff --git a/test/memory.test.ts b/test/memory.test.ts index bc0e35e..3bb5a02 100644 --- a/test/memory.test.ts +++ b/test/memory.test.ts @@ -380,6 +380,18 @@ test('bigint mode', () => { ).toEqual(n); }); +test('tokenizer setup', () => { + db.initTokenizer(); +}); + +test('tokenizer setup after close', () => { + db.close(); + expect(() => db.initTokenizer()).toThrowError('Database closed'); + + // Just to fix afterEach + db = new Database(); +}); + test('signalTokenize', () => { expect(db.signalTokenize('a b c')).toEqual(['a', 'b', 'c']); });