Skip to content

fix: Migrate from better-sqlite3 to node-sqlite3-wasm #2246

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"@eslint/js": "~8.57.0",
"@octokit/types": "^11.1.0",
"@swc/core": "^1.3.76",
"@types/better-sqlite3": "^7.6.11",
"@types/cors": "^2.8.17",
"@types/fs-extra": "^9.0.13",
"@types/gitconfiglocal": "^2.0.1",
Expand Down Expand Up @@ -103,7 +102,6 @@
"applicationinsights": "^2.1.4",
"async": "^3.2.4",
"axios": "^0.27.2",
"better-sqlite3": "^11.5.0",
"body-parser": "^1.20.2",
"boxen": "^5.0.1",
"chalk": "^4.1.2",
Expand Down Expand Up @@ -131,6 +129,7 @@
"lunr": "^2.3.9",
"minimatch": "^5.1.2",
"moo": "^0.5.1",
"node-sqlite3-wasm": "^0.8.34",
"open": "^8.2.1",
"openapi-diff": "^0.23.6",
"openapi-types": "^12.1.3",
Expand Down Expand Up @@ -167,9 +166,7 @@
"resources",
"built/appmap.html",
"built/sequenceDiagram.html",
"built/docs",
"../../node_modules/better-sqlite3/build/Release/better_sqlite3.node",
"node_modules/better-sqlite3/build/Release/better_sqlite3.node"
"built/docs"
],
"outputPath": "dist"
},
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/cmds/search/search.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sqlite3 from 'node-sqlite3-wasm';
import yargs from 'yargs';
import sqlite3 from 'better-sqlite3';
import assert from 'assert';
import { readFileSync } from 'fs';
import { writeFile } from 'fs/promises';
Expand Down Expand Up @@ -186,7 +186,7 @@ export const handler = async (argv: ArgumentTypes) => {
};

