UNPKG

@gensx/storage

Version:

Cloud storage, blobs, sqlite, and vector database providers/hooks for GenSX.

1 lines 23.9 kB
{"version":3,"file":"filesystem.cjs","sources":["@gensx/storage/../../../../src/database/filesystem.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/only-throw-error */\n\nimport type { Client, InArgs, ResultSet } from \"@libsql/client\";\n\nimport * as fs from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport * as path from \"node:path\";\n\nconst LIBSQL_CLIENT = \"@libsql/client\";\nconst requireLibsql = createRequire(import.meta.url);\n\nfunction getLibsql() {\n try {\n return requireLibsql(LIBSQL_CLIENT) as typeof import(\"@libsql/client\");\n } catch {\n throw new Error(\n '@libsql/client is required to use local databases in @gensx/storage but is not installed. Install it as a dev dependency by running: npm install -d @libsql/client\\n\\nAlternatively, you can use cloud databases instead by setting the storage kind to \"cloud\" in your configuration.',\n );\n }\n}\n\nimport { fromBase64UrlSafe, toBase64UrlSafe } from \"../utils/base64.js\";\nimport {\n Database,\n DatabaseBatchResult,\n DatabaseConstraintError,\n DatabaseError,\n DatabaseInfo,\n DatabaseInternalError,\n DatabaseNotFoundError,\n DatabasePermissionDeniedError,\n DatabaseResult,\n DatabaseStatement,\n DatabaseStorage,\n DatabaseSyntaxError,\n DatabaseTableInfo,\n DeleteDatabaseResult,\n EnsureDatabaseResult,\n} from \"./types.js\";\n\n/**\n * Helper to convert between filesystem/libSQL errors and DatabaseErrors\n */\nfunction handleError(err: unknown, operation: string): never {\n if (err instanceof DatabaseError) {\n throw err;\n }\n\n if (err instanceof Error) {\n const nodeErr = err as NodeJS.ErrnoException;\n\n if (nodeErr.code === \"ENOENT\") {\n throw new DatabaseNotFoundError(\n `Database not found: ${String(err.message)}`,\n err,\n );\n } else if (nodeErr.code === \"EACCES\") {\n throw new DatabasePermissionDeniedError(\n `Permission denied for operation ${operation}: ${String(err.message)}`,\n err,\n );\n }\n\n // Handle libSQL specific errors\n const message = err.message.toLowerCase();\n\n if (message.includes(\"syntax error\")) {\n throw new DatabaseSyntaxError(\n `Syntax error in ${operation}: ${err.message}`,\n err,\n );\n }\n\n if (\n message.includes(\"constraint failed\") ||\n message.includes(\"unique constraint\") ||\n message.includes(\"foreign key constraint\")\n ) {\n throw new DatabaseConstraintError(\n `Constraint violation in ${operation}: ${err.message}`,\n err,\n );\n }\n }\n\n // Default error case\n throw new DatabaseInternalError(\n `Error during ${operation}: ${String(err)}`,\n err as Error,\n );\n}\n\n/**\n * Convert libSQL ResultSet to our DatabaseResult format\n */\nfunction mapResult(result: ResultSet): DatabaseResult {\n return {\n columns: result.columns,\n rows: result.rows.map((row) => Object.values(row)),\n rowsAffected: result.rowsAffected,\n lastInsertId: result.lastInsertRowid\n ? Number(result.lastInsertRowid)\n : undefined,\n };\n}\n\n/**\n * Implementation of Database interface for filesystem storage\n */\nexport class FileSystemDatabase implements Database {\n private client: Client;\n private dbPath: string;\n private dbName: string;\n\n constructor(rootPath: string, dbName: string) {\n this.dbName = dbName;\n this.dbPath = path.join(rootPath, `${dbName}.db`);\n const { createClient } = getLibsql();\n this.client = createClient({ url: `file:${this.dbPath}` });\n }\n\n async execute(sql: string, params?: InArgs): Promise<DatabaseResult> {\n try {\n const result = await this.client.execute({\n sql,\n args: params,\n });\n\n return mapResult(result);\n } catch (err) {\n throw handleError(err, \"execute\");\n }\n }\n\n async batch(statements: DatabaseStatement[]): Promise<DatabaseBatchResult> {\n try {\n const results: DatabaseResult[] = [];\n\n // Create a transaction with explicit write mode\n const transactionPromise = this.client.transaction(\"write\");\n const transaction = await transactionPromise;\n\n try {\n // Execute each statement within the transaction\n for (const statement of statements) {\n const result = await transaction.execute({\n sql: statement.sql,\n args: statement.params,\n });\n\n results.push(mapResult(result));\n }\n\n // Commit the transaction if all statements succeeded\n await transaction.commit();\n return { results };\n } catch (err) {\n // Transaction will be rolled back in the finally block\n throw err;\n } finally {\n // Always close the transaction\n transaction.close();\n }\n } catch (err) {\n throw handleError(err, \"batch\");\n }\n }\n\n async executeMultiple(sql: string): Promise<DatabaseBatchResult> {\n try {\n // Split the SQL by semicolons, ignoring those in quotes or comments\n const statements = sql\n .split(\";\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((s) => ({ sql: `${s};` }));\n\n const results: DatabaseResult[] = [];\n\n // Execute each statement without transaction\n for (const statement of statements) {\n try {\n const result = await this.client.execute({ sql: statement.sql });\n results.push(mapResult(result));\n } catch (_) {\n // If one statement fails, we still try to execute the others\n results.push({\n columns: [],\n rows: [],\n rowsAffected: 0,\n lastInsertId: undefined,\n });\n }\n }\n\n return { results };\n } catch (err) {\n throw handleError(err, \"executeMultiple\");\n }\n }\n\n async migrate(sql: string): Promise<DatabaseBatchResult> {\n try {\n // Disable foreign keys, run migrations, then re-enable foreign keys\n const results: DatabaseResult[] = [];\n\n // Disable foreign keys\n const disableResult = await this.client.execute({\n sql: \"PRAGMA foreign_keys = OFF;\",\n });\n results.push(mapResult(disableResult));\n\n // Split and execute migration statements\n const migrationStatements = sql\n .split(\";\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .map((s) => ({ sql: `${s};` }));\n\n // Execute migrations\n for (const statement of migrationStatements) {\n try {\n const result = await this.client.execute({ sql: statement.sql });\n results.push(mapResult(result));\n } catch (err) {\n // Re-enable foreign keys before rethrowing\n await this.client.execute({ sql: \"PRAGMA foreign_keys = ON;\" });\n throw err;\n }\n }\n\n // Re-enable foreign keys\n const enableResult = await this.client.execute({\n sql: \"PRAGMA foreign_keys = ON;\",\n });\n results.push(mapResult(enableResult));\n\n return { results };\n } catch (err) {\n throw handleError(err, \"migrate\");\n }\n }\n\n async getInfo(): Promise<DatabaseInfo> {\n try {\n // Get file stats\n let stats;\n try {\n stats = await fs.stat(this.dbPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n // Database file doesn't exist yet, return minimal info\n return {\n name: this.dbName,\n size: 0,\n lastModified: new Date(),\n tables: [],\n };\n }\n throw err;\n }\n\n // Get table information\n const tablesResult = await this.client.execute({\n sql: \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';\",\n });\n\n const tables: DatabaseTableInfo[] = [];\n\n for (const row of tablesResult.rows) {\n const tableName = row.name as string;\n\n // Get column information for this table\n const columnsResult = await this.client.execute({\n sql: `PRAGMA table_info(${tableName});`,\n });\n\n const columns = columnsResult.rows.map((col) => ({\n name: col.name as string,\n type: col.type as string,\n notNull: Boolean(col.notnull),\n defaultValue: col.dflt_value,\n primaryKey: Boolean(col.pk),\n }));\n\n tables.push({\n name: tableName,\n columns,\n });\n }\n\n return {\n name: this.dbName,\n size: stats.size,\n lastModified: stats.mtime,\n tables,\n };\n } catch (err) {\n throw handleError(err, \"getInfo\");\n }\n }\n\n close() {\n try {\n this.client.close();\n } catch (err) {\n throw handleError(err, \"close\");\n }\n }\n}\n\n/**\n * Implementation of DatabaseStorage interface for filesystem storage\n */\nexport class FileSystemDatabaseStorage implements DatabaseStorage {\n private databases = new Map<string, FileSystemDatabase>();\n\n constructor(private rootPath: string) {\n // Ensure rootPath exists on instantiation\n void this.ensureRootDir();\n }\n\n /**\n * Ensure the root directory exists\n */\n private async ensureRootDir(): Promise<void> {\n try {\n await fs.mkdir(this.rootPath, { recursive: true });\n } catch (err) {\n throw handleError(err, \"ensureRootDir\");\n }\n }\n\n getDatabase(name: string): Database {\n let db = this.databases.get(name);\n if (!db) {\n db = new FileSystemDatabase(this.rootPath, name);\n this.databases.set(name, db);\n }\n return db;\n }\n\n async listDatabases(options?: { limit?: number; cursor?: string }): Promise<{\n databases: { name: string; createdAt: Date }[];\n nextCursor?: string;\n }> {\n try {\n const files = await fs.readdir(this.rootPath);\n\n // Filter for .db files and remove extension\n let dbFiles = files\n .filter((file) => file.endsWith(\".db\"))\n .map((file) => file.slice(0, -3)); // Remove .db extension\n\n // Sort files for consistent pagination\n dbFiles.sort();\n\n // If cursor is provided, start after that file\n if (options?.cursor) {\n const lastFile = fromBase64UrlSafe(options.cursor);\n const startIndex = dbFiles.findIndex((file) => file > lastFile);\n if (startIndex !== -1) {\n dbFiles = dbFiles.slice(startIndex);\n } else {\n dbFiles = [];\n }\n }\n\n // Apply limit if provided\n let nextCursor: string | undefined;\n if (options?.limit && options.limit < dbFiles.length) {\n const limitedFiles = dbFiles.slice(0, options.limit);\n // Set cursor to last file for next page\n nextCursor = toBase64UrlSafe(limitedFiles[limitedFiles.length - 1]);\n dbFiles = limitedFiles;\n }\n\n // Get creation dates for each database file\n const databases = await Promise.all(\n dbFiles.map(async (file) => {\n const filePath = path.join(this.rootPath, `${file}.db`);\n const stats = await fs.stat(filePath);\n return {\n name: file,\n createdAt: stats.birthtime,\n };\n }),\n );\n\n return {\n databases,\n ...(nextCursor && { nextCursor }),\n };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return {\n databases: [],\n };\n }\n throw handleError(err, \"listDatabases\");\n }\n }\n\n async ensureDatabase(name: string): Promise<EnsureDatabaseResult> {\n try {\n const dbPath = path.join(this.rootPath, `${name}.db`);\n\n // First check if database file exists\n let exists = false;\n try {\n await fs.access(dbPath);\n exists = true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw err;\n }\n }\n\n if (exists) {\n // If it exists, make sure it's in our cache\n if (!this.databases.has(name)) {\n this.getDatabase(name);\n }\n return { exists: true, created: false };\n }\n\n // Ensure the directory exists\n await this.ensureRootDir();\n\n // Create an empty database by getting a database instance\n // which will initialize the file\n const db = this.getDatabase(name);\n\n // Execute a simple query to ensure the file is created\n await db.execute(\"SELECT 1\");\n\n return { exists: false, created: true };\n } catch (err) {\n throw handleError(err, \"ensureDatabase\");\n }\n }\n\n async deleteDatabase(name: string): Promise<DeleteDatabaseResult> {\n try {\n const dbPath = path.join(this.rootPath, `${name}.db`);\n\n // Close any open connection to this database\n if (this.databases.has(name)) {\n const db = this.databases.get(name)!;\n db.close();\n this.databases.delete(name);\n }\n\n // Check if file exists\n try {\n await fs.access(dbPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { deleted: false };\n }\n throw err;\n }\n\n // Delete the file\n await fs.unlink(dbPath);\n return { deleted: true };\n } catch (err) {\n throw handleError(err, \"deleteDatabase\");\n }\n }\n\n hasEnsuredDatabase(name: string): boolean {\n return this.databases.has(name);\n }\n}\n"],"names":["createRequire","DatabaseError","DatabaseNotFoundError","DatabasePermissionDeniedError","DatabaseSyntaxError","DatabaseConstraintError","DatabaseInternalError","path","fs","fromBase64UrlSafe","toBase64UrlSafe"],"mappings":"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"}