@dbcube/core 5.1.15 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/bin.cjs +7 -3
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +7 -3
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +182 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +113 -47
- package/dist/index.d.ts +113 -47
- package/dist/index.js +182 -86
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/Engine.ts","../src/lib/Arquitecture.ts","../src/lib/Donwloader.ts","../src/lib/Binary.ts","../src/lib/Config.ts","../src/lib/DaemonClient.ts","../src/lib/QueryEngine.ts","../src/lib/SqliteExecutor.ts","../src/lib/DbConfig.ts","../src/lib/FileLogger.ts","../src/lib/Processors.ts"],"sourcesContent":["import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { spawn } from \"child_process\";\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport { DaemonClient } from './DaemonClient';\r\n\r\nclass Engine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private daemonFailed = false;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n this.timeout = timeout;\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n /**\r\n * Returns a connected DaemonClient for this database, or null when\r\n * daemon mode is disabled/unavailable (then callers use spawn mode).\r\n */\r\n private async getDaemon(): Promise<DaemonClient | null> {\r\n if (this.daemonFailed || !DaemonClient.isEnabled()) return null;\r\n await this.initializeBinary();\r\n if (!this.binary) return null;\r\n\r\n const binaryPath = this.binary['query_engine' as keyof BinaryType];\r\n if (!binaryPath) return null;\r\n\r\n const client = DaemonClient.get(this.name, binaryPath, this.arguments);\r\n const ok = await client.ensure();\r\n if (!ok) {\r\n this.daemonFailed = true; // don't retry on every query\r\n return null;\r\n }\r\n return client;\r\n }\r\n\r\n /**\r\n * Executes a DML plan. Uses the persistent daemon (sub-millisecond\r\n * overhead) when available; falls back to one-shot spawn otherwise.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.execute(dml, txId);\r\n } catch (error: any) {\r\n if (txId) throw error; // a transaction can't change transport mid-flight\r\n // fall through to spawn mode\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'execute', '--dml', JSON.stringify(dml)] as any);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.raw(query, params, txId);\r\n } catch (error: any) {\r\n if (txId) throw error;\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'raw', '--query', query, '--params', JSON.stringify(params)] as any);\r\n }\r\n\r\n /** Starts a transaction (daemon mode only). Returns the transaction id. */\r\n async beginTransaction(): Promise<string> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return daemon.begin();\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.commit(txId);\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.rollback(txId);\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', this.config.config.PORT,\r\n '--user', this.config.config.USER,\r\n '--password', this.config.config.PASSWORD,\r\n '--motor', this.config.type\r\n ];\r\n }\r\n return args;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n // Use __filename for CJS, process.cwd() for ESM\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: []) {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n stdoutBuffer += data.toString();\r\n console.log(stdoutBuffer)\r\n\r\n // Buscar respuesta JSON completa\r\n const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n stderrBuffer += data.toString();\r\n console.log(stderrBuffer)\r\n\r\n // Buscar respuesta JSON completa\r\n const match = stderrBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n}\r\n\r\nexport { Engine }","import * as os from 'os';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\n\r\ninterface SystemInfo {\r\n platform: string;\r\n arch: string;\r\n release: string;\r\n type: string;\r\n endianness: string;\r\n cpus: number;\r\n}\r\n\r\ninterface BinaryInfo {\r\n name: string;\r\n path: string;\r\n exists: boolean;\r\n executable: boolean;\r\n}\r\n\r\nclass Arquitecture {\r\n private systemInfo: SystemInfo;\r\n\r\n constructor() {\r\n this.systemInfo = this.detectSystemInfo();\r\n }\r\n\r\n /**\r\n * Detecta información completa del sistema\r\n */\r\n private detectSystemInfo(): SystemInfo {\r\n return {\r\n platform: os.platform(),\r\n arch: os.arch(),\r\n release: os.release(),\r\n type: os.type(),\r\n endianness: os.endianness(),\r\n cpus: os.cpus().length\r\n };\r\n }\r\n\r\n /**\r\n * Obtiene la plataforma normalizada\r\n */\r\n getPlatform(): string {\r\n const platform = this.systemInfo.platform;\r\n \r\n switch (platform) {\r\n case 'win32':\r\n return 'windows';\r\n case 'darwin':\r\n return 'macos';\r\n case 'linux':\r\n return 'linux';\r\n case 'freebsd':\r\n return 'freebsd';\r\n case 'openbsd':\r\n return 'openbsd';\r\n case 'sunos':\r\n return 'solaris';\r\n default:\r\n return platform;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene la arquitectura normalizada\r\n */\r\n getArchitecture(): string {\r\n const arch = this.systemInfo.arch;\r\n \r\n switch (arch) {\r\n case 'x64':\r\n return 'x86_64';\r\n case 'x32':\r\n case 'ia32':\r\n return 'i686';\r\n case 'arm64':\r\n return 'aarch64';\r\n case 'arm':\r\n return 'armv7';\r\n case 'ppc64':\r\n return 'powerpc64';\r\n case 'ppc':\r\n return 'powerpc';\r\n case 's390x':\r\n return 's390x';\r\n case 'mips':\r\n return 'mips';\r\n case 'mipsel':\r\n return 'mipsel';\r\n default:\r\n return arch;\r\n }\r\n }\r\n\r\n /**\r\n * Genera el nombre del binario basado en la arquitectura\r\n */\r\n getBinaryName(baseName: string): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n \r\n return `${baseName}-${platform}-${arch}${extension}`;\r\n }\r\n\r\n /**\r\n * Obtiene información completa del sistema\r\n */\r\n getSystemInfo(): SystemInfo {\r\n return { ...this.systemInfo };\r\n }\r\n\r\n /**\r\n * Obtiene el triple de destino (target triple) para Rust\r\n */\r\n getRustTargetTriple(): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n \r\n // Mapeo de plataformas y arquitecturas a target triples de Rust\r\n const targetMap: { [key: string]: string } = {\r\n 'linux-x86_64': 'x86_64-unknown-linux-gnu',\r\n 'linux-i686': 'i686-unknown-linux-gnu',\r\n 'linux-aarch64': 'aarch64-unknown-linux-gnu',\r\n 'linux-armv7': 'armv7-unknown-linux-gnueabihf',\r\n 'macos-x86_64': 'x86_64-apple-darwin',\r\n 'macos-aarch64': 'aarch64-apple-darwin',\r\n 'windows-x86_64': 'x86_64-pc-windows-msvc',\r\n 'windows-i686': 'i686-pc-windows-msvc',\r\n 'windows-aarch64': 'aarch64-pc-windows-msvc',\r\n 'freebsd-x86_64': 'x86_64-unknown-freebsd',\r\n };\r\n \r\n const key = `${platform}-${arch}`;\r\n return targetMap[key] || `${arch}-unknown-${platform}`;\r\n }\r\n\r\n /**\r\n * Muestra información detallada del sistema\r\n */\r\n printSystemInfo(): void {\r\n console.log('🖥️ System Information:');\r\n console.log('├─ Platform:', this.getPlatform());\r\n console.log('├─ Arquitecture:', this.getArchitecture());\r\n console.log('├─ OS Type:', this.systemInfo.type);\r\n console.log('├─ OS Release:', this.systemInfo.release);\r\n console.log('├─ Endianness:', this.systemInfo.endianness);\r\n console.log('├─ CPUs:', this.systemInfo.cpus);\r\n console.log('└─ Rust Target:', this.getRustTargetTriple());\r\n }\r\n}\r\n\r\nexport { \r\n Arquitecture, \r\n SystemInfo,\r\n BinaryInfo\r\n};","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport followRedirects from 'follow-redirects';\r\nconst { https } = followRedirects;\r\nimport * as unzipper from \"unzipper\";\r\nimport { IncomingMessage } from 'http';\r\nimport ora from \"ora\";\r\nimport chalk from \"chalk\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\ninterface DownloadProgress {\r\n downloaded: number;\r\n total: number;\r\n percentage: number;\r\n}\r\n\r\ninterface BinaryVersion {\r\n date_published: string;\r\n name: string;\r\n version: string;\r\n platforms: string[];\r\n download_url: string;\r\n}\r\n\r\nclass Downloader {\r\n private static mainSpinner: any = null;\r\n private static currentSpinner: any = null;\r\n private static readonly VERSION_URLS = {\r\n query: 'https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json',\r\n schema: 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json',\r\n sqlite: 'https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json'\r\n };\r\n\r\n /**\r\n * Fetch latest version from GitHub\r\n */\r\n private static async fetchLatestVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<string> {\r\n const url = this.VERSION_URLS[prefix];\r\n\r\n return new Promise((resolve, reject) => {\r\n https.get(url, (response: IncomingMessage) => {\r\n let data = '';\r\n\r\n response.on('data', (chunk) => {\r\n data += chunk;\r\n });\r\n\r\n response.on('end', () => {\r\n try {\r\n const versions: BinaryVersion[] = JSON.parse(data);\r\n if (versions && versions.length > 0) {\r\n // Get the latest version (first in array)\r\n resolve(versions[0].version);\r\n } else {\r\n reject(new Error('No versions found'));\r\n }\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n\r\n response.on('error', reject);\r\n }).on('error', reject);\r\n });\r\n }\r\n\r\n /**\r\n * Extract version from binary filename\r\n * Example: schema-engine-v1.0.0-windows-x64.exe -> v1.0.0\r\n */\r\n private static extractVersionFromFilename(filename: string): string | null {\r\n const match = filename.match(/-(v\\d+\\.\\d+\\.\\d+)-/);\r\n return match ? match[1] : null;\r\n }\r\n\r\n /**\r\n * Get local version of installed binary\r\n */\r\n private static getLocalVersion(binDir: string, prefix: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-v`);\r\n const binaryFile = files.find(f => binaryPattern.test(f));\r\n\r\n if (binaryFile) {\r\n return this.extractVersionFromFilename(binaryFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Compare versions (returns true if remote is newer)\r\n */\r\n private static isNewerVersion(localVersion: string | null, remoteVersion: string): boolean {\r\n if (!localVersion) return true; // No local version, download\r\n\r\n // Remove 'v' prefix if exists\r\n const cleanLocal = localVersion.replace(/^v/, '');\r\n const cleanRemote = remoteVersion.replace(/^v/, '');\r\n\r\n const localParts = cleanLocal.split('.').map(Number);\r\n const remoteParts = cleanRemote.split('.').map(Number);\r\n\r\n for (let i = 0; i < 3; i++) {\r\n if (remoteParts[i] > localParts[i]) return true;\r\n if (remoteParts[i] < localParts[i]) return false;\r\n }\r\n\r\n return false; // Versions are equal\r\n }\r\n\r\n /**\r\n * Delete old binary files\r\n */\r\n private static deleteOldBinary(binDir: string, prefix: string): void {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-`);\r\n\r\n files.forEach(file => {\r\n if (binaryPattern.test(file)) {\r\n const filePath = path.join(binDir, file);\r\n try {\r\n fs.unlinkSync(filePath);\r\n console.log(`🗑️ Deleted old binary: ${file}`);\r\n } catch (err) {\r\n console.warn(`⚠️ Could not delete: ${file}`);\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n // Ignore errors\r\n }\r\n }\r\n\r\n static get(prefix: string): BinaryType & { name: string; url: string; version: string } {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Note: This is a sync method, version will be \"latest\" placeholder\r\n // The actual version will be resolved during download\r\n const baseName = `${prefix}-engine-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-latest-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version: \"latest\",\r\n query_engine: binaryName,\r\n schema_engine: `${prefix}-engine-${plat}-${archSuffix}${platform === \"windows\" ? \".exe\" : \"\"}`\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Get binary info with actual version from GitHub\r\n */\r\n static async getWithVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<BinaryType & { name: string; url: string; version: string }> {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Fetch latest version from GitHub\r\n const version = await this.fetchLatestVersion(prefix);\r\n\r\n const baseName = `${prefix}-engine-${version}-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${version}-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version,\r\n query_engine: binaryName,\r\n schema_engine: binaryName\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n static async download(targetDir?: string): Promise<void> {\r\n const binDir = targetDir || this.getDefaultBinDir();\r\n fs.mkdirSync(binDir, { recursive: true });\r\n\r\n // Initialize main spinner\r\n this.mainSpinner = ora({\r\n text: chalk.blue('Verificando versiones de binarios...'),\r\n spinner: 'dots12'\r\n }).start();\r\n\r\n const binariesToProcess: Array<{ prefix: 'query' | 'schema' | 'sqlite'; needsUpdate: boolean; localVersion: string | null; remoteVersion: string }> = [];\r\n\r\n // Check versions for all engines\r\n for (const prefix of ['query', 'schema', 'sqlite'] as const) {\r\n try {\r\n const localVersion = this.getLocalVersion(binDir, prefix);\r\n const remoteVersion = await this.fetchLatestVersion(prefix);\r\n const needsUpdate = this.isNewerVersion(localVersion, remoteVersion);\r\n\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate,\r\n localVersion,\r\n remoteVersion\r\n });\r\n\r\n if (needsUpdate) {\r\n console.log(`\\n📦 ${prefix}-engine: ${localVersion || 'not installed'} → ${remoteVersion}`);\r\n } else if (localVersion) {\r\n console.log(`\\n✅ ${prefix}-engine: ${localVersion} (up to date)`);\r\n }\r\n } catch (error) {\r\n console.warn(`⚠️ Could not check version for ${prefix}-engine, will attempt download`);\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate: true,\r\n localVersion: null,\r\n remoteVersion: 'latest'\r\n });\r\n }\r\n }\r\n\r\n const binariesToDownload = binariesToProcess.filter(b => b.needsUpdate);\r\n\r\n if (binariesToDownload.length === 0) {\r\n this.mainSpinner.succeed(chalk.green('All binaries are up to date'));\r\n return;\r\n }\r\n\r\n // Show update progress\r\n this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);\r\n\r\n try {\r\n // Download and update binaries in parallel\r\n await Promise.all(binariesToDownload.map(async (binary) => {\r\n const maxRetries = 3;\r\n let attempt = 0;\r\n\r\n while (attempt <= maxRetries) {\r\n try {\r\n // Get binary info with version\r\n const binaryInfo = await this.getWithVersion(binary.prefix);\r\n\r\n if (!binaryInfo.name || !binaryInfo.url) {\r\n throw new Error(`Platform or architecture not supported for ${binary.prefix}`);\r\n }\r\n\r\n const tempZipPath = path.join(os.tmpdir(), `dbcube-${binary.prefix}-${Date.now()}.zip`);\r\n const finalBinaryPath = path.join(binDir, binaryInfo.name);\r\n\r\n // Delete old binary first\r\n this.deleteOldBinary(binDir, binary.prefix);\r\n\r\n // Download\r\n await this.downloadFileWithProgress(binaryInfo.url, tempZipPath, binary.prefix);\r\n\r\n // Extract\r\n await this.extractBinary(tempZipPath, finalBinaryPath, binary.prefix);\r\n\r\n console.log(`✅ ${binary.prefix}-engine updated to ${binary.remoteVersion}`);\r\n break;\r\n\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n\r\n if (attempt < maxRetries && (\r\n errorMessage.includes('ECONNRESET') ||\r\n errorMessage.includes('timeout') ||\r\n errorMessage.includes('ETIMEDOUT') ||\r\n errorMessage.includes('ENOTFOUND')\r\n )) {\r\n attempt++;\r\n console.log(`🔄 Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);\r\n await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 1000));\r\n } else {\r\n throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);\r\n }\r\n }\r\n }\r\n }));\r\n\r\n // Complete successfully\r\n this.mainSpinner.succeed(chalk.green('Binaries updated successfully'));\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n this.mainSpinner.fail(chalk.red(`Error updating binaries: ${errorMessage}`));\r\n throw error;\r\n }\r\n }\r\n\r\n private static updateMainProgress(binary: string, current: number, total: number, status: string, attempt?: number) {\r\n const progressBar = this.createProgressBar(current, total);\r\n const statusEmojis = {\r\n downloading: '📥',\r\n extracting: '📦',\r\n completed: '✅',\r\n exists: '✅',\r\n retrying: '🔄'\r\n };\r\n\r\n const statusMessages = {\r\n downloading: chalk.blue('descargando'),\r\n extracting: chalk.yellow('extrayendo'),\r\n completed: chalk.green('completado'),\r\n exists: chalk.gray('existe'),\r\n retrying: chalk.yellow(`reintentando (${attempt}/${3})`)\r\n };\r\n\r\n const emoji = statusEmojis[status as keyof typeof statusEmojis] || '📥';\r\n const message = statusMessages[status as keyof typeof statusMessages] || status;\r\n\r\n this.mainSpinner.text = `${progressBar} ${emoji} ${chalk.bold(binary)} - ${message}`;\r\n }\r\n\r\n private static createProgressBar(current: number, total: number, width: number = 20): string {\r\n const filled = Math.round((current / total) * width);\r\n const empty = width - filled;\r\n const filledBar = chalk.green('█'.repeat(filled));\r\n const emptyBar = chalk.gray('░'.repeat(empty));\r\n const percentage = chalk.bold(`${current}/${total}`);\r\n return `[${filledBar}${emptyBar}] ${percentage}`;\r\n }\r\n\r\n private static downloadFileWithProgress(url: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const request = https.get(url, { timeout: 0 }, (response: IncomingMessage) => {\r\n if (response.statusCode === 302 || response.statusCode === 301) {\r\n const redirectUrl = response.headers.location;\r\n if (redirectUrl) {\r\n return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(resolve).catch(reject);\r\n }\r\n }\r\n\r\n if (response.statusCode !== 200) {\r\n reject(new Error(`HTTP ${response.statusCode} para ${prefix}`));\r\n return;\r\n }\r\n\r\n const file = fs.createWriteStream(outputPath);\r\n const totalBytes = parseInt(response.headers['content-length'] || '0', 10);\r\n let downloadedBytes = 0;\r\n\r\n response.on('data', (chunk) => {\r\n downloadedBytes += chunk.length;\r\n file.write(chunk);\r\n\r\n if (totalBytes > 0) {\r\n const progress: DownloadProgress = {\r\n downloaded: downloadedBytes,\r\n total: totalBytes,\r\n percentage: (downloadedBytes / totalBytes) * 100\r\n };\r\n this.updateDownloadProgress(prefix, progress);\r\n }\r\n });\r\n\r\n response.on('end', () => {\r\n file.end();\r\n resolve();\r\n });\r\n\r\n response.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n\r\n file.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n });\r\n\r\n request.on('error', reject);\r\n request.on('timeout', () => {\r\n request.destroy();\r\n reject(new Error(`Timeout descargando ${prefix}`));\r\n });\r\n });\r\n }\r\n\r\n private static updateDownloadProgress(binary: string, progress: DownloadProgress) {\r\n const percentage = progress.percentage.toFixed(1);\r\n const downloaded = (progress.downloaded / 1024 / 1024).toFixed(1);\r\n const total = (progress.total / 1024 / 1024).toFixed(1);\r\n\r\n // Create a mini progress bar for the binary\r\n const barWidth = 15;\r\n const filled = Math.round((progress.percentage / 100) * barWidth);\r\n const empty = barWidth - filled;\r\n const progressBar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\r\n\r\n const progressText = `[${progressBar}] ${percentage}% (${downloaded}/${total}MB)`;\r\n this.mainSpinner.text = `📥 ${chalk.bold(binary)} - ${progressText}`;\r\n }\r\n\r\n private static extractBinary(zipPath: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n let extracted = false;\r\n\r\n fs.createReadStream(zipPath)\r\n .pipe(unzipper.Parse())\r\n .on('entry', (entry: unzipper.Entry) => {\r\n if (entry.type === 'File' && !extracted) {\r\n extracted = true;\r\n const writeStream = fs.createWriteStream(outputPath);\r\n\r\n entry.pipe(writeStream);\r\n\r\n writeStream.on('finish', () => {\r\n if (process.platform !== 'win32') {\r\n fs.chmodSync(outputPath, 0o755);\r\n }\r\n this.cleanupFile(zipPath);\r\n resolve();\r\n });\r\n\r\n writeStream.on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n });\r\n } else {\r\n entry.autodrain();\r\n }\r\n })\r\n .on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n })\r\n .on('close', () => {\r\n if (!extracted) {\r\n this.cleanupFile(zipPath);\r\n reject(new Error(`No se encontró archivo válido en el ZIP para ${prefix}`));\r\n }\r\n });\r\n });\r\n }\r\n\r\n private static cleanupFile(filePath: string): void {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n\r\n private static getDefaultBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n // Test write permissions\r\n const testFile = path.join(dir, '.test');\r\n fs.writeFileSync(testFile, 'test');\r\n fs.unlinkSync(testFile);\r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n}\r\n\r\nexport { Downloader };","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\"\r\nimport { Downloader } from \"./Donwloader\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\nclass Binary{\r\n private static isDownloading = false;\r\n private static downloadPromise: Promise<void> | null = null;\r\n private static cachedBinaries: { [key: string]: string } = {};\r\n\r\n static async ensureBinariesExist(): Promise<void> {\r\n if (this.isDownloading && this.downloadPromise) {\r\n await this.downloadPromise;\r\n return;\r\n }\r\n\r\n const binDir = this.getBinDir();\r\n\r\n // Always check and download/update binaries\r\n if (!this.isDownloading) {\r\n this.isDownloading = true;\r\n this.downloadPromise = this.downloadBinaries();\r\n\r\n try {\r\n await this.downloadPromise;\r\n } finally {\r\n this.isDownloading = false;\r\n this.downloadPromise = null;\r\n }\r\n }\r\n }\r\n\r\n private static async downloadBinaries(): Promise<void> {\r\n try {\r\n const binDir = this.getBinDir();\r\n await Downloader.download(binDir);\r\n } catch (error) {\r\n console.warn('⚠️ Dbcube: Error descargando binarios:', (error as Error).message);\r\n console.log('🔧 Los binarios se intentarán descargar en la próxima ejecución');\r\n }\r\n }\r\n\r\n private static getBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n \r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n\r\n\r\n private static findVersionedBinary(binDir: string, prefix: string, platform: string, arch: string): string {\r\n // Check cache first\r\n const cacheKey = `${prefix}-${platform}-${arch}`;\r\n if (this.cachedBinaries[cacheKey]) {\r\n const cachedPath = path.join(binDir, this.cachedBinaries[cacheKey]);\r\n if (fs.existsSync(cachedPath)) {\r\n return cachedPath;\r\n }\r\n }\r\n\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n const pattern = new RegExp(`^${prefix}-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platform}-${arch}${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n this.cachedBinaries[cacheKey] = matchingFile;\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n // Fallback to non-versioned name (for backwards compatibility)\r\n const fallbackName = `${prefix}-engine-${platform}-${arch}${platform === 'windows' ? '.exe' : ''}`;\r\n return path.join(binDir, fallbackName);\r\n }\r\n\r\n static async get(): Promise<BinaryType> {\r\n await this.ensureBinariesExist();\r\n\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n const binDir = this.getBinDir();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n return {\r\n query_engine: this.findVersionedBinary(binDir, 'query', plat, archSuffix),\r\n schema_engine: this.findVersionedBinary(binDir, 'schema', plat, archSuffix)\r\n };\r\n }\r\n\r\n return {\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n}\r\n\r\nexport { Binary }","/**\r\n * Tipo para la configuración de una base de datos\r\n */\r\ntype DatabaseConfig = Record<string, any>;\r\n\r\n/**\r\n * Tipo para la configuración general del ORM\r\n */\r\ninterface ConfigData {\r\n [key: string]: any;\r\n databases?: Record<string, DatabaseConfig>;\r\n}\r\n\r\n/**\r\n * Clase para manejar la configuración del ORM\r\n */\r\nexport class Config {\r\n private data: ConfigData = {};\r\n private databases: Record<string, DatabaseConfig> = {};\r\n\r\n /**\r\n * Establece la configuración\r\n * @param configData - Datos de configuración\r\n */\r\n set(configData: ConfigData): void {\r\n this.data = configData;\r\n\r\n if (configData.databases) {\r\n this.databases = configData.databases;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor de configuración\r\n * @param key - Clave de configuración\r\n * @returns Valor de configuración\r\n */\r\n get<T = any>(key: string): T {\r\n return this.data[key];\r\n }\r\n\r\n /**\r\n * Obtiene la configuración de una base de datos específica\r\n * @param dbName - Nombre de la base de datos\r\n * @returns Configuración de la base de datos o null\r\n */\r\n getDatabase(dbName: string): DatabaseConfig | null {\r\n return this.databases[dbName] || null;\r\n }\r\n\r\n /**\r\n * Obtiene todas las bases de datos configuradas\r\n * @returns Todas las configuraciones de bases de datos\r\n */\r\n getAllDatabases(): Record<string, DatabaseConfig> {\r\n return this.databases;\r\n }\r\n}\r\n\r\nexport default Config;\r\n","import net from 'net';\nimport fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\ninterface DaemonResponse {\n status: number;\n message: string;\n data: any;\n}\n\ninterface PendingRequest {\n resolve: (r: DaemonResponse) => void;\n reject: (e: Error) => void;\n timer: NodeJS.Timeout;\n}\n\n/**\n * TCP client for the query-engine daemon (server mode).\n *\n * Instead of spawning a new engine process per query (30-80ms overhead),\n * the daemon keeps the engine alive with warm connection pools and serves\n * requests over a local TCP socket in <1ms. One daemon per database name.\n */\nexport class DaemonClient {\n private static registry: Map<string, DaemonClient> = new Map();\n\n private name: string;\n private binaryPath: string;\n private engineArgs: string[];\n private socket: net.Socket | null = null;\n private buffer = '';\n private pending: PendingRequest[] = [];\n private starting: Promise<boolean> | null = null;\n private requestTimeout: number;\n\n private constructor(name: string, binaryPath: string, engineArgs: string[], requestTimeout = 30000) {\n this.name = name;\n this.binaryPath = binaryPath;\n this.engineArgs = engineArgs;\n this.requestTimeout = requestTimeout;\n }\n\n static get(name: string, binaryPath: string, engineArgs: string[]): DaemonClient {\n let client = this.registry.get(name);\n if (!client) {\n client = new DaemonClient(name, binaryPath, engineArgs);\n this.registry.set(name, client);\n }\n return client;\n }\n\n static isEnabled(): boolean {\n const flag = process.env.DBCUBE_DAEMON;\n if (flag === '0' || flag === 'false') return false;\n return true; // ON by default — fastest path with automatic fallback\n }\n\n private portfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.json`);\n }\n\n /**\n * Ensures a usable daemon connection. Returns false when the daemon\n * can't be used (old binary, startup failure) so callers fall back\n * to one-shot spawn mode.\n */\n async ensure(): Promise<boolean> {\n if (this.socket && !this.socket.destroyed) return true;\n if (this.starting) return this.starting;\n\n this.starting = this.connectOrStart().catch(() => false);\n const result = await this.starting;\n this.starting = null;\n return result;\n }\n\n private async connectOrStart(): Promise<boolean> {\n // 1. Try an existing daemon via portfile\n const port = this.readPortfile();\n if (port && await this.tryConnect(port)) return true;\n\n // 2. Stale portfile — remove and start a fresh daemon\n try { fs.unlinkSync(this.portfilePath()); } catch { /* not there */ }\n\n this.spawnDaemon();\n\n // 3. Poll the portfile while the daemon boots (up to 10s)\n const deadline = Date.now() + 10000;\n while (Date.now() < deadline) {\n await new Promise(r => setTimeout(r, 150));\n const newPort = this.readPortfile();\n if (newPort && await this.tryConnect(newPort)) return true;\n }\n return false;\n }\n\n private readPortfile(): number | null {\n try {\n const raw = fs.readFileSync(this.portfilePath(), 'utf8');\n const info = JSON.parse(raw);\n return typeof info.port === 'number' ? info.port : null;\n } catch {\n return null;\n }\n }\n\n private spawnDaemon(): void {\n const child = spawn(this.binaryPath, [...this.engineArgs, '--action', 'server', '--tcp-port', '9944'], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n });\n child.unref();\n }\n\n private tryConnect(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = net.createConnection({ host: '127.0.0.1', port }, async () => {\n socket.setNoDelay(true);\n this.attach(socket);\n // Verify it's a current-generation daemon (supports ping)\n try {\n const pong = await this.send({ action: 'ping' });\n resolve(pong.status === 200);\n } catch {\n this.detach();\n resolve(false);\n }\n });\n socket.once('error', () => resolve(false));\n socket.setTimeout(3000, () => { socket.destroy(); resolve(false); });\n });\n }\n\n private attach(socket: net.Socket): void {\n this.socket = socket;\n this.buffer = '';\n socket.setTimeout(0);\n socket.on('data', (chunk: Buffer | string) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n socket.on('close', () => this.detach());\n socket.on('error', () => this.detach());\n }\n\n private detach(): void {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = null;\n }\n // Fail anything still in flight\n for (const req of this.pending.splice(0)) {\n clearTimeout(req.timer);\n req.reject(new Error('Daemon connection lost'));\n }\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += chunk.toString('utf8');\n let idx: number;\n while ((idx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, idx).trim();\n this.buffer = this.buffer.slice(idx + 1);\n if (!line) continue;\n const marker = line.indexOf('PROCESS_RESPONSE:');\n if (marker === -1) continue; // engine log noise\n const jsonPart = line.slice(marker + 'PROCESS_RESPONSE:'.length);\n const req = this.pending.shift();\n if (!req) continue;\n clearTimeout(req.timer);\n try {\n req.resolve(JSON.parse(jsonPart));\n } catch (e: any) {\n req.reject(new Error(`Invalid daemon response: ${e.message}`));\n }\n }\n }\n\n /**\n * Sends a request to the daemon. Responses arrive in FIFO order on the\n * single socket, so pending requests resolve in send order.\n */\n send(payload: Record<string, any>): Promise<DaemonResponse> {\n return new Promise((resolve, reject) => {\n if (!this.socket || this.socket.destroyed) {\n reject(new Error('Daemon not connected'));\n return;\n }\n const timer = setTimeout(() => {\n const i = this.pending.findIndex(p => p.timer === timer);\n if (i !== -1) this.pending.splice(i, 1);\n reject(new Error('Daemon request timeout'));\n }, this.requestTimeout);\n\n this.pending.push({ resolve, reject, timer });\n this.socket.write(JSON.stringify(payload) + '\\n');\n });\n }\n\n async execute(dml: object, txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'execute', dml: JSON.stringify(dml) };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async raw(query: string, params: any[] = [], txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'raw', query, params };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async begin(): Promise<string> {\n const res = await this.send({ action: 'begin' });\n if (res.status !== 200 || !res.data?.tx_id) {\n throw new Error(res.message || 'Failed to begin transaction');\n }\n return res.data.tx_id;\n }\n\n async commit(txId: string): Promise<void> {\n const res = await this.send({ action: 'commit', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to commit transaction');\n }\n\n async rollback(txId: string): Promise<void> {\n const res = await this.send({ action: 'rollback', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to rollback transaction');\n }\n\n async shutdown(): Promise<void> {\n try { await this.send({ action: 'shutdown' }); } catch { /* daemon exits mid-response */ }\n this.detach();\n try { fs.unlinkSync(this.portfilePath()); } catch { /* already gone */ }\n }\n}\n\nexport default DaemonClient;\n","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport * as net from 'net';\r\nimport { spawn, ChildProcess } from \"child_process\";\r\n\r\n// Almacén global de servidores TCP y conexiones persistentes\r\nconst globalTcpServers = new Map<string, { port: number, process: ChildProcess | null }>();\r\nconst globalTcpConnections = new Map<string, net.Socket | null>();\r\n\r\n// Cola de peticiones para cada conexión (evita race conditions)\r\nconst connectionQueues = new Map<string, Array<{\r\n args: string[],\r\n resolve: (value: any) => void,\r\n reject: (reason: any) => void\r\n}>>();\r\nconst connectionProcessing = new Map<string, boolean>();\r\n\r\n// Query Cache para evitar JSON.parse repetido\r\nconst queryCache = new Map<string, any>();\r\nlet cacheSize = 0;\r\nconst MAX_CACHE_SIZE = 500;\r\n\r\nclass QueryEngine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private connectionId: string;\r\n private tcpPort: number;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n this.timeout = timeout;\r\n this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || 'localhost'}`;\r\n this.tcpPort = this.generatePort();\r\n }\r\n\r\n private generatePort(): number {\r\n // Empezar desde el puerto 9944 y buscar hacia abajo\r\n return 9944;\r\n }\r\n\r\n private async findAvailablePort(startPort: number): Promise<number> {\r\n for (let port = startPort; port >= 9900; port--) {\r\n if (await this.isPortAvailable(port)) {\r\n return port;\r\n }\r\n }\r\n throw new Error('No available ports found in range 9900-9944');\r\n }\r\n\r\n private isPortAvailable(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const tester = net.createServer();\r\n\r\n tester.once('error', () => resolve(false));\r\n tester.once('listening', () => {\r\n tester.close();\r\n resolve(true);\r\n });\r\n\r\n tester.listen(port, '127.0.0.1');\r\n });\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', this.config.config.PORT,\r\n '--user', this.config.config.USER,\r\n '--password', this.config.config.PASSWORD,\r\n '--motor', this.config.type\r\n ];\r\n }\r\n return args;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: string[]): Promise<ResponseEngine> {\r\n // Detectar si es una acción execute de query_engine\r\n const actionIndex = args.findIndex(arg => arg === '--action');\r\n const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === 'execute';\r\n const isQueryEngine = binary === 'query_engine';\r\n\r\n if (isQueryEngine && isExecuteAction) {\r\n // Solo query_engine con execute usa servidor TCP con cola\r\n return this.executeWithTcpServer(args);\r\n } else {\r\n // Para otras acciones, usar método normal\r\n return this.createProcess(binary, args);\r\n }\r\n }\r\n\r\n private async executeWithTcpServer(args: string[]): Promise<ResponseEngine> {\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n // Si no hay servidor TCP, iniciarlo\r\n if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {\r\n await this.startTcpServer();\r\n // Solo verificar la primera vez\r\n await this.waitForServerReady();\r\n }\r\n\r\n // Enviar consulta via TCP con sistema de cola\r\n return this.sendTcpRequestFast(args);\r\n }\r\n\r\n private async waitForServerReady(): Promise<void> {\r\n const maxRetries = 10;\r\n const retryDelay = 500; // 500ms entre intentos\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not found');\r\n }\r\n\r\n for (let i = 0; i < maxRetries; i++) {\r\n if (await this.isServerResponding(serverInfo.port)) {\r\n return;\r\n }\r\n await this.sleep(retryDelay);\r\n }\r\n throw new Error('TCP server failed to become ready within timeout');\r\n }\r\n\r\n private async isServerResponding(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const client = new net.Socket();\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n resolve(false);\r\n }, 1000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n client.destroy();\r\n resolve(true);\r\n });\r\n\r\n client.on('error', () => {\r\n clearTimeout(timeout);\r\n resolve(false);\r\n });\r\n });\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n private getCachedDML(dmlJson: string): any {\r\n // Buscar en cache primero\r\n if (queryCache.has(dmlJson)) {\r\n return queryCache.get(dmlJson);\r\n }\r\n\r\n // Parse y guardar en cache si hay espacio\r\n const parsed = JSON.parse(dmlJson);\r\n\r\n if (cacheSize < MAX_CACHE_SIZE) {\r\n queryCache.set(dmlJson, parsed);\r\n cacheSize++;\r\n }\r\n\r\n return parsed;\r\n }\r\n\r\n private async startTcpServer(): Promise<void> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n // Buscar puerto disponible\r\n this.tcpPort = await this.findAvailablePort(this.tcpPort);\r\n\r\n return new Promise((resolve, reject) => {\r\n // Iniciar el query_engine como servidor TCP\r\n const serverArgs = [...this.arguments, '--action', 'server', '--tcp-port', this.tcpPort.toString()];\r\n const serverProcess = spawn(this.binary!['query_engine' as keyof BinaryType], serverArgs);\r\n\r\n let started = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!started) {\r\n serverProcess.kill();\r\n reject(new Error('TCP server startup timeout'));\r\n }\r\n }, 15000); // Aumentar timeout a 15 segundos\r\n\r\n serverProcess.stdout.on('data', (data) => {\r\n const output = data.toString();\r\n\r\n if (output.includes('TCP Server listening on')) {\r\n if (!started) {\r\n started = true;\r\n clearTimeout(timeout);\r\n globalTcpServers.set(this.connectionId, {\r\n port: this.tcpPort,\r\n process: serverProcess\r\n });\r\n resolve();\r\n }\r\n }\r\n });\r\n\r\n serverProcess.stderr.on('data', (data) => {\r\n console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);\r\n });\r\n\r\n serverProcess.on('close', (code) => {\r\n globalTcpServers.delete(this.connectionId);\r\n });\r\n\r\n serverProcess.on('error', (error) => {\r\n if (!started) {\r\n clearTimeout(timeout);\r\n reject(error);\r\n }\r\n });\r\n });\r\n }\r\n\r\n private async sendTcpRequestFast(args: string[]): Promise<ResponseEngine> {\r\n // Usar sistema de cola para serializar peticiones y evitar race conditions\r\n return new Promise((resolve, reject) => {\r\n // Agregar petición a la cola\r\n let queue = connectionQueues.get(this.connectionId);\r\n if (!queue) {\r\n queue = [];\r\n connectionQueues.set(this.connectionId, queue);\r\n }\r\n\r\n queue.push({ args, resolve, reject });\r\n\r\n // Procesar cola si no se está procesando\r\n this.processQueue();\r\n });\r\n }\r\n\r\n private async processQueue(): Promise<void> {\r\n // Si ya se está procesando esta cola, salir\r\n if (connectionProcessing.get(this.connectionId)) {\r\n return;\r\n }\r\n\r\n const queue = connectionQueues.get(this.connectionId);\r\n if (!queue || queue.length === 0) {\r\n return;\r\n }\r\n\r\n // Marcar como procesando\r\n connectionProcessing.set(this.connectionId, true);\r\n\r\n try {\r\n // Obtener información del servidor\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not initialized');\r\n }\r\n\r\n // Procesar peticiones de forma secuencial\r\n while (queue.length > 0) {\r\n const request = queue.shift();\r\n if (!request) break;\r\n\r\n try {\r\n // Verificar si hay conexión persistente\r\n let connection = globalTcpConnections.get(this.connectionId);\r\n\r\n if (!connection || connection.destroyed || connection.readyState !== 'open') {\r\n // Crear nueva conexión si no existe\r\n connection = await this.createNewConnection(serverInfo.port);\r\n globalTcpConnections.set(this.connectionId, connection);\r\n }\r\n\r\n // Ejecutar petición y esperar respuesta\r\n const result = await this.executeOnConnection(connection, request.args);\r\n request.resolve(result);\r\n } catch (error) {\r\n // Si hay error, limpiar conexión y rechazar\r\n globalTcpConnections.delete(this.connectionId);\r\n request.reject(error);\r\n }\r\n }\r\n } finally {\r\n // Marcar como no procesando\r\n connectionProcessing.set(this.connectionId, false);\r\n }\r\n }\r\n\r\n private async createNewConnection(port: number): Promise<net.Socket> {\r\n return new Promise((resolve, reject) => {\r\n const client = new net.Socket();\r\n client.setNoDelay(true);\r\n client.setKeepAlive(true, 60000);\r\n\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n reject(new Error('Connection timeout'));\r\n }, 5000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n resolve(client);\r\n });\r\n\r\n client.on('error', (error) => {\r\n clearTimeout(timeout);\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n private async executeOnConnection(connection: net.Socket, args: string[]): Promise<ResponseEngine> {\r\n return new Promise((resolve, reject) => {\r\n // Convertir args en un objeto de comando\r\n const command: any = {};\r\n\r\n for (let i = 0; i < args.length; i += 2) {\r\n if (args[i].startsWith('--')) {\r\n const key = args[i].substring(2); // Remover '--'\r\n const value = args[i + 1];\r\n command[key] = value;\r\n }\r\n }\r\n\r\n let responseBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(new Error('Request timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const onData = (data: Buffer) => {\r\n responseBuffer += data.toString();\r\n const match = responseBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match && !isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolve({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n reject(new Error('Failed to parse response'));\r\n }\r\n }\r\n };\r\n\r\n const onError = (error: Error) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(error);\r\n }\r\n };\r\n\r\n connection.on('data', onData);\r\n connection.on('error', onError);\r\n\r\n // Enviar comando como JSON\r\n connection.write(JSON.stringify(command));\r\n });\r\n }\r\n\r\n private async createProcess(binary: string, args: string[]): Promise<ResponseEngine> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n stdoutBuffer += data.toString();\r\n\r\n const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n stderrBuffer += data.toString();\r\n\r\n const match = stderrBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n\r\n async disconnect(): Promise<ResponseEngine> {\r\n // Cerrar conexión TCP persistente si existe\r\n const connection = globalTcpConnections.get(this.connectionId);\r\n if (connection && connection.readyState === 'open') {\r\n connection.write(JSON.stringify({ action: 'disconnect' }));\r\n connection.destroy();\r\n globalTcpConnections.delete(this.connectionId);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n if (serverInfo && serverInfo.process && !serverInfo.process.killed) {\r\n serverInfo.process.kill();\r\n globalTcpServers.delete(this.connectionId);\r\n\r\n return {\r\n status: 200,\r\n message: 'TCP server and connections stopped',\r\n data: null\r\n };\r\n }\r\n\r\n return {\r\n status: 200,\r\n message: 'No TCP server to stop',\r\n data: null\r\n };\r\n }\r\n}\r\n\r\nexport { QueryEngine }","import { exec } from 'child_process';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\nimport { promisify } from 'util';\r\nimport { Binary } from './Binary';\r\nimport { createRequire } from 'module';\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\ninterface SqliteResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\nexport class SqliteExecutor {\r\n private binaryPath: string;\r\n private dbPath: string;\r\n\r\n constructor(dbPath: string) {\r\n this.dbPath = dbPath;\r\n this.binaryPath = this.getBinaryPath();\r\n }\r\n\r\n private findVersionedBinary(binDir: string, platform: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // Pattern to match versioned binaries: sqlite-engine-v1.0.0-windows-x64.exe\r\n const pattern = new RegExp(`^sqlite-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platformName}-x64${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getBinaryPath(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find the binary in the new location first\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n const platform = process.platform;\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // First, try to find versioned binary in all possible directories\r\n for (const dir of possibleDirs) {\r\n const versionedPath = this.findVersionedBinary(dir, platform);\r\n if (versionedPath && fs.existsSync(versionedPath)) {\r\n return versionedPath;\r\n }\r\n }\r\n\r\n // Fallback to non-versioned name\r\n const binaryName = `sqlite-engine-${platformName}-x64${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, binaryName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // Fallback to old format if new format not found\r\n const fallbackName = `sqlite-engine${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, fallbackName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // If nothing found, return the preferred path (will trigger download)\r\n return path.join(possibleDirs[0], binaryName);\r\n }\r\n\r\n private async executeBinary(args: string[]): Promise<SqliteResult> {\r\n const escapedArgs = args.map(arg => {\r\n if (arg.includes(' ') || arg.includes('\"') || arg.includes('(') || arg.includes(')')) {\r\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\r\n }\r\n return arg;\r\n });\r\n \r\n const command = `\"${this.binaryPath}\" ${escapedArgs.join(' ')}`;\r\n \r\n try {\r\n const { stdout, stderr } = await execAsync(command, {\r\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\r\n timeout: 30000 // 30s timeout\r\n });\r\n\r\n if (stderr && stderr.trim()) {\r\n console.warn('SQLite Engine Warning:', stderr);\r\n }\r\n\r\n const result = JSON.parse(stdout.trim());\r\n return result;\r\n } catch (error: any) {\r\n if (error.stdout) {\r\n try {\r\n const result = JSON.parse(error.stdout.trim());\r\n return result;\r\n } catch (parseError) {\r\n // Fall through to generic error\r\n }\r\n }\r\n \r\n throw new Error(`SQLite execution failed: ${error.message}`);\r\n }\r\n }\r\n\r\n async connect(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'connect',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success';\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async exists(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'exists',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success' && result.data === true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async query(sql: string, params?: any[]): Promise<SqliteResult> {\r\n const args = [\r\n '--action', 'query',\r\n '--database', this.dbPath,\r\n '--query', sql\r\n ];\r\n\r\n if (params && params.length > 0) {\r\n args.push('--params', JSON.stringify(params));\r\n }\r\n\r\n return this.executeBinary(args);\r\n }\r\n\r\n // Método para múltiples queries (como lo hace better-sqlite3)\r\n async queryMultiple(sql: string): Promise<SqliteResult> {\r\n return this.query(sql);\r\n }\r\n\r\n // Método prepare que simula prepared statements\r\n prepare(sql: string) {\r\n return {\r\n all: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n return Array.isArray(result.data) ? result.data : [];\r\n },\r\n run: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n \r\n // Si es un RunResult, devolverlo tal como está\r\n if (typeof result.data === 'object' && \r\n result.data.hasOwnProperty('changes') && \r\n result.data.hasOwnProperty('lastID')) {\r\n return result.data as RunResult;\r\n }\r\n \r\n return { changes: 0, lastID: 0 };\r\n }\r\n };\r\n }\r\n\r\n // Para compatibilidad con better-sqlite3 API sincrona usando deasync si es necesario\r\n prepareSync(sql: string) {\r\n // Get __filename equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const requireUrl = __filename || import.meta.url;\r\n const require = createRequire(requireUrl);\r\n const deasync = require('deasync');\r\n \r\n return {\r\n all: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else {\r\n result = Array.isArray(res.data) ? res.data : [];\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n },\r\n run: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else if (typeof res.data === 'object' && \r\n res.data.hasOwnProperty('changes') && \r\n res.data.hasOwnProperty('lastID')) {\r\n result = res.data;\r\n } else {\r\n result = { changes: 0, lastID: 0 };\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n }\r\n };\r\n }\r\n}","import { SqliteExecutor } from './SqliteExecutor';\r\nimport * as path from 'path';\r\nimport fs from 'fs';\r\n\r\nconst rootPath = path.resolve(process.cwd(), '.dbcube');\r\n\r\ninterface DatabaseConfig {\r\n name?: string;\r\n HOST?: string;\r\n USER?: string;\r\n PASSWORD?: string;\r\n DATABASE?: string;\r\n PORT?: number;\r\n}\r\n\r\ninterface QueryResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\ninterface ParametrizedQueryResult {\r\n query: string;\r\n parameters: any[];\r\n}\r\n\r\nclass SQLite {\r\n private executor: SqliteExecutor | null = null;\r\n private database?: string;\r\n \r\n constructor(config: DatabaseConfig) {\r\n this.database = config.DATABASE;\r\n }\r\n\r\n async ifExist(): Promise<Boolean> {\r\n if (this.database) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n if (fs.existsSync(configPath)) {\r\n return true;\r\n }\r\n \r\n // También verificar usando el executor\r\n if (!this.executor) {\r\n this.executor = new SqliteExecutor(configPath);\r\n }\r\n return await this.executor.exists();\r\n }\r\n return false;\r\n }\r\n\r\n async connect(): Promise<SqliteExecutor> {\r\n return new Promise(async (resolve, reject) => {\r\n try {\r\n if (!this.executor) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n this.executor = new SqliteExecutor(configPath);\r\n const connected = await this.executor.connect();\r\n \r\n if (!connected) {\r\n throw new Error('Failed to connect to SQLite database');\r\n }\r\n }\r\n resolve(this.executor);\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.executor) {\r\n // SQLiteExecutor no necesita cerrar conexión persistente\r\n this.executor = null;\r\n }\r\n resolve();\r\n });\r\n }\r\n\r\n async query(sqlQuery: string): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n // Usar queryMultiple que maneja múltiples comandos SQL\r\n const result = await this.executor.queryMultiple(sqlQuery);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n async queryWithParameters(sqlQuery: string, params: any[] = []): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!Array.isArray(params)) {\r\n throw new Error('Parameters must be an array.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n const result = await this.executor.query(sqlQuery, params);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n console.log(error);\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n convertToParameterizedQuery(sql: string): ParametrizedQueryResult {\r\n const normalizedSql = sql.replace(/\\s+/g, ' ').trim();\r\n \r\n const baseQueryMatch = normalizedSql.match(/^(.+?)\\s+VALUES\\s*\\(/i);\r\n if (!baseQueryMatch) {\r\n throw new Error('No se pudo encontrar la estructura VALUES en la consulta');\r\n }\r\n \r\n const baseQuery = baseQueryMatch[1];\r\n \r\n const valuesStartIndex = normalizedSql.toUpperCase().indexOf('VALUES');\r\n const valuesSection = normalizedSql.substring(valuesStartIndex);\r\n const valuesMatch = valuesSection.match(/VALUES\\s*\\((.+)\\)\\s*;?\\s*$/i);\r\n if (!valuesMatch) {\r\n throw new Error('No se pudieron extraer los valores de la consulta');\r\n }\r\n \r\n const valuesString = valuesMatch[1];\r\n \r\n function parseValues(str: string): any[] {\r\n const values: any[] = [];\r\n let currentValue = '';\r\n let inQuotes = false;\r\n let quoteChar = '';\r\n let inCompute = false;\r\n let computeDepth = 0;\r\n \r\n for (let i = 0; i < str.length; i++) {\r\n const char = str[i];\r\n const prevChar = str[i - 1];\r\n \r\n if (!inQuotes && str.substring(i, i + 8) === '@compute') {\r\n inCompute = true;\r\n }\r\n \r\n if (inCompute && char === '(') {\r\n computeDepth++;\r\n } else if (inCompute && char === ')') {\r\n computeDepth--;\r\n if (computeDepth === 0) {\r\n inCompute = false;\r\n }\r\n }\r\n \r\n if (!inCompute && (char === '\"' || char === \"'\") && prevChar !== '\\\\') {\r\n if (!inQuotes) {\r\n inQuotes = true;\r\n quoteChar = char;\r\n } else if (char === quoteChar) {\r\n if (str[i + 1] === quoteChar) {\r\n currentValue += char + char;\r\n i++;\r\n continue;\r\n } else {\r\n inQuotes = false;\r\n quoteChar = '';\r\n }\r\n }\r\n }\r\n \r\n if (!inQuotes && !inCompute && char === ',') {\r\n values.push(cleanValue(currentValue.trim()));\r\n currentValue = '';\r\n continue;\r\n }\r\n \r\n currentValue += char;\r\n }\r\n \r\n if (currentValue.trim()) {\r\n values.push(cleanValue(currentValue.trim()));\r\n }\r\n \r\n return values;\r\n }\r\n \r\n function cleanValue(value: string): any {\r\n value = value.trim();\r\n \r\n if (value.startsWith('@compute')) {\r\n return value;\r\n }\r\n \r\n if ((value.startsWith('\"') && value.endsWith('\"')) || \r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\r\n value = value.slice(1, -1);\r\n value = value.replace(/''/g, \"'\").replace(/\"\"/g, '\"');\r\n }\r\n \r\n return value;\r\n }\r\n \r\n const parameters = parseValues(valuesString);\r\n const placeholders = parameters.map(() => '?').join(', ');\r\n const parametrizedQuery = `${baseQuery} VALUES (${placeholders});`;\r\n \r\n return {\r\n query: parametrizedQuery,\r\n parameters: parameters\r\n };\r\n }\r\n}\r\n\r\nexport const DbConfig = new SQLite({DATABASE: \"config\"});\r\nexport default DbConfig;","import * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { EventEmitter } from 'events';\r\n\r\ninterface InterceptOptions {\r\n interceptLog?: boolean;\r\n interceptError?: boolean;\r\n interceptWarn?: boolean;\r\n keepOriginal?: boolean;\r\n useBuffer?: boolean;\r\n}\r\n\r\ninterface ReadOptions {\r\n lines?: number | null;\r\n fromEnd?: boolean;\r\n asArray?: boolean;\r\n}\r\n\r\ninterface WatchOptions {\r\n persistent?: boolean;\r\n interval?: number;\r\n fromEnd?: boolean;\r\n}\r\n\r\ninterface WatchController {\r\n id: string;\r\n stop: () => void;\r\n isWatching: () => boolean;\r\n}\r\n\r\nexport interface InterceptController {\r\n restore: () => void;\r\n commit: () => Promise<boolean>;\r\n discard: () => number;\r\n hasBuffer: () => boolean;\r\n getBufferSize: () => number;\r\n}\r\n\r\ninterface DeleteResult {\r\n filePath: string;\r\n deleted: boolean;\r\n error: string | null;\r\n}\r\n\r\ntype LogLevel = 'INFO' | 'ERROR' | 'WARN' | 'DEBUG';\r\n\r\nexport class FileLogger extends EventEmitter {\r\n private static watchers = new Map<string, (curr: fs.Stats, prev: fs.Stats) => void>(); // Store listener functions\r\n private static buffers = new Map<string, string[]>();\r\n \r\n /**\r\n * Escribe un log en el archivo especificado\r\n * @param filePath - Ruta del archivo de log\r\n * @param message - Mensaje a escribir\r\n * @param level - Nivel del log (INFO, ERROR, WARN, DEBUG)\r\n * @param append - Si debe agregar al final del archivo (default: true)\r\n */\r\n static async write(filePath: string, message: string, level: LogLevel = 'INFO', append: boolean = true): Promise<boolean> {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Formatear el mensaje con timestamp\r\n const timestamp = new Date().toISOString();\r\n const formattedMessage = `[${timestamp}] [${level}] ${message}\\n`;\r\n \r\n // Si existe un buffer para este archivo, agregarlo al buffer en lugar de escribir directamente\r\n if (FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.get(filePath)!.push(formattedMessage);\r\n return true;\r\n }\r\n \r\n // Escribir al archivo normalmente\r\n if (append) {\r\n await fs.promises.appendFile(filePath, formattedMessage, 'utf8');\r\n } else {\r\n await fs.promises.writeFile(filePath, formattedMessage, 'utf8');\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error('Error escribiendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Inicia un buffer temporal para un archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static startBuffer(filePath: string): void {\r\n if (!FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.set(filePath, []);\r\n }\r\n }\r\n \r\n /**\r\n * Confirma y escribe todos los logs del buffer al archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static async commitBuffer(filePath: string): Promise<boolean> {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n if (buffer && buffer.length > 0) {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Escribir todos los logs del buffer\r\n const content = buffer.join('');\r\n await fs.promises.appendFile(filePath, content, 'utf8');\r\n \r\n // Limpiar el buffer\r\n FileLogger.buffers.delete(filePath);\r\n return true;\r\n } catch (error) {\r\n console.error('Error confirmando buffer:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n // Limpiar el buffer aunque esté vacío\r\n FileLogger.buffers.delete(filePath);\r\n return false;\r\n }\r\n \r\n /**\r\n * Descarta todos los logs del buffer sin escribirlos\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static discardBuffer(filePath: string): number {\r\n if (FileLogger.buffers.has(filePath)) {\r\n const discardedCount = FileLogger.buffers.get(filePath)!.length;\r\n FileLogger.buffers.delete(filePath);\r\n return discardedCount;\r\n }\r\n return 0;\r\n }\r\n \r\n /**\r\n * Verifica si existe un buffer activo para un archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static hasBuffer(filePath: string): boolean {\r\n return FileLogger.buffers.has(filePath);\r\n }\r\n \r\n /**\r\n * Obtiene el número de logs en el buffer\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static getBufferSize(filePath: string): number {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n return buffer ? buffer.length : 0;\r\n }\r\n \r\n /**\r\n * Intercepta console.log y console.error para escribir a archivo\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de interceptación\r\n */\r\n static interceptConsole(filePath: string, options: InterceptOptions = {}): InterceptController {\r\n const {\r\n interceptLog = true,\r\n interceptError = true,\r\n interceptWarn = true,\r\n keepOriginal = true, // Mantener el comportamiento original de console\r\n useBuffer = false // Usar buffer temporal\r\n } = options;\r\n \r\n // Iniciar buffer si se solicita\r\n if (useBuffer) {\r\n FileLogger.startBuffer(filePath);\r\n }\r\n \r\n // Guardar referencias originales\r\n const originalLog = console.log;\r\n const originalError = console.error;\r\n const originalWarn = console.warn;\r\n \r\n if (interceptLog) {\r\n console.log = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'INFO').catch(err => {\r\n originalError('Error escribiendo log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalLog.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptError) {\r\n console.error = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'ERROR').catch(err => {\r\n originalError('Error escribiendo error log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalError.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptWarn) {\r\n console.warn = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'WARN').catch(err => {\r\n originalError('Error escribiendo warn log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalWarn.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n // Retornar función para restaurar console original\r\n return {\r\n restore: () => {\r\n if (interceptLog) console.log = originalLog;\r\n if (interceptError) console.error = originalError;\r\n if (interceptWarn) console.warn = originalWarn;\r\n },\r\n commit: async () => {\r\n if (useBuffer) {\r\n return await FileLogger.commitBuffer(filePath);\r\n }\r\n return false;\r\n },\r\n discard: () => {\r\n if (useBuffer) {\r\n return FileLogger.discardBuffer(filePath);\r\n }\r\n return 0;\r\n },\r\n hasBuffer: () => FileLogger.hasBuffer(filePath),\r\n getBufferSize: () => FileLogger.getBufferSize(filePath)\r\n };\r\n }\r\n \r\n /**\r\n * Lee el contenido completo del archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de lectura\r\n * @returns Contenido del archivo\r\n */\r\n static async read(filePath: string, options: ReadOptions = {}): Promise<string | string[]> {\r\n const { \r\n lines = null, // Número de líneas a leer (null = todas)\r\n fromEnd = false, // Si debe leer desde el final\r\n asArray = false // Si debe retornar como array de líneas\r\n } = options;\r\n \r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n return asArray ? [] : '';\r\n }\r\n \r\n let content = await fs.promises.readFile(filePath, 'utf8');\r\n \r\n if (asArray) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n \r\n if (lines !== null) {\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n }\r\n \r\n return linesArray;\r\n }\r\n \r\n // Si se especifica número de líneas y no es array\r\n if (lines !== null) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n content = linesArray.join('\\n');\r\n }\r\n \r\n return content;\r\n } catch (error) {\r\n console.error('Error leyendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Observa un archivo de log en tiempo real\r\n * @param filePath - Ruta del archivo de log\r\n * @param callback - Función callback para nuevas líneas\r\n * @param options - Opciones del watcher\r\n * @returns Objeto con métodos para controlar el watcher\r\n */\r\n static watch(filePath: string, callback: (line: string, filePath: string) => void, options: WatchOptions = {}): WatchController {\r\n const {\r\n persistent = true,\r\n interval = 100,\r\n fromEnd = true // Empezar desde el final del archivo\r\n } = options;\r\n \r\n let lastSize = 0;\r\n let lastPosition = 0;\r\n \r\n // Inicializar posición si el archivo ya existe\r\n if (fs.existsSync(filePath)) {\r\n const stats = fs.statSync(filePath);\r\n lastSize = stats.size;\r\n lastPosition = fromEnd ? stats.size : 0;\r\n }\r\n \r\n // Fixed: Correct listener function signature for fs.watchFile\r\n const listener = async (curr: fs.Stats, prev: fs.Stats) => {\r\n try {\r\n if (curr.size > lastSize) {\r\n // El archivo ha crecido\r\n const stream = fs.createReadStream(filePath, {\r\n start: lastPosition,\r\n end: curr.size - 1,\r\n encoding: 'utf8'\r\n });\r\n \r\n let buffer = '';\r\n \r\n stream.on('data', (chunk) => {\r\n buffer += chunk;\r\n const lines = buffer.split('\\n');\r\n \r\n // Procesar líneas completas\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n if (lines[i].trim()) {\r\n callback(lines[i].trim(), filePath);\r\n }\r\n }\r\n \r\n // Guardar la línea incompleta\r\n buffer = lines[lines.length - 1];\r\n });\r\n \r\n stream.on('end', () => {\r\n // Procesar la última línea si existe\r\n if (buffer.trim()) {\r\n callback(buffer.trim(), filePath);\r\n }\r\n });\r\n \r\n lastSize = curr.size;\r\n lastPosition = curr.size;\r\n }\r\n } catch (error) {\r\n console.error('Error en watcher:', error);\r\n }\r\n };\r\n \r\n // Watcher para cambios en el archivo\r\n fs.watchFile(filePath, { persistent, interval }, listener);\r\n \r\n // Guardar referencia del watcher\r\n const watcherId = `${filePath}_${Date.now()}`;\r\n // Store listener reference for cleanup\r\n FileLogger.watchers.set(watcherId, listener as any);\r\n \r\n // Retornar objeto de control\r\n return {\r\n id: watcherId,\r\n stop: () => {\r\n const storedListener = FileLogger.watchers.get(watcherId);\r\n if (storedListener) {\r\n fs.unwatchFile(filePath, storedListener);\r\n FileLogger.watchers.delete(watcherId);\r\n }\r\n },\r\n isWatching: () => FileLogger.watchers.has(watcherId)\r\n };\r\n }\r\n \r\n /**\r\n * Detiene todos los watchers activos\r\n */\r\n static stopAllWatchers(): void {\r\n for (const [watcherId] of FileLogger.watchers) {\r\n const filePath = watcherId.split('_')[0];\r\n fs.unwatchFile(filePath);\r\n }\r\n FileLogger.watchers.clear();\r\n }\r\n \r\n /**\r\n * Métodos de conveniencia para diferentes niveles de log\r\n */\r\n static async info(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'INFO');\r\n }\r\n \r\n static async error(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'ERROR');\r\n }\r\n \r\n static async warn(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'WARN');\r\n }\r\n \r\n static async debug(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'DEBUG');\r\n }\r\n \r\n /**\r\n * Limpia logs antiguos\r\n * @param filePath - Ruta del archivo de log\r\n * @param maxLines - Máximo número de líneas a mantener\r\n */\r\n static async cleanup(filePath: string, maxLines: number = 1000): Promise<number> {\r\n try {\r\n const lines = await this.read(filePath, { asArray: true }) as string[];\r\n \r\n if (lines.length > maxLines) {\r\n const keepLines = lines.slice(-maxLines);\r\n const content = keepLines.join('\\n') + '\\n';\r\n await fs.promises.writeFile(filePath, content, 'utf8');\r\n return lines.length - maxLines; // Líneas eliminadas\r\n }\r\n \r\n return 0;\r\n } catch (error) {\r\n console.error('Error limpiando logs:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina un archivo de log\r\n * @param filePath - Ruta del archivo de log a eliminar\r\n */\r\n static async deleteLogFile(filePath: string): Promise<boolean> {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n await fs.promises.unlink(filePath);\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n console.error('Error eliminando archivo de log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina múltiples archivos de log\r\n * @param filePaths - Array de rutas de archivos de log a eliminar\r\n */\r\n static async deleteLogFiles(filePaths: string[]): Promise<DeleteResult[]> {\r\n const results: DeleteResult[] = [];\r\n \r\n for (const filePath of filePaths) {\r\n try {\r\n const deleted = await this.deleteLogFile(filePath);\r\n results.push({ filePath, deleted, error: null });\r\n } catch (error) {\r\n results.push({ filePath, deleted: false, error: (error as Error).message });\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n}\r\n\r\nexport default FileLogger;","import { ComputedFieldConfig, DataObject, DataType } from \"../@types/DataObject\";\r\nimport { Column, DatabaseType, TableSchema } from \"../@types/Processor\";\r\nimport DbConfig from \"./DbConfig\";\r\n\r\nexport class ComputedFieldProcessor {\r\n\r\n static async getComputedFields(name: string): Promise<any[]> {\r\n let computedFields = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.query(`SELECT * FROM dbcube_computes_config WHERE database_ref='${name}'`);\r\n computedFields = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n computedFields = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n computedFields = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return computedFields;\r\n }\r\n\r\n /**\r\n * Processes computed field instruction and returns the computed value\r\n * @param instruction - The @compute instruction\r\n * @param rowData - The row data containing column values\r\n * @returns The computed value or null if there's an error\r\n */\r\n static processInstruction(instruction: string, rowData: Record<string, any>): any {\r\n try {\r\n // Remove @compute wrapper and extract the function content\r\n const functionMatch = instruction.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*{([\\s\\S]*?)}\\s*\\)/);\r\n\r\n if (!functionMatch) {\r\n throw new Error('Invalid @compute instruction format');\r\n }\r\n\r\n let functionBody: string = functionMatch[1].trim();\r\n\r\n // Clean up the function body - remove trailing semicolon if present\r\n if (functionBody.endsWith(';')) {\r\n functionBody = functionBody.slice(0, -1).trim();\r\n }\r\n\r\n // Replace @column(columnName) with actual values\r\n functionBody = functionBody.replace(/@column\\(([^)]+)\\)/g, (_match, columnName: string) => {\r\n const cleanColumnName = columnName.trim().replace(/['\"]/g, '');\r\n const value = rowData[cleanColumnName];\r\n\r\n if (value === null || value === undefined) {\r\n return 'null';\r\n } else if (typeof value === 'string') {\r\n return `\"${value.replace(/\"/g, '\\\\\"')}\"`;\r\n } else if (typeof value === 'number' || typeof value === 'boolean') {\r\n return value.toString();\r\n } else if (value instanceof Date) {\r\n return `new Date(\"${value.toISOString()}\")`;\r\n } else {\r\n return JSON.stringify(value);\r\n }\r\n });\r\n\r\n // Create and execute the function\r\n const computeFunction = new Function(functionBody);\r\n return computeFunction();\r\n } catch (error) {\r\n console.error('Error processing computed field:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Extracts column dependencies from a computed field instruction\r\n * @param instruction - The @compute instruction\r\n * @returns Array of column names that this computed field depends on\r\n */\r\n static extractDependencies(instruction: string): string[] {\r\n const dependencies: string[] = [];\r\n const columnMatches = instruction.match(/@column\\(([^)]+)\\)/g);\r\n\r\n if (columnMatches) {\r\n for (const match of columnMatches) {\r\n const innerMatch = match.match(/@column\\(([^)]+)\\)/);\r\n if (innerMatch) {\r\n const columnName = innerMatch[1].trim().replace(/['\"]/g, '');\r\n if (!dependencies.includes(columnName)) {\r\n dependencies.push(columnName);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return dependencies;\r\n }\r\n\r\n /**\r\n * Adds computed fields to an array of data objects based on configuration array\r\n * @param data - Array of data objects\r\n * @param computedConfigs - Array of computed field configurations\r\n * @returns Array with the new computed fields added\r\n */\r\n static computedFields<T extends DataObject>(\r\n data: T[],\r\n computedConfigs: ComputedFieldConfig[]\r\n ): T[] {\r\n\r\n return data.map((item, index) => {\r\n let processedItem: any = { ...item };\r\n\r\n // Procesar cada configuración de campo computado\r\n computedConfigs.forEach((config) => {\r\n try {\r\n const { column: fieldName, type, instruction } = config;\r\n\r\n // Reemplazar @column(fieldName) con el valor real del objeto\r\n let processedExpression = instruction.replace(\r\n /@column\\(([^)]+)\\)/g,\r\n (match, columnName) => {\r\n // Remover comillas si las tiene\r\n const cleanColumnName = columnName.replace(/['\"]/g, '');\r\n const value = processedItem[cleanColumnName];\r\n\r\n // Convertir el valor a string seguro para la evaluación\r\n if (typeof value === 'string') {\r\n return `\"${value}\"`;\r\n } else if (value === null || value === undefined) {\r\n return 'null';\r\n } else {\r\n return String(value);\r\n }\r\n }\r\n );\r\n\r\n // Extraer la función dentro de @compute\r\n const computeMatch = processedExpression.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*\\{(.*)\\}\\s*\\)/s);\r\n if (!computeMatch) {\r\n throw new Error(`Formato de @compute inválido para campo ${fieldName}`);\r\n }\r\n\r\n const functionBody = computeMatch[1];\r\n\r\n // Crear y ejecutar la función\r\n const computeFunction = new Function(functionBody);\r\n let result = computeFunction();\r\n\r\n // Aplicar conversión de tipo\r\n result = convertToType(result, type as DataType);\r\n\r\n // Agregar el nuevo campo al objeto procesado\r\n processedItem[fieldName] = result;\r\n\r\n } catch (error) {\r\n console.error(`Error procesando campo ${config.column} en item ${index}:`, error);\r\n // En caso de error, asignar null al campo\r\n processedItem[config.column] = null;\r\n }\r\n });\r\n\r\n return processedItem;\r\n });\r\n }\r\n}\r\n\r\nexport class TableProcessor {\r\n static async generateAlterQueries(\r\n nowQuery: string,\r\n dbType: DatabaseType,\r\n tableName: string,\r\n database_ref: string,\r\n ): Promise<string[]> {\r\n function parseCreateTableQuery(query: string, dbType: DatabaseType): TableSchema {\r\n // Limpiar y normalizar la query\r\n const cleanQuery = query.trim().replace(/\\s+/g, ' ');\r\n\r\n // Extraer el nombre de la tabla\r\n const tableNameMatch = cleanQuery.match(/CREATE TABLE (?:IF NOT EXISTS )?(\\w+)/i);\r\n if (!tableNameMatch) {\r\n throw new Error('No se pudo extraer el nombre de la tabla');\r\n }\r\n\r\n const tableName = tableNameMatch[1];\r\n\r\n // Extraer las definiciones de columnas\r\n const columnsMatch = cleanQuery.match(/\\((.+)\\)/);\r\n if (!columnsMatch) {\r\n throw new Error('No se pudieron extraer las definiciones de columnas');\r\n }\r\n\r\n const columnsString = columnsMatch[1];\r\n const columnDefinitions = columnsString.split(',').map(def => def.trim());\r\n\r\n const columns: Column[] = [];\r\n\r\n for (const def of columnDefinitions) {\r\n // Skip constraints that aren't column definitions\r\n if (def.toUpperCase().startsWith('PRIMARY KEY') ||\r\n def.toUpperCase().startsWith('FOREIGN KEY') ||\r\n def.toUpperCase().startsWith('CONSTRAINT')) {\r\n continue;\r\n }\r\n\r\n const parts = def.split(/\\s+/);\r\n if (parts.length < 2) continue;\r\n\r\n const columnName = parts[0];\r\n const columnType = parts[1];\r\n\r\n const column: Column = {\r\n name: columnName,\r\n type: columnType,\r\n nullable: !def.toUpperCase().includes('NOT NULL'),\r\n primaryKey: def.toUpperCase().includes('PRIMARY KEY'),\r\n autoIncrement: def.toUpperCase().includes('AUTOINCREMENT') || def.toUpperCase().includes('AUTO_INCREMENT')\r\n };\r\n\r\n columns.push(column);\r\n }\r\n\r\n return { tableName, columns };\r\n }\r\n\r\n function generateMySQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // Modificar columna existente\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} MODIFY COLUMN ${columnDef};`);\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generatePostgreSQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'postgres');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // PostgreSQL requiere comandos separados para diferentes modificaciones\r\n if (column.type !== oldColumn.type) {\r\n const pgType = column.type.replace('INTEGER', 'INT').replace('TEXT', 'VARCHAR');\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} TYPE ${pgType};`);\r\n }\r\n\r\n if (column.nullable !== oldColumn.nullable) {\r\n const constraint = column.nullable ? 'DROP NOT NULL' : 'SET NOT NULL';\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${constraint};`);\r\n }\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generateSQLiteQueries(\r\n nowSchema: TableSchema,\r\n oldSchema: TableSchema,\r\n tableName: string\r\n ): string[] {\r\n // SQLite no soporta DROP COLUMN directamente, necesitamos recrear la tabla\r\n const queries: string[] = [];\r\n\r\n // Verificar si hay diferencias\r\n if (schemasEqual(nowSchema, oldSchema)) {\r\n return queries; // No hay cambios\r\n }\r\n\r\n const tempTableName = `${tableName}_temp_${Date.now()}`;\r\n\r\n // 1. Crear tabla temporal con el nuevo esquema\r\n const createTempQuery = buildCreateTableQuery(nowSchema, 'sqlite', tempTableName);\r\n queries.push(createTempQuery);\r\n\r\n // 2. Copiar datos compatibles\r\n const commonColumns = nowSchema.columns\r\n .filter(col => oldSchema.columns.some(oldCol => oldCol.name.toLowerCase() === col.name.toLowerCase()))\r\n .map(col => col.name);\r\n\r\n if (commonColumns.length > 0) {\r\n const columnsList = commonColumns.join(', ');\r\n queries.push(`INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName};`);\r\n }\r\n\r\n // 3. Eliminar tabla original\r\n queries.push(`DROP TABLE ${tableName};`);\r\n\r\n // 4. Renombrar tabla temporal\r\n queries.push(`ALTER TABLE ${tempTableName} RENAME TO ${tableName};`);\r\n\r\n return queries;\r\n }\r\n\r\n function generateMongoDBQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n collectionName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Campos a eliminar\r\n const fieldsToRemove: string[] = [];\r\n for (const [fieldName] of oldColumns) {\r\n if (!nowColumns.has(fieldName)) {\r\n fieldsToRemove.push(fieldName);\r\n }\r\n }\r\n\r\n if (fieldsToRemove.length > 0) {\r\n const unsetFields = fieldsToRemove.reduce((acc, field) => {\r\n acc[field] = \"\";\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n queries.push(`db.${collectionName}.updateMany({}, { $unset: ${JSON.stringify(unsetFields)} });`);\r\n }\r\n\r\n // Campos a agregar (con valores por defecto)\r\n const fieldsToAdd: Record<string, any> = {};\r\n for (const [fieldName, column] of nowColumns) {\r\n if (!oldColumns.has(fieldName)) {\r\n // Valor por defecto según el tipo\r\n let defaultValue: any = null;\r\n if (!column.nullable) {\r\n switch (column.type.toUpperCase()) {\r\n case 'INTEGER':\r\n defaultValue = 0;\r\n break;\r\n case 'TEXT':\r\n case 'VARCHAR':\r\n defaultValue = '';\r\n break;\r\n default:\r\n defaultValue = null;\r\n }\r\n }\r\n fieldsToAdd[fieldName] = defaultValue;\r\n }\r\n }\r\n\r\n if (Object.keys(fieldsToAdd).length > 0) {\r\n queries.push(`db.${collectionName}.updateMany({}, { $set: ${JSON.stringify(fieldsToAdd)} });`);\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function buildColumnDefinition(column: Column, dbType: DatabaseType): string {\r\n let def = `${column.name} ${column.type}`;\r\n\r\n if (column.primaryKey) {\r\n def += ' PRIMARY KEY';\r\n }\r\n\r\n if (column.autoIncrement) {\r\n if (dbType === 'mysql') {\r\n def += ' AUTO_INCREMENT';\r\n } else if (dbType === 'sqlite') {\r\n def += ' AUTOINCREMENT';\r\n } else if (dbType === 'postgres') {\r\n def = def.replace(column.type, 'SERIAL');\r\n }\r\n }\r\n\r\n if (!column.nullable) {\r\n def += ' NOT NULL';\r\n }\r\n\r\n return def;\r\n }\r\n\r\n function buildCreateTableQuery(schema: TableSchema, dbType: DatabaseType, tableName?: string): string {\r\n const name = tableName || schema.tableName;\r\n const columnDefs = schema.columns.map(col => buildColumnDefinition(col, dbType));\r\n return `CREATE TABLE ${name} (${columnDefs.join(', ')});`;\r\n }\r\n\r\n function columnsEqual(col1: Column, col2: Column): boolean {\r\n return col1.name.toLowerCase() === col2.name.toLowerCase() &&\r\n col1.type === col2.type &&\r\n col1.nullable === col2.nullable &&\r\n col1.primaryKey === col2.primaryKey &&\r\n col1.autoIncrement === col2.autoIncrement;\r\n }\r\n\r\n function schemasEqual(schema1: TableSchema, schema2: TableSchema): boolean {\r\n if (schema1.columns.length !== schema2.columns.length) {\r\n return false;\r\n }\r\n\r\n const cols1 = new Map(schema1.columns.map(col => [col.name.toLowerCase(), col]));\r\n const cols2 = new Map(schema2.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n for (const [name, col1] of cols1) {\r\n const col2 = cols2.get(name);\r\n if (!col2 || !columnsEqual(col1, col2)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.query(`SELECT * FROM dbcube_schemas_config WHERE table_ref='${tableName}' AND database_ref='${database_ref}'`);\r\n const oldQuery = queryComputes.data[0];\r\n\r\n // Validar que oldQuery existe y tiene struct\r\n if (!oldQuery || !oldQuery.struct) {\r\n console.error('No exist a previus schema please execute the refresh first...', oldQuery);\r\n return [];\r\n }\r\n\r\n const nowSchema = parseCreateTableQuery(nowQuery, dbType);\r\n const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);\r\n\r\n // Verificar que el nombre de tabla coincida\r\n if (nowSchema.tableName.toLowerCase() !== tableName.toLowerCase()) {\r\n throw new Error(`El nombre de tabla en la query (${nowSchema.tableName}) no coincide con el parámetro (${tableName})`);\r\n }\r\n\r\n // Crear mapas para facilitar la comparación\r\n const nowColumns = new Map(nowSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n const oldColumns = new Map(oldSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n switch (dbType) {\r\n case 'mysql':\r\n return generateMySQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'postgres':\r\n return generatePostgreSQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'sqlite':\r\n return generateSQLiteQueries(nowSchema, oldSchema, tableName);\r\n\r\n case 'mongodb':\r\n return generateMongoDBQueries(nowColumns, oldColumns, tableName);\r\n\r\n default:\r\n throw new Error(`Tipo de base de datos no soportado: ${dbType}`);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n } else {\r\n return [nowQuery];\r\n }\r\n }\r\n\r\n static async saveQuery(table_ref: string, database_ref: string, struct: string): Promise<void> {\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n await DbConfig.query(`DELETE FROM dbcube_schemas_config WHERE table_ref='${table_ref}' AND database_ref='${database_ref}'`);\r\n\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;\r\n await DbConfig.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n }\r\n}\r\n\r\nexport class TriggerProcessor {\r\n\r\n static async getTriggers(name: string): Promise<any[]> {\r\n let triggers = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.query(`SELECT * FROM dbcube_triggers_config WHERE database_ref='${name}'`);\r\n triggers = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n triggers = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n triggers = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return triggers;\r\n }\r\n}\r\n\r\n// Utils\r\nfunction convertToType(value: any, type: DataType): any {\r\n switch (type) {\r\n case 'string':\r\n return String(value);\r\n case 'number':\r\n const num = Number(value);\r\n return isNaN(num) ? 0 : num;\r\n case 'boolean':\r\n return Boolean(value);\r\n case 'date':\r\n return value instanceof Date ? value : new Date(value);\r\n case 'object':\r\n return value;\r\n default:\r\n return value;\r\n }\r\n}"],"mappings":"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","names":["path","platform","arch","os","resolve","arch","platform","__filename","fs","path","os","fileURLToPath","dirname","__filename","platform","arch","spawn","fs","path","resolve","path","require","resolve","spawn","path","createRequire","net","spawn","resolve","path","require","path","fs","createRequire","fileURLToPath","dirname","platform","__filename","require","path","fs","resolve","fs","path","type","dbType","tableName"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/Engine.ts","../src/lib/Arquitecture.ts","../src/lib/Donwloader.ts","../src/lib/Binary.ts","../src/lib/Config.ts","../src/lib/DaemonClient.ts","../src/lib/QueryEngine.ts","../src/lib/SqliteExecutor.ts","../src/lib/DbConfig.ts","../src/lib/FileLogger.ts","../src/lib/Processors.ts"],"sourcesContent":["import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { spawn } from \"child_process\";\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport { DaemonClient } from './DaemonClient';\r\n\r\nclass Engine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private daemonFailed = false;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n this.timeout = timeout;\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n /**\r\n * Returns a connected DaemonClient for this database, or null when\r\n * daemon mode is disabled/unavailable (then callers use spawn mode).\r\n */\r\n private async getDaemon(): Promise<DaemonClient | null> {\r\n if (this.daemonFailed || !DaemonClient.isEnabled()) return null;\r\n await this.initializeBinary();\r\n if (!this.binary) return null;\r\n\r\n const binaryPath = this.binary['query_engine' as keyof BinaryType];\r\n if (!binaryPath) return null;\r\n\r\n const client = DaemonClient.get(this.name, binaryPath, this.arguments);\r\n const ok = await client.ensure();\r\n if (!ok) {\r\n this.daemonFailed = true; // don't retry on every query\r\n return null;\r\n }\r\n return client;\r\n }\r\n\r\n /**\r\n * Executes a DML plan. Uses the persistent daemon (sub-millisecond\r\n * overhead) when available; falls back to one-shot spawn otherwise.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.execute(dml, txId);\r\n } catch (error: any) {\r\n if (txId) throw error; // a transaction can't change transport mid-flight\r\n // fall through to spawn mode\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'execute', '--dml', JSON.stringify(dml)] as any);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.raw(query, params, txId);\r\n } catch (error: any) {\r\n if (txId) throw error;\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'raw', '--query', query, '--params', JSON.stringify(params)] as any);\r\n }\r\n\r\n /** Starts a transaction (daemon mode only). Returns the transaction id. */\r\n async beginTransaction(): Promise<string> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return daemon.begin();\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.commit(txId);\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.rollback(txId);\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n return args;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n // Use __filename for CJS, process.cwd() for ESM\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: []) {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n const text = data.toString();\r\n stdoutBuffer += text;\r\n // Mostrar solo el chunk nuevo (no el buffer acumulado) y sin\r\n // la línea de protocolo PROCESS_RESPONSE\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n\r\n // Buscar respuesta JSON completa\r\n const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n const text = data.toString();\r\n stderrBuffer += text;\r\n // Mostrar solo el chunk nuevo (los logs de usuario del engine\r\n // van por stderr) y sin la línea de protocolo\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n\r\n // Buscar respuesta JSON completa\r\n const match = stderrBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n}\r\n\r\nexport { Engine }","import * as os from 'os';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\n\r\ninterface SystemInfo {\r\n platform: string;\r\n arch: string;\r\n release: string;\r\n type: string;\r\n endianness: string;\r\n cpus: number;\r\n}\r\n\r\ninterface BinaryInfo {\r\n name: string;\r\n path: string;\r\n exists: boolean;\r\n executable: boolean;\r\n}\r\n\r\nclass Arquitecture {\r\n private systemInfo: SystemInfo;\r\n\r\n constructor() {\r\n this.systemInfo = this.detectSystemInfo();\r\n }\r\n\r\n /**\r\n * Detecta información completa del sistema\r\n */\r\n private detectSystemInfo(): SystemInfo {\r\n return {\r\n platform: os.platform(),\r\n arch: os.arch(),\r\n release: os.release(),\r\n type: os.type(),\r\n endianness: os.endianness(),\r\n cpus: os.cpus().length\r\n };\r\n }\r\n\r\n /**\r\n * Obtiene la plataforma normalizada\r\n */\r\n getPlatform(): string {\r\n const platform = this.systemInfo.platform;\r\n \r\n switch (platform) {\r\n case 'win32':\r\n return 'windows';\r\n case 'darwin':\r\n return 'macos';\r\n case 'linux':\r\n return 'linux';\r\n case 'freebsd':\r\n return 'freebsd';\r\n case 'openbsd':\r\n return 'openbsd';\r\n case 'sunos':\r\n return 'solaris';\r\n default:\r\n return platform;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene la arquitectura normalizada\r\n */\r\n getArchitecture(): string {\r\n const arch = this.systemInfo.arch;\r\n \r\n switch (arch) {\r\n case 'x64':\r\n return 'x86_64';\r\n case 'x32':\r\n case 'ia32':\r\n return 'i686';\r\n case 'arm64':\r\n return 'aarch64';\r\n case 'arm':\r\n return 'armv7';\r\n case 'ppc64':\r\n return 'powerpc64';\r\n case 'ppc':\r\n return 'powerpc';\r\n case 's390x':\r\n return 's390x';\r\n case 'mips':\r\n return 'mips';\r\n case 'mipsel':\r\n return 'mipsel';\r\n default:\r\n return arch;\r\n }\r\n }\r\n\r\n /**\r\n * Genera el nombre del binario basado en la arquitectura\r\n */\r\n getBinaryName(baseName: string): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n \r\n return `${baseName}-${platform}-${arch}${extension}`;\r\n }\r\n\r\n /**\r\n * Obtiene información completa del sistema\r\n */\r\n getSystemInfo(): SystemInfo {\r\n return { ...this.systemInfo };\r\n }\r\n\r\n /**\r\n * Obtiene el triple de destino (target triple) para Rust\r\n */\r\n getRustTargetTriple(): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n \r\n // Mapeo de plataformas y arquitecturas a target triples de Rust\r\n const targetMap: { [key: string]: string } = {\r\n 'linux-x86_64': 'x86_64-unknown-linux-gnu',\r\n 'linux-i686': 'i686-unknown-linux-gnu',\r\n 'linux-aarch64': 'aarch64-unknown-linux-gnu',\r\n 'linux-armv7': 'armv7-unknown-linux-gnueabihf',\r\n 'macos-x86_64': 'x86_64-apple-darwin',\r\n 'macos-aarch64': 'aarch64-apple-darwin',\r\n 'windows-x86_64': 'x86_64-pc-windows-msvc',\r\n 'windows-i686': 'i686-pc-windows-msvc',\r\n 'windows-aarch64': 'aarch64-pc-windows-msvc',\r\n 'freebsd-x86_64': 'x86_64-unknown-freebsd',\r\n };\r\n \r\n const key = `${platform}-${arch}`;\r\n return targetMap[key] || `${arch}-unknown-${platform}`;\r\n }\r\n\r\n /**\r\n * Muestra información detallada del sistema\r\n */\r\n printSystemInfo(): void {\r\n console.log('🖥️ System Information:');\r\n console.log('├─ Platform:', this.getPlatform());\r\n console.log('├─ Arquitecture:', this.getArchitecture());\r\n console.log('├─ OS Type:', this.systemInfo.type);\r\n console.log('├─ OS Release:', this.systemInfo.release);\r\n console.log('├─ Endianness:', this.systemInfo.endianness);\r\n console.log('├─ CPUs:', this.systemInfo.cpus);\r\n console.log('└─ Rust Target:', this.getRustTargetTriple());\r\n }\r\n}\r\n\r\nexport { \r\n Arquitecture, \r\n SystemInfo,\r\n BinaryInfo\r\n};","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport followRedirects from 'follow-redirects';\r\nconst { https } = followRedirects;\r\nimport * as unzipper from \"unzipper\";\r\nimport { IncomingMessage } from 'http';\r\nimport ora from \"ora\";\r\nimport chalk from \"chalk\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\ninterface DownloadProgress {\r\n downloaded: number;\r\n total: number;\r\n percentage: number;\r\n}\r\n\r\ninterface BinaryVersion {\r\n date_published: string;\r\n name: string;\r\n version: string;\r\n platforms: string[];\r\n download_url: string;\r\n}\r\n\r\nclass Downloader {\r\n private static mainSpinner: any = null;\r\n private static currentSpinner: any = null;\r\n private static readonly VERSION_URLS = {\r\n query: 'https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json',\r\n schema: 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json',\r\n sqlite: 'https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json'\r\n };\r\n\r\n /**\r\n * Fetch latest version from GitHub\r\n */\r\n private static async fetchLatestVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<string> {\r\n const url = this.VERSION_URLS[prefix];\r\n\r\n return new Promise((resolve, reject) => {\r\n https.get(url, (response: IncomingMessage) => {\r\n let data = '';\r\n\r\n response.on('data', (chunk) => {\r\n data += chunk;\r\n });\r\n\r\n response.on('end', () => {\r\n try {\r\n const versions: BinaryVersion[] = JSON.parse(data);\r\n if (versions && versions.length > 0) {\r\n // Get the latest version (first in array)\r\n resolve(versions[0].version);\r\n } else {\r\n reject(new Error('No versions found'));\r\n }\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n\r\n response.on('error', reject);\r\n }).on('error', reject);\r\n });\r\n }\r\n\r\n /**\r\n * Extract version from binary filename\r\n * Example: schema-engine-v1.0.0-windows-x64.exe -> v1.0.0\r\n */\r\n private static extractVersionFromFilename(filename: string): string | null {\r\n const match = filename.match(/-(v\\d+\\.\\d+\\.\\d+)-/);\r\n return match ? match[1] : null;\r\n }\r\n\r\n /**\r\n * Get local version of installed binary\r\n */\r\n private static getLocalVersion(binDir: string, prefix: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-v`);\r\n const binaryFile = files.find(f => binaryPattern.test(f));\r\n\r\n if (binaryFile) {\r\n return this.extractVersionFromFilename(binaryFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Compare versions (returns true if remote is newer)\r\n */\r\n private static isNewerVersion(localVersion: string | null, remoteVersion: string): boolean {\r\n if (!localVersion) return true; // No local version, download\r\n\r\n // Remove 'v' prefix if exists\r\n const cleanLocal = localVersion.replace(/^v/, '');\r\n const cleanRemote = remoteVersion.replace(/^v/, '');\r\n\r\n const localParts = cleanLocal.split('.').map(Number);\r\n const remoteParts = cleanRemote.split('.').map(Number);\r\n\r\n for (let i = 0; i < 3; i++) {\r\n if (remoteParts[i] > localParts[i]) return true;\r\n if (remoteParts[i] < localParts[i]) return false;\r\n }\r\n\r\n return false; // Versions are equal\r\n }\r\n\r\n /**\r\n * Delete old binary files\r\n */\r\n private static deleteOldBinary(binDir: string, prefix: string): void {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-`);\r\n\r\n files.forEach(file => {\r\n if (binaryPattern.test(file)) {\r\n const filePath = path.join(binDir, file);\r\n try {\r\n fs.unlinkSync(filePath);\r\n console.log(`🗑️ Deleted old binary: ${file}`);\r\n } catch (err) {\r\n console.warn(`⚠️ Could not delete: ${file}`);\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n // Ignore errors\r\n }\r\n }\r\n\r\n static get(prefix: string): BinaryType & { name: string; url: string; version: string } {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Note: This is a sync method, version will be \"latest\" placeholder\r\n // The actual version will be resolved during download\r\n const baseName = `${prefix}-engine-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-latest-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version: \"latest\",\r\n query_engine: binaryName,\r\n schema_engine: `${prefix}-engine-${plat}-${archSuffix}${platform === \"windows\" ? \".exe\" : \"\"}`\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Get binary info with actual version from GitHub\r\n */\r\n static async getWithVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<BinaryType & { name: string; url: string; version: string }> {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Fetch latest version from GitHub\r\n const version = await this.fetchLatestVersion(prefix);\r\n\r\n const baseName = `${prefix}-engine-${version}-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${version}-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version,\r\n query_engine: binaryName,\r\n schema_engine: binaryName\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n static async download(targetDir?: string): Promise<void> {\r\n const binDir = targetDir || this.getDefaultBinDir();\r\n fs.mkdirSync(binDir, { recursive: true });\r\n\r\n // Initialize main spinner\r\n this.mainSpinner = ora({\r\n text: chalk.blue('Verificando versiones de binarios...'),\r\n spinner: 'dots12'\r\n }).start();\r\n\r\n const binariesToProcess: Array<{ prefix: 'query' | 'schema' | 'sqlite'; needsUpdate: boolean; localVersion: string | null; remoteVersion: string }> = [];\r\n\r\n // Check versions for all engines\r\n for (const prefix of ['query', 'schema', 'sqlite'] as const) {\r\n try {\r\n const localVersion = this.getLocalVersion(binDir, prefix);\r\n const remoteVersion = await this.fetchLatestVersion(prefix);\r\n const needsUpdate = this.isNewerVersion(localVersion, remoteVersion);\r\n\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate,\r\n localVersion,\r\n remoteVersion\r\n });\r\n\r\n if (needsUpdate) {\r\n console.log(`\\n📦 ${prefix}-engine: ${localVersion || 'not installed'} → ${remoteVersion}`);\r\n } else if (localVersion) {\r\n console.log(`\\n✅ ${prefix}-engine: ${localVersion} (up to date)`);\r\n }\r\n } catch (error) {\r\n console.warn(`⚠️ Could not check version for ${prefix}-engine, will attempt download`);\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate: true,\r\n localVersion: null,\r\n remoteVersion: 'latest'\r\n });\r\n }\r\n }\r\n\r\n const binariesToDownload = binariesToProcess.filter(b => b.needsUpdate);\r\n\r\n if (binariesToDownload.length === 0) {\r\n this.mainSpinner.succeed(chalk.green('All binaries are up to date'));\r\n return;\r\n }\r\n\r\n // Show update progress\r\n this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);\r\n\r\n try {\r\n // Download and update binaries in parallel. allSettled: si una\r\n // descarga falla las demás terminan igual y se reportan TODOS los\r\n // errores (Promise.all descartaba los resultados restantes).\r\n const results = await Promise.allSettled(binariesToDownload.map(async (binary) => {\r\n const maxRetries = 3;\r\n let attempt = 0;\r\n\r\n while (attempt <= maxRetries) {\r\n try {\r\n // Get binary info with version\r\n const binaryInfo = await this.getWithVersion(binary.prefix);\r\n\r\n if (!binaryInfo.name || !binaryInfo.url) {\r\n throw new Error(`Platform or architecture not supported for ${binary.prefix}`);\r\n }\r\n\r\n const tempZipPath = path.join(os.tmpdir(), `dbcube-${binary.prefix}-${Date.now()}.zip`);\r\n const finalBinaryPath = path.join(binDir, binaryInfo.name);\r\n\r\n // Delete old binary first\r\n this.deleteOldBinary(binDir, binary.prefix);\r\n\r\n // Download\r\n await this.downloadFileWithProgress(binaryInfo.url, tempZipPath, binary.prefix);\r\n\r\n // Extract\r\n await this.extractBinary(tempZipPath, finalBinaryPath, binary.prefix);\r\n\r\n console.log(`✅ ${binary.prefix}-engine updated to ${binary.remoteVersion}`);\r\n break;\r\n\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n\r\n if (attempt < maxRetries && (\r\n errorMessage.includes('ECONNRESET') ||\r\n errorMessage.includes('timeout') ||\r\n errorMessage.includes('ETIMEDOUT') ||\r\n errorMessage.includes('ENOTFOUND')\r\n )) {\r\n attempt++;\r\n console.log(`🔄 Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);\r\n await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 1000));\r\n } else {\r\n throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);\r\n }\r\n }\r\n }\r\n }));\r\n\r\n const failures = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');\r\n if (failures.length > 0) {\r\n const messages = failures.map(f => f.reason instanceof Error ? f.reason.message : String(f.reason));\r\n throw new Error(messages.join(' | '));\r\n }\r\n\r\n // Complete successfully\r\n this.mainSpinner.succeed(chalk.green('Binaries updated successfully'));\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n this.mainSpinner.fail(chalk.red(`Error updating binaries: ${errorMessage}`));\r\n throw error;\r\n }\r\n }\r\n\r\n private static updateMainProgress(binary: string, current: number, total: number, status: string, attempt?: number) {\r\n const progressBar = this.createProgressBar(current, total);\r\n const statusEmojis = {\r\n downloading: '📥',\r\n extracting: '📦',\r\n completed: '✅',\r\n exists: '✅',\r\n retrying: '🔄'\r\n };\r\n\r\n const statusMessages = {\r\n downloading: chalk.blue('descargando'),\r\n extracting: chalk.yellow('extrayendo'),\r\n completed: chalk.green('completado'),\r\n exists: chalk.gray('existe'),\r\n retrying: chalk.yellow(`reintentando (${attempt}/${3})`)\r\n };\r\n\r\n const emoji = statusEmojis[status as keyof typeof statusEmojis] || '📥';\r\n const message = statusMessages[status as keyof typeof statusMessages] || status;\r\n\r\n this.mainSpinner.text = `${progressBar} ${emoji} ${chalk.bold(binary)} - ${message}`;\r\n }\r\n\r\n private static createProgressBar(current: number, total: number, width: number = 20): string {\r\n const filled = Math.round((current / total) * width);\r\n const empty = width - filled;\r\n const filledBar = chalk.green('█'.repeat(filled));\r\n const emptyBar = chalk.gray('░'.repeat(empty));\r\n const percentage = chalk.bold(`${current}/${total}`);\r\n return `[${filledBar}${emptyBar}] ${percentage}`;\r\n }\r\n\r\n private static downloadFileWithProgress(url: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const request = https.get(url, { timeout: 0 }, (response: IncomingMessage) => {\r\n if (response.statusCode === 302 || response.statusCode === 301) {\r\n const redirectUrl = response.headers.location;\r\n if (redirectUrl) {\r\n return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(resolve).catch(reject);\r\n }\r\n }\r\n\r\n if (response.statusCode !== 200) {\r\n reject(new Error(`HTTP ${response.statusCode} para ${prefix}`));\r\n return;\r\n }\r\n\r\n const file = fs.createWriteStream(outputPath);\r\n const totalBytes = parseInt(response.headers['content-length'] || '0', 10);\r\n let downloadedBytes = 0;\r\n\r\n response.on('data', (chunk) => {\r\n downloadedBytes += chunk.length;\r\n file.write(chunk);\r\n\r\n if (totalBytes > 0) {\r\n const progress: DownloadProgress = {\r\n downloaded: downloadedBytes,\r\n total: totalBytes,\r\n percentage: (downloadedBytes / totalBytes) * 100\r\n };\r\n this.updateDownloadProgress(prefix, progress);\r\n }\r\n });\r\n\r\n response.on('end', () => {\r\n // Resolver recién cuando el archivo está flushed a disco;\r\n // si no, extractBinary puede leer un ZIP incompleto\r\n file.end(() => resolve());\r\n });\r\n\r\n response.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n\r\n file.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n });\r\n\r\n request.on('error', reject);\r\n request.on('timeout', () => {\r\n request.destroy();\r\n reject(new Error(`Timeout descargando ${prefix}`));\r\n });\r\n });\r\n }\r\n\r\n private static updateDownloadProgress(binary: string, progress: DownloadProgress) {\r\n const percentage = progress.percentage.toFixed(1);\r\n const downloaded = (progress.downloaded / 1024 / 1024).toFixed(1);\r\n const total = (progress.total / 1024 / 1024).toFixed(1);\r\n\r\n // Create a mini progress bar for the binary\r\n const barWidth = 15;\r\n const filled = Math.round((progress.percentage / 100) * barWidth);\r\n const empty = barWidth - filled;\r\n const progressBar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\r\n\r\n const progressText = `[${progressBar}] ${percentage}% (${downloaded}/${total}MB)`;\r\n this.mainSpinner.text = `📥 ${chalk.bold(binary)} - ${progressText}`;\r\n }\r\n\r\n private static extractBinary(zipPath: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n let extracted = false;\r\n\r\n fs.createReadStream(zipPath)\r\n .pipe(unzipper.Parse())\r\n .on('entry', (entry: unzipper.Entry) => {\r\n if (entry.type === 'File' && !extracted) {\r\n extracted = true;\r\n const writeStream = fs.createWriteStream(outputPath);\r\n\r\n entry.pipe(writeStream);\r\n\r\n writeStream.on('finish', () => {\r\n if (process.platform !== 'win32') {\r\n fs.chmodSync(outputPath, 0o755);\r\n }\r\n this.cleanupFile(zipPath);\r\n resolve();\r\n });\r\n\r\n writeStream.on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n });\r\n } else {\r\n entry.autodrain();\r\n }\r\n })\r\n .on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n })\r\n .on('close', () => {\r\n if (!extracted) {\r\n this.cleanupFile(zipPath);\r\n reject(new Error(`No se encontró archivo válido en el ZIP para ${prefix}`));\r\n }\r\n });\r\n });\r\n }\r\n\r\n private static cleanupFile(filePath: string): void {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n\r\n private static getDefaultBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n // Test write permissions\r\n const testFile = path.join(dir, '.test');\r\n fs.writeFileSync(testFile, 'test');\r\n fs.unlinkSync(testFile);\r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n}\r\n\r\nexport { Downloader };","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\"\r\nimport { Downloader } from \"./Donwloader\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\nclass Binary{\r\n private static isDownloading = false;\r\n private static downloadPromise: Promise<void> | null = null;\r\n private static cachedBinaries: { [key: string]: string } = {};\r\n\r\n static async ensureBinariesExist(): Promise<void> {\r\n if (this.isDownloading && this.downloadPromise) {\r\n await this.downloadPromise;\r\n return;\r\n }\r\n\r\n const binDir = this.getBinDir();\r\n\r\n // Always check and download/update binaries\r\n if (!this.isDownloading) {\r\n this.isDownloading = true;\r\n this.downloadPromise = this.downloadBinaries();\r\n\r\n try {\r\n await this.downloadPromise;\r\n } finally {\r\n this.isDownloading = false;\r\n this.downloadPromise = null;\r\n }\r\n }\r\n }\r\n\r\n private static async downloadBinaries(): Promise<void> {\r\n try {\r\n const binDir = this.getBinDir();\r\n await Downloader.download(binDir);\r\n } catch (error) {\r\n console.warn('⚠️ Dbcube: Error descargando binarios:', (error as Error).message);\r\n console.log('🔧 Los binarios se intentarán descargar en la próxima ejecución');\r\n }\r\n }\r\n\r\n private static getBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n \r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n\r\n\r\n private static findVersionedBinary(binDir: string, prefix: string, platform: string, arch: string): string {\r\n // Check cache first\r\n const cacheKey = `${prefix}-${platform}-${arch}`;\r\n if (this.cachedBinaries[cacheKey]) {\r\n const cachedPath = path.join(binDir, this.cachedBinaries[cacheKey]);\r\n if (fs.existsSync(cachedPath)) {\r\n return cachedPath;\r\n }\r\n }\r\n\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n const pattern = new RegExp(`^${prefix}-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platform}-${arch}${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n this.cachedBinaries[cacheKey] = matchingFile;\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n // Fallback to non-versioned name (for backwards compatibility)\r\n const fallbackName = `${prefix}-engine-${platform}-${arch}${platform === 'windows' ? '.exe' : ''}`;\r\n return path.join(binDir, fallbackName);\r\n }\r\n\r\n static async get(): Promise<BinaryType> {\r\n await this.ensureBinariesExist();\r\n\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n const binDir = this.getBinDir();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n return {\r\n query_engine: this.findVersionedBinary(binDir, 'query', plat, archSuffix),\r\n schema_engine: this.findVersionedBinary(binDir, 'schema', plat, archSuffix)\r\n };\r\n }\r\n\r\n return {\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n}\r\n\r\nexport { Binary }","/**\n * Connection parameters for one database.\n */\nexport interface DatabaseConnectionConfig {\n /** Host name or IP (not used by SQLite) */\n HOST?: string;\n /** Database user (not used by SQLite) */\n USER?: string;\n /** Database password (not used by SQLite) */\n PASSWORD?: string;\n /** Database name (SQLite: file name without extension) */\n DATABASE: string;\n /** Port (not used by SQLite) */\n PORT?: number | string;\n}\n\n/**\n * Connection-pool tuning. Every field is optional — engine defaults apply\n * when omitted (maxConnections 5 — 10 for SQLite —, minConnections 2,\n * acquireTimeoutMs 3000, idleTimeoutMs 3600000).\n */\nexport interface DatabasePoolConfig {\n /** Max simultaneous connections held by the engine pool */\n maxConnections?: number;\n /** Connections kept warm even when idle */\n minConnections?: number;\n /** How long to wait for a free connection before failing (ms) */\n acquireTimeoutMs?: number;\n /** Close connections idle longer than this (ms) */\n idleTimeoutMs?: number;\n}\n\n/**\n * Daemon-mode tuning.\n */\nexport interface DatabaseDaemonConfig {\n /** Set to false to disable the persistent TCP daemon (one-shot mode).\n * Transactions require the daemon. Equivalent to DBCUBE_DAEMON=0. */\n enabled?: boolean;\n /** Per-request timeout against the daemon (ms, default 30000) */\n requestTimeoutMs?: number;\n}\n\nexport type DatabaseType = 'mysql' | 'postgres' | 'postgresql' | 'sqlite' | 'mongodb';\n\n/**\n * One database entry in dbcube.config.js.\n */\nexport interface DatabaseDefinition {\n type: DatabaseType;\n config: DatabaseConnectionConfig;\n pool?: DatabasePoolConfig;\n daemon?: DatabaseDaemonConfig;\n}\n\n/**\n * Shape accepted by config.set().\n */\nexport interface ConfigData {\n databases?: Record<string, DatabaseDefinition>;\n [key: string]: unknown;\n}\n\n/**\n * Clase para manejar la configuración del ORM\n */\nexport class Config {\n private data: ConfigData = {};\n private databases: Record<string, DatabaseDefinition> = {};\n\n /**\n * Establece la configuración\n * @param configData - Datos de configuración\n */\n set(configData: ConfigData): void {\n this.data = configData;\n\n if (configData.databases) {\n this.databases = configData.databases;\n }\n }\n\n /**\n * Obtiene un valor de configuración\n * @param key - Clave de configuración\n */\n get<T = unknown>(key: string): T {\n return this.data[key] as T;\n }\n\n /**\n * Obtiene la configuración de una base de datos específica\n * @param dbName - Nombre de la base de datos\n */\n getDatabase(dbName: string): DatabaseDefinition | null {\n return this.databases[dbName] || null;\n }\n\n /**\n * Obtiene todas las bases de datos configuradas\n */\n getAllDatabases(): Record<string, DatabaseDefinition> {\n return this.databases;\n }\n}\n\nexport default Config;\n","import net from 'net';\nimport fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\ninterface DaemonResponse {\n status: number;\n message: string;\n data: any;\n}\n\ninterface PendingRequest {\n resolve: (r: DaemonResponse) => void;\n reject: (e: Error) => void;\n timer: NodeJS.Timeout;\n}\n\n/**\n * TCP client for the query-engine daemon (server mode).\n *\n * Instead of spawning a new engine process per query (30-80ms overhead),\n * the daemon keeps the engine alive with warm connection pools and serves\n * requests over a local TCP socket in <1ms. One daemon per database name.\n */\nexport class DaemonClient {\n private static registry: Map<string, DaemonClient> = new Map();\n\n private name: string;\n private binaryPath: string;\n private engineArgs: string[];\n private socket: net.Socket | null = null;\n private buffer = '';\n private pending: PendingRequest[] = [];\n private starting: Promise<boolean> | null = null;\n private requestTimeout: number;\n\n private constructor(name: string, binaryPath: string, engineArgs: string[], requestTimeout = 30000) {\n this.name = name;\n this.binaryPath = binaryPath;\n this.engineArgs = engineArgs;\n this.requestTimeout = requestTimeout;\n }\n\n static get(name: string, binaryPath: string, engineArgs: string[]): DaemonClient {\n let client = this.registry.get(name);\n if (!client) {\n client = new DaemonClient(name, binaryPath, engineArgs);\n this.registry.set(name, client);\n }\n return client;\n }\n\n static isEnabled(): boolean {\n const flag = process.env.DBCUBE_DAEMON;\n if (flag === '0' || flag === 'false') return false;\n return true; // ON by default — fastest path with automatic fallback\n }\n\n private portfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.json`);\n }\n\n private lockfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.lock`);\n }\n\n /**\n * Exclusive-create lock so two processes never spawn two daemons for the\n * same database at once. Stale locks (crashed starter) expire after 15s.\n */\n private acquireSpawnLock(): boolean {\n const lockPath = this.lockfilePath();\n try {\n fs.mkdirSync(path.dirname(lockPath), { recursive: true });\n const fd = fs.openSync(lockPath, 'wx');\n fs.writeSync(fd, String(process.pid));\n fs.closeSync(fd);\n return true;\n } catch {\n try {\n const age = Date.now() - fs.statSync(lockPath).mtimeMs;\n if (age > 15000) {\n fs.unlinkSync(lockPath);\n return this.acquireSpawnLock();\n }\n } catch { /* lock vanished between checks */ }\n return false;\n }\n }\n\n private releaseSpawnLock(): void {\n try { fs.unlinkSync(this.lockfilePath()); } catch { /* already gone */ }\n }\n\n /**\n * Ensures a usable daemon connection. Returns false when the daemon\n * can't be used (old binary, startup failure) so callers fall back\n * to one-shot spawn mode.\n */\n async ensure(): Promise<boolean> {\n if (this.socket && !this.socket.destroyed) return true;\n if (this.starting) return this.starting;\n\n this.starting = this.connectOrStart().catch(() => false);\n const result = await this.starting;\n this.starting = null;\n return result;\n }\n\n private async connectOrStart(): Promise<boolean> {\n // 1. Try an existing daemon via portfile\n const port = this.readPortfile();\n if (port && await this.tryConnect(port)) return true;\n\n // 2. Stale portfile — remove and start a fresh daemon. The spawn lock\n // ensures only one process boots the daemon; the rest just wait for\n // the new portfile to appear.\n const gotLock = this.acquireSpawnLock();\n try {\n if (gotLock) {\n try { fs.unlinkSync(this.portfilePath()); } catch { /* not there */ }\n this.spawnDaemon();\n }\n\n // 3. Poll the portfile while the daemon boots (up to 10s)\n const deadline = Date.now() + 10000;\n while (Date.now() < deadline) {\n await new Promise(r => setTimeout(r, 150));\n const newPort = this.readPortfile();\n if (newPort && await this.tryConnect(newPort)) return true;\n }\n return false;\n } finally {\n if (gotLock) this.releaseSpawnLock();\n }\n }\n\n private readPortfile(): number | null {\n try {\n const raw = fs.readFileSync(this.portfilePath(), 'utf8');\n const info = JSON.parse(raw);\n const port = info?.port;\n return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;\n } catch {\n return null;\n }\n }\n\n private spawnDaemon(): void {\n const child = spawn(this.binaryPath, [...this.engineArgs, '--action', 'server', '--tcp-port', '9944'], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n });\n child.unref();\n }\n\n private tryConnect(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = net.createConnection({ host: '127.0.0.1', port }, async () => {\n socket.setNoDelay(true);\n this.attach(socket);\n // Verify it's a current-generation daemon (supports ping).\n // Short timeout: if the port was reused by an unrelated\n // process, we must not hang the full request timeout.\n try {\n const pong = await this.send({ action: 'ping' }, 2000);\n resolve(pong.status === 200);\n } catch {\n this.detach();\n resolve(false);\n }\n });\n socket.once('error', () => resolve(false));\n socket.setTimeout(3000, () => { socket.destroy(); resolve(false); });\n });\n }\n\n private attach(socket: net.Socket): void {\n this.socket = socket;\n this.buffer = '';\n socket.setTimeout(0);\n socket.on('data', (chunk: Buffer | string) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n socket.on('close', () => this.detach());\n socket.on('error', () => this.detach());\n }\n\n private detach(): void {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = null;\n }\n // Fail anything still in flight\n for (const req of this.pending.splice(0)) {\n clearTimeout(req.timer);\n req.reject(new Error('Daemon connection lost'));\n }\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += chunk.toString('utf8');\n let idx: number;\n while ((idx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, idx).trim();\n this.buffer = this.buffer.slice(idx + 1);\n if (!line) continue;\n const marker = line.indexOf('PROCESS_RESPONSE:');\n if (marker === -1) continue; // engine log noise\n const jsonPart = line.slice(marker + 'PROCESS_RESPONSE:'.length);\n const req = this.pending.shift();\n if (!req) continue;\n clearTimeout(req.timer);\n try {\n req.resolve(JSON.parse(jsonPart));\n } catch (e: any) {\n req.reject(new Error(`Invalid daemon response: ${e.message}`));\n }\n }\n }\n\n /**\n * Sends a request to the daemon. Responses arrive in FIFO order on the\n * single socket, so pending requests resolve in send order.\n */\n send(payload: Record<string, any>, timeoutMs?: number): Promise<DaemonResponse> {\n return new Promise((resolve, reject) => {\n if (!this.socket || this.socket.destroyed) {\n reject(new Error('Daemon not connected'));\n return;\n }\n const timer = setTimeout(() => {\n const i = this.pending.findIndex(p => p.timer === timer);\n if (i !== -1) this.pending.splice(i, 1);\n reject(new Error('Daemon request timeout'));\n // La respuesta tardía de este request llegaría igual y se\n // emparejaría con el siguiente pending (FIFO desincronizado,\n // datos cruzados). La conexión ya no es confiable: descartarla.\n this.detach();\n }, timeoutMs ?? this.requestTimeout);\n\n this.pending.push({ resolve, reject, timer });\n this.socket.write(JSON.stringify(payload) + '\\n');\n });\n }\n\n async execute(dml: object, txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'execute', dml: JSON.stringify(dml) };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async raw(query: string, params: any[] = [], txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'raw', query, params };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async begin(): Promise<string> {\n const res = await this.send({ action: 'begin' });\n if (res.status !== 200 || !res.data?.tx_id) {\n throw new Error(res.message || 'Failed to begin transaction');\n }\n return res.data.tx_id;\n }\n\n async commit(txId: string): Promise<void> {\n const res = await this.send({ action: 'commit', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to commit transaction');\n }\n\n async rollback(txId: string): Promise<void> {\n const res = await this.send({ action: 'rollback', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to rollback transaction');\n }\n\n async shutdown(): Promise<void> {\n try { await this.send({ action: 'shutdown' }); } catch { /* daemon exits mid-response */ }\n this.detach();\n try { fs.unlinkSync(this.portfilePath()); } catch { /* already gone */ }\n }\n}\n\nexport default DaemonClient;\n","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport * as net from 'net';\r\nimport { spawn, ChildProcess } from \"child_process\";\r\n\r\n// Almacén global de servidores TCP y conexiones persistentes\r\nconst globalTcpServers = new Map<string, { port: number, process: ChildProcess | null }>();\r\nconst globalTcpConnections = new Map<string, net.Socket | null>();\r\n\r\n// Cola de peticiones para cada conexión (evita race conditions)\r\nconst connectionQueues = new Map<string, Array<{\r\n command: Record<string, any>,\r\n resolve: (value: any) => void,\r\n reject: (reason: any) => void\r\n}>>();\r\nconst connectionProcessing = new Map<string, boolean>();\r\n\r\n// Query Cache para evitar JSON.parse repetido\r\nconst queryCache = new Map<string, any>();\r\nconst MAX_CACHE_SIZE = 500;\r\n\r\nclass QueryEngine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private connectionId: string;\r\n private tcpPort: number;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n // daemon.requestTimeoutMs de dbcube.config.js manda sobre el default\r\n this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;\r\n this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || 'localhost'}`;\r\n this.tcpPort = this.generatePort();\r\n }\r\n\r\n private generatePort(): number {\r\n // Empezar desde el puerto 9944 y buscar hacia abajo\r\n return 9944;\r\n }\r\n\r\n private async findAvailablePort(startPort: number): Promise<number> {\r\n for (let port = startPort; port >= 9900; port--) {\r\n if (await this.isPortAvailable(port)) {\r\n return port;\r\n }\r\n }\r\n throw new Error('No available ports found in range 9900-9944');\r\n }\r\n\r\n private isPortAvailable(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const tester = net.createServer();\r\n\r\n tester.once('error', () => resolve(false));\r\n tester.once('listening', () => {\r\n tester.close();\r\n resolve(true);\r\n });\r\n\r\n tester.listen(port, '127.0.0.1');\r\n });\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n\r\n // Tuning de pool desde la sección `pool` de dbcube.config.js\r\n const pool = this.config.pool ?? {};\r\n if (pool.maxConnections != null) args.push('--max-connections', String(pool.maxConnections));\r\n if (pool.minConnections != null) args.push('--min-connections', String(pool.minConnections));\r\n if (pool.acquireTimeoutMs != null) args.push('--acquire-timeout-ms', String(pool.acquireTimeoutMs));\r\n if (pool.idleTimeoutMs != null) args.push('--idle-timeout-ms', String(pool.idleTimeoutMs));\r\n\r\n return args;\r\n }\r\n\r\n /** El daemon puede desactivarse por config (daemon.enabled=false) o por env (DBCUBE_DAEMON=0). */\r\n private daemonEnabled(): boolean {\r\n const flag = process.env.DBCUBE_DAEMON;\r\n if (flag === '0' || flag === 'false') return false;\r\n return this.config?.daemon?.enabled !== false;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: string[]): Promise<ResponseEngine> {\r\n // Detectar si es una acción execute de query_engine\r\n const actionIndex = args.findIndex(arg => arg === '--action');\r\n const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === 'execute';\r\n const isQueryEngine = binary === 'query_engine';\r\n\r\n if (isQueryEngine && isExecuteAction) {\r\n // Solo query_engine con execute usa servidor TCP con cola\r\n return this.executeWithTcpServer(this.argsToCommand(args));\r\n } else {\r\n // Para otras acciones, usar método normal\r\n return this.createProcess(binary, args);\r\n }\r\n }\r\n\r\n private argsToCommand(args: string[]): Record<string, any> {\r\n const command: Record<string, any> = {};\r\n for (let i = 0; i < args.length; i += 2) {\r\n if (args[i].startsWith('--')) {\r\n command[args[i].substring(2)] = args[i + 1];\r\n }\r\n }\r\n return command;\r\n }\r\n\r\n /**\r\n * Executes a DML plan over the persistent TCP server.\r\n * Pass txId to run it inside an active transaction.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const command: Record<string, any> = { action: 'execute', dml: JSON.stringify(dml) };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters\r\n * over the persistent TCP server.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const command: Record<string, any> = { action: 'raw', query, params };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /** Starts a server-side transaction and returns its id. */\r\n async beginTransaction(): Promise<string> {\r\n const res = await this.executeWithTcpServer({ action: 'begin' });\r\n if (res.status !== 200 || !res.data?.tx_id) {\r\n throw new Error(String(res.message || 'Failed to begin transaction (update the query-engine binary: npx dbcube update)'));\r\n }\r\n return res.data.tx_id;\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const res = await this.executeWithTcpServer({ action: 'commit', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to commit transaction'));\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const res = await this.executeWithTcpServer({ action: 'rollback', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to rollback transaction'));\r\n }\r\n\r\n private async executeWithTcpServer(command: Record<string, any>): Promise<ResponseEngine> {\r\n // Daemon desactivado: ejecutar one-shot por spawn. Las transacciones\r\n // requieren el daemon (la TX vive en su memoria entre requests).\r\n if (!this.daemonEnabled()) {\r\n if (command.tx_id || ['begin', 'commit', 'rollback'].includes(command.action)) {\r\n throw new Error('Transactions require daemon mode. Remove daemon.enabled=false from dbcube.config.js (or unset DBCUBE_DAEMON=0).');\r\n }\r\n const args: string[] = [];\r\n for (const [key, value] of Object.entries(command)) {\r\n args.push(`--${key.replace(/_/g, '-')}`, typeof value === 'string' ? value : JSON.stringify(value));\r\n }\r\n return this.createProcess('query_engine', args);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n // Si no hay servidor TCP, iniciarlo\r\n if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {\r\n await this.startTcpServer();\r\n // Solo verificar la primera vez\r\n await this.waitForServerReady();\r\n }\r\n\r\n // Enviar consulta via TCP con sistema de cola\r\n return this.sendTcpRequestFast(command);\r\n }\r\n\r\n private async waitForServerReady(): Promise<void> {\r\n const maxRetries = 10;\r\n const retryDelay = 500; // 500ms entre intentos\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not found');\r\n }\r\n\r\n for (let i = 0; i < maxRetries; i++) {\r\n if (await this.isServerResponding(serverInfo.port)) {\r\n return;\r\n }\r\n await this.sleep(retryDelay);\r\n }\r\n throw new Error('TCP server failed to become ready within timeout');\r\n }\r\n\r\n private async isServerResponding(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const client = new net.Socket();\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n resolve(false);\r\n }, 1000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n client.destroy();\r\n resolve(true);\r\n });\r\n\r\n client.on('error', () => {\r\n clearTimeout(timeout);\r\n resolve(false);\r\n });\r\n });\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n private getCachedDML(dmlJson: string): any {\r\n // Buscar en cache primero\r\n if (queryCache.has(dmlJson)) {\r\n return queryCache.get(dmlJson);\r\n }\r\n\r\n // Parse y guardar en cache, desalojando la entrada más vieja si está\r\n // lleno (Map conserva orden de inserción)\r\n const parsed = JSON.parse(dmlJson);\r\n\r\n if (queryCache.size >= MAX_CACHE_SIZE) {\r\n const oldest = queryCache.keys().next().value;\r\n if (oldest !== undefined) queryCache.delete(oldest);\r\n }\r\n queryCache.set(dmlJson, parsed);\r\n\r\n return parsed;\r\n }\r\n\r\n private async startTcpServer(): Promise<void> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n // Buscar puerto disponible\r\n this.tcpPort = await this.findAvailablePort(this.tcpPort);\r\n\r\n return new Promise((resolve, reject) => {\r\n // Iniciar el query_engine como servidor TCP\r\n const serverArgs = [...this.arguments, '--action', 'server', '--tcp-port', this.tcpPort.toString()];\r\n const serverProcess = spawn(this.binary!['query_engine' as keyof BinaryType], serverArgs);\r\n\r\n let started = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!started) {\r\n serverProcess.kill();\r\n reject(new Error('TCP server startup timeout'));\r\n }\r\n }, 15000); // Aumentar timeout a 15 segundos\r\n\r\n serverProcess.stdout.on('data', (data) => {\r\n const output = data.toString();\r\n\r\n if (output.includes('TCP Server listening on')) {\r\n if (!started) {\r\n started = true;\r\n clearTimeout(timeout);\r\n globalTcpServers.set(this.connectionId, {\r\n port: this.tcpPort,\r\n process: serverProcess\r\n });\r\n resolve();\r\n }\r\n }\r\n });\r\n\r\n serverProcess.stderr.on('data', (data) => {\r\n console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);\r\n });\r\n\r\n serverProcess.on('close', (code) => {\r\n globalTcpServers.delete(this.connectionId);\r\n });\r\n\r\n serverProcess.on('error', (error) => {\r\n if (!started) {\r\n clearTimeout(timeout);\r\n reject(error);\r\n }\r\n });\r\n });\r\n }\r\n\r\n private async sendTcpRequestFast(command: Record<string, any>): Promise<ResponseEngine> {\r\n // Usar sistema de cola para serializar peticiones y evitar race conditions\r\n return new Promise((resolve, reject) => {\r\n // Agregar petición a la cola\r\n let queue = connectionQueues.get(this.connectionId);\r\n if (!queue) {\r\n queue = [];\r\n connectionQueues.set(this.connectionId, queue);\r\n }\r\n\r\n queue.push({ command, resolve, reject });\r\n\r\n // Procesar cola si no se está procesando\r\n this.processQueue();\r\n });\r\n }\r\n\r\n private async processQueue(): Promise<void> {\r\n // Si ya se está procesando esta cola, salir\r\n if (connectionProcessing.get(this.connectionId)) {\r\n return;\r\n }\r\n\r\n const queue = connectionQueues.get(this.connectionId);\r\n if (!queue || queue.length === 0) {\r\n return;\r\n }\r\n\r\n // Marcar como procesando\r\n connectionProcessing.set(this.connectionId, true);\r\n\r\n try {\r\n // Obtener información del servidor\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not initialized');\r\n }\r\n\r\n // Procesar peticiones de forma secuencial\r\n while (queue.length > 0) {\r\n const request = queue.shift();\r\n if (!request) break;\r\n\r\n try {\r\n // Verificar si hay conexión persistente\r\n let connection = globalTcpConnections.get(this.connectionId);\r\n\r\n if (!connection || connection.destroyed || connection.readyState !== 'open') {\r\n // Crear nueva conexión si no existe\r\n connection = await this.createNewConnection(serverInfo.port);\r\n globalTcpConnections.set(this.connectionId, connection);\r\n }\r\n\r\n // Ejecutar petición y esperar respuesta\r\n const result = await this.executeOnConnection(connection, request.command);\r\n request.resolve(result);\r\n } catch (error) {\r\n // Destruir el socket además de olvidarlo: si solo se borra\r\n // del Map queda abierto (leak) y su respuesta tardía podría\r\n // llegar a un listener viejo\r\n const staleConnection = globalTcpConnections.get(this.connectionId);\r\n if (staleConnection) {\r\n try { staleConnection.destroy(); } catch { /* ya cerrado */ }\r\n }\r\n globalTcpConnections.delete(this.connectionId);\r\n request.reject(error);\r\n }\r\n }\r\n } finally {\r\n // Marcar como no procesando\r\n connectionProcessing.set(this.connectionId, false);\r\n }\r\n }\r\n\r\n private async createNewConnection(port: number): Promise<net.Socket> {\r\n return new Promise((resolve, reject) => {\r\n const client = new net.Socket();\r\n client.setNoDelay(true);\r\n client.setKeepAlive(true, 60000);\r\n\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n reject(new Error('Connection timeout'));\r\n }, 5000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n resolve(client);\r\n });\r\n\r\n client.on('error', (error) => {\r\n clearTimeout(timeout);\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n private async executeOnConnection(connection: net.Socket, command: Record<string, any>): Promise<ResponseEngine> {\r\n return new Promise((resolve, reject) => {\r\n let responseBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(new Error('Request timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const onData = (data: Buffer) => {\r\n responseBuffer += data.toString();\r\n const match = responseBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match && !isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolve({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n reject(new Error('Failed to parse response'));\r\n }\r\n }\r\n };\r\n\r\n const onError = (error: Error) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(error);\r\n }\r\n };\r\n\r\n connection.on('data', onData);\r\n connection.on('error', onError);\r\n\r\n // Enviar comando como JSON delimitado por '\\n' (framing del servidor)\r\n connection.write(JSON.stringify(command) + '\\n');\r\n });\r\n }\r\n\r\n private async createProcess(binary: string, args: string[]): Promise<ResponseEngine> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n stdoutBuffer += data.toString();\r\n\r\n const match = stdoutBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n stderrBuffer += data.toString();\r\n\r\n const match = stderrBuffer.match(/PROCESS_RESPONSE:(\\{.*\\})/);\r\n if (match) {\r\n try {\r\n const response: ProcessResponse = JSON.parse(match[1]);\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n });\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n\r\n async disconnect(): Promise<ResponseEngine> {\r\n // Cerrar conexión TCP persistente si existe\r\n const connection = globalTcpConnections.get(this.connectionId);\r\n if (connection && connection.readyState === 'open') {\r\n connection.write(JSON.stringify({ action: 'disconnect' }));\r\n connection.destroy();\r\n globalTcpConnections.delete(this.connectionId);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n if (serverInfo && serverInfo.process && !serverInfo.process.killed) {\r\n serverInfo.process.kill();\r\n globalTcpServers.delete(this.connectionId);\r\n\r\n return {\r\n status: 200,\r\n message: 'TCP server and connections stopped',\r\n data: null\r\n };\r\n }\r\n\r\n return {\r\n status: 200,\r\n message: 'No TCP server to stop',\r\n data: null\r\n };\r\n }\r\n}\r\n\r\nexport { QueryEngine }","import { exec } from 'child_process';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\nimport { promisify } from 'util';\r\nimport { Binary } from './Binary';\r\nimport { createRequire } from 'module';\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\ninterface SqliteResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\nexport class SqliteExecutor {\r\n private binaryPath: string;\r\n private dbPath: string;\r\n\r\n constructor(dbPath: string) {\r\n this.dbPath = dbPath;\r\n this.binaryPath = this.getBinaryPath();\r\n }\r\n\r\n private findVersionedBinary(binDir: string, platform: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // Pattern to match versioned binaries: sqlite-engine-v1.0.0-windows-x64.exe\r\n const pattern = new RegExp(`^sqlite-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platformName}-x64${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getBinaryPath(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find the binary in the new location first\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n const platform = process.platform;\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // First, try to find versioned binary in all possible directories\r\n for (const dir of possibleDirs) {\r\n const versionedPath = this.findVersionedBinary(dir, platform);\r\n if (versionedPath && fs.existsSync(versionedPath)) {\r\n return versionedPath;\r\n }\r\n }\r\n\r\n // Fallback to non-versioned name\r\n const binaryName = `sqlite-engine-${platformName}-x64${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, binaryName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // Fallback to old format if new format not found\r\n const fallbackName = `sqlite-engine${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, fallbackName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // If nothing found, return the preferred path (will trigger download)\r\n return path.join(possibleDirs[0], binaryName);\r\n }\r\n\r\n private async executeBinary(args: string[]): Promise<SqliteResult> {\r\n const escapedArgs = args.map(arg => {\r\n if (arg.includes(' ') || arg.includes('\"') || arg.includes('(') || arg.includes(')')) {\r\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\r\n }\r\n return arg;\r\n });\r\n \r\n const command = `\"${this.binaryPath}\" ${escapedArgs.join(' ')}`;\r\n \r\n try {\r\n const { stdout, stderr } = await execAsync(command, {\r\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\r\n timeout: 30000 // 30s timeout\r\n });\r\n\r\n if (stderr && stderr.trim()) {\r\n console.warn('SQLite Engine Warning:', stderr);\r\n }\r\n\r\n const result = JSON.parse(stdout.trim());\r\n return result;\r\n } catch (error: any) {\r\n if (error.stdout) {\r\n try {\r\n const result = JSON.parse(error.stdout.trim());\r\n return result;\r\n } catch (parseError) {\r\n // Fall through to generic error\r\n }\r\n }\r\n \r\n throw new Error(`SQLite execution failed: ${error.message}`);\r\n }\r\n }\r\n\r\n async connect(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'connect',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success';\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async exists(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'exists',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success' && result.data === true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async query(sql: string, params?: any[]): Promise<SqliteResult> {\r\n const args = [\r\n '--action', 'query',\r\n '--database', this.dbPath,\r\n '--query', sql\r\n ];\r\n\r\n if (params && params.length > 0) {\r\n args.push('--params', JSON.stringify(params));\r\n }\r\n\r\n return this.executeBinary(args);\r\n }\r\n\r\n // Método para múltiples queries (como lo hace better-sqlite3)\r\n async queryMultiple(sql: string): Promise<SqliteResult> {\r\n return this.query(sql);\r\n }\r\n\r\n // Método prepare que simula prepared statements\r\n prepare(sql: string) {\r\n return {\r\n all: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n return Array.isArray(result.data) ? result.data : [];\r\n },\r\n run: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n \r\n // Si es un RunResult, devolverlo tal como está\r\n if (typeof result.data === 'object' && \r\n result.data.hasOwnProperty('changes') && \r\n result.data.hasOwnProperty('lastID')) {\r\n return result.data as RunResult;\r\n }\r\n \r\n return { changes: 0, lastID: 0 };\r\n }\r\n };\r\n }\r\n\r\n // Para compatibilidad con better-sqlite3 API sincrona usando deasync si es necesario\r\n prepareSync(sql: string) {\r\n // Get __filename equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const requireUrl = __filename || import.meta.url;\r\n const require = createRequire(requireUrl);\r\n const deasync = require('deasync');\r\n \r\n return {\r\n all: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else {\r\n result = Array.isArray(res.data) ? res.data : [];\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n },\r\n run: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else if (typeof res.data === 'object' && \r\n res.data.hasOwnProperty('changes') && \r\n res.data.hasOwnProperty('lastID')) {\r\n result = res.data;\r\n } else {\r\n result = { changes: 0, lastID: 0 };\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n }\r\n };\r\n }\r\n}","import { SqliteExecutor } from './SqliteExecutor';\r\nimport * as path from 'path';\r\nimport fs from 'fs';\r\n\r\nconst rootPath = path.resolve(process.cwd(), '.dbcube');\r\n\r\ninterface DatabaseConfig {\r\n name?: string;\r\n HOST?: string;\r\n USER?: string;\r\n PASSWORD?: string;\r\n DATABASE?: string;\r\n PORT?: number;\r\n}\r\n\r\ninterface QueryResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\ninterface ParametrizedQueryResult {\r\n query: string;\r\n parameters: any[];\r\n}\r\n\r\nclass SQLite {\r\n private executor: SqliteExecutor | null = null;\r\n private database?: string;\r\n \r\n constructor(config: DatabaseConfig) {\r\n this.database = config.DATABASE;\r\n }\r\n\r\n async ifExist(): Promise<Boolean> {\r\n if (this.database) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n if (fs.existsSync(configPath)) {\r\n return true;\r\n }\r\n \r\n // También verificar usando el executor\r\n if (!this.executor) {\r\n this.executor = new SqliteExecutor(configPath);\r\n }\r\n return await this.executor.exists();\r\n }\r\n return false;\r\n }\r\n\r\n async connect(): Promise<SqliteExecutor> {\r\n return new Promise(async (resolve, reject) => {\r\n try {\r\n if (!this.executor) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n this.executor = new SqliteExecutor(configPath);\r\n const connected = await this.executor.connect();\r\n \r\n if (!connected) {\r\n throw new Error('Failed to connect to SQLite database');\r\n }\r\n }\r\n resolve(this.executor);\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.executor) {\r\n // SQLiteExecutor no necesita cerrar conexión persistente\r\n this.executor = null;\r\n }\r\n resolve();\r\n });\r\n }\r\n\r\n async query(sqlQuery: string): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n // Usar queryMultiple que maneja múltiples comandos SQL\r\n const result = await this.executor.queryMultiple(sqlQuery);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n async queryWithParameters(sqlQuery: string, params: any[] = []): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!Array.isArray(params)) {\r\n throw new Error('Parameters must be an array.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n const result = await this.executor.query(sqlQuery, params);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n console.log(error);\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n convertToParameterizedQuery(sql: string): ParametrizedQueryResult {\r\n const normalizedSql = sql.replace(/\\s+/g, ' ').trim();\r\n \r\n const baseQueryMatch = normalizedSql.match(/^(.+?)\\s+VALUES\\s*\\(/i);\r\n if (!baseQueryMatch) {\r\n throw new Error('No se pudo encontrar la estructura VALUES en la consulta');\r\n }\r\n \r\n const baseQuery = baseQueryMatch[1];\r\n \r\n const valuesStartIndex = normalizedSql.toUpperCase().indexOf('VALUES');\r\n const valuesSection = normalizedSql.substring(valuesStartIndex);\r\n const valuesMatch = valuesSection.match(/VALUES\\s*\\((.+)\\)\\s*;?\\s*$/i);\r\n if (!valuesMatch) {\r\n throw new Error('No se pudieron extraer los valores de la consulta');\r\n }\r\n \r\n const valuesString = valuesMatch[1];\r\n \r\n function parseValues(str: string): any[] {\r\n const values: any[] = [];\r\n let currentValue = '';\r\n let inQuotes = false;\r\n let quoteChar = '';\r\n let inCompute = false;\r\n let computeDepth = 0;\r\n \r\n for (let i = 0; i < str.length; i++) {\r\n const char = str[i];\r\n const prevChar = str[i - 1];\r\n \r\n if (!inQuotes && str.substring(i, i + 8) === '@compute') {\r\n inCompute = true;\r\n }\r\n \r\n if (inCompute && char === '(') {\r\n computeDepth++;\r\n } else if (inCompute && char === ')') {\r\n computeDepth--;\r\n if (computeDepth === 0) {\r\n inCompute = false;\r\n }\r\n }\r\n \r\n if (!inCompute && (char === '\"' || char === \"'\") && prevChar !== '\\\\') {\r\n if (!inQuotes) {\r\n inQuotes = true;\r\n quoteChar = char;\r\n } else if (char === quoteChar) {\r\n if (str[i + 1] === quoteChar) {\r\n currentValue += char + char;\r\n i++;\r\n continue;\r\n } else {\r\n inQuotes = false;\r\n quoteChar = '';\r\n }\r\n }\r\n }\r\n \r\n if (!inQuotes && !inCompute && char === ',') {\r\n values.push(cleanValue(currentValue.trim()));\r\n currentValue = '';\r\n continue;\r\n }\r\n \r\n currentValue += char;\r\n }\r\n \r\n if (currentValue.trim()) {\r\n values.push(cleanValue(currentValue.trim()));\r\n }\r\n \r\n return values;\r\n }\r\n \r\n function cleanValue(value: string): any {\r\n value = value.trim();\r\n \r\n if (value.startsWith('@compute')) {\r\n return value;\r\n }\r\n \r\n if ((value.startsWith('\"') && value.endsWith('\"')) || \r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\r\n value = value.slice(1, -1);\r\n value = value.replace(/''/g, \"'\").replace(/\"\"/g, '\"');\r\n }\r\n \r\n return value;\r\n }\r\n \r\n const parameters = parseValues(valuesString);\r\n const placeholders = parameters.map(() => '?').join(', ');\r\n const parametrizedQuery = `${baseQuery} VALUES (${placeholders});`;\r\n \r\n return {\r\n query: parametrizedQuery,\r\n parameters: parameters\r\n };\r\n }\r\n}\r\n\r\nexport const DbConfig = new SQLite({DATABASE: \"config\"});\r\nexport default DbConfig;","import * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { EventEmitter } from 'events';\r\n\r\ninterface InterceptOptions {\r\n interceptLog?: boolean;\r\n interceptError?: boolean;\r\n interceptWarn?: boolean;\r\n keepOriginal?: boolean;\r\n useBuffer?: boolean;\r\n}\r\n\r\ninterface ReadOptions {\r\n lines?: number | null;\r\n fromEnd?: boolean;\r\n asArray?: boolean;\r\n}\r\n\r\ninterface WatchOptions {\r\n persistent?: boolean;\r\n interval?: number;\r\n fromEnd?: boolean;\r\n}\r\n\r\ninterface WatchController {\r\n id: string;\r\n stop: () => void;\r\n isWatching: () => boolean;\r\n}\r\n\r\nexport interface InterceptController {\r\n restore: () => void;\r\n commit: () => Promise<boolean>;\r\n discard: () => number;\r\n hasBuffer: () => boolean;\r\n getBufferSize: () => number;\r\n}\r\n\r\ninterface DeleteResult {\r\n filePath: string;\r\n deleted: boolean;\r\n error: string | null;\r\n}\r\n\r\ntype LogLevel = 'INFO' | 'ERROR' | 'WARN' | 'DEBUG';\r\n\r\nexport class FileLogger extends EventEmitter {\r\n private static watchers = new Map<string, (curr: fs.Stats, prev: fs.Stats) => void>(); // Store listener functions\r\n private static buffers = new Map<string, string[]>();\r\n \r\n /**\r\n * Escribe un log en el archivo especificado\r\n * @param filePath - Ruta del archivo de log\r\n * @param message - Mensaje a escribir\r\n * @param level - Nivel del log (INFO, ERROR, WARN, DEBUG)\r\n * @param append - Si debe agregar al final del archivo (default: true)\r\n */\r\n static async write(filePath: string, message: string, level: LogLevel = 'INFO', append: boolean = true): Promise<boolean> {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Formatear el mensaje con timestamp\r\n const timestamp = new Date().toISOString();\r\n const formattedMessage = `[${timestamp}] [${level}] ${message}\\n`;\r\n \r\n // Si existe un buffer para este archivo, agregarlo al buffer en lugar de escribir directamente\r\n if (FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.get(filePath)!.push(formattedMessage);\r\n return true;\r\n }\r\n \r\n // Escribir al archivo normalmente\r\n if (append) {\r\n await fs.promises.appendFile(filePath, formattedMessage, 'utf8');\r\n } else {\r\n await fs.promises.writeFile(filePath, formattedMessage, 'utf8');\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error('Error escribiendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Inicia un buffer temporal para un archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static startBuffer(filePath: string): void {\r\n if (!FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.set(filePath, []);\r\n }\r\n }\r\n \r\n /**\r\n * Confirma y escribe todos los logs del buffer al archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static async commitBuffer(filePath: string): Promise<boolean> {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n if (buffer && buffer.length > 0) {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Escribir todos los logs del buffer\r\n const content = buffer.join('');\r\n await fs.promises.appendFile(filePath, content, 'utf8');\r\n \r\n // Limpiar el buffer\r\n FileLogger.buffers.delete(filePath);\r\n return true;\r\n } catch (error) {\r\n console.error('Error confirmando buffer:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n // Limpiar el buffer aunque esté vacío\r\n FileLogger.buffers.delete(filePath);\r\n return false;\r\n }\r\n \r\n /**\r\n * Descarta todos los logs del buffer sin escribirlos\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static discardBuffer(filePath: string): number {\r\n if (FileLogger.buffers.has(filePath)) {\r\n const discardedCount = FileLogger.buffers.get(filePath)!.length;\r\n FileLogger.buffers.delete(filePath);\r\n return discardedCount;\r\n }\r\n return 0;\r\n }\r\n \r\n /**\r\n * Verifica si existe un buffer activo para un archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static hasBuffer(filePath: string): boolean {\r\n return FileLogger.buffers.has(filePath);\r\n }\r\n \r\n /**\r\n * Obtiene el número de logs en el buffer\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static getBufferSize(filePath: string): number {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n return buffer ? buffer.length : 0;\r\n }\r\n \r\n /**\r\n * Intercepta console.log y console.error para escribir a archivo\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de interceptación\r\n */\r\n static interceptConsole(filePath: string, options: InterceptOptions = {}): InterceptController {\r\n const {\r\n interceptLog = true,\r\n interceptError = true,\r\n interceptWarn = true,\r\n keepOriginal = true, // Mantener el comportamiento original de console\r\n useBuffer = false // Usar buffer temporal\r\n } = options;\r\n \r\n // Iniciar buffer si se solicita\r\n if (useBuffer) {\r\n FileLogger.startBuffer(filePath);\r\n }\r\n \r\n // Guardar referencias originales\r\n const originalLog = console.log;\r\n const originalError = console.error;\r\n const originalWarn = console.warn;\r\n \r\n if (interceptLog) {\r\n console.log = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'INFO').catch(err => {\r\n originalError('Error escribiendo log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalLog.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptError) {\r\n console.error = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'ERROR').catch(err => {\r\n originalError('Error escribiendo error log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalError.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptWarn) {\r\n console.warn = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'WARN').catch(err => {\r\n originalError('Error escribiendo warn log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalWarn.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n // Retornar función para restaurar console original\r\n return {\r\n restore: () => {\r\n if (interceptLog) console.log = originalLog;\r\n if (interceptError) console.error = originalError;\r\n if (interceptWarn) console.warn = originalWarn;\r\n },\r\n commit: async () => {\r\n if (useBuffer) {\r\n return await FileLogger.commitBuffer(filePath);\r\n }\r\n return false;\r\n },\r\n discard: () => {\r\n if (useBuffer) {\r\n return FileLogger.discardBuffer(filePath);\r\n }\r\n return 0;\r\n },\r\n hasBuffer: () => FileLogger.hasBuffer(filePath),\r\n getBufferSize: () => FileLogger.getBufferSize(filePath)\r\n };\r\n }\r\n \r\n /**\r\n * Lee el contenido completo del archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de lectura\r\n * @returns Contenido del archivo\r\n */\r\n static async read(filePath: string, options: ReadOptions = {}): Promise<string | string[]> {\r\n const { \r\n lines = null, // Número de líneas a leer (null = todas)\r\n fromEnd = false, // Si debe leer desde el final\r\n asArray = false // Si debe retornar como array de líneas\r\n } = options;\r\n \r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n return asArray ? [] : '';\r\n }\r\n \r\n let content = await fs.promises.readFile(filePath, 'utf8');\r\n \r\n if (asArray) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n \r\n if (lines !== null) {\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n }\r\n \r\n return linesArray;\r\n }\r\n \r\n // Si se especifica número de líneas y no es array\r\n if (lines !== null) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n content = linesArray.join('\\n');\r\n }\r\n \r\n return content;\r\n } catch (error) {\r\n console.error('Error leyendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Observa un archivo de log en tiempo real\r\n * @param filePath - Ruta del archivo de log\r\n * @param callback - Función callback para nuevas líneas\r\n * @param options - Opciones del watcher\r\n * @returns Objeto con métodos para controlar el watcher\r\n */\r\n static watch(filePath: string, callback: (line: string, filePath: string) => void, options: WatchOptions = {}): WatchController {\r\n const {\r\n persistent = true,\r\n interval = 100,\r\n fromEnd = true // Empezar desde el final del archivo\r\n } = options;\r\n \r\n let lastSize = 0;\r\n let lastPosition = 0;\r\n \r\n // Inicializar posición si el archivo ya existe\r\n if (fs.existsSync(filePath)) {\r\n const stats = fs.statSync(filePath);\r\n lastSize = stats.size;\r\n lastPosition = fromEnd ? stats.size : 0;\r\n }\r\n \r\n // Fixed: Correct listener function signature for fs.watchFile\r\n const listener = async (curr: fs.Stats, prev: fs.Stats) => {\r\n try {\r\n if (curr.size > lastSize) {\r\n // El archivo ha crecido\r\n const stream = fs.createReadStream(filePath, {\r\n start: lastPosition,\r\n end: curr.size - 1,\r\n encoding: 'utf8'\r\n });\r\n \r\n let buffer = '';\r\n \r\n stream.on('data', (chunk) => {\r\n buffer += chunk;\r\n const lines = buffer.split('\\n');\r\n \r\n // Procesar líneas completas\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n if (lines[i].trim()) {\r\n callback(lines[i].trim(), filePath);\r\n }\r\n }\r\n \r\n // Guardar la línea incompleta\r\n buffer = lines[lines.length - 1];\r\n });\r\n \r\n stream.on('end', () => {\r\n // Procesar la última línea si existe\r\n if (buffer.trim()) {\r\n callback(buffer.trim(), filePath);\r\n }\r\n });\r\n \r\n lastSize = curr.size;\r\n lastPosition = curr.size;\r\n }\r\n } catch (error) {\r\n console.error('Error en watcher:', error);\r\n }\r\n };\r\n \r\n // Watcher para cambios en el archivo\r\n fs.watchFile(filePath, { persistent, interval }, listener);\r\n \r\n // Guardar referencia del watcher\r\n const watcherId = `${filePath}_${Date.now()}`;\r\n // Store listener reference for cleanup\r\n FileLogger.watchers.set(watcherId, listener as any);\r\n \r\n // Retornar objeto de control\r\n return {\r\n id: watcherId,\r\n stop: () => {\r\n const storedListener = FileLogger.watchers.get(watcherId);\r\n if (storedListener) {\r\n fs.unwatchFile(filePath, storedListener);\r\n FileLogger.watchers.delete(watcherId);\r\n }\r\n },\r\n isWatching: () => FileLogger.watchers.has(watcherId)\r\n };\r\n }\r\n \r\n /**\r\n * Detiene todos los watchers activos\r\n */\r\n static stopAllWatchers(): void {\r\n for (const [watcherId] of FileLogger.watchers) {\r\n const filePath = watcherId.split('_')[0];\r\n fs.unwatchFile(filePath);\r\n }\r\n FileLogger.watchers.clear();\r\n }\r\n \r\n /**\r\n * Métodos de conveniencia para diferentes niveles de log\r\n */\r\n static async info(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'INFO');\r\n }\r\n \r\n static async error(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'ERROR');\r\n }\r\n \r\n static async warn(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'WARN');\r\n }\r\n \r\n static async debug(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'DEBUG');\r\n }\r\n \r\n /**\r\n * Limpia logs antiguos\r\n * @param filePath - Ruta del archivo de log\r\n * @param maxLines - Máximo número de líneas a mantener\r\n */\r\n static async cleanup(filePath: string, maxLines: number = 1000): Promise<number> {\r\n try {\r\n const lines = await this.read(filePath, { asArray: true }) as string[];\r\n \r\n if (lines.length > maxLines) {\r\n const keepLines = lines.slice(-maxLines);\r\n const content = keepLines.join('\\n') + '\\n';\r\n await fs.promises.writeFile(filePath, content, 'utf8');\r\n return lines.length - maxLines; // Líneas eliminadas\r\n }\r\n \r\n return 0;\r\n } catch (error) {\r\n console.error('Error limpiando logs:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina un archivo de log\r\n * @param filePath - Ruta del archivo de log a eliminar\r\n */\r\n static async deleteLogFile(filePath: string): Promise<boolean> {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n await fs.promises.unlink(filePath);\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n console.error('Error eliminando archivo de log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina múltiples archivos de log\r\n * @param filePaths - Array de rutas de archivos de log a eliminar\r\n */\r\n static async deleteLogFiles(filePaths: string[]): Promise<DeleteResult[]> {\r\n const results: DeleteResult[] = [];\r\n \r\n for (const filePath of filePaths) {\r\n try {\r\n const deleted = await this.deleteLogFile(filePath);\r\n results.push({ filePath, deleted, error: null });\r\n } catch (error) {\r\n results.push({ filePath, deleted: false, error: (error as Error).message });\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n}\r\n\r\nexport default FileLogger;","import { ComputedFieldConfig, DataObject, DataType } from \"../@types/DataObject\";\r\nimport { Column, DatabaseType, TableSchema } from \"../@types/Processor\";\r\nimport DbConfig from \"./DbConfig\";\r\n\r\nexport class ComputedFieldProcessor {\r\n\r\n static async getComputedFields(name: string): Promise<any[]> {\r\n let computedFields = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_computes_config WHERE database_ref=?`, [name]);\r\n computedFields = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n computedFields = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n computedFields = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return computedFields;\r\n }\r\n\r\n /**\r\n * Processes computed field instruction and returns the computed value\r\n * @param instruction - The @compute instruction\r\n * @param rowData - The row data containing column values\r\n * @returns The computed value or null if there's an error\r\n */\r\n static processInstruction(instruction: string, rowData: Record<string, any>): any {\r\n try {\r\n // Remove @compute wrapper and extract the function content\r\n const functionMatch = instruction.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*{([\\s\\S]*?)}\\s*\\)/);\r\n\r\n if (!functionMatch) {\r\n throw new Error('Invalid @compute instruction format');\r\n }\r\n\r\n let functionBody: string = functionMatch[1].trim();\r\n\r\n // Clean up the function body - remove trailing semicolon if present\r\n if (functionBody.endsWith(';')) {\r\n functionBody = functionBody.slice(0, -1).trim();\r\n }\r\n\r\n // Replace @column(columnName) with references into the row parameter.\r\n // Values are passed as data (never interpolated as code) so row content\r\n // cannot inject JavaScript into the compute function.\r\n functionBody = functionBody.replace(/@column\\(([^)]+)\\)/g, (_match, columnName: string) => {\r\n const cleanColumnName = columnName.trim().replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n });\r\n\r\n // Create and execute the function\r\n const computeFunction = new Function('__row', functionBody);\r\n return computeFunction(rowData);\r\n } catch (error) {\r\n console.error('Error processing computed field:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Extracts column dependencies from a computed field instruction\r\n * @param instruction - The @compute instruction\r\n * @returns Array of column names that this computed field depends on\r\n */\r\n static extractDependencies(instruction: string): string[] {\r\n const dependencies: string[] = [];\r\n const columnMatches = instruction.match(/@column\\(([^)]+)\\)/g);\r\n\r\n if (columnMatches) {\r\n for (const match of columnMatches) {\r\n const innerMatch = match.match(/@column\\(([^)]+)\\)/);\r\n if (innerMatch) {\r\n const columnName = innerMatch[1].trim().replace(/['\"]/g, '');\r\n if (!dependencies.includes(columnName)) {\r\n dependencies.push(columnName);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return dependencies;\r\n }\r\n\r\n /**\r\n * Adds computed fields to an array of data objects based on configuration array\r\n * @param data - Array of data objects\r\n * @param computedConfigs - Array of computed field configurations\r\n * @returns Array with the new computed fields added\r\n */\r\n static computedFields<T extends DataObject>(\r\n data: T[],\r\n computedConfigs: ComputedFieldConfig[]\r\n ): T[] {\r\n\r\n return data.map((item, index) => {\r\n let processedItem: any = { ...item };\r\n\r\n // Procesar cada configuración de campo computado\r\n computedConfigs.forEach((config) => {\r\n try {\r\n const { column: fieldName, type, instruction } = config;\r\n\r\n // Reemplazar @column(fieldName) por referencias al parámetro de fila.\r\n // Los valores viajan como datos (nunca como código): el contenido de la\r\n // fila no puede inyectar JavaScript en la función de cómputo.\r\n let processedExpression = instruction.replace(\r\n /@column\\(([^)]+)\\)/g,\r\n (match, columnName) => {\r\n const cleanColumnName = columnName.replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n }\r\n );\r\n\r\n // Extraer la función dentro de @compute\r\n const computeMatch = processedExpression.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*\\{(.*)\\}\\s*\\)/s);\r\n if (!computeMatch) {\r\n throw new Error(`Formato de @compute inválido para campo ${fieldName}`);\r\n }\r\n\r\n const functionBody = computeMatch[1];\r\n\r\n // Crear y ejecutar la función\r\n const computeFunction = new Function('__row', functionBody);\r\n let result = computeFunction(processedItem);\r\n\r\n // Aplicar conversión de tipo\r\n result = convertToType(result, type as DataType);\r\n\r\n // Agregar el nuevo campo al objeto procesado\r\n processedItem[fieldName] = result;\r\n\r\n } catch (error) {\r\n console.error(`Error procesando campo ${config.column} en item ${index}:`, error);\r\n // En caso de error, asignar null al campo\r\n processedItem[config.column] = null;\r\n }\r\n });\r\n\r\n return processedItem;\r\n });\r\n }\r\n}\r\n\r\nexport class TableProcessor {\r\n static async generateAlterQueries(\r\n nowQuery: string,\r\n dbType: DatabaseType,\r\n tableName: string,\r\n database_ref: string,\r\n ): Promise<string[]> {\r\n function parseCreateTableQuery(query: string, dbType: DatabaseType): TableSchema {\r\n // Limpiar y normalizar la query\r\n const cleanQuery = query.trim().replace(/\\s+/g, ' ');\r\n\r\n // Extraer el nombre de la tabla\r\n const tableNameMatch = cleanQuery.match(/CREATE TABLE (?:IF NOT EXISTS )?(\\w+)/i);\r\n if (!tableNameMatch) {\r\n throw new Error('No se pudo extraer el nombre de la tabla');\r\n }\r\n\r\n const tableName = tableNameMatch[1];\r\n\r\n // Extraer las definiciones de columnas\r\n const columnsMatch = cleanQuery.match(/\\((.+)\\)/);\r\n if (!columnsMatch) {\r\n throw new Error('No se pudieron extraer las definiciones de columnas');\r\n }\r\n\r\n const columnsString = columnsMatch[1];\r\n const columnDefinitions = columnsString.split(',').map(def => def.trim());\r\n\r\n const columns: Column[] = [];\r\n\r\n for (const def of columnDefinitions) {\r\n // Skip constraints that aren't column definitions\r\n if (def.toUpperCase().startsWith('PRIMARY KEY') ||\r\n def.toUpperCase().startsWith('FOREIGN KEY') ||\r\n def.toUpperCase().startsWith('CONSTRAINT')) {\r\n continue;\r\n }\r\n\r\n const parts = def.split(/\\s+/);\r\n if (parts.length < 2) continue;\r\n\r\n const columnName = parts[0];\r\n const columnType = parts[1];\r\n\r\n const column: Column = {\r\n name: columnName,\r\n type: columnType,\r\n nullable: !def.toUpperCase().includes('NOT NULL'),\r\n primaryKey: def.toUpperCase().includes('PRIMARY KEY'),\r\n autoIncrement: def.toUpperCase().includes('AUTOINCREMENT') || def.toUpperCase().includes('AUTO_INCREMENT')\r\n };\r\n\r\n columns.push(column);\r\n }\r\n\r\n return { tableName, columns };\r\n }\r\n\r\n function generateMySQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // Modificar columna existente\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} MODIFY COLUMN ${columnDef};`);\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generatePostgreSQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'postgres');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // PostgreSQL requiere comandos separados para diferentes modificaciones\r\n if (column.type !== oldColumn.type) {\r\n const pgType = column.type.replace('INTEGER', 'INT').replace('TEXT', 'VARCHAR');\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} TYPE ${pgType};`);\r\n }\r\n\r\n if (column.nullable !== oldColumn.nullable) {\r\n const constraint = column.nullable ? 'DROP NOT NULL' : 'SET NOT NULL';\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${constraint};`);\r\n }\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generateSQLiteQueries(\r\n nowSchema: TableSchema,\r\n oldSchema: TableSchema,\r\n tableName: string\r\n ): string[] {\r\n // SQLite no soporta DROP COLUMN directamente, necesitamos recrear la tabla\r\n const queries: string[] = [];\r\n\r\n // Verificar si hay diferencias\r\n if (schemasEqual(nowSchema, oldSchema)) {\r\n return queries; // No hay cambios\r\n }\r\n\r\n const tempTableName = `${tableName}_temp_${Date.now()}`;\r\n\r\n // 1. Crear tabla temporal con el nuevo esquema\r\n const createTempQuery = buildCreateTableQuery(nowSchema, 'sqlite', tempTableName);\r\n queries.push(createTempQuery);\r\n\r\n // 2. Copiar datos compatibles\r\n const commonColumns = nowSchema.columns\r\n .filter(col => oldSchema.columns.some(oldCol => oldCol.name.toLowerCase() === col.name.toLowerCase()))\r\n .map(col => col.name);\r\n\r\n if (commonColumns.length > 0) {\r\n const columnsList = commonColumns.join(', ');\r\n queries.push(`INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName};`);\r\n }\r\n\r\n // 3. Eliminar tabla original\r\n queries.push(`DROP TABLE ${tableName};`);\r\n\r\n // 4. Renombrar tabla temporal\r\n queries.push(`ALTER TABLE ${tempTableName} RENAME TO ${tableName};`);\r\n\r\n return queries;\r\n }\r\n\r\n function generateMongoDBQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n collectionName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Campos a eliminar\r\n const fieldsToRemove: string[] = [];\r\n for (const [fieldName] of oldColumns) {\r\n if (!nowColumns.has(fieldName)) {\r\n fieldsToRemove.push(fieldName);\r\n }\r\n }\r\n\r\n if (fieldsToRemove.length > 0) {\r\n const unsetFields = fieldsToRemove.reduce((acc, field) => {\r\n acc[field] = \"\";\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n queries.push(`db.${collectionName}.updateMany({}, { $unset: ${JSON.stringify(unsetFields)} });`);\r\n }\r\n\r\n // Campos a agregar (con valores por defecto)\r\n const fieldsToAdd: Record<string, any> = {};\r\n for (const [fieldName, column] of nowColumns) {\r\n if (!oldColumns.has(fieldName)) {\r\n // Valor por defecto según el tipo\r\n let defaultValue: any = null;\r\n if (!column.nullable) {\r\n switch (column.type.toUpperCase()) {\r\n case 'INTEGER':\r\n defaultValue = 0;\r\n break;\r\n case 'TEXT':\r\n case 'VARCHAR':\r\n defaultValue = '';\r\n break;\r\n default:\r\n defaultValue = null;\r\n }\r\n }\r\n fieldsToAdd[fieldName] = defaultValue;\r\n }\r\n }\r\n\r\n if (Object.keys(fieldsToAdd).length > 0) {\r\n queries.push(`db.${collectionName}.updateMany({}, { $set: ${JSON.stringify(fieldsToAdd)} });`);\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function buildColumnDefinition(column: Column, dbType: DatabaseType): string {\r\n let def = `${column.name} ${column.type}`;\r\n\r\n if (column.primaryKey) {\r\n def += ' PRIMARY KEY';\r\n }\r\n\r\n if (column.autoIncrement) {\r\n if (dbType === 'mysql') {\r\n def += ' AUTO_INCREMENT';\r\n } else if (dbType === 'sqlite') {\r\n def += ' AUTOINCREMENT';\r\n } else if (dbType === 'postgres') {\r\n def = def.replace(column.type, 'SERIAL');\r\n }\r\n }\r\n\r\n if (!column.nullable) {\r\n def += ' NOT NULL';\r\n }\r\n\r\n return def;\r\n }\r\n\r\n function buildCreateTableQuery(schema: TableSchema, dbType: DatabaseType, tableName?: string): string {\r\n const name = tableName || schema.tableName;\r\n const columnDefs = schema.columns.map(col => buildColumnDefinition(col, dbType));\r\n return `CREATE TABLE ${name} (${columnDefs.join(', ')});`;\r\n }\r\n\r\n function columnsEqual(col1: Column, col2: Column): boolean {\r\n return col1.name.toLowerCase() === col2.name.toLowerCase() &&\r\n col1.type === col2.type &&\r\n col1.nullable === col2.nullable &&\r\n col1.primaryKey === col2.primaryKey &&\r\n col1.autoIncrement === col2.autoIncrement;\r\n }\r\n\r\n function schemasEqual(schema1: TableSchema, schema2: TableSchema): boolean {\r\n if (schema1.columns.length !== schema2.columns.length) {\r\n return false;\r\n }\r\n\r\n const cols1 = new Map(schema1.columns.map(col => [col.name.toLowerCase(), col]));\r\n const cols2 = new Map(schema2.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n for (const [name, col1] of cols1) {\r\n const col2 = cols2.get(name);\r\n if (!col2 || !columnsEqual(col1, col2)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla de schemas existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_schemas_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [tableName, database_ref]);\r\n const oldQuery = queryComputes.data[0];\r\n\r\n // Sin esquema previo registrado: tabla nueva → devolver el CREATE\r\n // (el engine lo ejecuta como CREATE TABLE IF NOT EXISTS en modo refresh)\r\n if (!oldQuery || !oldQuery.struct) {\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n }\r\n\r\n const nowSchema = parseCreateTableQuery(nowQuery, dbType);\r\n const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);\r\n\r\n // Verificar que el nombre de tabla coincida\r\n if (nowSchema.tableName.toLowerCase() !== tableName.toLowerCase()) {\r\n throw new Error(`El nombre de tabla en la query (${nowSchema.tableName}) no coincide con el parámetro (${tableName})`);\r\n }\r\n\r\n // Crear mapas para facilitar la comparación\r\n const nowColumns = new Map(nowSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n const oldColumns = new Map(oldSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n switch (dbType) {\r\n case 'mysql':\r\n return generateMySQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'postgres':\r\n return generatePostgreSQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'sqlite':\r\n return generateSQLiteQueries(nowSchema, oldSchema, tableName);\r\n\r\n case 'mongodb':\r\n return generateMongoDBQueries(nowColumns, oldColumns, tableName);\r\n\r\n default:\r\n throw new Error(`Tipo de base de datos no soportado: ${dbType}`);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n } else {\r\n return [nowQuery];\r\n }\r\n }\r\n\r\n static async saveQuery(table_ref: string, database_ref: string, struct: string): Promise<void> {\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n await DbConfig.queryWithParameters(`DELETE FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [table_ref, database_ref]);\r\n\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;\r\n await DbConfig.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n }\r\n}\r\n\r\nexport class TriggerProcessor {\r\n\r\n static async getTriggers(name: string): Promise<any[]> {\r\n let triggers = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_triggers_config WHERE database_ref=?`, [name]);\r\n triggers = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n triggers = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n triggers = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return triggers;\r\n }\r\n}\r\n\r\n// Utils\r\nfunction convertToType(value: any, type: DataType): any {\r\n switch (type) {\r\n case 'string':\r\n return String(value);\r\n case 'number':\r\n const num = Number(value);\r\n return isNaN(num) ? 0 : num;\r\n case 'boolean':\r\n return Boolean(value);\r\n case 'date':\r\n return value instanceof Date ? value : new Date(value);\r\n case 'object':\r\n return value;\r\n default:\r\n return value;\r\n }\r\n}"],"mappings":"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","names":["path","platform","arch","os","resolve","arch","platform","__filename","fs","path","os","fileURLToPath","dirname","__filename","platform","arch","spawn","fs","path","resolve","path","require","resolve","spawn","path","createRequire","net","spawn","resolve","path","require","path","fs","createRequire","fileURLToPath","dirname","platform","__filename","require","path","fs","resolve","fs","path","type","dbType","tableName"]}
|