const index = await buildIndexInTempDir('appmaps', async (indexFile) => {
const db = new sqlite3(indexFile);
const db = new sqlite3.Database(indexFile);
const fileIndex = new FileIndex(db);
await buildAppMapIndex(fileIndex, [process.cwd()]);
return fileIndex;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/rpc/explain/index-files.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sqlite3 from 'better-sqlite3';
import type sqlite3 from 'node-sqlite3-wasm';

import {
buildFileIndex,
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/rpc/explain/index-snippets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sqlite3 from 'node-sqlite3-wasm';

import {
buildSnippetIndex,
FileSearchResult,
Expand All @@ -6,7 +8,6 @@ import {
readFileSafe,
SnippetIndex,
} from '@appland/search';
import sqlite3 from 'better-sqlite3';

export default async function indexSnippets(
db: sqlite3.Database,
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/rpc/explain/index/appmap-file-index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sqlite3 from 'better-sqlite3';
import sqlite3 from 'node-sqlite3-wasm';

import { FileIndex, SessionId } from '@appland/search';

Expand All @@ -10,7 +10,7 @@ export async function buildAppMapFileIndex(
appmapDirectories: string[]
): Promise<CloseableIndex<FileIndex>> {
return await buildIndexInTempDir<FileIndex>('appmaps', async (indexFile) => {
const db = new sqlite3(indexFile);
const db = new sqlite3.Database(indexFile);
const fileIndex = new FileIndex(db);
await buildAppMapIndex(fileIndex, appmapDirectories);
return fileIndex;
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/rpc/explain/index/project-file-index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sqlite3 from 'better-sqlite3';
import makeDebug from 'debug';
import sqlite3 from 'node-sqlite3-wasm';

import {
buildFileIndex,
Expand Down Expand Up @@ -71,7 +71,7 @@ export async function buildProjectFileIndex(
excludePatterns: RegExp[] | undefined
): Promise<CloseableIndex<FileIndex>> {
return await buildIndexInTempDir('files', async (indexFile) => {
const db = new sqlite3(indexFile);
const db = new sqlite3.Database(indexFile);
return await indexFiles(db, sourceDirectories, includePatterns, excludePatterns);
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sqlite3 from 'better-sqlite3';
import sqlite3 from 'node-sqlite3-wasm';

import { FileSearchResult, SessionId, SnippetIndex } from '@appland/search';

import buildIndexInTempDir, { CloseableIndex } from './build-index-in-temp-dir';
Expand Down Expand Up @@ -76,7 +77,7 @@ export async function buildProjectFileSnippetIndex(
fileSearchResults: FileSearchResult[]
): Promise<ProjectFileSnippetIndex> {
const snippetIndex = await buildIndexInTempDir('snippets', async (indexFile) => {
const db = new sqlite3(indexFile);
const db = new sqlite3.Database(indexFile);
return await indexSnippets(db, fileSearchResults);
});

Expand Down
6 changes: 4 additions & 2 deletions packages/cli/src/rpc/search/search.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { isAbsolute, join } from 'path';
import sqlite3 from 'better-sqlite3';

import sqlite3 from 'node-sqlite3-wasm';

import { FileIndex, generateSessionId } from '@appland/search';
import { SearchRpc } from '@appland/rpc';

Expand Down Expand Up @@ -62,7 +64,7 @@ export async function handler(
// Search across all AppMaps, creating a map from AppMap id to AppMapSearchResult
const maxResults = options.maxDiagrams || options.maxResults || DEFAULT_MAX_DIAGRAMS;
const index = await buildIndexInTempDir('appmaps', async (indexFile) => {
const db = new sqlite3(indexFile);
const db = new sqlite3.Database(indexFile);
const fileIndex = new FileIndex(db);
await buildAppMapIndex(
fileIndex,
Expand Down
3 changes: 1 addition & 2 deletions packages/search/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"author": "AppLand, Inc",
"license": "Commons Clause + MIT",
"devDependencies": {
"@types/better-sqlite3": "^7.6.11",
"@types/jest": "^29.5.4",
"@types/node": "^16",
"eslint": "^9",
Expand All @@ -39,8 +38,8 @@
"typescript-eslint": "^8.11.0"
},
"dependencies": {
"better-sqlite3": "^11.5.0",
"isbinaryfile": "^5.0.4",
"node-sqlite3-wasm": "^0.8.34",
"yargs": "^17.7.2"
}
}
4 changes: 2 additions & 2 deletions packages/search/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import sqlite3 from 'better-sqlite3';
import makeDebug from 'debug';
import sqlite3 from 'node-sqlite3-wasm';

import { fileTokens } from './tokenize';
import FileIndex from './file-index';
Expand Down Expand Up @@ -62,7 +62,7 @@ const cli = yargs(hideBin(process.argv))
return !filterRE.test(path);
};

const db = new sqlite3(':memory:');
const db = new sqlite3.Database(':memory:');
const fileIndex = new FileIndex(db);
const sessionId = generateSessionId();

Expand Down
17 changes: 9 additions & 8 deletions packages/search/src/file-index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sqlite3 from 'better-sqlite3';
import type sqlite3 from 'node-sqlite3-wasm';

import { SessionId } from './session-id';

const CREATE_TABLE_SQL = `CREATE VIRTUAL TABLE file_content USING fts5(
Expand Down Expand Up @@ -74,22 +75,22 @@ export type FileSearchResult = {
export default class FileIndex {
#insert: sqlite3.Statement;
#updateBoost: sqlite3.Statement;
#deleteSession: sqlite3.Statement<string>;
#search: sqlite3.Statement<[string, string, number]>;
#deleteSession: sqlite3.Statement;
#search: sqlite3.Statement;

constructor(public database: sqlite3.Database) {
this.database.exec(CREATE_TABLE_SQL);
this.database.exec(CREATE_BOOST_TABLE_SQL);
this.database.pragma('journal_mode = OFF');
this.database.pragma('synchronous = OFF');
this.database.exec('PRAGMA journal_mode = OFF');
this.database.exec('PRAGMA synchronous = OFF');
this.#insert = this.database.prepare(INSERT_SQL);
this.#updateBoost = this.database.prepare(UPDATE_BOOST_SQL);
this.#deleteSession = this.database.prepare(DELETE_SESSION_SQL);
this.#search = this.database.prepare(SEARCH_SQL);
}

indexFile(directory: string, filePath: string, symbols: string, words: string): void {
this.#insert.run(directory, filePath, symbols, words);
this.#insert.run([directory, filePath, symbols, words]);
}

/**
Expand All @@ -99,7 +100,7 @@ export default class FileIndex {
* @param boostFactor - The factor by which to boost the file's relevance.
*/
boostFile(sessionId: SessionId, filePath: string, boostFactor: number): void {
this.#updateBoost.run(sessionId, filePath, boostFactor);
this.#updateBoost.run([sessionId, filePath, boostFactor]);
}

/**
Expand All @@ -118,7 +119,7 @@ export default class FileIndex {
* @returns An array of search results with directory, file path, and score.
*/
search(sessionId: SessionId, query: string, limit = 10): FileSearchResult[] {
const rows = this.#search.all(sessionId, query, limit) as FileIndexRow[];
const rows = this.#search.all([sessionId, query, limit]) as FileIndexRow[];
return rows.map((row) => ({
directory: row.directory,
filePath: row.file_path,
Expand Down
2 changes: 1 addition & 1 deletion packages/search/src/git.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { exec as execCallback, spawn } from 'child_process';
import { exec as execCallback, spawn } from 'node:child_process';
import { PathLike } from 'fs';
import { promisify } from 'util';

Expand Down
18 changes: 10 additions & 8 deletions packages/search/src/snippet-index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import assert from 'assert';
import sqlite3 from 'better-sqlite3';

import type sqlite3 from 'node-sqlite3-wasm';

import { SessionId } from './session-id';

const CREATE_SNIPPET_CONTENT_TABLE_SQL = `CREATE VIRTUAL TABLE snippet_content USING fts5(
Expand Down Expand Up @@ -115,14 +117,14 @@ type SnippetSearchRow = {
export default class SnippetIndex {
#insertSnippet: sqlite3.Statement;
#updateSnippetBoost: sqlite3.Statement;
#deleteSession: sqlite3.Statement<[string]>;
#searchSnippet: sqlite3.Statement<[string, string, number]>;
#deleteSession: sqlite3.Statement;
#searchSnippet: sqlite3.Statement;

constructor(public database: sqlite3.Database) {
this.database.exec(CREATE_SNIPPET_CONTENT_TABLE_SQL);
this.database.exec(CREATE_SNIPPET_BOOST_TABLE_SQL);
this.database.pragma('journal_mode = OFF');
this.database.pragma('synchronous = OFF');
this.database.exec('PRAGMA journal_mode = OFF');
this.database.exec('PRAGMA synchronous = OFF');
this.#insertSnippet = this.database.prepare(INSERT_SNIPPET_SQL);
this.#deleteSession = this.database.prepare(DELETE_SESSION_SQL);
this.#updateSnippetBoost = this.database.prepare(UPDATE_SNIPPET_BOOST_SQL);
Expand Down Expand Up @@ -152,7 +154,7 @@ export default class SnippetIndex {
words: string,
content: string
): void {
this.#insertSnippet.run(encodeSnippetId(snippetId), directory, symbols, words, content);
this.#insertSnippet.run([encodeSnippetId(snippetId), directory, symbols, words, content]);
}

/**
Expand All @@ -162,11 +164,11 @@ export default class SnippetIndex {
* @param boostFactor - The factor by which to boost the snippet's relevance.
*/
boostSnippet(sessionId: SessionId, snippetId: SnippetId, boostFactor: number): void {
this.#updateSnippetBoost.run(sessionId, encodeSnippetId(snippetId), boostFactor);
this.#updateSnippetBoost.run([sessionId, encodeSnippetId(snippetId), boostFactor]);
}

searchSnippets(sessionId: SessionId, query: string, limit = 10): SnippetSearchResult[] {
const rows = this.#searchSnippet.all(sessionId, query, limit) as SnippetSearchRow[];
const rows = this.#searchSnippet.all([sessionId, query, limit]) as SnippetSearchRow[];
return rows.map((row) => ({
directory: row.directory,
snippetId: parseSnippetId(row.snippet_id),
Expand Down
6 changes: 4 additions & 2 deletions packages/search/test/file-index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { strict as assert } from 'assert';
import sqlite3 from 'better-sqlite3';

import sqlite3 from 'node-sqlite3-wasm';

import FileIndex, { FileSearchResult } from '../src/file-index';
import { generateSessionId, SessionId } from '../src/session-id';

Expand All @@ -16,7 +18,7 @@ describe('FileIndex', () => {
const directory = 'src';

beforeEach(() => {
db = new sqlite3(':memory:');
db = new sqlite3.Database(':memory:');
index = new FileIndex(db);
sessionId = generateSessionId();
});
Expand Down
5 changes: 3 additions & 2 deletions packages/search/test/snippet-index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { strict as assert } from 'assert';
import sqlite3 from 'better-sqlite3';

import sqlite3 from 'node-sqlite3-wasm';

import SnippetIndex, {
fileChunkSnippetId,
Expand All @@ -26,7 +27,7 @@ describe('SnippetIndex', () => {
const snippet4: SnippetId = { type: 'code-snippet', id: 'test4.txt:31' };

beforeEach(() => {
db = new sqlite3(':memory:');
db = new sqlite3.Database(':memory:');
index = new SnippetIndex(db);
sessionId = generateSessionId();
});
Expand Down
Loading
Loading