mirror of
https://github.com/czlonkowski/n8n-mcp.git
synced 2026-02-06 21:43:07 +00:00
fix: pre-build FTS5 index for Docker compatibility
- Add FTS5 pre-creation in fetch-templates.ts before data import - Create prebuild-fts5.ts script to ensure FTS5 tables exist - Improve logging in template-repository.ts for better debugging - Add npm script 'prebuild:fts5' for manual FTS5 setup This ensures template search works consistently in Docker mode where runtime FTS5 table creation might fail due to permissions. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -38,37 +38,62 @@ export class TemplateRepository {
|
||||
|
||||
if (this.hasFTS5Support) {
|
||||
try {
|
||||
// Create FTS5 virtual table
|
||||
this.db.exec(`
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS templates_fts USING fts5(
|
||||
name, description, content=templates
|
||||
);
|
||||
`);
|
||||
// Check if FTS5 table already exists
|
||||
const ftsExists = this.db.prepare(`
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='templates_fts'
|
||||
`).get() as { name: string } | undefined;
|
||||
|
||||
// Create triggers to keep FTS5 in sync
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_ai AFTER INSERT ON templates BEGIN
|
||||
INSERT INTO templates_fts(rowid, name, description)
|
||||
VALUES (new.id, new.name, new.description);
|
||||
END;
|
||||
`);
|
||||
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_au AFTER UPDATE ON templates BEGIN
|
||||
UPDATE templates_fts SET name = new.name, description = new.description
|
||||
WHERE rowid = new.id;
|
||||
END;
|
||||
`);
|
||||
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_ad AFTER DELETE ON templates BEGIN
|
||||
DELETE FROM templates_fts WHERE rowid = old.id;
|
||||
END;
|
||||
`);
|
||||
|
||||
logger.info('FTS5 support enabled for template search');
|
||||
} catch (error) {
|
||||
logger.warn('Failed to initialize FTS5 for templates:', error);
|
||||
if (ftsExists) {
|
||||
logger.info('FTS5 table already exists for templates');
|
||||
|
||||
// Verify FTS5 is working by doing a test query
|
||||
try {
|
||||
const testCount = this.db.prepare('SELECT COUNT(*) as count FROM templates_fts').get() as { count: number };
|
||||
logger.info(`FTS5 enabled with ${testCount.count} indexed entries`);
|
||||
} catch (testError) {
|
||||
logger.warn('FTS5 table exists but query failed:', testError);
|
||||
this.hasFTS5Support = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Create FTS5 virtual table
|
||||
logger.info('Creating FTS5 virtual table for templates...');
|
||||
this.db.exec(`
|
||||
CREATE VIRTUAL TABLE IF NOT EXISTS templates_fts USING fts5(
|
||||
name, description, content=templates
|
||||
);
|
||||
`);
|
||||
|
||||
// Create triggers to keep FTS5 in sync
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_ai AFTER INSERT ON templates BEGIN
|
||||
INSERT INTO templates_fts(rowid, name, description)
|
||||
VALUES (new.id, new.name, new.description);
|
||||
END;
|
||||
`);
|
||||
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_au AFTER UPDATE ON templates BEGIN
|
||||
UPDATE templates_fts SET name = new.name, description = new.description
|
||||
WHERE rowid = new.id;
|
||||
END;
|
||||
`);
|
||||
|
||||
this.db.exec(`
|
||||
CREATE TRIGGER IF NOT EXISTS templates_ad AFTER DELETE ON templates BEGIN
|
||||
DELETE FROM templates_fts WHERE rowid = old.id;
|
||||
END;
|
||||
`);
|
||||
|
||||
logger.info('FTS5 support enabled for template search');
|
||||
}
|
||||
} catch (error: any) {
|
||||
logger.warn('Failed to initialize FTS5 for templates:', {
|
||||
message: error.message,
|
||||
code: error.code,
|
||||
stack: error.stack
|
||||
});
|
||||
this.hasFTS5Support = false;
|
||||
}
|
||||
} else {
|
||||
@@ -158,25 +183,36 @@ export class TemplateRepository {
|
||||
* Search templates by name or description
|
||||
*/
|
||||
searchTemplates(query: string, limit: number = 20): StoredTemplate[] {
|
||||
logger.debug(`Searching templates for: "${query}" (FTS5: ${this.hasFTS5Support})`);
|
||||
|
||||
// If FTS5 is not supported, go straight to LIKE search
|
||||
if (!this.hasFTS5Support) {
|
||||
logger.debug('Using LIKE search (FTS5 not available)');
|
||||
return this.searchTemplatesLIKE(query, limit);
|
||||
}
|
||||
|
||||
try {
|
||||
// Use FTS for search
|
||||
const ftsQuery = query.split(' ').map(term => `"${term}"`).join(' OR ');
|
||||
logger.debug(`FTS5 query: ${ftsQuery}`);
|
||||
|
||||
return this.db.prepare(`
|
||||
const results = this.db.prepare(`
|
||||
SELECT t.* FROM templates t
|
||||
JOIN templates_fts ON t.id = templates_fts.rowid
|
||||
WHERE templates_fts MATCH ?
|
||||
ORDER BY rank, t.views DESC
|
||||
LIMIT ?
|
||||
`).all(ftsQuery, limit) as StoredTemplate[];
|
||||
|
||||
logger.debug(`FTS5 search returned ${results.length} results`);
|
||||
return results;
|
||||
} catch (error: any) {
|
||||
// If FTS5 query fails, fallback to LIKE search
|
||||
logger.warn('FTS5 template search failed, using LIKE fallback:', error.message);
|
||||
logger.warn('FTS5 template search failed, using LIKE fallback:', {
|
||||
message: error.message,
|
||||
query: query,
|
||||
ftsQuery: query.split(' ').map(term => `"${term}"`).join(' OR ')
|
||||
});
|
||||
return this.searchTemplatesLIKE(query, limit);
|
||||
}
|
||||
}
|
||||
@@ -186,13 +222,17 @@ export class TemplateRepository {
|
||||
*/
|
||||
private searchTemplatesLIKE(query: string, limit: number = 20): StoredTemplate[] {
|
||||
const likeQuery = `%${query}%`;
|
||||
logger.debug(`Using LIKE search with pattern: ${likeQuery}`);
|
||||
|
||||
return this.db.prepare(`
|
||||
const results = this.db.prepare(`
|
||||
SELECT * FROM templates
|
||||
WHERE name LIKE ? OR description LIKE ?
|
||||
ORDER BY views DESC, created_at DESC
|
||||
LIMIT ?
|
||||
`).all(likeQuery, likeQuery, limit) as StoredTemplate[];
|
||||
|
||||
logger.debug(`LIKE search returned ${results.length} results`);
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user