@dqcai/sqlite 3.0.1 → 3.0.2
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/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1 -1
- package/lib/index.mjs.map +1 -1
- package/lib/index.umd.js +1 -1
- package/lib/index.umd.js.map +1 -1
- package/lib/logger/logger-config.d.ts.map +1 -1
- package/package.json +1 -1
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../node_modules/@dqcai/logger/lib/index.mjs","../src/logger/logger-config.ts","../src/core/universal-dao.ts","../src/core/database-factory.ts","../src/core/database-manager.ts","../src/core/base-service.ts","../src/query/query-builder.ts","../src/core/service-manager.ts","../src/adapters/base-adapter.ts","../src/index.ts"],"sourcesContent":["const h=(...a)=>a.map(e=>typeof e==\"object\"?JSON.stringify(e,null,2):String(e)).join(\" \");class y{constructor(e){this.transports=new Map,this.transportFactory=null,this.config=e,this.sessionId=e.sessionId||this.generateSessionId()}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getSessionId(){return this.sessionId}renewSession(){return this.sessionId=this.generateSessionId(),this.sessionId}setTransportFactory(e){this.transportFactory=e}addTransport(e){this.transports.set(e.name,e)}removeTransport(e){return this.transports.delete(e)}getTransport(e){return this.transports.get(e)}listTransports(){return Array.from(this.transports.keys())}setModuleConfig(e,t){this.config.modules[e]=t}getModuleConfig(e){return this.config.modules[e]}setGlobalEnabled(e){this.config.enabled=e}isGlobalEnabled(){return this.config.enabled}setDefaultLevel(e){this.config.defaultLevel=e}getConfig(){return JSON.parse(JSON.stringify(this.config))}setMetadata(e){this.config.metadata=Object.assign(Object.assign({},this.config.metadata),e)}shouldLog(e,t){if(!this.config.enabled)return!1;const o=this.config.modules[e];return o?o.enabled&&o.levels.includes(t):this.isLevelEnabled(t,this.config.defaultLevel)}isLevelEnabled(e,t){const o=[\"trace\",\"debug\",\"info\",\"warn\",\"error\"],r=o.indexOf(e),i=o.indexOf(t);return r===-1||i===-1?!1:r>=i}getTransportsForModule(e){const t=this.config.modules[e];return((t==null?void 0:t.transports)||[\"console\"]).map(o=>this.transports.get(o)).filter(o=>o!==void 0)}async sendToTransports(e,t){if(t.length===0)return;const o=t.map(async r=>{try{await r.log(e)}catch(i){console.error(`[UniversalLogger] Transport ${r.name} failed:`,i)}});await Promise.allSettled(o)}async log(e,t,o,r){if(!this.shouldLog(e,t))return;const i={timestamp:new Date().toISOString(),level:t,module:e,message:o,data:r,metadata:this.config.metadata,sessionId:this.sessionId},l=this.getTransportsForModule(e);await this.sendToTransports(i,l)}async trace(e,...t){const o=h(...t);await this.log(e,\"trace\",o)}async debug(e,...t){const o=h(...t);await this.log(e,\"debug\",o)}async info(e,...t){const o=h(...t);await this.log(e,\"info\",o)}async warn(e,...t){const o=h(...t);await this.log(e,\"warn\",o)}async error(e,...t){const o=h(...t);await this.log(e,\"error\",o)}async flush(){const e=Array.from(this.transports.values()).filter(t=>typeof t.flush==\"function\").map(t=>t.flush());await Promise.allSettled(e)}async cleanup(){const e=Array.from(this.transports.values()).filter(t=>typeof t.cleanup==\"function\").map(t=>t.cleanup());await Promise.allSettled(e)}createModuleLogger(e){return new b(e,this)}}class b{constructor(e,t){this.module=e,this.logger=t}async flush(){await this.logger.flush()}async trace(...e){const t=h(...e);await this.logger.trace(this.module,t)}async debug(...e){const t=h(...e);await this.logger.debug(this.module,t)}async info(...e){const t=h(...e);await this.logger.info(this.module,t)}async warn(...e){const t=h(...e);await this.logger.warn(this.module,t)}async error(...e){const t=h(...e);await this.logger.error(this.module,t)}getModuleName(){return this.module}}const d=(...a)=>a.map(e=>typeof e==\"object\"?JSON.stringify(e,null,2):String(e)).join(\" \");class ${constructor(e,t){this.moduleName=e,this.logger=t.createModuleLogger(e),this.logger.info(`${e} initialized`).catch(o=>{console.error(`Failed to log initialization for ${e}:`,o)})}logTrace(...e){const t=d(...e);this.logger.trace(t).catch(o=>{console.error(`Failed to log trace [${this.moduleName}]:`,o)})}logDebug(...e){const t=d(...e);this.logger.debug(t).catch(o=>{console.error(`Failed to log debug [${this.moduleName}]:`,o)})}logInfo(...e){const t=d(...e);this.logger.info(t).catch(o=>{console.error(`Failed to log info [${this.moduleName}]:`,o)})}logWarn(...e){const t=d(...e);this.logger.warn(t).catch(o=>{console.error(`Failed to log warn [${this.moduleName}]:`,o)})}logError(...e){const t=d(...e);this.logger.error(t).catch(o=>{console.error(`Failed to log error [${this.moduleName}]:`,o)})}async logTraceAsync(...e){const t=d(...e);await this.logger.trace(t)}async logDebugAsync(...e){const t=d(...e);await this.logger.debug(t)}async logInfoAsync(...e){const t=d(...e);await this.logger.info(t)}async logWarnAsync(...e){const t=d(...e);await this.logger.warn(t)}async logErrorAsync(...e){const t=d(...e);await this.logger.error(t)}async flushLogs(){typeof this.logger.flush==\"function\"&&await this.logger.flush()}getModuleName(){return this.moduleName}}class p{constructor(e={}){this.name=\"console\",this.config=Object.assign({colorize:!0,timestamp:!0,prefix:\"\"},e)}log(e){const t=[];this.config.timestamp&&t.push(`[${e.timestamp}]`),this.config.prefix&&t.push(`[${this.config.prefix}]`),t.push(`[${e.module}]`,`[${e.level.toUpperCase()}]`,e.message);const o=t.join(\" \"),r=e.data?[e.data]:[];this.config.colorize?this.logWithColor(e.level,o,r):this.logWithoutColor(e.level,o,r)}logWithColor(e,t,o){const r={trace:\"#999999\",debug:\"#0066cc\",info:\"#00cc66\",warn:\"#ff9900\",error:\"#cc0000\"}[e];console.log(`%c${t}`,`color: ${r}`,...o)}logWithoutColor(e,t,o){switch(e){case\"error\":console.error(t,...o);break;case\"warn\":console.warn(t,...o);break;case\"info\":console.info(t,...o);break;default:console.log(t,...o)}}}class v{constructor(){this.transportCreators=new Map,this.registerTransport(\"console\",e=>new p(e))}registerTransport(e,t){this.transportCreators.set(e,t)}create(e,t){const o=this.transportCreators.get(e);return o?o(t):null}getAvailableTransports(){return Array.from(this.transportCreators.keys())}}class w{constructor(){this.config={enabled:!0,defaultLevel:\"info\",modules:{}}}setEnabled(e){return this.config.enabled=e,this}setDefaultLevel(e){return this.config.defaultLevel=e,this}setSessionId(e){return this.config.sessionId=e,this}setMetadata(e){return this.config.metadata=e,this}addModule(e,t=!0,o=[\"info\",\"warn\",\"error\"],r=[\"console\"]){return this.config.modules[e]={enabled:t,levels:o,transports:r},this}build(){return JSON.parse(JSON.stringify(this.config))}}class m{static createDevelopmentConfig(){return new w().setEnabled(!0).setDefaultLevel(\"debug\").addModule(\"DatabaseManager\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).build()}static createProductionConfig(){return new w().setEnabled(!0).setDefaultLevel(\"warn\").addModule(\"DatabaseManager\",!0,[\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!1,[],[]).build()}static createCustomConfig(e=!1){return e?m.createDevelopmentConfig():m.createProductionConfig()}}function L(a,e,t){const o=t.value;t.value=async function(...r){this.moduleName||this.constructor.name;const i=this.logger;if(i)try{await i.debug(`Calling method: ${e}`,{args:r.length,argTypes:r.map(s=>typeof s)});const l=Date.now();try{const s=await o.apply(this,r),c=Date.now()-l;return await i.debug(`Method ${e} completed in ${c}ms`),s}catch(s){const c=Date.now()-l;throw await i.error(`Method ${e} failed after ${c}ms`,{error:s instanceof Error?s.message:String(s),stack:s instanceof Error?s.stack:void 0}),s}}catch(l){return console.warn(`[LogMethod] Logging failed for ${e}:`,l),await o.apply(this,r)}else return await o.apply(this,r)}}function M(a=1e3){return function(e,t,o){const r=o.value;o.value=async function(...i){const l=Date.now();try{const s=await r.apply(this,i),c=Date.now()-l,n=this.logger;if(n&&c>a)try{await n.warn(`Slow method detected: ${t} took ${c}ms`,{threshold:a,duration:c,methodName:t,className:this.constructor.name,args:i.length,timestamp:new Date().toISOString()})}catch(g){console.warn(`[LogPerformance] Logging failed for ${t}:`,g)}return s}catch(s){const c=Date.now()-l,n=this.logger;if(n)try{await n.error(`Method ${t} failed after ${c}ms`,{threshold:a,duration:c,methodName:t,className:this.constructor.name,error:s instanceof Error?s.message:String(s)})}catch(g){console.warn(`[LogPerformance] Logging failed for ${t}:`,g)}throw s}}}}function S(a=\"debug\"){return function(e,t,o){const r=o.value;o.value=async function(...i){const l=this.logger,s=`${this.constructor.name}.${t}`;if(l){const c=Date.now();try{await l[a](`\\u2192 Entering ${s}`,{args:i.map((u,f)=>({index:f,type:typeof u,value:typeof u==\"object\"?\"[Object]\":String(u).slice(0,100)}))});const n=await r.apply(this,i),g=Date.now()-c;return await l[a](`\\u2190 Exiting ${s} (${g}ms)`,{duration:g,resultType:typeof n,hasResult:n!==void 0}),n}catch(n){const g=Date.now()-c;throw await l.error(`\\u2717 ${s} threw error (${g}ms)`,{duration:g,error:n instanceof Error?n.message:String(n)}),n}}else return await r.apply(this,i)}}}function C(a=6e4){const e=new Map;return function(t,o,r){const i=r.value;r.value=async function(...l){const s=`${this.constructor.name}.${o}.${JSON.stringify(l)}`,c=Date.now(),n=e.get(s),g=this.logger;if(n&&n.expires>c){if(g)try{await g.debug(`Cache HIT for ${o}`,{cacheKey:s})}catch(f){console.warn(\"[LogCache] Logging failed:\",f)}return n.value}if(g)try{await g.debug(`Cache MISS for ${o}`,{cacheKey:s})}catch(f){console.warn(\"[LogCache] Logging failed:\",f)}const u=await i.apply(this,l);return e.set(s,{value:u,expires:c+a}),u}}}function D(a=3,e=1e3){return function(t,o,r){const i=r.value;r.value=async function(...l){const s=this.logger;let c;for(let n=1;n<=a;n++)try{return s&&n>1&&await s.info(`Retry attempt ${n}/${a} for ${o}`),await i.apply(this,l)}catch(g){if(c=g,s)try{await s.warn(`Attempt ${n}/${a} failed for ${o}`,{attempt:n,maxRetries:a,error:g instanceof Error?g.message:String(g),willRetry:n<a})}catch(u){console.warn(\"[LogRetry] Logging failed:\",u)}if(n<a){const u=e*Math.pow(2,n-1);await new Promise(f=>setTimeout(f,u))}}if(s)try{await s.error(`All ${a} attempts failed for ${o}`,{maxRetries:a,finalError:c instanceof Error?c.message:String(c)})}catch(n){console.warn(\"[LogRetry] Final logging failed:\",n)}throw c}}}function T(a,e=\"debug\"){return function(t){return class extends t{constructor(...o){super(...o);const r=o.find(i=>i&&typeof i==\"object\"&&typeof i.createModuleLogger==\"function\");if(r&&!this.logger){const i=a||t.name;this.logger=r.createModuleLogger(i),this.moduleName=i}}}}}const N=a=>{const e=a||m.createDevelopmentConfig(),t=new y(e);return t.addTransport(new p),t};export{$ as BaseModule,p as ConsoleTransport,v as DefaultTransportFactory,T as EnableLogging,C as LogCache,L as LogMethod,S as LogMethodFlow,M as LogPerformance,D as LogRetry,w as LoggerConfigBuilder,m as LoggerUtils,b as ModuleLogger,y as UniversalLogger,N as createLogger};\n//# sourceMappingURL=index.mjs.map\n","// src/logger/logger-config.ts - Logger configuration for UniversalSQLite\r\nimport {\r\n BaseModule,\r\n LoggerConfigBuilder,\r\n createLogger,\r\n UniversalLogger,\r\n} from \"@dqcai/logger\";\r\n\r\n// export lại module thư viện cho các module con sử dụng\r\nexport { BaseModule };\r\n\r\n/**\r\n * Predefined modules for UniversalSQLite library\r\n */\r\nexport enum SQLiteModules {\r\n // Core modules\r\n DATABASE_MANAGER = \"DatabaseManager\",\r\n DATABASE_FACTORY = \"DatabaseFactory\",\r\n UNIVERSAL_DAO = \"UniversalDAO\",\r\n BASE_SERVICE = \"BaseService\",\r\n SERVICE_MANAGER = \"ServiceManager\",\r\n\r\n // Query modules\r\n QUERY_BUILDER = \"QueryBuilder\",\r\n\r\n // Adapter modules\r\n BASE_ADAPTER = \"BaseAdapter\",\r\n\r\n // Main interface\r\n UNIVERSAL_SQLITE = \"UniversalSQLite\",\r\n\r\n // Transaction & Connection\r\n TRANSACTION = \"Transaction\",\r\n CONNECTION = \"Connection\",\r\n}\r\n\r\n/**\r\n * Default logger configuration for UniversalSQLite\r\n */\r\nexport class SQLiteLoggerConfig {\r\n private static instance: UniversalLogger | null = null;\r\n private static currentConfig: any = null;\r\n\r\n /**\r\n * Create default logger configuration\r\n */\r\n static createDefaultConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(false) // Default: disabled for production\r\n .setDefaultLevel(\"trace\") // Default level\r\n\r\n // Core modules - usually important\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_SQLITE,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // DAO and Services - detailed debugging\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_DAO,\r\n false,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_SERVICE,\r\n false,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.SERVICE_MANAGER,\r\n false,\r\n [\"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // Query building - can be verbose\r\n .addModule(\r\n SQLiteModules.QUERY_BUILDER,\r\n false,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // Adapters - platform specific\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n false,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Initialize logger with default or custom configuration\r\n */\r\n static initialize(customConfig?: any): UniversalLogger {\r\n const config = customConfig || SQLiteLoggerConfig.createDefaultConfig();\r\n SQLiteLoggerConfig.currentConfig = config;\r\n if (\r\n config.enabled &&\r\n (config.defaultLevel === \"trace\" || config.defaultLevel === \"debug\")\r\n ) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.initialize()\",\r\n JSON.stringify(config, null, 2)\r\n );\r\n }\r\n SQLiteLoggerConfig.instance = createLogger(config);\r\n return SQLiteLoggerConfig.instance;\r\n }\r\n\r\n /**\r\n * Get current logger instance\r\n */\r\n static getInstance(): UniversalLogger {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.enabled &&\r\n (SQLiteLoggerConfig.currentConfig.defaultLevel === \"trace\" ||\r\n SQLiteLoggerConfig.currentConfig.defaultLevel === \"debug\")\r\n ) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.getInstance()\",\r\n JSON.stringify(SQLiteLoggerConfig.currentConfig, null, 2)\r\n );\r\n }\r\n if (!SQLiteLoggerConfig.instance) {\r\n return SQLiteLoggerConfig.initialize();\r\n }\r\n return SQLiteLoggerConfig.instance;\r\n }\r\n\r\n /**\r\n * Update logger configuration at runtime\r\n */\r\n static updateConfiguration(newConfig: any): void {\r\n if (\r\n newConfig &&\r\n newConfig.enabled &&\r\n (newConfig.defaultLevel === \"trace\" || newConfig.defaultLevel === \"debug\")\r\n ) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.updateConfiguration()\",\r\n JSON.stringify(newConfig, null, 2)\r\n );\r\n }\r\n SQLiteLoggerConfig.currentConfig = newConfig;\r\n SQLiteLoggerConfig.instance = createLogger(newConfig);\r\n if (\r\n newConfig &&\r\n newConfig.enabled &&\r\n (newConfig.defaultLevel === \"trace\" ||\r\n newConfig.defaultLevel === \"debug\" ||\r\n newConfig.defaultLevel === \"info\")\r\n ) {\r\n console.log(\r\n \"SQLiteLoggerConfig.updateConfiguration()\",\r\n JSON.stringify(SQLiteLoggerConfig.instance, null, 2)\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Enable/disable logging globally\r\n */\r\n static setEnabled(enabled: boolean): void {\r\n if (SQLiteLoggerConfig.currentConfig) {\r\n SQLiteLoggerConfig.currentConfig.enabled = enabled;\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Enable specific module\r\n */\r\n static enableModule(\r\n moduleName: string,\r\n levels?: string[],\r\n appenders?: string[]\r\n ): void {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.modules\r\n ) {\r\n SQLiteLoggerConfig.currentConfig.modules[moduleName] = {\r\n enabled: true,\r\n levels: levels || [\"debug\", \"info\", \"warn\", \"error\"],\r\n appenders: appenders || [\"console\"],\r\n };\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Disable specific module\r\n */\r\n static disableModule(moduleName: string): void {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.modules\r\n ) {\r\n SQLiteLoggerConfig.currentConfig.modules[moduleName] = {\r\n enabled: false,\r\n };\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Create debug-only configuration\r\n */\r\n static createDebugConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(true)\r\n .setDefaultLevel(\"trace\")\r\n\r\n // Enable all modules for debugging\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_SQLITE,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_DAO,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_SERVICE,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.SERVICE_MANAGER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.QUERY_BUILDER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Create production-safe configuration (errors and warnings only)\r\n */\r\n static createProductionConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(true)\r\n .setDefaultLevel(\"warn\")\r\n\r\n // Only critical errors in production\r\n .addModule(SQLiteModules.UNIVERSAL_SQLITE, true, [\"error\"], [\"console\"])\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(SQLiteModules.UNIVERSAL_DAO, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.BASE_SERVICE, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.SERVICE_MANAGER, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.QUERY_BUILDER, true, [\"error\"], [\"console\"])\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Reset to default configuration\r\n */\r\n static reset(): UniversalLogger {\r\n return SQLiteLoggerConfig.initialize();\r\n }\r\n}\r\n\r\n/**\r\n * Export logger instance for use throughout the library\r\n */\r\nexport const sqliteLogger = SQLiteLoggerConfig.getInstance();\r\n\r\n/**\r\n * Helper function to create module-specific logger\r\n */\r\nexport const createModuleLogger = (moduleName: string) => {\r\n const logger = SQLiteLoggerConfig.getInstance();\r\n return {\r\n trace: (message: string, ...args: any[]) =>\r\n logger.trace(moduleName, message, ...args),\r\n debug: (message: string, ...args: any[]) =>\r\n logger.debug(moduleName, message, ...args),\r\n info: (message: string, ...args: any[]) =>\r\n logger.info(moduleName, message, ...args),\r\n warn: (message: string, ...args: any[]) =>\r\n logger.warn(moduleName, message, ...args),\r\n error: (message: string, ...args: any[]) =>\r\n logger.error(moduleName, message, ...args),\r\n };\r\n};\r\n","// src/core/universal-dao.ts\r\nimport {\r\n ColumnDefinition,\r\n DatabaseSchema,\r\n ImportOptions,\r\n ImportResult,\r\n IndexDefinition,\r\n QueryTable,\r\n SQLiteAdapter,\r\n SQLiteConnection,\r\n SQLiteResult,\r\n SQLiteRow,\r\n TableDefinition,\r\n TypeMappingConfig,\r\n WhereClause,\r\n ColumnMapping,\r\n} from \"../types\";\r\n\r\n// Import logger configuration for internal use\r\nimport { SQLiteModules, createModuleLogger } from \"../logger/logger-config\";\r\n\r\nexport class UniversalDAO {\r\n private connection: SQLiteConnection | null = null;\r\n private isConnected: boolean = false;\r\n private inTransaction: boolean = false;\r\n private typeMappingConfig: TypeMappingConfig[\"type_mapping\"] | null = null;\r\n private createIfNotExists: boolean = false;\r\n private forceRecreate: boolean = false;\r\n private logger = createModuleLogger(SQLiteModules.UNIVERSAL_DAO);\r\n\r\n constructor(\r\n private adapter: SQLiteAdapter,\r\n private dbPath: string,\r\n private options?: {\r\n createIfNotExists?: boolean; // Mặc định false - không tạo mới nếu đã tồn tại\r\n forceRecreate?: boolean; // Mặc định false - ép tạo lại = true\r\n }\r\n ) {\r\n this.createIfNotExists = options?.createIfNotExists ?? false;\r\n this.forceRecreate = options?.forceRecreate ?? false;\r\n\r\n this.logger.trace(\"UniversalDAO constructor initialized\", {\r\n dbPath: this.dbPath,\r\n createIfNotExists: this.createIfNotExists,\r\n forceRecreate: this.forceRecreate,\r\n });\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.logger.trace(\"Attempting to connect to database\", {\r\n dbPath: this.dbPath,\r\n });\r\n\r\n if (this.isConnected) {\r\n this.logger.debug(\"Already connected to database, skipping connection\");\r\n return;\r\n }\r\n\r\n try {\r\n this.connection = await this.adapter.connect(this.dbPath);\r\n this.isConnected = true;\r\n this.logger.info(\"Successfully connected to database\", {\r\n dbPath: this.dbPath,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to connect to database\", {\r\n dbPath: this.dbPath,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n this.logger.trace(\"Attempting to disconnect from database\");\r\n\r\n if (this.connection && this.isConnected) {\r\n try {\r\n await this.connection.close();\r\n this.connection = null;\r\n this.isConnected = false;\r\n this.logger.info(\"Successfully disconnected from database\");\r\n } catch (error) {\r\n this.logger.error(\"Error during database disconnection\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n } else {\r\n this.logger.debug(\"Database was not connected, nothing to disconnect\");\r\n }\r\n }\r\n\r\n async close(): Promise<void> {\r\n this.logger.trace(\"Closing database connection\");\r\n await this.disconnect();\r\n }\r\n\r\n // Type mapping utilities\r\n setTypeMappingConfig(config: TypeMappingConfig[\"type_mapping\"]): void {\r\n this.logger.trace(\"Setting type mapping configuration\", { config });\r\n this.typeMappingConfig = config;\r\n this.logger.debug(\"Type mapping configuration updated\");\r\n }\r\n\r\n private convertToSQLiteType(genericType: string): string {\r\n this.logger.trace(\"Converting generic type to SQLite type\", {\r\n genericType,\r\n });\r\n\r\n if (!this.typeMappingConfig || !this.typeMappingConfig.sqlite) {\r\n const defaultType = this.getDefaultSQLiteType(genericType);\r\n this.logger.debug(\"Using default type mapping\", {\r\n genericType,\r\n sqliteType: defaultType,\r\n });\r\n return defaultType;\r\n }\r\n\r\n const sqliteMapping = this.typeMappingConfig.sqlite;\r\n const mappedType = sqliteMapping[genericType.toLowerCase()] || \"TEXT\";\r\n this.logger.debug(\"Using custom type mapping\", {\r\n genericType,\r\n sqliteType: mappedType,\r\n });\r\n return mappedType;\r\n }\r\n\r\n private getDefaultSQLiteType(genericType: string): string {\r\n const defaultMapping: Record<string, string> = {\r\n string: \"TEXT\",\r\n varchar: \"TEXT\",\r\n char: \"TEXT\",\r\n email: \"TEXT\",\r\n url: \"TEXT\",\r\n uuid: \"TEXT\",\r\n integer: \"INTEGER\",\r\n bigint: \"INTEGER\",\r\n smallint: \"INTEGER\",\r\n tinyint: \"INTEGER\",\r\n decimal: \"REAL\",\r\n numeric: \"REAL\",\r\n float: \"REAL\",\r\n double: \"REAL\",\r\n boolean: \"INTEGER\",\r\n timestamp: \"TEXT\",\r\n datetime: \"TEXT\",\r\n date: \"TEXT\",\r\n time: \"TEXT\",\r\n json: \"TEXT\",\r\n array: \"TEXT\",\r\n blob: \"BLOB\",\r\n binary: \"BLOB\",\r\n };\r\n return defaultMapping[genericType.toLowerCase()] || \"TEXT\";\r\n }\r\n\r\n private processColumnDefinition(col: ColumnDefinition): ColumnDefinition {\r\n this.logger.trace(\"Processing column definition\", {\r\n columnName: col.name,\r\n originalType: col.type,\r\n });\r\n\r\n const processedCol: ColumnDefinition = { ...col };\r\n processedCol.type = this.convertToSQLiteType(col.type);\r\n\r\n const options: string[] = [];\r\n if (col.constraints) {\r\n this.logger.trace(\"Processing column constraints\", {\r\n columnName: col.name,\r\n constraints: col.constraints,\r\n });\r\n\r\n const constraints = col.constraints.toUpperCase().split(\" \");\r\n if (constraints.includes(\"PRIMARY\")) {\r\n options.push(\"PRIMARY KEY\");\r\n processedCol.primary_key = true;\r\n }\r\n if (\r\n constraints.includes(\"AUTO_INCREMENT\") ||\r\n constraints.includes(\"AUTOINCREMENT\")\r\n ) {\r\n if (processedCol.primary_key) options.push(\"AUTOINCREMENT\");\r\n processedCol.auto_increment = true;\r\n }\r\n if (constraints.includes(\"NOT\") && constraints.includes(\"NULL\")) {\r\n options.push(\"NOT NULL\");\r\n processedCol.nullable = false;\r\n }\r\n if (constraints.includes(\"UNIQUE\")) {\r\n if (!processedCol.primary_key) options.push(\"UNIQUE\");\r\n processedCol.unique = true;\r\n }\r\n // Handle DEFAULT values\r\n const defaultIndex = constraints.indexOf(\"DEFAULT\");\r\n if (defaultIndex !== -1 && constraints.length > defaultIndex + 1) {\r\n const defaultValue = constraints[defaultIndex + 1];\r\n options.push(`DEFAULT ${defaultValue}`);\r\n processedCol.default = defaultValue;\r\n }\r\n }\r\n\r\n processedCol.option_key = options.join(\" \").trim();\r\n this.logger.debug(\"Column definition processed\", {\r\n columnName: col.name,\r\n finalType: processedCol.type,\r\n options: processedCol.option_key,\r\n });\r\n\r\n return processedCol;\r\n }\r\n\r\n // Schema initialization with enhanced options\r\n async initializeFromSchema(schema: DatabaseSchema): Promise<void> {\r\n this.logger.info(\"Initializing database schema\", {\r\n schemaVersion: schema.version,\r\n tableCount: Object.keys(schema.schemas).length,\r\n });\r\n\r\n this.ensureConnected();\r\n\r\n // Check if schema already exists\r\n let hasExistingSchema = false;\r\n try {\r\n const result = await this.execute(\r\n \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n );\r\n hasExistingSchema = result.rows.length > 0;\r\n if (hasExistingSchema) {\r\n this.logger.debug(\"Existing schema detected\", {\r\n currentVersion: result.rows[0]?.version,\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.debug(\r\n \"No existing schema found or schema info table missing\"\r\n );\r\n hasExistingSchema = false;\r\n }\r\n\r\n // Handle existing schema based on options\r\n if (hasExistingSchema && !this.createIfNotExists && !this.forceRecreate) {\r\n this.logger.info(\r\n \"Schema exists and no recreation options set, using existing schema\"\r\n );\r\n if (schema.type_mapping) {\r\n this.setTypeMappingConfig(schema.type_mapping);\r\n }\r\n return;\r\n }\r\n\r\n if (hasExistingSchema && this.forceRecreate) {\r\n this.logger.warn(\r\n \"Force recreate option enabled, dropping all existing tables\"\r\n );\r\n await this.dropAllTables();\r\n }\r\n\r\n if (schema.type_mapping) {\r\n this.setTypeMappingConfig(schema.type_mapping);\r\n }\r\n\r\n try {\r\n this.logger.debug(\"Enabling foreign key constraints\");\r\n await this.execute(\"PRAGMA foreign_keys = ON\");\r\n } catch (error) {\r\n this.logger.warn(\"Failed to enable foreign key constraints\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n\r\n await this.beginTransaction();\r\n\r\n try {\r\n this.logger.info(\"Creating tables from schema\");\r\n for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n this.logger.debug(\"Creating table\", {\r\n tableName,\r\n columnCount: tableConfig.cols.length,\r\n });\r\n\r\n const tableDefinition: TableDefinition = {\r\n name: tableName,\r\n cols: tableConfig.cols.map((col) =>\r\n this.processColumnDefinition(col)\r\n ),\r\n description: tableConfig.description,\r\n indexes: tableConfig.indexes,\r\n foreign_keys: tableConfig.foreign_keys,\r\n };\r\n await this.createTableWithForeignKeys(tableDefinition);\r\n }\r\n\r\n this.logger.info(\"Creating indexes for tables\");\r\n for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n if (tableConfig.indexes?.length) {\r\n this.logger.debug(\"Creating indexes for table\", {\r\n tableName,\r\n indexCount: tableConfig.indexes.length,\r\n });\r\n await this.createIndexesForTable(tableName, tableConfig.indexes);\r\n }\r\n }\r\n\r\n await this.setSchemaVersion(schema.version);\r\n await this.commitTransaction();\r\n this.logger.info(\"Schema initialization completed successfully\", {\r\n version: schema.version,\r\n });\r\n } catch (error) {\r\n this.logger.error(\r\n \"Schema initialization failed, rolling back transaction\",\r\n {\r\n error: error instanceof Error ? error.message : String(error),\r\n }\r\n );\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n private async dropAllTables(): Promise<void> {\r\n this.logger.info(\"Dropping all existing tables\");\r\n\r\n const tables = await this.execute(\r\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\r\n );\r\n\r\n this.logger.debug(\"Found tables to drop\", {\r\n tableCount: tables.rows.length,\r\n });\r\n\r\n await this.beginTransaction();\r\n\r\n try {\r\n for (const table of tables.rows) {\r\n this.logger.trace(\"Dropping table\", { tableName: table.name });\r\n await this.execute(`DROP TABLE IF EXISTS ${table.name}`);\r\n }\r\n await this.commitTransaction();\r\n this.logger.info(\"All tables dropped successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to drop tables, rolling back\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n private async createTableWithForeignKeys(\r\n table: TableDefinition\r\n ): Promise<void> {\r\n this.logger.trace(\"Creating table with foreign keys\", {\r\n tableName: table.name,\r\n });\r\n\r\n const columnDefs = table.cols.map((col) =>\r\n `${col.name} ${col.type} ${col.option_key || \"\"}`.trim()\r\n );\r\n\r\n const foreignKeyDefs: string[] = [];\r\n if (table.foreign_keys) {\r\n this.logger.debug(\"Processing foreign keys\", {\r\n tableName: table.name,\r\n fkCount: table.foreign_keys.length,\r\n });\r\n for (const fk of table.foreign_keys) {\r\n let fkSql = `FOREIGN KEY (${fk.column}) REFERENCES ${fk.references.table}(${fk.references.column})`;\r\n if (fk.on_delete) fkSql += ` ON DELETE ${fk.on_delete}`;\r\n if (fk.on_update) fkSql += ` ON UPDATE ${fk.on_update}`;\r\n foreignKeyDefs.push(fkSql);\r\n }\r\n }\r\n\r\n const allDefs = [...columnDefs, ...foreignKeyDefs];\r\n const sql = `CREATE TABLE IF NOT EXISTS ${table.name} (${allDefs.join(\r\n \", \"\r\n )})`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.debug(\"Table created successfully\", {\r\n tableName: table.name,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to create table\", {\r\n tableName: table.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private async createIndexesForTable(\r\n tableName: string,\r\n indexes: IndexDefinition[]\r\n ): Promise<void> {\r\n this.logger.trace(\"Creating indexes for table\", {\r\n tableName,\r\n indexCount: indexes.length,\r\n });\r\n\r\n for (const index of indexes) {\r\n const columns = index.columns.join(\", \");\r\n const isUnique = index.unique || false;\r\n const sql = `CREATE ${isUnique ? \"UNIQUE\" : \"\"} INDEX IF NOT EXISTS ${\r\n index.name\r\n } ON ${tableName} (${columns})`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.debug(\"Index created successfully\", {\r\n indexName: index.name,\r\n tableName,\r\n columns: index.columns,\r\n unique: isUnique,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to create index\", {\r\n indexName: index.name,\r\n tableName,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n // Transaction management\r\n async beginTransaction(): Promise<void> {\r\n this.logger.trace(\"Beginning transaction\");\r\n\r\n if (this.inTransaction) {\r\n const error = new Error(\"Transaction already in progress\");\r\n this.logger.error(\"Cannot begin transaction\", { error: error.message });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"BEGIN TRANSACTION\");\r\n this.inTransaction = true;\r\n this.logger.debug(\"Transaction started successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to begin transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async commitTransaction(): Promise<void> {\r\n this.logger.trace(\"Committing transaction\");\r\n\r\n if (!this.inTransaction) {\r\n const error = new Error(\"No transaction in progress\");\r\n this.logger.error(\"Cannot commit transaction\", { error: error.message });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"COMMIT\");\r\n this.inTransaction = false;\r\n this.logger.debug(\"Transaction committed successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to commit transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async rollbackTransaction(): Promise<void> {\r\n this.logger.trace(\"Rolling back transaction\");\r\n\r\n if (!this.inTransaction) {\r\n const error = new Error(\"No transaction in progress\");\r\n this.logger.error(\"Cannot rollback transaction\", {\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"ROLLBACK\");\r\n this.inTransaction = false;\r\n this.logger.debug(\"Transaction rolled back successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to rollback transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Schema management\r\n async getSchemaVersion(): Promise<string> {\r\n this.logger.trace(\"Getting schema version\");\r\n\r\n try {\r\n const result = await this.getRst(\r\n \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n );\r\n const version = result.version || \"0\";\r\n this.logger.debug(\"Schema version retrieved\", { version });\r\n return version;\r\n } catch (error) {\r\n this.logger.debug(\"No schema version found, returning default\", {\r\n defaultVersion: \"0\",\r\n });\r\n return \"0\";\r\n }\r\n }\r\n\r\n async setSchemaVersion(version: string): Promise<void> {\r\n this.logger.trace(\"Setting schema version\", { version });\r\n\r\n try {\r\n await this.execute(`CREATE TABLE IF NOT EXISTS _schema_info (\r\n version TEXT NOT NULL,\r\n applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\r\n )`);\r\n await this.execute(`INSERT INTO _schema_info (version) VALUES (?)`, [\r\n version,\r\n ]);\r\n this.logger.info(\"Schema version set successfully\", { version });\r\n } catch (error) {\r\n this.logger.error(\"Failed to set schema version\", {\r\n version,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // CRUD Operations\r\n async insert(insertTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing insert operation\", {\r\n tableName: insertTable.name,\r\n });\r\n\r\n const validCols = insertTable.cols.filter(\r\n (col) => col.value !== undefined && col.value !== null\r\n );\r\n\r\n if (validCols.length === 0) {\r\n const error = new Error(\"No valid columns to insert\");\r\n this.logger.error(\"Insert operation failed\", {\r\n tableName: insertTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n const columnNames = validCols.map((col) => col.name).join(\", \");\r\n const placeholders = validCols.map(() => \"?\").join(\", \");\r\n const params = validCols.map((col) =>\r\n typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n );\r\n\r\n const sql = `INSERT INTO ${insertTable.name} (${columnNames}) VALUES (${placeholders})`;\r\n\r\n this.logger.debug(\"Executing insert query\", {\r\n tableName: insertTable.name,\r\n columnCount: validCols.length,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.info(\"Insert operation completed successfully\", {\r\n tableName: insertTable.name,\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowid: result.lastInsertRowId,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Insert operation failed\", {\r\n tableName: insertTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async update(updateTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing update operation\", {\r\n tableName: updateTable.name,\r\n });\r\n\r\n const setCols = updateTable.cols.filter(\r\n (col) =>\r\n col.value !== undefined &&\r\n !updateTable.wheres?.some((w) => w.name === col.name)\r\n );\r\n\r\n if (setCols.length === 0) {\r\n const error = new Error(\"No columns to update\");\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n const setClause = setCols.map((col) => `${col.name} = ?`).join(\", \");\r\n const params = setCols.map((col) =>\r\n typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n );\r\n\r\n let sql = `UPDATE ${updateTable.name} SET ${setClause}`;\r\n const whereClause = this.buildWhereClause(updateTable.wheres);\r\n\r\n if (!whereClause.sql) {\r\n const error = new Error(\"WHERE clause is required for UPDATE operation\");\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n sql += whereClause.sql;\r\n params.push(...whereClause.params);\r\n\r\n this.logger.debug(\"Executing update query\", {\r\n tableName: updateTable.name,\r\n updateColumnCount: setCols.length,\r\n whereConditions: updateTable.wheres?.length || 0,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.info(\"Update operation completed successfully\", {\r\n tableName: updateTable.name,\r\n rowsAffected: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async delete(deleteTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing delete operation\", {\r\n tableName: deleteTable.name,\r\n });\r\n\r\n let sql = `DELETE FROM ${deleteTable.name}`;\r\n const whereClause = this.buildWhereClause(deleteTable.wheres);\r\n\r\n if (!whereClause.sql) {\r\n const error = new Error(\"WHERE clause is required for DELETE operation\");\r\n this.logger.error(\"Delete operation failed\", {\r\n tableName: deleteTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n sql += whereClause.sql;\r\n\r\n this.logger.debug(\"Executing delete query\", {\r\n tableName: deleteTable.name,\r\n whereConditions: deleteTable.wheres?.length || 0,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, whereClause.params);\r\n this.logger.info(\"Delete operation completed successfully\", {\r\n tableName: deleteTable.name,\r\n rowsAffected: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Delete operation failed\", {\r\n tableName: deleteTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async select(selectTable: QueryTable): Promise<SQLiteRow> {\r\n this.logger.trace(\"Performing select single operation\", {\r\n tableName: selectTable.name,\r\n });\r\n\r\n const { sql, params } = this.buildSelectQuery(selectTable, \" LIMIT 1\");\r\n\r\n this.logger.debug(\"Executing select single query\", {\r\n tableName: selectTable.name,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n const row = result.rows[0] || {};\r\n this.logger.debug(\"Select single operation completed\", {\r\n tableName: selectTable.name,\r\n hasResult: !!result.rows[0],\r\n });\r\n return row;\r\n } catch (error) {\r\n this.logger.error(\"Select single operation failed\", {\r\n tableName: selectTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async selectAll(selectTable: QueryTable): Promise<SQLiteRow[]> {\r\n this.logger.trace(\"Performing select all operation\", {\r\n tableName: selectTable.name,\r\n });\r\n\r\n const { sql, params } = this.buildSelectQuery(selectTable);\r\n\r\n this.logger.debug(\"Executing select all query\", {\r\n tableName: selectTable.name,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.debug(\"Select all operation completed\", {\r\n tableName: selectTable.name,\r\n rowCount: result.rows.length,\r\n });\r\n return result.rows;\r\n } catch (error) {\r\n this.logger.error(\"Select all operation failed\", {\r\n tableName: selectTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Utility methods\r\n private buildSelectQuery(\r\n selectTable: QueryTable,\r\n suffix: string = \"\"\r\n ): { sql: string; params: any[] } {\r\n const columns =\r\n selectTable.cols.length > 0\r\n ? selectTable.cols.map((col) => col.name).join(\", \")\r\n : \"*\";\r\n\r\n let sql = `SELECT ${columns} FROM ${selectTable.name}`;\r\n const whereClause = this.buildWhereClause(selectTable.wheres);\r\n sql += whereClause.sql;\r\n\r\n if (selectTable.orderbys?.length) {\r\n const orderBy = selectTable.orderbys\r\n .map((o) => `${o.name} ${o.direction || \"ASC\"}`)\r\n .join(\", \");\r\n sql += ` ORDER BY ${orderBy}`;\r\n }\r\n\r\n if (selectTable.limitOffset) {\r\n if (selectTable.limitOffset.limit)\r\n sql += ` LIMIT ${selectTable.limitOffset.limit}`;\r\n if (selectTable.limitOffset.offset)\r\n sql += ` OFFSET ${selectTable.limitOffset.offset}`;\r\n }\r\n\r\n sql += suffix;\r\n return { sql, params: whereClause.params };\r\n }\r\n\r\n private buildWhereClause(\r\n wheres?: WhereClause[],\r\n clause: string = \"WHERE\"\r\n ): { sql: string; params: any[] } {\r\n if (!wheres || wheres.length === 0) {\r\n return { sql: \"\", params: [] };\r\n }\r\n\r\n const conditions: string[] = [];\r\n const params: any[] = [];\r\n\r\n for (const where of wheres) {\r\n const operator = where.operator || \"=\";\r\n conditions.push(`${where.name} ${operator} ?`);\r\n params.push(where.value);\r\n }\r\n\r\n return { sql: ` ${clause} ${conditions.join(\" AND \")}`, params };\r\n }\r\n\r\n convertJsonToQueryTable(\r\n tableName: string,\r\n json: Record<string, any>,\r\n idFields: string[] = [\"id\"]\r\n ): QueryTable {\r\n this.logger.trace(\"Converting JSON to QueryTable\", {\r\n tableName,\r\n fieldCount: Object.keys(json).length,\r\n idFields,\r\n });\r\n\r\n const queryTable: QueryTable = { name: tableName, cols: [], wheres: [] };\r\n\r\n for (const [key, value] of Object.entries(json)) {\r\n queryTable.cols.push({ name: key, value });\r\n if (idFields.includes(key) && value !== undefined) {\r\n queryTable.wheres?.push({ name: key, value });\r\n }\r\n }\r\n\r\n this.logger.debug(\"JSON converted to QueryTable\", {\r\n tableName,\r\n columnCount: queryTable.cols.length,\r\n whereCount: queryTable.wheres?.length || 0,\r\n });\r\n\r\n return queryTable;\r\n }\r\n\r\n // Enhanced Data Import functionality\r\n async importData(options: ImportOptions): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import operation\", {\r\n tableName: options.tableName,\r\n totalRows: options.data.length,\r\n batchSize: options.batchSize || 1000,\r\n validateData: options.validateData,\r\n updateOnConflict: options.updateOnConflict,\r\n skipErrors: options.skipErrors,\r\n });\r\n\r\n const startTime = Date.now();\r\n const result: ImportResult = {\r\n totalRows: options.data.length,\r\n successRows: 0,\r\n errorRows: 0,\r\n errors: [],\r\n executionTime: 0,\r\n };\r\n\r\n if (!this.isConnected) {\r\n const error = new Error(\"Database is not connected\");\r\n this.logger.error(\"Import failed - database not connected\");\r\n throw error;\r\n }\r\n\r\n if (!options.data || options.data.length === 0) {\r\n this.logger.warn(\"No data provided for import, returning empty result\");\r\n result.executionTime = Date.now() - startTime;\r\n return result;\r\n }\r\n\r\n const tableInfo = await this.getTableInfo(options.tableName);\r\n if (tableInfo.length === 0) {\r\n const error = new Error(`Table '${options.tableName}' does not exist`);\r\n this.logger.error(\"Import failed - table does not exist\", {\r\n tableName: options.tableName,\r\n });\r\n throw error;\r\n }\r\n\r\n this.logger.debug(\"Table info retrieved for import\", {\r\n tableName: options.tableName,\r\n columnCount: tableInfo.length,\r\n });\r\n\r\n const columnMap = new Map(\r\n tableInfo.map((col) => [col.name.toLowerCase(), col])\r\n );\r\n const batchSize = options.batchSize || 1000;\r\n let processedCount = 0;\r\n const skipAutoIncrementPK = !options.includeAutoIncrementPK;\r\n\r\n try {\r\n await this.beginTransaction();\r\n\r\n for (let i = 0; i < options.data.length; i += batchSize) {\r\n const batch = options.data.slice(i, i + batchSize);\r\n this.logger.debug(\"Processing import batch\", {\r\n batchNumber: Math.floor(i / batchSize) + 1,\r\n batchSize: batch.length,\r\n totalBatches: Math.ceil(options.data.length / batchSize),\r\n });\r\n\r\n for (let j = 0; j < batch.length; j++) {\r\n const rowIndex = i + j;\r\n const rowData = batch[j];\r\n\r\n try {\r\n const processedData = options.validateData\r\n ? this.validateAndTransformRow(\r\n rowData,\r\n columnMap,\r\n options.tableName,\r\n skipAutoIncrementPK\r\n )\r\n : this.transformRowData(rowData, columnMap, skipAutoIncrementPK);\r\n\r\n if (options.updateOnConflict && options.conflictColumns) {\r\n await this.insertOrUpdate(\r\n options.tableName,\r\n processedData,\r\n options.conflictColumns\r\n );\r\n } else {\r\n await this.insertRow(options.tableName, processedData);\r\n }\r\n\r\n result.successRows++;\r\n } catch (error) {\r\n result.errorRows++;\r\n const errorInfo = {\r\n rowIndex,\r\n error: error instanceof Error ? error.message : String(error),\r\n rowData,\r\n };\r\n result.errors.push(errorInfo);\r\n\r\n this.logger.warn(\"Row import failed\", {\r\n rowIndex,\r\n tableName: options.tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n\r\n if (options.onError) {\r\n options.onError(\r\n error instanceof Error ? error : new Error(String(error)),\r\n rowIndex,\r\n rowData\r\n );\r\n }\r\n\r\n if (!options.skipErrors) {\r\n this.logger.error(\r\n \"Import operation stopped due to error and skipErrors=false\"\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n processedCount++;\r\n if (options.onProgress && processedCount % 100 === 0) {\r\n options.onProgress(processedCount, options.data.length);\r\n }\r\n }\r\n }\r\n\r\n await this.commitTransaction();\r\n this.logger.info(\"Data import completed successfully\", {\r\n tableName: options.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows,\r\n executionTime: Date.now() - startTime,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Import operation failed, rolling back transaction\", {\r\n tableName: options.tableName,\r\n processedCount,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n\r\n if (options.onProgress) {\r\n options.onProgress(processedCount, options.data.length);\r\n }\r\n\r\n result.executionTime = Date.now() - startTime;\r\n return result;\r\n }\r\n\r\n // Import with column mapping\r\n async importDataWithMapping(\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import with column mapping\", {\r\n tableName,\r\n dataRows: data.length,\r\n mappingCount: columnMappings.length,\r\n });\r\n\r\n const transformedData = data.map((row, index) => {\r\n this.logger.trace(\"Transforming row with column mappings\", {\r\n rowIndex: index,\r\n });\r\n const newRow: Record<string, any> = {};\r\n\r\n columnMappings.forEach((mapping) => {\r\n if (row.hasOwnProperty(mapping.sourceColumn)) {\r\n let value = row[mapping.sourceColumn];\r\n\r\n if (mapping.transform) {\r\n try {\r\n value = mapping.transform(value);\r\n } catch (error) {\r\n this.logger.warn(\"Column transformation failed\", {\r\n rowIndex: index,\r\n sourceColumn: mapping.sourceColumn,\r\n targetColumn: mapping.targetColumn,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n }\r\n\r\n newRow[mapping.targetColumn] = value;\r\n }\r\n });\r\n\r\n return newRow;\r\n });\r\n\r\n this.logger.debug(\"Data transformation completed\", {\r\n originalRowCount: data.length,\r\n transformedRowCount: transformedData.length,\r\n });\r\n\r\n return await this.importData({\r\n tableName,\r\n data: transformedData,\r\n ...options,\r\n });\r\n }\r\n\r\n // Import from CSV\r\n async importFromCSV(\r\n tableName: string,\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting CSV import\", {\r\n tableName,\r\n csvLength: csvData.length,\r\n delimiter: options.delimiter || \",\",\r\n hasHeader: options.hasHeader !== false,\r\n });\r\n\r\n const delimiter = options.delimiter || \",\";\r\n const hasHeader = options.hasHeader !== false;\r\n\r\n const lines = csvData.split(\"\\n\").filter((line) => line.trim());\r\n if (lines.length === 0) {\r\n const error = new Error(\"CSV data is empty\");\r\n this.logger.error(\"CSV import failed - empty data\");\r\n throw error;\r\n }\r\n\r\n let headers: string[] = [];\r\n let dataStartIndex = 0;\r\n\r\n if (hasHeader) {\r\n headers = lines[0]\r\n .split(delimiter)\r\n .map((h) => h.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n dataStartIndex = 1;\r\n this.logger.debug(\"CSV headers extracted\", {\r\n headers,\r\n headerCount: headers.length,\r\n });\r\n } else {\r\n const firstRowCols = lines[0].split(delimiter).length;\r\n headers = Array.from(\r\n { length: firstRowCols },\r\n (_, i) => `column_${i + 1}`\r\n );\r\n this.logger.debug(\"Generated column headers for headerless CSV\", {\r\n columnCount: firstRowCols,\r\n headers,\r\n });\r\n }\r\n\r\n const data: Record<string, any>[] = [];\r\n for (let i = dataStartIndex; i < lines.length; i++) {\r\n const values = lines[i]\r\n .split(delimiter)\r\n .map((v) => v.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n const row: Record<string, any> = {};\r\n\r\n headers.forEach((header, index) => {\r\n row[header] = values[index] || null;\r\n });\r\n\r\n data.push(row);\r\n }\r\n\r\n this.logger.debug(\"CSV data parsed\", {\r\n totalLines: lines.length,\r\n dataRows: data.length,\r\n skipHeader: hasHeader,\r\n });\r\n\r\n if (options.columnMappings) {\r\n this.logger.debug(\"Using column mappings for CSV import\");\r\n return await this.importDataWithMapping(\r\n tableName,\r\n data,\r\n options.columnMappings,\r\n options\r\n );\r\n } else {\r\n return await this.importData({\r\n tableName,\r\n data,\r\n ...options,\r\n });\r\n }\r\n }\r\n\r\n private validateAndTransformRow(\r\n rowData: Record<string, any>,\r\n columnMap: Map<string, any>,\r\n tableName: string,\r\n skipAutoIncrementPK: boolean = true\r\n ): Record<string, any> {\r\n this.logger.trace(\"Validating and transforming row data\", { tableName });\r\n\r\n const processedRow: Record<string, any> = {};\r\n\r\n for (const [columnName, columnInfo] of columnMap.entries()) {\r\n const isRequired = columnInfo.notnull === 1 && !columnInfo.dflt_value;\r\n const isPrimaryKey = columnInfo.pk === 1;\r\n const isAutoIncrementPK =\r\n isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n continue;\r\n }\r\n\r\n const value = this.findValueForColumn(rowData, columnName);\r\n\r\n if (isRequired && (value === null || value === undefined)) {\r\n const error = new Error(\r\n `Required column '${columnName}' is missing or null in table '${tableName}'`\r\n );\r\n this.logger.error(\"Row validation failed\", {\r\n tableName,\r\n columnName,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n if (value !== null && value !== undefined) {\r\n try {\r\n processedRow[columnName] = this.convertValueToColumnType(\r\n value,\r\n columnInfo.type\r\n );\r\n } catch (error) {\r\n this.logger.error(\"Value conversion failed during validation\", {\r\n tableName,\r\n columnName,\r\n value,\r\n columnType: columnInfo.type,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n return processedRow;\r\n }\r\n\r\n private transformRowData(\r\n rowData: Record<string, any>,\r\n columnMap: Map<string, any>,\r\n skipAutoIncrementPK: boolean = true\r\n ): Record<string, any> {\r\n this.logger.trace(\"Transforming row data without validation\");\r\n\r\n const processedRow: Record<string, any> = {};\r\n\r\n for (const [key, value] of Object.entries(rowData)) {\r\n const columnName = key.toLowerCase();\r\n const columnInfo = columnMap.get(columnName);\r\n\r\n if (!columnInfo) {\r\n this.logger.trace(\"Column not found in table schema, skipping\", {\r\n columnName: key,\r\n });\r\n continue;\r\n }\r\n\r\n const isPrimaryKey = columnInfo.pk === 1;\r\n const isAutoIncrementPK =\r\n isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n continue;\r\n }\r\n\r\n if (value !== null && value !== undefined) {\r\n try {\r\n processedRow[key] = this.convertValueToColumnType(\r\n value,\r\n columnInfo.type\r\n );\r\n } catch (error) {\r\n this.logger.warn(\"Value conversion failed during transformation\", {\r\n columnName: key,\r\n value,\r\n columnType: columnInfo.type,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n // Continue processing other columns\r\n }\r\n }\r\n }\r\n\r\n return processedRow;\r\n }\r\n\r\n private findValueForColumn(\r\n rowData: Record<string, any>,\r\n columnName: string\r\n ): any {\r\n if (rowData.hasOwnProperty(columnName)) {\r\n return rowData[columnName];\r\n }\r\n\r\n const lowerColumnName = columnName.toLowerCase();\r\n for (const [key, value] of Object.entries(rowData)) {\r\n if (key.toLowerCase() === lowerColumnName) {\r\n return value;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private convertValueToColumnType(value: any, columnType: string): any {\r\n if (value === null || value === undefined) {\r\n return null;\r\n }\r\n\r\n const type = columnType.toLowerCase();\r\n\r\n try {\r\n if (type.includes(\"integer\") || type.includes(\"int\")) {\r\n if (typeof value === \"boolean\") {\r\n return value ? 1 : 0;\r\n }\r\n const num = parseInt(String(value));\r\n return isNaN(num) ? null : num;\r\n }\r\n\r\n if (\r\n type.includes(\"real\") ||\r\n type.includes(\"float\") ||\r\n type.includes(\"decimal\")\r\n ) {\r\n const num = parseFloat(String(value));\r\n return isNaN(num) ? null : num;\r\n }\r\n\r\n if (type.includes(\"boolean\")) {\r\n if (typeof value === \"boolean\") {\r\n return value ? 1 : 0;\r\n }\r\n if (typeof value === \"string\") {\r\n const lower = value.toLowerCase();\r\n return lower === \"true\" || lower === \"1\" || lower === \"yes\" ? 1 : 0;\r\n }\r\n return value ? 1 : 0;\r\n }\r\n\r\n if (type.includes(\"json\")) {\r\n if (typeof value === \"object\") {\r\n return JSON.stringify(value);\r\n }\r\n if (typeof value === \"string\") {\r\n try {\r\n JSON.parse(value);\r\n return value;\r\n } catch {\r\n throw new Error(\r\n `Invalid JSON format for column type '${columnType}'`\r\n );\r\n }\r\n }\r\n return JSON.stringify(value);\r\n }\r\n\r\n if (type.includes(\"timestamp\") || type.includes(\"datetime\")) {\r\n if (value instanceof Date) {\r\n return value.toISOString();\r\n }\r\n if (typeof value === \"string\" || typeof value === \"number\") {\r\n const date = new Date(value);\r\n return isNaN(date.getTime()) ? value : date.toISOString();\r\n }\r\n return String(value);\r\n }\r\n\r\n return String(value);\r\n } catch (error) {\r\n throw new Error(\r\n `Cannot convert value '${value}' to column type '${columnType}'`\r\n );\r\n }\r\n }\r\n\r\n private async insertRow(\r\n tableName: string,\r\n data: Record<string, any>\r\n ): Promise<void> {\r\n const columns = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = columns.map(() => \"?\").join(\", \");\r\n\r\n const sql = `INSERT INTO ${tableName} (${columns.join(\r\n \", \"\r\n )}) VALUES (${placeholders})`;\r\n\r\n try {\r\n await this.execute(sql, values);\r\n } catch (error) {\r\n this.logger.trace(\"Insert row failed\", {\r\n tableName,\r\n columns,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private async insertOrUpdate(\r\n tableName: string,\r\n data: Record<string, any>,\r\n conflictColumns: string[]\r\n ): Promise<void> {\r\n this.logger.trace(\"Attempting insert or update\", {\r\n tableName,\r\n conflictColumns,\r\n });\r\n\r\n try {\r\n await this.insertRow(tableName, data);\r\n } catch (error) {\r\n if (this.isConflictError(error)) {\r\n this.logger.debug(\"Insert conflict detected, attempting update\", {\r\n tableName,\r\n });\r\n await this.updateRowByColumns(tableName, data, conflictColumns);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n private async updateRowByColumns(\r\n tableName: string,\r\n data: Record<string, any>,\r\n conflictColumns: string[]\r\n ): Promise<void> {\r\n const allColumns = Object.keys(data);\r\n const updateColumns = allColumns.filter(\r\n (col) => !conflictColumns.includes(col)\r\n );\r\n const whereColumns = conflictColumns;\r\n\r\n if (updateColumns.length === 0) {\r\n this.logger.debug(\"No columns to update, skipping update operation\", {\r\n tableName,\r\n });\r\n return;\r\n }\r\n\r\n const setClause = updateColumns.map((col) => `${col} = ?`).join(\", \");\r\n const whereClause = whereColumns.map((col) => `${col} = ?`).join(\" AND \");\r\n\r\n const updateValues = updateColumns.map((col) => data[col]);\r\n const whereValues = whereColumns.map((col) => data[col]);\r\n const allValues = [...updateValues, ...whereValues];\r\n\r\n const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;\r\n\r\n try {\r\n await this.execute(sql, allValues);\r\n this.logger.trace(\"Update by columns completed\", {\r\n tableName,\r\n updateColumns,\r\n whereColumns,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Update by columns failed\", {\r\n tableName,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private isConflictError(error: any): boolean {\r\n return (\r\n error.code === \"SQLITE_CONSTRAINT_UNIQUE\" ||\r\n error.code === \"SQLITE_CONSTRAINT_PRIMARYKEY\" ||\r\n (error.message && error.message.includes(\"UNIQUE constraint failed\"))\r\n );\r\n }\r\n\r\n // Database info methods\r\n async getDatabaseInfo(): Promise<any> {\r\n this.logger.trace(\"Getting database information\");\r\n\r\n try {\r\n const tables = await this.execute(\r\n \"SELECT name FROM sqlite_master WHERE type='table'\"\r\n );\r\n const version = await this.getSchemaVersion();\r\n\r\n const info = {\r\n name: this.dbPath,\r\n tables: tables.rows.map((t) => t.name),\r\n isConnected: this.isConnected,\r\n version,\r\n };\r\n\r\n this.logger.debug(\"Database information retrieved\", {\r\n tableCount: info.tables.length,\r\n isConnected: info.isConnected,\r\n version: info.version,\r\n });\r\n\r\n return info;\r\n } catch (error) {\r\n this.logger.error(\"Failed to get database information\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async getTableInfo(tableName: string): Promise<any[]> {\r\n this.logger.trace(\"Getting table information\", { tableName });\r\n\r\n try {\r\n const result = await this.execute(`PRAGMA table_info(${tableName})`);\r\n this.logger.debug(\"Table information retrieved\", {\r\n tableName,\r\n columnCount: result.rows.length,\r\n });\r\n return result.rows;\r\n } catch (error) {\r\n this.logger.error(\"Failed to get table information\", {\r\n tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async dropTable(tableName: string): Promise<void> {\r\n this.logger.info(\"Dropping table\", { tableName });\r\n\r\n const sql = `DROP TABLE IF EXISTS ${tableName}`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.info(\"Table dropped successfully\", { tableName });\r\n } catch (error) {\r\n this.logger.error(\"Failed to drop table\", {\r\n tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Connection check method\r\n isConnectionOpen(): boolean {\r\n const isOpen = this.isConnected && !!this.connection;\r\n this.logger.trace(\"Connection status checked\", { isOpen });\r\n return isOpen;\r\n }\r\n\r\n async ensureConnected(): Promise<void> {\r\n if (!this.isConnectionOpen()) {\r\n this.logger.debug(\"Connection not open, attempting to connect\");\r\n await this.connect();\r\n }\r\n }\r\n\r\n async execute(sql: string, params: any[] = []): Promise<SQLiteResult> {\r\n this.logger.trace(\"Executing SQL query\", {\r\n sql: sql.substring(0, 100) + (sql.length > 100 ? \"...\" : \"\"),\r\n paramCount: params.length,\r\n });\r\n\r\n this.ensureConnected();\r\n\r\n try {\r\n const result = await this.connection!.execute(sql, params);\r\n this.logger.trace(\"SQL query executed successfully\", {\r\n rowsAffected: result.rowsAffected,\r\n rowsReturned: result.rows?.length || 0,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"SQL query execution failed\", {\r\n sql: sql.substring(0, 200) + (sql.length > 200 ? \"...\" : \"\"),\r\n paramCount: params.length,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async getRst(sql: string, params: any[] = []): Promise<SQLiteRow> {\r\n const result = await this.execute(sql, params);\r\n return result.rows[0] || {};\r\n }\r\n\r\n async getRsts(sql: string, params: any[] = []): Promise<SQLiteRow[]> {\r\n const result = await this.execute(sql, params);\r\n return result.rows;\r\n }\r\n}\r\n","// src/core/database-factory.ts\r\nimport { SQLiteAdapter, DatabaseSchema, DbFactoryOptions } from \"../types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n\r\n/**\r\n * Universal DatabaseFactory - A powerful utility class designed to create and manage\r\n * UniversalDAO instances from JSON schema across all operating systems and frameworks\r\n * using TypeScript and JavaScript. It provides methods for creating new, opening existing\r\n * databases, checking integrity, and managing database lifecycle.\r\n */\r\nexport class DatabaseFactory {\r\n private static adapters: SQLiteAdapter[] = [];\r\n\r\n /**\r\n * Register a SQLite adapter for use by the factory\r\n * @param adapter The SQLite adapter to register\r\n */\r\n static registerAdapter(adapter: SQLiteAdapter): void {\r\n logger.info(`Registering SQLite adapter: ${adapter.constructor.name}`, {\r\n adapterName: adapter.constructor.name,\r\n totalAdapters: this.adapters.length + 1,\r\n });\r\n\r\n this.adapters.push(adapter);\r\n\r\n logger.debug(\r\n `Successfully registered adapter. Total adapters: ${this.adapters.length}`\r\n );\r\n }\r\n\r\n /**\r\n * Get information about the current runtime environment\r\n * @returns A string describing the current environment\r\n */\r\n static getEnvironmentInfo(): string {\r\n logger.trace(\"Detecting runtime environment\");\r\n\r\n let environment: string;\r\n\r\n if (\r\n typeof navigator !== \"undefined\" &&\r\n navigator.product === \"ReactNative\"\r\n ) {\r\n environment = \"React Native\";\r\n } else if (typeof globalThis.Bun !== \"undefined\") {\r\n environment = \"Bun\";\r\n } else if (typeof globalThis.Deno !== \"undefined\") {\r\n environment = \"Deno\";\r\n } else if (typeof window !== \"undefined\") {\r\n environment = \"Browser\";\r\n } else if (typeof process !== \"undefined\") {\r\n environment = \"Node.js\";\r\n } else {\r\n environment = \"Unknown\";\r\n }\r\n\r\n logger.debug(`Detected runtime environment: ${environment}`);\r\n return environment;\r\n }\r\n\r\n /**\r\n * Detect the best available SQLite adapter for the current environment\r\n * @returns The best available SQLite adapter\r\n * @throws Error if no supported adapter is found\r\n */\r\n private static detectBestAdapter(): SQLiteAdapter {\r\n logger.trace(\"Detecting best available SQLite adapter\", {\r\n totalAdapters: this.adapters.length,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n\r\n for (const adapter of this.adapters) {\r\n logger.trace(`Testing adapter: ${adapter.constructor.name}`);\r\n\r\n if (adapter.isSupported()) {\r\n logger.info(`Selected adapter: ${adapter.constructor.name}`, {\r\n adapterName: adapter.constructor.name,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n return adapter;\r\n }\r\n\r\n logger.debug(\r\n `Adapter ${adapter.constructor.name} is not supported in current environment`\r\n );\r\n }\r\n\r\n logger.error(\"No supported SQLite adapter found\", {\r\n totalAdapters: this.adapters.length,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n\r\n throw new Error(\"No supported SQLite adapter found\");\r\n }\r\n\r\n /**\r\n * Validate schema version compatibility between database and config\r\n * @param dao The UniversalDAO instance\r\n * @param schema The database schema configuration\r\n */\r\n private static async validateSchemaVersion(\r\n dao: UniversalDAO,\r\n schema: DatabaseSchema\r\n ): Promise<void> {\r\n logger.trace(\"Validating schema version compatibility\", {\r\n databaseName: schema.database_name,\r\n configVersion: schema.version,\r\n });\r\n\r\n try {\r\n const dbInfo = await dao.getDatabaseInfo();\r\n logger.debug(\"Retrieved database info\", {\r\n databaseVersion: dbInfo.version,\r\n configVersion: schema.version,\r\n });\r\n\r\n if (dbInfo.version !== schema.version) {\r\n const errorMsg = `Schema version mismatch: database (${dbInfo.version}) vs config (${schema.version})`;\r\n logger.error(\"Schema version mismatch\", {\r\n databaseName: schema.database_name,\r\n databaseVersion: dbInfo.version,\r\n configVersion: schema.version,\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Schema version validation successful\", {\r\n databaseName: schema.database_name,\r\n version: schema.version,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error during schema version validation\", {\r\n databaseName: schema.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error validating schema version for ${schema.database_name}: ${\r\n (error as Error).message\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate the provided schema object to ensure it has minimum required properties\r\n * @param schema The schema object to validate\r\n * @returns True if the schema is valid, otherwise throws an error\r\n */\r\n private static validateSchema(schema: any): schema is DatabaseSchema {\r\n logger.trace(\"Validating database schema configuration\");\r\n\r\n if (!schema) {\r\n logger.error(\"Schema validation failed: null or undefined schema\");\r\n throw new Error(\"Schema configuration is null or undefined.\");\r\n }\r\n\r\n if (\r\n typeof schema.database_name !== \"string\" ||\r\n schema.database_name.trim() === \"\"\r\n ) {\r\n logger.error(\"Schema validation failed: invalid database_name\", {\r\n databaseName: schema.database_name,\r\n type: typeof schema.database_name,\r\n });\r\n throw new Error(\r\n \"Invalid or missing 'database_name' in schema. This is required to name the database file.\"\r\n );\r\n }\r\n\r\n if (\r\n typeof schema.schemas !== \"object\" ||\r\n schema.schemas === null ||\r\n Object.keys(schema.schemas).length === 0\r\n ) {\r\n logger.error(\"Schema validation failed: invalid schemas object\", {\r\n databaseName: schema.database_name,\r\n schemasType: typeof schema.schemas,\r\n schemasCount: schema.schemas ? Object.keys(schema.schemas).length : 0,\r\n });\r\n throw new Error(\r\n \"Invalid or missing 'schemas' object in schema. At least one table definition is required.\"\r\n );\r\n }\r\n\r\n logger.debug(\"Schema validation successful\", {\r\n databaseName: schema.database_name,\r\n tablesCount: Object.keys(schema.schemas).length,\r\n version: schema.version,\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Create a new UniversalDAO instance (equivalent to SQLiteDAO)\r\n * @param dbPath Path to the database file\r\n * @param options Configuration options\r\n * @returns A new UniversalDAO instance\r\n */\r\n static createDAO(\r\n dbPath: string,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n createIfNotExists?: boolean;\r\n forceRecreate?: boolean;\r\n }\r\n ): UniversalDAO {\r\n logger.info(\"Creating new UniversalDAO instance\", {\r\n dbPath,\r\n hasCustomAdapter: !!options?.adapter,\r\n createIfNotExists: options?.createIfNotExists ?? false,\r\n forceRecreate: options?.forceRecreate ?? false,\r\n });\r\n\r\n let adapter: SQLiteAdapter;\r\n\r\n if (options?.adapter) {\r\n logger.debug(\"Using provided custom adapter\", {\r\n adapterName: options.adapter.constructor.name,\r\n });\r\n adapter = options.adapter;\r\n } else {\r\n logger.debug(\"Detecting best adapter automatically\");\r\n adapter = this.detectBestAdapter();\r\n }\r\n\r\n const dao = new UniversalDAO(adapter, dbPath, {\r\n createIfNotExists: options?.createIfNotExists ?? false,\r\n forceRecreate: options?.forceRecreate ?? false,\r\n });\r\n\r\n logger.debug(\"UniversalDAO instance created successfully\", {\r\n dbPath,\r\n adapterName: adapter.constructor.name,\r\n });\r\n\r\n return dao;\r\n }\r\n\r\n /**\r\n * Opens an existing database without initializing its schema.\r\n * Includes integrity check to detect corrupted files.\r\n * @param dbName The name of the database (e.g., 'core.db' or 'core').\r\n * @param options Additional options for database connection.\r\n * @returns A promise that resolves to a connected UniversalDAO instance.\r\n */\r\n public static async openExisting(\r\n dbName: string,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Opening existing database\", { dbName, options });\r\n\r\n // Determine the database file path\r\n const dbFileName = dbName.endsWith(\".db\") ? dbName : `${dbName}.db`;\r\n logger.debug(\"Resolved database filename\", {\r\n originalName: dbName,\r\n resolvedName: dbFileName,\r\n });\r\n\r\n // Create and connect DAO instance\r\n const dao = this.createDAO(dbFileName, options);\r\n\r\n try {\r\n logger.debug(\"Connecting to database\", { dbFileName });\r\n await dao.connect();\r\n\r\n logger.debug(\"Running integrity check\", { dbFileName });\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n\r\n logger.info(\"Database opened successfully\", { dbFileName });\r\n return dao;\r\n } catch (error) {\r\n logger.error(\"Error opening database\", {\r\n dbFileName,\r\n error: (error as Error).message,\r\n });\r\n\r\n try {\r\n await dao.close();\r\n } catch (closeError) {\r\n logger.warn(\"Error closing DAO after failed open\", {\r\n dbFileName,\r\n closeError: (closeError as Error).message,\r\n });\r\n }\r\n\r\n throw new Error(\r\n `Error opening database '${dbFileName}': ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Internal method to create or open database with various options\r\n * @param options Configuration options\r\n * @param isForceInit Allow re-initialization of existing database\r\n * @param isForceDelete Force delete and recreate database\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n private static async createOrOpenInternal(\r\n options: DbFactoryOptions,\r\n isForceInit: boolean = false,\r\n isForceDelete: boolean = false\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating or opening database internally\", {\r\n isForceInit,\r\n isForceDelete,\r\n hasConfig: !!options.config,\r\n hasConfigAsset: !!options.configAsset,\r\n });\r\n\r\n let schema: DatabaseSchema;\r\n\r\n // Step 1: Load schema\r\n logger.trace(\"Loading database schema\");\r\n if (options.config) {\r\n logger.debug(\"Using provided config object\");\r\n schema = options.config;\r\n } else if (options.configAsset) {\r\n logger.debug(\"Using provided config asset\");\r\n schema = options.configAsset;\r\n } else {\r\n logger.error(\"No database schema configuration provided\");\r\n throw new Error(\r\n \"Either 'config', 'configAsset', or 'configPath' must be provided to the factory.\"\r\n );\r\n }\r\n\r\n // Step 2: Validate schema\r\n logger.trace(\"Validating schema configuration\");\r\n this.validateSchema(schema);\r\n\r\n // Step 3: Determine database path\r\n const dbFileName = schema.database_name.endsWith(\".db\")\r\n ? schema.database_name\r\n : `${schema.database_name}.db`;\r\n\r\n logger.debug(\"Database filename resolved\", {\r\n originalName: schema.database_name,\r\n resolvedName: dbFileName,\r\n });\r\n\r\n // Step 4: Create DAO instance\r\n logger.debug(\"Creating DAO instance\", {\r\n dbFileName,\r\n hasCustomAdapter: !!options.adapter,\r\n createIfNotExists: isForceInit,\r\n forceRecreate: isForceDelete,\r\n });\r\n\r\n const dao = this.createDAO(dbFileName, {\r\n adapter: options.adapter,\r\n createIfNotExists: isForceInit,\r\n forceRecreate: isForceDelete,\r\n });\r\n\r\n try {\r\n // Step 5: Connect to database\r\n logger.debug(\"Connecting to database\", { dbFileName });\r\n await dao.connect();\r\n\r\n // Step 6: Initialize schema if needed\r\n logger.debug(\"Initializing database schema\", { dbFileName });\r\n await dao.initializeFromSchema(schema);\r\n\r\n // Step 7: Validate schema version compatibility\r\n logger.debug(\"Validating schema version compatibility\");\r\n try {\r\n await this.validateSchemaVersion(dao, schema);\r\n } catch (schemaError: any) {\r\n logger.error(\"Schema version validation failed\", {\r\n dbFileName,\r\n error: schemaError.message,\r\n });\r\n\r\n await dao.close();\r\n throw new Error(\r\n `Schema mismatch in existing database. Use forceRecreate=true to recreate with updated schema. Error: ${schemaError.message}`\r\n );\r\n }\r\n\r\n logger.info(\"Database created/opened successfully\", {\r\n dbFileName,\r\n databaseName: schema.database_name,\r\n version: schema.version,\r\n });\r\n\r\n return dao;\r\n } catch (error) {\r\n logger.error(\"Error during database creation/opening\", {\r\n dbFileName,\r\n error: (error as Error).message,\r\n });\r\n\r\n if (dao.isConnectionOpen()) {\r\n try {\r\n await dao.close();\r\n } catch (closeError) {\r\n logger.warn(\"Error closing DAO after failed operation\", {\r\n dbFileName,\r\n closeError: (closeError as Error).message,\r\n });\r\n }\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new database (DANGEROUS - will delete existing database)\r\n * Only use this for migrations or development, not in production\r\n * @param options Configuration options\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async create(options: DbFactoryOptions): Promise<UniversalDAO> {\r\n logger.warn(\r\n \"Creating database with force recreate - this will delete existing database\",\r\n {\r\n databaseName:\r\n options.config?.database_name || options.configAsset?.database_name,\r\n }\r\n );\r\n\r\n return this.createOrOpenInternal(options, true, true);\r\n }\r\n\r\n /**\r\n * Smart method to create or open database\r\n * Only creates new tables if they don't exist and initializes file initially\r\n * Will check if file exists and is valid before deciding to create new or open existing\r\n * @param options Database configuration options\r\n * @param isForceInit Force re-initialization of tables even if they exist (default: false)\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createOrOpen(\r\n options: DbFactoryOptions,\r\n isForceInit: boolean = false\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Smart create or open database\", {\r\n databaseName:\r\n options.config?.database_name || options.configAsset?.database_name,\r\n isForceInit,\r\n });\r\n\r\n return this.createOrOpenInternal(options, isForceInit);\r\n }\r\n\r\n /**\r\n * Convenience method to create a database from a JSON asset\r\n * @param configAsset The imported/required JSON configuration\r\n * @param options Additional options for database creation\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createFromAsset(\r\n configAsset: DatabaseSchema,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating database from asset\", {\r\n databaseName: configAsset.database_name,\r\n version: configAsset.version,\r\n });\r\n\r\n try {\r\n return await this.create({\r\n ...options,\r\n configAsset,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error creating database from asset\", {\r\n databaseName: configAsset.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error creating database from asset: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Convenience method to create a database from a configuration object\r\n * @param config The database schema configuration object\r\n * @param options Additional options for database creation\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createFromConfig(\r\n config: DatabaseSchema,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating database from config\", {\r\n databaseName: config.database_name,\r\n version: config.version,\r\n });\r\n\r\n try {\r\n return await this.create({\r\n ...options,\r\n config,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error creating database from config\", {\r\n databaseName: config.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error creating database from config: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n}\r\n\r\nexport default DatabaseFactory;\r\n","// src/core/database-manager.ts\r\n\r\nimport {\r\n DatabaseSchema,\r\n ImportOptions,\r\n ImportResult,\r\n ColumnMapping,\r\n} from \"../types\";\r\nimport { DatabaseFactory } from \"./database-factory\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_MANAGER);\r\n\r\nexport type DatabaseConnections = {\r\n [key: string]: UniversalDAO;\r\n};\r\n\r\nexport interface RoleConfig {\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n}\r\n\r\nexport type RoleRegistry = {\r\n [roleName: string]: RoleConfig;\r\n};\r\n\r\nexport interface DatabaseImportConfig {\r\n databaseKey: string;\r\n tableName: string;\r\n data: Record<string, any>[];\r\n options?: Partial<ImportOptions>;\r\n columnMappings?: ColumnMapping[];\r\n}\r\n\r\nexport interface BulkImportResult {\r\n totalDatabases: number;\r\n successDatabases: number;\r\n results: Record<string, ImportResult>;\r\n errors: Record<string, Error>;\r\n executionTime: number;\r\n}\r\n\r\nexport interface SchemaManager {\r\n getSchema(key: string): DatabaseSchema | undefined;\r\n registerSchema(key: string, schema: DatabaseSchema): void;\r\n getAllSchemaKeys(): string[];\r\n hasSchema(key: string): boolean;\r\n}\r\n\r\nexport class DatabaseManager {\r\n private static maxConnections = 10;\r\n private static connections: DatabaseConnections = {};\r\n private static isInitialized = false;\r\n private static roleRegistry: RoleRegistry = {};\r\n private static currentRole: string | null = null;\r\n private static currentUserRoles: string[] = [];\r\n private static activeDatabases: Set<string> = new Set();\r\n private static isClosingConnections = false;\r\n\r\n // Schema management - support dynamic schemas\r\n private static schemaConfigurations: Record<string, DatabaseSchema> = {};\r\n private static schemaManager: SchemaManager | null = null;\r\n\r\n // Event system for database reconnection\r\n private static eventListeners: Map<\r\n string,\r\n Array<(dao: UniversalDAO) => void>\r\n > = new Map();\r\n\r\n /**\r\n * Get the maximum number of allowed database connections\r\n */\r\n public static getMaxConnections(): number {\r\n logger.trace(\"Getting max connections\", {\r\n maxConnections: this.maxConnections,\r\n });\r\n return this.maxConnections;\r\n }\r\n\r\n /**\r\n * Set the maximum number of allowed database connections\r\n * @param maxConnections - The maximum number of connections (must be positive)\r\n * @throws Error if maxConnections is not positive or if current connections exceed the new limit\r\n */\r\n public static setMaxConnections(maxConnections: number): void {\r\n logger.debug(\"Setting max connections\", {\r\n newMaxConnections: maxConnections,\r\n currentMax: this.maxConnections,\r\n });\r\n\r\n if (maxConnections <= 0) {\r\n logger.error(\"Invalid max connections value\", { maxConnections });\r\n throw new Error(\"Maximum connections must be a positive number\");\r\n }\r\n\r\n const currentConnectionCount = Object.keys(this.connections).length;\r\n if (currentConnectionCount > maxConnections) {\r\n logger.error(\r\n \"Cannot set max connections - would exceed current active connections\",\r\n {\r\n requestedMax: maxConnections,\r\n currentActiveConnections: currentConnectionCount,\r\n activeConnectionKeys: Object.keys(this.connections),\r\n }\r\n );\r\n throw new Error(\r\n `Cannot set maximum connections to ${maxConnections}. ` +\r\n `Current active connections (${currentConnectionCount}) exceed the new limit. ` +\r\n `Please close some connections first.`\r\n );\r\n }\r\n\r\n this.maxConnections = maxConnections;\r\n logger.info(\"Max connections updated successfully\", {\r\n newMaxConnections: maxConnections,\r\n currentActiveConnections: currentConnectionCount,\r\n });\r\n }\r\n\r\n /**\r\n * Set a schema manager for dynamic schema handling\r\n */\r\n public static setSchemaManager(manager: SchemaManager): void {\r\n logger.debug(\"Setting schema manager\", {\r\n hadPreviousManager: this.schemaManager !== null,\r\n });\r\n this.schemaManager = manager;\r\n logger.info(\"Schema manager set successfully\");\r\n }\r\n\r\n /**\r\n * Register a schema configuration dynamically\r\n */\r\n public static registerSchema(key: string, schema: DatabaseSchema): void {\r\n logger.debug(\"Registering schema\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n this.schemaConfigurations[key] = schema;\r\n logger.info(\"Schema registered successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n }\r\n\r\n /**\r\n * Register multiple schemas at once\r\n */\r\n public static registerSchemas(schemas: Record<string, DatabaseSchema>): void {\r\n const schemaKeys = Object.keys(schemas);\r\n logger.debug(\"Registering multiple schemas\", {\r\n count: schemaKeys.length,\r\n keys: schemaKeys,\r\n });\r\n\r\n Object.entries(schemas).forEach(([key, schema]) => {\r\n this.registerSchema(key, schema);\r\n });\r\n\r\n logger.info(\"Multiple schemas registered successfully\", {\r\n count: schemaKeys.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get schema from internal store or external manager\r\n */\r\n private static getSchema(key: string): DatabaseSchema | undefined {\r\n logger.trace(\"Getting schema\", { key });\r\n\r\n // Try internal schemas first\r\n if (this.schemaConfigurations[key]) {\r\n logger.trace(\"Schema found in internal configurations\", { key });\r\n return this.schemaConfigurations[key];\r\n }\r\n\r\n // Try external schema manager\r\n if (this.schemaManager) {\r\n logger.trace(\"Checking external schema manager\", { key });\r\n const schema = this.schemaManager.getSchema(key);\r\n if (schema) {\r\n logger.trace(\"Schema found in external manager\", { key });\r\n return schema;\r\n }\r\n }\r\n\r\n logger.warn(\"Schema not found\", { key });\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Get all available schema keys\r\n */\r\n public static getAvailableSchemas(): string[] {\r\n const internalKeys = Object.keys(this.schemaConfigurations);\r\n const externalKeys = this.schemaManager?.getAllSchemaKeys() || [];\r\n const allKeys = [...new Set([...internalKeys, ...externalKeys])];\r\n\r\n logger.trace(\"Getting available schemas\", {\r\n internalCount: internalKeys.length,\r\n externalCount: externalKeys.length,\r\n totalUnique: allKeys.length,\r\n });\r\n\r\n return allKeys;\r\n }\r\n\r\n /**\r\n * Register a role configuration\r\n */\r\n public static registerRole(roleConfig: RoleConfig): void {\r\n logger.debug(\"Registering role\", {\r\n roleName: roleConfig.roleName,\r\n requiredDatabases: roleConfig.requiredDatabases,\r\n optionalDatabases: roleConfig.optionalDatabases,\r\n priority: roleConfig.priority,\r\n });\r\n\r\n this.roleRegistry[roleConfig.roleName] = roleConfig;\r\n logger.info(\"Role registered successfully\", {\r\n roleName: roleConfig.roleName,\r\n });\r\n }\r\n\r\n /**\r\n * Register multiple roles\r\n */\r\n public static registerRoles(roleConfigs: RoleConfig[]): void {\r\n logger.debug(\"Registering multiple roles\", { count: roleConfigs.length });\r\n roleConfigs.forEach((config) => this.registerRole(config));\r\n logger.info(\"Multiple roles registered successfully\", {\r\n count: roleConfigs.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get all registered roles\r\n */\r\n public static getRegisteredRoles(): RoleRegistry {\r\n logger.trace(\"Getting registered roles\", {\r\n count: Object.keys(this.roleRegistry).length,\r\n });\r\n return { ...this.roleRegistry };\r\n }\r\n\r\n /**\r\n * Get databases for a specific role\r\n */\r\n public static getRoleDatabases(roleName: string): string[] {\r\n logger.trace(\"Getting role databases\", { roleName });\r\n\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (!roleConfig) {\r\n logger.error(\"Role not found in registry\", {\r\n roleName,\r\n availableRoles: Object.keys(this.roleRegistry),\r\n });\r\n throw new Error(`Role '${roleName}' is not registered.`);\r\n }\r\n\r\n const databases = [\r\n ...roleConfig.requiredDatabases,\r\n ...(roleConfig.optionalDatabases || []),\r\n ];\r\n\r\n logger.trace(\"Role databases retrieved\", { roleName, databases });\r\n return databases;\r\n }\r\n\r\n /**\r\n * Get databases for current user roles\r\n */\r\n public static getCurrentUserDatabases(): string[] {\r\n logger.trace(\"Getting current user databases\", {\r\n currentUserRoles: this.currentUserRoles,\r\n });\r\n\r\n const allDatabases = new Set<string>();\r\n allDatabases.add(\"core\"); // Core database is always included\r\n\r\n for (const roleName of this.currentUserRoles) {\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (roleConfig) {\r\n roleConfig.requiredDatabases.forEach((db) => allDatabases.add(db));\r\n if (roleConfig.optionalDatabases) {\r\n roleConfig.optionalDatabases.forEach((db) => allDatabases.add(db));\r\n }\r\n } else {\r\n logger.warn(\"Role config not found for current user role\", {\r\n roleName,\r\n });\r\n }\r\n }\r\n\r\n const result = Array.from(allDatabases);\r\n logger.debug(\"Current user databases calculated\", {\r\n userRoles: this.currentUserRoles,\r\n databases: result,\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Initialize core database connection\r\n */\r\n public static async initializeCoreConnection(): Promise<void> {\r\n logger.debug(\"Initializing core database connection\");\r\n\r\n if (this.connections[\"core\"]) {\r\n logger.debug(\"Core connection already exists\");\r\n return;\r\n }\r\n\r\n try {\r\n const coreSchema = this.getSchema(\"core\");\r\n if (!coreSchema) {\r\n logger.error(\"Core database schema not found\");\r\n throw new Error(\"Core database schema not found.\");\r\n }\r\n\r\n logger.debug(\"Creating core database connection\", {\r\n schemaName: coreSchema.database_name,\r\n });\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: coreSchema },\r\n false\r\n );\r\n\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[\"core\"] = dao;\r\n logger.info(\"Core database connection initialized successfully\");\r\n } catch (error) {\r\n logger.error(\"Error initializing core database\", {\r\n error: (error as Error).message,\r\n });\r\n throw new Error(\r\n `Error initializing core database: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Set current user roles and initialize connections\r\n */\r\n public static async setCurrentUserRoles(\r\n userRoles: string[],\r\n primaryRole?: string\r\n ): Promise<void> {\r\n logger.debug(\"Setting current user roles\", { userRoles, primaryRole });\r\n\r\n // Validate roles exist\r\n for (const roleName of userRoles) {\r\n if (!this.roleRegistry[roleName]) {\r\n logger.error(\"Role not registered\", {\r\n roleName,\r\n availableRoles: Object.keys(this.roleRegistry),\r\n });\r\n throw new Error(\r\n `Role '${roleName}' is not registered. Please register it first.`\r\n );\r\n }\r\n }\r\n\r\n const previousRoles = [...this.currentUserRoles];\r\n this.currentUserRoles = userRoles;\r\n this.currentRole = primaryRole || userRoles[0] || null;\r\n\r\n logger.info(\"User roles updated\", {\r\n previousRoles,\r\n newRoles: userRoles,\r\n primaryRole: this.currentRole,\r\n });\r\n\r\n try {\r\n await this.initializeUserRoleConnections();\r\n await this.cleanupUnusedConnections(previousRoles);\r\n logger.info(\"User role connections initialized successfully\");\r\n } catch (error) {\r\n logger.error(\"Failed to initialize user role connections\", {\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current user roles\r\n */\r\n public static getCurrentUserRoles(): string[] {\r\n logger.trace(\"Getting current user roles\", {\r\n roles: this.currentUserRoles,\r\n });\r\n return [...this.currentUserRoles];\r\n }\r\n\r\n /**\r\n * Get current primary role\r\n */\r\n public static getCurrentRole(): string | null {\r\n logger.trace(\"Getting current primary role\", { role: this.currentRole });\r\n return this.currentRole;\r\n }\r\n\r\n /**\r\n * Initialize connections for current user roles\r\n */\r\n private static async initializeUserRoleConnections(): Promise<void> {\r\n const requiredDatabases = this.getCurrentUserDatabases();\r\n logger.debug(\"Initializing user role connections\", { requiredDatabases });\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n const initPromises = requiredDatabases.map(async (dbKey) => {\r\n if (this.connections[dbKey]) {\r\n logger.trace(\"Database already connected\", { dbKey });\r\n return; // Already connected\r\n }\r\n\r\n try {\r\n logger.debug(\"Initializing database connection\", { dbKey });\r\n const schema = this.getSchema(dbKey);\r\n if (!schema) {\r\n throw new Error(\r\n `Database key '${dbKey}' not found in schema configurations.`\r\n );\r\n }\r\n\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[dbKey] = dao;\r\n logger.info(\"Database connection initialized\", {\r\n dbKey,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize database connection\", {\r\n dbKey,\r\n error: err.message,\r\n });\r\n\r\n // Check if database is required for any role\r\n const isRequired = this.currentUserRoles.some((roleName) => {\r\n const roleConfig = this.roleRegistry[roleName];\r\n return roleConfig && roleConfig.requiredDatabases.includes(dbKey);\r\n });\r\n\r\n if (isRequired) {\r\n failedInitializations.push({ key: dbKey, error: err });\r\n } else {\r\n logger.warn(\"Optional database initialization failed\", {\r\n dbKey,\r\n error: err.message,\r\n });\r\n }\r\n // Optional databases that fail are ignored\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize required databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize required databases for user roles:\\n${errorSummary}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup unused connections\r\n */\r\n private static async cleanupUnusedConnections(\r\n previousRoles: string[]\r\n ): Promise<void> {\r\n logger.debug(\"Cleaning up unused connections\", { previousRoles });\r\n\r\n const previousDatabases = new Set<string>();\r\n previousDatabases.add(\"core\");\r\n\r\n for (const roleName of previousRoles) {\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (roleConfig) {\r\n roleConfig.requiredDatabases.forEach((db) => previousDatabases.add(db));\r\n if (roleConfig.optionalDatabases) {\r\n roleConfig.optionalDatabases.forEach((db) =>\r\n previousDatabases.add(db)\r\n );\r\n }\r\n }\r\n }\r\n\r\n const currentDatabases = new Set(this.getCurrentUserDatabases());\r\n const databasesToClose = Array.from(previousDatabases).filter(\r\n (db) => !currentDatabases.has(db)\r\n );\r\n\r\n logger.debug(\"Databases to cleanup\", {\r\n databasesToClose,\r\n previousDatabaseCount: previousDatabases.size,\r\n currentDatabaseCount: currentDatabases.size,\r\n });\r\n\r\n if (databasesToClose.length > 0) {\r\n for (const dbKey of databasesToClose) {\r\n if (this.connections[dbKey]) {\r\n try {\r\n logger.debug(\"Closing unused database connection\", { dbKey });\r\n await this.connections[dbKey].close();\r\n delete this.connections[dbKey];\r\n logger.info(\"Database connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection during cleanup\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue cleanup\r\n }\r\n }\r\n }\r\n logger.info(\"Cleanup completed\", { closedConnections: databasesToClose });\r\n } else {\r\n logger.debug(\"No connections to cleanup\");\r\n }\r\n }\r\n\r\n /**\r\n * Check if current user has access to database\r\n */\r\n public static hasAccessToDatabase(dbKey: string): boolean {\r\n const hasAccess = this.getSchema(dbKey) !== undefined;\r\n logger.trace(\"Checking database access\", { dbKey, hasAccess });\r\n return hasAccess;\r\n }\r\n\r\n /**\r\n * Get database connection\r\n */\r\n public static get(key: string): UniversalDAO {\r\n logger.trace(\"Getting database connection\", { key });\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied to database\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n const dao = this.connections[key];\r\n if (!dao) {\r\n logger.error(\"Database not connected\", {\r\n key,\r\n availableConnections: Object.keys(this.connections),\r\n });\r\n throw new Error(\r\n `Database '${key}' is not connected. Please ensure it's initialized.`\r\n );\r\n }\r\n\r\n logger.trace(\"Database connection retrieved successfully\", { key });\r\n return dao;\r\n }\r\n\r\n /**\r\n * Register event listener for database reconnection\r\n */\r\n public static onDatabaseReconnect(\r\n schemaName: string,\r\n callback: (dao: UniversalDAO) => void\r\n ): void {\r\n logger.debug(\"Registering database reconnect listener\", { schemaName });\r\n\r\n if (!this.eventListeners.has(schemaName)) {\r\n this.eventListeners.set(schemaName, []);\r\n }\r\n this.eventListeners.get(schemaName)!.push(callback);\r\n\r\n logger.trace(\"Database reconnect listener registered\", {\r\n schemaName,\r\n listenerCount: this.eventListeners.get(schemaName)!.length,\r\n });\r\n }\r\n\r\n /**\r\n * Remove event listener for database reconnection\r\n */\r\n public static offDatabaseReconnect(\r\n schemaName: string,\r\n callback: (dao: UniversalDAO) => void\r\n ): void {\r\n logger.debug(\"Removing database reconnect listener\", { schemaName });\r\n\r\n const listeners = this.eventListeners.get(schemaName);\r\n if (listeners) {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1) {\r\n listeners.splice(index, 1);\r\n logger.trace(\"Database reconnect listener removed\", {\r\n schemaName,\r\n remainingListeners: listeners.length,\r\n });\r\n } else {\r\n logger.warn(\"Database reconnect listener not found for removal\", {\r\n schemaName,\r\n });\r\n }\r\n } else {\r\n logger.warn(\"No listeners found for schema\", { schemaName });\r\n }\r\n }\r\n\r\n /**\r\n * Notify listeners of database reconnection\r\n */\r\n private static notifyDatabaseReconnect(\r\n schemaName: string,\r\n dao: UniversalDAO\r\n ): void {\r\n const listeners = this.eventListeners.get(schemaName);\r\n if (listeners) {\r\n logger.debug(\"Notifying database reconnect listeners\", {\r\n schemaName,\r\n listenerCount: listeners.length,\r\n });\r\n\r\n listeners.forEach((callback, index) => {\r\n try {\r\n callback(dao);\r\n logger.trace(\"Database reconnect listener notified\", {\r\n schemaName,\r\n listenerIndex: index,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error in database reconnect listener\", {\r\n schemaName,\r\n listenerIndex: index,\r\n error: (error as Error).message,\r\n });\r\n // Handle callback errors gracefully\r\n }\r\n });\r\n } else {\r\n logger.trace(\"No listeners to notify for database reconnection\", {\r\n schemaName,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections\r\n */\r\n private static async closeAllConnections(): Promise<void> {\r\n if (this.isClosingConnections) {\r\n logger.debug(\"Already closing connections, skipping\");\r\n return;\r\n }\r\n\r\n logger.info(\"Closing all database connections\", {\r\n connectionCount: Object.keys(this.connections).length,\r\n });\r\n\r\n this.isClosingConnections = true;\r\n try {\r\n // Save active databases\r\n const currentActiveDb = Object.keys(this.connections);\r\n currentActiveDb.forEach((dbKey) => this.activeDatabases.add(dbKey));\r\n\r\n logger.debug(\"Saving active database list for potential reconnection\", {\r\n activeDatabases: currentActiveDb,\r\n });\r\n\r\n const closePromises = Object.entries(this.connections).map(\r\n async ([dbKey, dao]) => {\r\n try {\r\n logger.debug(\"Closing database connection\", { dbKey });\r\n await dao.close();\r\n logger.trace(\"Database connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue closing\r\n }\r\n }\r\n );\r\n\r\n await Promise.all(closePromises);\r\n this.connections = {};\r\n logger.info(\"All database connections closed successfully\");\r\n } finally {\r\n this.isClosingConnections = false;\r\n }\r\n }\r\n\r\n /**\r\n * Reopen connections\r\n */\r\n public static async reopenConnections(): Promise<void> {\r\n logger.info(\"Reopening database connections\");\r\n\r\n try {\r\n await this.initializeCoreConnection();\r\n\r\n if (this.currentUserRoles.length > 0) {\r\n await this.initializeUserRoleConnections();\r\n }\r\n\r\n // Reinitialize previously active databases\r\n const activeDbArray = Array.from(this.activeDatabases);\r\n logger.debug(\"Reinitializing previously active databases\", {\r\n activeDatabases: activeDbArray,\r\n });\r\n\r\n if (activeDbArray.length > 0) {\r\n for (const dbKey of activeDbArray) {\r\n if (!this.connections[dbKey]) {\r\n const schema = this.getSchema(dbKey);\r\n if (schema) {\r\n try {\r\n logger.debug(\"Reopening database connection\", { dbKey });\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.connect();\r\n this.connections[dbKey] = dao;\r\n this.notifyDatabaseReconnect(dbKey, dao);\r\n logger.info(\"Database connection reopened\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Failed to reopen database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue\r\n }\r\n } else {\r\n logger.warn(\"Schema not found for previously active database\", {\r\n dbKey,\r\n });\r\n }\r\n } else if (this.connections[dbKey]) {\r\n // Database exists, notify services\r\n logger.trace(\"Database already connected, notifying listeners\", {\r\n dbKey,\r\n });\r\n this.notifyDatabaseReconnect(dbKey, this.connections[dbKey]);\r\n }\r\n }\r\n }\r\n\r\n logger.info(\"Database connections reopened successfully\");\r\n } catch (error) {\r\n logger.error(\"Failed to reopen database connections\", {\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Ensure database connection exists and is active\r\n */\r\n public static async ensureDatabaseConnection(\r\n key: string\r\n ): Promise<UniversalDAO> {\r\n logger.debug(\"Ensuring database connection\", { key });\r\n this.activeDatabases.add(key);\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied when ensuring database connection\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n if (this.connections[key]) {\r\n try {\r\n const isConnected = this.connections[key].isConnectionOpen();\r\n if (isConnected) {\r\n logger.trace(\"Database connection already active\", { key });\r\n return this.connections[key];\r\n } else {\r\n // Clean up inactive connection\r\n logger.warn(\"Database connection inactive, cleaning up\", { key });\r\n try {\r\n await this.connections[key].close().catch(() => {});\r\n } catch (error) {\r\n logger.debug(\"Error during connection cleanup\", {\r\n key,\r\n error: (error as Error).message,\r\n });\r\n // Ignore cleanup errors\r\n }\r\n delete this.connections[key];\r\n }\r\n } catch (error) {\r\n logger.error(\"Error checking connection status\", {\r\n key,\r\n error: (error as Error).message,\r\n });\r\n delete this.connections[key];\r\n }\r\n }\r\n\r\n // Create new connection\r\n logger.debug(\"Creating new database connection\", { key });\r\n return await this.getLazyLoading(key);\r\n }\r\n\r\n /**\r\n * Get all connections\r\n */\r\n public static getConnections(): DatabaseConnections {\r\n logger.trace(\"Getting all connections\", {\r\n count: Object.keys(this.connections).length,\r\n });\r\n return { ...this.connections };\r\n }\r\n\r\n /**\r\n * Open all existing databases\r\n */\r\n public static async openAllExisting(\r\n databaseKeys: string[]\r\n ): Promise<boolean> {\r\n logger.info(\"Opening all existing databases\", { databaseKeys });\r\n const failedOpens: { key: string; error: Error }[] = [];\r\n\r\n for (const key of databaseKeys) {\r\n try {\r\n logger.debug(\"Opening database\", { key });\r\n const schema = this.getSchema(key);\r\n if (!schema) {\r\n throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n }\r\n\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[key] = dao;\r\n logger.info(\"Database opened successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to open database\", { key, error: err.message });\r\n failedOpens.push({ key, error: err });\r\n }\r\n }\r\n\r\n if (failedOpens.length > 0) {\r\n const errorSummary = failedOpens\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to open one or more databases\", {\r\n failedDatabases: failedOpens.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(`Failed to open one or more databases:\\n${errorSummary}`);\r\n }\r\n\r\n this.isInitialized = true;\r\n logger.info(\"All databases opened successfully\", {\r\n count: databaseKeys.length,\r\n });\r\n return true;\r\n }\r\n\r\n /**\r\n * Initialize databases lazily\r\n */\r\n public static async initLazySchema(databaseKeys: string[]): Promise<boolean> {\r\n logger.debug(\"Initializing databases lazily\", { databaseKeys });\r\n\r\n const invalidKeys = databaseKeys.filter((key) => !this.getSchema(key));\r\n if (invalidKeys.length > 0) {\r\n logger.error(\"Invalid database keys found\", { invalidKeys });\r\n throw new Error(\r\n `Invalid database keys: ${invalidKeys.join(\", \")}. Schemas not found.`\r\n );\r\n }\r\n\r\n const newConnectionsCount = databaseKeys.filter(\r\n (key) => !this.connections[key]\r\n ).length;\r\n const currentConnectionsCount = Object.keys(this.connections).length;\r\n\r\n if (currentConnectionsCount + newConnectionsCount > this.maxConnections) {\r\n logger.error(\"Would exceed maximum connections\", {\r\n currentConnections: currentConnectionsCount,\r\n newConnections: newConnectionsCount,\r\n maxConnections: this.maxConnections,\r\n });\r\n throw new Error(\r\n `Cannot initialize ${newConnectionsCount} new connections. Would exceed maximum of ${this.maxConnections} connections. Current: ${currentConnectionsCount}`\r\n );\r\n }\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n const initPromises = databaseKeys.map(async (key) => {\r\n if (this.connections[key]) {\r\n logger.trace(\"Database already initialized\", { key });\r\n return; // Already initialized\r\n }\r\n\r\n try {\r\n logger.debug(\"Initializing database\", { key });\r\n const schema = this.getSchema(key)!;\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[key] = dao;\r\n logger.info(\"Database initialized successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize database\", {\r\n key,\r\n error: err.message,\r\n });\r\n failedInitializations.push({ key, error: err });\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize one or more databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize one or more databases:\\n${errorSummary}`\r\n );\r\n }\r\n\r\n if (Object.keys(this.connections).length > 0) {\r\n this.isInitialized = true;\r\n logger.info(\"Lazy schema initialization completed\", {\r\n initializedCount: databaseKeys.length - failedInitializations.length,\r\n });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Initialize all available databases\r\n */\r\n public static async initializeAll(): Promise<void> {\r\n if (this.isInitialized) {\r\n logger.debug(\"Database manager already initialized\");\r\n return;\r\n }\r\n\r\n const availableSchemas = this.getAvailableSchemas();\r\n logger.info(\"Initializing all available databases\", {\r\n schemaCount: availableSchemas.length,\r\n schemas: availableSchemas,\r\n });\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n const initPromises = availableSchemas.map(async (key) => {\r\n try {\r\n logger.debug(\"Initializing schema\", { key });\r\n const schema = this.getSchema(key)!;\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n this.connections[key] = dao;\r\n logger.info(\"Schema initialized successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize schema\", {\r\n key,\r\n error: err.message,\r\n });\r\n failedInitializations.push({ key, error: err });\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n this.isInitialized = false;\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize one or more databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize one or more databases:\\n${errorSummary}`\r\n );\r\n }\r\n\r\n this.isInitialized = true;\r\n logger.info(\"All databases initialized successfully\", {\r\n totalSchemas: availableSchemas.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get database with lazy loading\r\n */\r\n public static async getLazyLoading(key: string): Promise<UniversalDAO> {\r\n logger.debug(\"Getting database with lazy loading\", { key });\r\n this.activeDatabases.add(key);\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied for lazy loading\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n if (!this.connections[key]) {\r\n const schema = this.getSchema(key);\r\n if (!schema) {\r\n logger.error(\"Schema not found for lazy loading\", { key });\r\n throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n }\r\n\r\n if (Object.keys(this.connections).length >= this.maxConnections) {\r\n logger.error(\"Maximum connections reached\", {\r\n currentConnections: Object.keys(this.connections).length,\r\n maxConnections: this.maxConnections,\r\n });\r\n throw new Error(\"Maximum number of database connections reached\");\r\n }\r\n\r\n logger.debug(\"Creating new connection for lazy loading\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n const dao = await DatabaseFactory.createOrOpen({ config: schema }, false);\r\n await dao.connect();\r\n this.connections[key] = dao;\r\n logger.info(\"Database connection created via lazy loading\", { key });\r\n }\r\n\r\n this.isInitialized = true;\r\n return this.connections[key];\r\n }\r\n\r\n /**\r\n * Execute cross-schema transaction\r\n */\r\n public static async executeCrossSchemaTransaction(\r\n schemas: string[],\r\n callback: (daos: Record<string, UniversalDAO>) => Promise<void>\r\n ): Promise<void> {\r\n logger.debug(\"Executing cross-schema transaction\", { schemas });\r\n\r\n for (const key of schemas) {\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied for cross-schema transaction\", {\r\n key,\r\n schemas,\r\n });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n }\r\n\r\n const daos = schemas.reduce((acc, key) => {\r\n acc[key] = this.get(key);\r\n return acc;\r\n }, {} as Record<string, UniversalDAO>);\r\n\r\n logger.debug(\"Starting cross-schema transaction\", { schemas });\r\n\r\n try {\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.beginTransaction())\r\n );\r\n logger.trace(\"All transactions started successfully\");\r\n\r\n await callback(daos);\r\n logger.trace(\"Transaction callback completed successfully\");\r\n\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.commitTransaction())\r\n );\r\n logger.info(\"Cross-schema transaction completed successfully\", {\r\n schemas,\r\n });\r\n } catch (error) {\r\n logger.error(\"Cross-schema transaction failed, rolling back\", {\r\n schemas,\r\n error: (error as Error).message,\r\n });\r\n\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.rollbackTransaction())\r\n );\r\n logger.debug(\"Cross-schema transaction rolled back\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data to table\r\n */\r\n public static async importDataToTable(\r\n databaseKey: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing data to table\", {\r\n databaseKey,\r\n tableName,\r\n recordCount: data.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for data import\", { databaseKey, tableName });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importData({\r\n tableName,\r\n data,\r\n ...options,\r\n });\r\n logger.info(\"Data import completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Data import failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n public static async importDataWithMapping(\r\n databaseKey: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing data with column mapping\", {\r\n databaseKey,\r\n tableName,\r\n recordCount: data.length,\r\n mappingCount: columnMappings.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for data import with mapping\", {\r\n databaseKey,\r\n tableName,\r\n });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importDataWithMapping(\r\n tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n logger.info(\"Data import with mapping completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Data import with mapping failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk import data\r\n */\r\n public static async bulkImport(\r\n importConfigs: DatabaseImportConfig[]\r\n ): Promise<BulkImportResult> {\r\n const startTime = Date.now();\r\n logger.info(\"Starting bulk import\", {\r\n configCount: importConfigs.length,\r\n configs: importConfigs.map((c) => ({\r\n databaseKey: c.databaseKey,\r\n tableName: c.tableName,\r\n recordCount: c.data.length,\r\n })),\r\n });\r\n\r\n const result: BulkImportResult = {\r\n totalDatabases: importConfigs.length,\r\n successDatabases: 0,\r\n results: {},\r\n errors: {},\r\n executionTime: 0,\r\n };\r\n\r\n for (const config of importConfigs) {\r\n const configKey = `${config.databaseKey}.${config.tableName}`;\r\n logger.debug(\"Processing bulk import config\", { configKey });\r\n\r\n try {\r\n if (!this.hasAccessToDatabase(config.databaseKey)) {\r\n throw new Error(\r\n `Access denied: Database '${config.databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(config.databaseKey);\r\n let importResult: ImportResult;\r\n\r\n if (config.columnMappings) {\r\n logger.trace(\"Using column mappings for import\", { configKey });\r\n importResult = await dao.importDataWithMapping(\r\n config.tableName,\r\n config.data,\r\n config.columnMappings,\r\n config.options\r\n );\r\n } else {\r\n logger.trace(\"Using direct import\", { configKey });\r\n importResult = await dao.importData({\r\n tableName: config.tableName,\r\n data: config.data,\r\n ...config.options,\r\n });\r\n }\r\n\r\n result.results[configKey] = importResult;\r\n result.successDatabases++;\r\n logger.info(\"Bulk import config completed successfully\", {\r\n configKey,\r\n importedRows: importResult.successRows,\r\n skippedRows: importResult.errorRows,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Bulk import config failed\", {\r\n configKey,\r\n error: err.message,\r\n });\r\n result.errors[configKey] = err;\r\n }\r\n }\r\n\r\n result.executionTime = Date.now() - startTime;\r\n logger.info(\"Bulk import completed\", {\r\n totalConfigs: result.totalDatabases,\r\n successfulConfigs: result.successDatabases,\r\n failedConfigs: Object.keys(result.errors).length,\r\n executionTimeMs: result.executionTime,\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Import from CSV\r\n */\r\n public static async importFromCSV(\r\n databaseKey: string,\r\n tableName: string,\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing from CSV\", {\r\n databaseKey,\r\n tableName,\r\n csvSize: csvData.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for CSV import\", { databaseKey, tableName });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importFromCSV(tableName, csvData, options);\r\n logger.info(\"CSV import completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"CSV import failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get connection count\r\n */\r\n public static getConnectionCount(): number {\r\n const count = Object.keys(this.connections).length;\r\n logger.trace(\"Getting connection count\", { count });\r\n return count;\r\n }\r\n\r\n /**\r\n * List all active connections\r\n */\r\n public static listConnections(): string[] {\r\n const connections = Object.keys(this.connections);\r\n logger.trace(\"Listing connections\", { connections });\r\n return connections;\r\n }\r\n\r\n /**\r\n * Close specific connection\r\n */\r\n public static async closeConnection(dbKey: string): Promise<void> {\r\n logger.debug(\"Closing specific connection\", { dbKey });\r\n\r\n const dao = this.connections[dbKey];\r\n if (dao) {\r\n try {\r\n await dao.disconnect();\r\n delete this.connections[dbKey];\r\n logger.info(\"Database connection closed successfully\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n } else {\r\n logger.warn(\"Attempted to close non-existent connection\", { dbKey });\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections and reset state\r\n */\r\n public static async closeAll(): Promise<void> {\r\n logger.info(\"Closing all connections and resetting state\");\r\n\r\n await this.closeAllConnections();\r\n\r\n this.currentUserRoles = [];\r\n this.currentRole = null;\r\n this.isInitialized = false;\r\n this.activeDatabases.clear();\r\n this.eventListeners.clear();\r\n this.isClosingConnections = false;\r\n\r\n logger.info(\"All connections closed and state reset successfully\");\r\n }\r\n\r\n /**\r\n * Logout user - close role-specific connections\r\n */\r\n public static async logout(): Promise<void> {\r\n logger.info(\"Logging out user\", {\r\n currentUserRoles: this.currentUserRoles,\r\n });\r\n\r\n const connectionsToClose = Object.keys(this.connections).filter(\r\n (key) => key !== \"core\"\r\n );\r\n\r\n logger.debug(\"Closing role-specific connections\", { connectionsToClose });\r\n\r\n for (const dbKey of connectionsToClose) {\r\n try {\r\n await this.connections[dbKey].close();\r\n delete this.connections[dbKey];\r\n logger.debug(\"Role-specific connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing connection during logout\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue cleanup\r\n }\r\n }\r\n\r\n this.currentUserRoles = [];\r\n this.currentRole = null;\r\n\r\n logger.info(\"User logout completed successfully\", {\r\n closedConnections: connectionsToClose.length,\r\n });\r\n }\r\n}\r\n","// src/core/base-service.ts\r\nimport {\r\n QueryTable,\r\n WhereClause,\r\n OrderByClause,\r\n ImportResult,\r\n ColumnMapping,\r\n ImportOptions,\r\n ServiceStatus,\r\n HealthCheckResult,\r\n} from \"../types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { DatabaseManager } from \"./database-manager\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.BASE_SERVICE);\r\n\r\nexport interface FindOptions {\r\n where?: WhereClause[];\r\n orderBy?: OrderByClause[];\r\n limit?: number;\r\n offset?: number;\r\n columns?: string[];\r\n}\r\n\r\nexport type ErrorHandler = (error: Error) => void;\r\nexport type EventHandler = (data: any) => void;\r\n\r\n/**\r\n * Universal BaseService - An enhanced abstract base class designed to provide\r\n * comprehensive CRUD operations and database management features across all\r\n * operating systems and frameworks using TypeScript and JavaScript.\r\n */\r\nexport abstract class BaseService<T = any> {\r\n protected dao: UniversalDAO | null = null;\r\n protected schemaName: string;\r\n protected tableName: string;\r\n protected isOpened: boolean = false;\r\n protected isInitialized: boolean = false;\r\n protected errorHandlers: Map<string, ErrorHandler> = new Map();\r\n protected eventListeners: Map<string, EventHandler[]> = new Map();\r\n protected primaryKeyFields: string[] = [\"id\"];\r\n private cache: Map<string, any> = new Map();\r\n private reconnectHandler: (dao: UniversalDAO) => void;\r\n\r\n constructor(schemaName: string, tableName?: string) {\r\n this.schemaName = schemaName;\r\n this.tableName = tableName || schemaName;\r\n\r\n logger.debug(\"Creating BaseService instance\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n primaryKeyFields: this.primaryKeyFields\r\n });\r\n\r\n // Register reconnect listener for database reconnection\r\n this.reconnectHandler = (newDao: UniversalDAO) => {\r\n logger.info(\"Database reconnected for service\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n \r\n this.dao = newDao;\r\n this._emit(\"daoReconnected\", { schemaName: this.schemaName });\r\n };\r\n\r\n DatabaseManager.onDatabaseReconnect(schemaName, this.reconnectHandler);\r\n this.bindMethods();\r\n \r\n logger.trace(\"BaseService instance created successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n }\r\n\r\n private bindMethods(): void {\r\n logger.trace(\"Binding service methods\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n methods.forEach((method) => {\r\n if (\r\n typeof (this as any)[method] === \"function\" &&\r\n method !== \"constructor\"\r\n ) {\r\n (this as any)[method] = (this as any)[method].bind(this);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Set primary key fields for the service\r\n */\r\n setPrimaryKeyFields(fields: string[]): this {\r\n logger.debug(\"Setting primary key fields\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n previousFields: this.primaryKeyFields,\r\n newFields: fields\r\n });\r\n\r\n this.primaryKeyFields = fields;\r\n return this;\r\n }\r\n\r\n /**\r\n * Initialize the service and establish database connection\r\n */\r\n async init(): Promise<this> {\r\n logger.info(\"Initializing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n try {\r\n if (this.isInitialized) {\r\n logger.debug(\"Service already initialized, skipping\", {\r\n schemaName: this.schemaName\r\n });\r\n return this;\r\n }\r\n\r\n logger.debug(\"Getting DAO from DatabaseManager\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n this.dao = await DatabaseManager.getLazyLoading(this.schemaName);\r\n\r\n if (!this.dao) {\r\n const errorMsg = `Failed to initialize DAO for schema: ${this.schemaName}`;\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n if (!this.dao.isConnectionOpen()) {\r\n logger.debug(\"DAO connection not open, connecting\", {\r\n schemaName: this.schemaName\r\n });\r\n await this.dao.connect();\r\n }\r\n\r\n this.isOpened = true;\r\n this.isInitialized = true;\r\n \r\n logger.info(\"BaseService initialized successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n this._emit(\"initialized\", { schemaName: this.schemaName });\r\n\r\n return this;\r\n } catch (error) {\r\n logger.error(\"Error initializing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"INIT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new record - Safe version với comprehensive error handling\r\n */\r\n async create(data: Partial<T>): Promise<T | null> {\r\n logger.debug(\"Creating new record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n hasData: !!data,\r\n dataKeys: data ? Object.keys(data) : []\r\n });\r\n\r\n await this._ensureInitialized();\r\n await this.ensureValidConnection();\r\n \r\n try {\r\n this._validateData(data);\r\n \r\n logger.trace(\"Building data table for insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const queryTable = this.buildDataTable(data as Record<string, any>);\r\n const result = await this.dao!.insert(queryTable);\r\n \r\n if (result.rowsAffected === 0) {\r\n const errorMsg = \"Insert operation failed - no rows affected\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n result\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Insert operation successful\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowId: result.lastInsertRowId\r\n });\r\n\r\n let createdRecord: T | null = null;\r\n const primaryKeyValue = data[this.primaryKeyFields[0] as keyof T];\r\n \r\n try {\r\n if (primaryKeyValue !== undefined && primaryKeyValue !== null) {\r\n logger.trace(\"Retrieving created record by primary key\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n primaryKeyField: this.primaryKeyFields[0],\r\n primaryKeyValue\r\n });\r\n createdRecord = await this.findById(primaryKeyValue as any);\r\n } else if (result.lastInsertRowId) {\r\n logger.trace(\"Retrieving created record by last insert ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n lastInsertRowId: result.lastInsertRowId\r\n });\r\n createdRecord = await this.findById(result.lastInsertRowId);\r\n }\r\n } catch (findError) {\r\n logger.warn(\"Could not retrieve created record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n findError: (findError as Error).message\r\n });\r\n }\r\n\r\n if (!createdRecord) {\r\n logger.debug(\"Using original data as created record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n createdRecord = data as T;\r\n }\r\n\r\n logger.info(\"Record created successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordRetrieved: !!createdRecord\r\n });\r\n\r\n this._emit(\"dataCreated\", { operation: \"create\", data: createdRecord });\r\n return createdRecord;\r\n } catch (error) {\r\n logger.error(\"Error creating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"CREATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Update an existing record\r\n */\r\n async update(id: any, data: Partial<T>): Promise<T | null> {\r\n logger.debug(\"Updating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n hasData: !!data,\r\n dataKeys: data ? Object.keys(data) : []\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required for update\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n this._validateData(data);\r\n \r\n const updateData = {\r\n ...data,\r\n [this.primaryKeyFields[0]]: id,\r\n };\r\n\r\n logger.trace(\"Building update query table\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const queryTable = this.buildDataTable(updateData as Record<string, any>);\r\n await this.dao!.update(queryTable);\r\n\r\n logger.debug(\"Update operation completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const result = await this.findById(id);\r\n \r\n logger.info(\"Record updated successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n recordFound: !!result\r\n });\r\n\r\n this._emit(\"dataUpdated\", { operation: \"update\", id, data: result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error updating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"UPDATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Delete a record by ID\r\n */\r\n async delete(id: any): Promise<boolean> {\r\n logger.debug(\"Deleting record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required for delete\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [],\r\n wheres: [{ name: this.primaryKeyFields[0], value: id }],\r\n };\r\n\r\n logger.trace(\"Executing delete operation\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n primaryKeyField: this.primaryKeyFields[0]\r\n });\r\n\r\n const result = await this.dao!.delete(queryTable);\r\n const success = result.rowsAffected > 0;\r\n\r\n if (success) {\r\n logger.info(\"Record deleted successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n rowsAffected: result.rowsAffected\r\n });\r\n this._emit(\"dataDeleted\", { operation: \"delete\", id });\r\n } else {\r\n logger.warn(\"Delete operation completed but no rows affected\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n }\r\n\r\n return success;\r\n } catch (error) {\r\n logger.error(\"Error deleting record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"DELETE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find a record by ID\r\n */\r\n async findById(id: any): Promise<T | null> {\r\n logger.debug(\"Finding record by ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const conditions = { [this.primaryKeyFields[0]]: id };\r\n \r\n logger.trace(\"Building select query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions\r\n });\r\n\r\n const queryTable = this.buildSelectTable(conditions);\r\n const result = await this.dao!.select(queryTable);\r\n\r\n const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n \r\n logger.debug(\"Find by ID completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n recordFound: !!record\r\n });\r\n\r\n this._emit(\"dataFetched\", { operation: \"findById\", id });\r\n return record;\r\n } catch (error) {\r\n logger.error(\"Error finding record by ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_BY_ID_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find the first record matching conditions\r\n */\r\n async findFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n logger.debug(\"Finding first record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n conditions\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.trace(\"Building select query for findFirst\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const queryTable = this.buildSelectTable(conditions);\r\n const result = await this.dao!.select(queryTable);\r\n\r\n const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n \r\n logger.debug(\"Find first completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordFound: !!record\r\n });\r\n\r\n this._emit(\"dataFetched\", { operation: \"findFirst\" });\r\n return record;\r\n } catch (error) {\r\n logger.error(\"Error finding first record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_FIRST_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find all records matching conditions\r\n */\r\n async findAll(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): Promise<T[]> {\r\n logger.debug(\"Finding all records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n hasLimit: !!options.limit,\r\n hasOffset: !!options.offset,\r\n hasOrderBy: !!(options.orderBy && options.orderBy.length > 0),\r\n limit: options.limit,\r\n offset: options.offset\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n // Build where clauses from conditions\r\n const whereFromConditions = this.buildWhereFromObject(conditions);\r\n const allWheres = [...whereFromConditions, ...(options.where || [])];\r\n\r\n logger.trace(\"Building query for findAll\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalWheres: allWheres.length,\r\n hasColumns: !!(options.columns && options.columns.length > 0)\r\n });\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: options.columns ? options.columns.map((name) => ({ name })) : [],\r\n wheres: allWheres,\r\n orderbys: options.orderBy,\r\n limitOffset: {\r\n limit: options.limit,\r\n offset: options.offset,\r\n },\r\n };\r\n\r\n const results = await this.dao!.selectAll(queryTable);\r\n \r\n logger.info(\"Find all completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordsFound: results.length,\r\n conditionsCount: Object.keys(conditions).length\r\n });\r\n\r\n this._emit(\"dataFetched\", {\r\n operation: \"findAll\",\r\n count: results.length,\r\n });\r\n return results as T[];\r\n } catch (error) {\r\n logger.error(\"Error finding all records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions,\r\n options,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_ALL_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Count records matching conditions\r\n */\r\n async count(where?: WhereClause[] | Record<string, any>): Promise<number> {\r\n logger.debug(\"Counting records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n hasWhere: !!where,\r\n whereType: where ? (Array.isArray(where) ? 'array' : 'object') : 'none'\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n let whereConditions: WhereClause[] = [];\r\n\r\n if (Array.isArray(where)) {\r\n whereConditions = where;\r\n logger.trace(\"Using array where conditions\", {\r\n schemaName: this.schemaName,\r\n whereCount: whereConditions.length\r\n });\r\n } else if (where && typeof where === \"object\") {\r\n whereConditions = this.buildWhereFromObject(where);\r\n logger.trace(\"Built where conditions from object\", {\r\n schemaName: this.schemaName,\r\n whereCount: whereConditions.length\r\n });\r\n }\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [{ name: \"COUNT(*) as count\" }],\r\n wheres: whereConditions,\r\n };\r\n\r\n const result = await this.dao!.select(queryTable);\r\n const count = result.count || 0;\r\n \r\n logger.debug(\"Count completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n count\r\n });\r\n\r\n return count;\r\n } catch (error) {\r\n logger.error(\"Error counting records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n where,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"COUNT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a record exists by ID\r\n */\r\n async exists(id: any): Promise<boolean> {\r\n logger.debug(\"Checking if record exists\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const item = await this.findById(id);\r\n const exists = item !== null;\r\n \r\n logger.debug(\"Existence check completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n exists\r\n });\r\n\r\n return exists;\r\n }\r\n\r\n /**\r\n * Truncate table (delete all records and reset auto-increment)\r\n */\r\n async truncate(): Promise<void> {\r\n logger.warn(\"Truncating table - this will delete all data\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.debug(\"Executing truncate operations\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this.dao!.execute(`DELETE FROM ${this.tableName}`);\r\n await this.dao!.execute(\r\n `DELETE FROM sqlite_sequence WHERE name='${this.tableName}'`\r\n );\r\n \r\n logger.info(\"Table truncated successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"tableTruncated\", { tableName: this.tableName });\r\n } catch (error) {\r\n logger.error(\"Error truncating table\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"TRUNCATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk insert records\r\n */\r\n async bulkInsert(items: Partial<T>[]): Promise<ImportResult> {\r\n logger.info(\"Starting bulk insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!Array.isArray(items) || items.length === 0) {\r\n const errorMsg = \"Items must be a non-empty array\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsType: typeof items,\r\n itemsLength: Array.isArray(items) ? items.length : 'N/A'\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Executing bulk insert operation\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length\r\n });\r\n\r\n const result = await this.dao!.importData({\r\n tableName: this.tableName,\r\n data: items as Record<string, any>[],\r\n batchSize: 1000,\r\n skipErrors: false,\r\n validateData: true,\r\n });\r\n\r\n logger.info(\"Bulk insert completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataBulkCreated\", {\r\n operation: \"bulkInsert\",\r\n count: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during bulk insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"BULK_INSERT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk create records with transaction support\r\n */\r\n async bulkCreate(dataArray: Record<string, any>[]): Promise<T[]> {\r\n logger.info(\"Starting bulk create with transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!Array.isArray(dataArray) || dataArray.length === 0) {\r\n const errorMsg = \"Data must be a non-empty array\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataType: typeof dataArray,\r\n dataLength: Array.isArray(dataArray) ? dataArray.length : 'N/A'\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const results: T[] = [];\r\n \r\n logger.debug(\"Executing bulk create in transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length\r\n });\r\n\r\n await this.executeTransaction(async () => {\r\n for (let i = 0; i < dataArray.length; i++) {\r\n const data = dataArray[i];\r\n \r\n if (i % 100 === 0) {\r\n logger.trace(\"Bulk create progress\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n processed: i,\r\n total: dataArray.length\r\n });\r\n }\r\n\r\n this._validateData(data);\r\n const queryTable = this.buildDataTable(data);\r\n await this.dao!.insert(queryTable);\r\n results.push(data as T);\r\n }\r\n });\r\n\r\n logger.info(\"Bulk create completed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordsCreated: results.length\r\n });\r\n\r\n this._emit(\"dataBulkCreated\", {\r\n operation: \"bulkCreate\",\r\n count: results.length,\r\n });\r\n return results;\r\n } catch (error) {\r\n logger.error(\"Error during bulk create\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"BULK_CREATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute operations within a transaction\r\n */\r\n async executeTransaction(callback: () => Promise<any>): Promise<any> {\r\n logger.debug(\"Starting transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.trace(\"Beginning database transaction\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n await this.dao!.beginTransaction();\r\n const result = await callback();\r\n \r\n logger.trace(\"Committing transaction\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n await this.dao!.commitTransaction();\r\n \r\n logger.info(\"Transaction completed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"transactionCompleted\", { operation: \"transaction\" });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Transaction failed, rolling back\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n try {\r\n await this.dao!.rollbackTransaction();\r\n logger.debug(\"Transaction rollback successful\", {\r\n schemaName: this.schemaName\r\n });\r\n } catch (rollbackError) {\r\n logger.error(\"Error during transaction rollback\", {\r\n schemaName: this.schemaName,\r\n rollbackError: (rollbackError as Error).message\r\n });\r\n this._handleError(\"ROLLBACK_ERROR\", rollbackError as Error);\r\n }\r\n \r\n this._handleError(\"TRANSACTION_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data from CSV\r\n */\r\n async importFromCSV(\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.info(\"Starting CSV import\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n csvDataLength: csvData.length,\r\n delimiter: options.delimiter,\r\n hasHeader: options.hasHeader,\r\n hasMappings: !!(options.columnMappings && options.columnMappings.length > 0)\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n const result = await this.dao!.importFromCSV(\r\n this.tableName,\r\n csvData,\r\n options\r\n );\r\n\r\n logger.info(\"CSV import completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataImported\", { operation: \"importFromCSV\", result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during CSV import\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n csvDataLength: csvData.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"IMPORT_CSV_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n async importDataWithMapping(\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.info(\"Starting import with column mapping\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataCount: data.length,\r\n mappingsCount: columnMappings.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n const result = await this.dao!.importDataWithMapping(\r\n this.tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n\r\n logger.info(\"Import with mapping completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataImported\", { operation: \"importWithMapping\", result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during import with mapping\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataCount: data.length,\r\n mappingsCount: columnMappings.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"IMPORT_MAPPING_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n // Utility methods\r\n protected buildSelectTable(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): QueryTable {\r\n logger.trace(\"Building select table query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n hasOptions: Object.keys(options).length > 0\r\n });\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [],\r\n wheres: [],\r\n orderbys: options.orderBy || [],\r\n limitOffset: {},\r\n };\r\n\r\n if (options.columns && options.columns.length > 0) {\r\n queryTable.cols = options.columns.map((name) => ({ name }));\r\n }\r\n\r\n if (conditions && Object.keys(conditions).length > 0) {\r\n queryTable.wheres = Object.entries(conditions).map(([key, value]) => ({\r\n name: key,\r\n value,\r\n operator: \"=\",\r\n }));\r\n }\r\n\r\n if (options.limit !== undefined) {\r\n queryTable.limitOffset!.limit = options.limit;\r\n }\r\n if (options.offset !== undefined) {\r\n queryTable.limitOffset!.offset = options.offset;\r\n }\r\n\r\n return queryTable;\r\n }\r\n\r\n protected buildDataTable(data: Record<string, any>): QueryTable {\r\n logger.trace(\"Building data table for query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataKeys: Object.keys(data)\r\n });\r\n\r\n return this.dao!.convertJsonToQueryTable(\r\n this.tableName,\r\n data,\r\n this.primaryKeyFields\r\n );\r\n }\r\n\r\n protected buildWhereFromObject(obj: Record<string, any>): WhereClause[] {\r\n const wheres = Object.entries(obj)\r\n .filter(([_, value]) => value !== undefined)\r\n .map(([key, value]) => ({ name: key, value }));\r\n\r\n logger.trace(\"Built where clauses from object\", {\r\n schemaName: this.schemaName,\r\n originalKeys: Object.keys(obj).length,\r\n filteredWheres: wheres.length\r\n });\r\n\r\n return wheres;\r\n }\r\n\r\n // Event system\r\n on(event: string, handler: EventHandler): this {\r\n logger.trace(\"Adding event listener\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event\r\n });\r\n\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, []);\r\n }\r\n this.eventListeners.get(event)!.push(handler);\r\n return this;\r\n }\r\n\r\n off(event: string, handler: EventHandler): this {\r\n logger.trace(\"Removing event listener\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event\r\n });\r\n\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n protected _emit(event: string, data: any): void {\r\n logger.trace(\"Emitting event\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event,\r\n hasData: !!data\r\n });\r\n\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n logger.error(\"Error in event handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event,\r\n error: (error as Error).message\r\n });\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Error handling\r\n setErrorHandler(errorType: string, handler: ErrorHandler): this {\r\n logger.debug(\"Setting error handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType\r\n });\r\n\r\n this.errorHandlers.set(errorType, handler);\r\n return this;\r\n }\r\n\r\n protected _handleError(errorType: string, error: Error): void {\r\n logger.error(\"Handling service error\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType,\r\n error: error.message\r\n });\r\n\r\n const handler = this.errorHandlers.get(errorType);\r\n if (handler) {\r\n try {\r\n handler(error);\r\n } catch (handlerError) {\r\n logger.error(\"Error in error handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType,\r\n handlerError: (handlerError as Error).message\r\n });\r\n }\r\n }\r\n this._emit(\"error\", { errorType, error });\r\n }\r\n\r\n protected _validateData(data: any): void {\r\n if (!data || typeof data !== \"object\") {\r\n const errorMsg = \"Data must be a valid object\";\r\n logger.error(\"Data validation failed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataType: typeof data,\r\n isNull: data === null\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n }\r\n\r\n protected async _ensureInitialized(): Promise<void> {\r\n if (!this.isInitialized) {\r\n logger.debug(\"Service not initialized, initializing now\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n await this.init();\r\n }\r\n }\r\n\r\n private async ensureValidConnection(): Promise<void> {\r\n logger.trace(\"Ensuring valid database connection\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n try {\r\n const isConnected = this.dao?.isConnectionOpen();\r\n if (!isConnected) {\r\n logger.debug(\"Connection not valid, getting new connection\", {\r\n schemaName: this.schemaName\r\n });\r\n this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n this.schemaName\r\n );\r\n }\r\n } catch (error) {\r\n logger.warn(\"Error checking connection, getting new connection\", {\r\n schemaName: this.schemaName,\r\n error: (error as Error).message\r\n });\r\n this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n this.schemaName\r\n );\r\n }\r\n }\r\n\r\n // Information and status methods\r\n async getDatabaseInfo(): Promise<any> {\r\n logger.trace(\"Getting database info\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n return await this.dao!.getDatabaseInfo();\r\n }\r\n\r\n async getTableInfo(): Promise<any[]> {\r\n logger.trace(\"Getting table info\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n return await this.dao!.getTableInfo(this.tableName);\r\n }\r\n\r\n getStatus(): ServiceStatus {\r\n const status = {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized,\r\n hasDao: !!this.dao,\r\n };\r\n\r\n logger.trace(\"Getting service status\", status);\r\n return status;\r\n }\r\n\r\n async healthCheck(): Promise<HealthCheckResult> {\r\n logger.debug(\"Performing health check\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n try {\r\n await this._ensureInitialized();\r\n const count = await this.count();\r\n \r\n const result = {\r\n healthy: true,\r\n schemaName: this.schemaName,\r\n recordCount: count,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n logger.info(\"Health check passed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordCount: count\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n const result = {\r\n healthy: false,\r\n schemaName: this.schemaName,\r\n error: (error as Error).message,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n logger.error(\"Health check failed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n return result;\r\n }\r\n }\r\n\r\n // Lifecycle management\r\n async close(): Promise<boolean> {\r\n logger.info(\"Closing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n try {\r\n if (this.dao) {\r\n await this.dao.close();\r\n logger.debug(\"DAO closed successfully\", {\r\n schemaName: this.schemaName\r\n });\r\n }\r\n\r\n this.isOpened = false;\r\n this.isInitialized = false;\r\n this.eventListeners.clear();\r\n this.errorHandlers.clear();\r\n this.cache.clear();\r\n\r\n logger.info(\"BaseService closed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"closed\", { schemaName: this.schemaName });\r\n return true;\r\n } catch (error) {\r\n logger.error(\"Error closing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"CLOSE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n logger.debug(\"Destroying BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n // Remove reconnect listener\r\n DatabaseManager.offDatabaseReconnect(\r\n this.schemaName,\r\n this.reconnectHandler\r\n );\r\n\r\n // Clear all resources\r\n this.eventListeners.clear();\r\n this.errorHandlers.clear();\r\n this.cache.clear();\r\n\r\n logger.trace(\"BaseService destroyed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n }\r\n\r\n // Alias methods for backward compatibility\r\n async getAll(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): Promise<T[]> {\r\n logger.trace(\"Using getAll alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n return this.findAll(conditions, options);\r\n }\r\n\r\n async getById(id: string | number): Promise<T | null> {\r\n logger.trace(\"Using getById alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n return this.findById(id);\r\n }\r\n\r\n async getFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n logger.trace(\"Using getFirst alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n return this.findFirst(conditions);\r\n }\r\n}","// src/query/query-builder.ts\r\nimport { UniversalDAO } from '../core/universal-dao';\r\nimport { SQLiteResult, SQLiteRow } from '../types';\r\n\r\nexport interface QueryCondition {\r\n field: string;\r\n operator: string;\r\n value: any;\r\n}\r\n\r\nexport interface JoinClause {\r\n type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL OUTER';\r\n table: string;\r\n condition: string;\r\n}\r\n\r\nexport interface SubQuery {\r\n query: QueryBuilder;\r\n alias: string;\r\n}\r\n\r\n/**\r\n * Enhanced QueryBuilder with advanced SQL query construction capabilities\r\n */\r\nexport class QueryBuilder {\r\n private tableName = '';\r\n private selectFields: string[] = ['*'];\r\n private joinClauses: JoinClause[] = [];\r\n private whereConditions: QueryCondition[] = [];\r\n private groupByFields: string[] = [];\r\n private havingConditions: QueryCondition[] = [];\r\n private orderByFields: string[] = [];\r\n private limitValue: number | null = null;\r\n private offsetValue: number | null = null;\r\n private params: any[] = [];\r\n private unionQueries: QueryBuilder[] = [];\r\n private subQueries: SubQuery[] = [];\r\n private cteQueries: Map<string, QueryBuilder> = new Map();\r\n private dao: UniversalDAO | null = null;\r\n\r\n constructor(dao?: UniversalDAO) {\r\n this.dao = dao || null;\r\n }\r\n\r\n static table(name: string, dao?: UniversalDAO): QueryBuilder {\r\n const builder = new QueryBuilder(dao);\r\n builder.tableName = name;\r\n return builder;\r\n }\r\n\r\n static from(name: string, dao?: UniversalDAO): QueryBuilder {\r\n return QueryBuilder.table(name, dao);\r\n }\r\n\r\n // SELECT operations\r\n select(fields: string | string[]): QueryBuilder {\r\n this.selectFields = Array.isArray(fields) ? fields : [fields];\r\n return this;\r\n }\r\n\r\n selectRaw(raw: string): QueryBuilder {\r\n this.selectFields = [raw];\r\n return this;\r\n }\r\n\r\n selectDistinct(fields: string | string[]): QueryBuilder {\r\n const fieldList = Array.isArray(fields) ? fields.join(', ') : fields;\r\n this.selectFields = [`DISTINCT ${fieldList}`];\r\n return this;\r\n }\r\n\r\n // JOIN operations\r\n join(table: string, condition: string, type: JoinClause['type'] = 'INNER'): QueryBuilder {\r\n this.joinClauses.push({ type, table, condition });\r\n return this;\r\n }\r\n\r\n innerJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'INNER');\r\n }\r\n\r\n leftJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'LEFT');\r\n }\r\n\r\n rightJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'RIGHT');\r\n }\r\n\r\n fullOuterJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'FULL OUTER');\r\n }\r\n\r\n // WHERE conditions\r\n where(field: string, operator: string, value?: any): QueryBuilder;\r\n where(field: string, value: any): QueryBuilder;\r\n where(conditions: Record<string, any>): QueryBuilder;\r\n where(fieldOrConditions: string | Record<string, any>, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n if (typeof fieldOrConditions === 'object') {\r\n // Handle object of conditions\r\n Object.entries(fieldOrConditions).forEach(([field, val]) => {\r\n this.whereConditions.push({ field, operator: '=', value: val });\r\n });\r\n return this;\r\n }\r\n\r\n let operator = '=';\r\n let actualValue = operatorOrValue;\r\n\r\n if (arguments.length === 3) {\r\n operator = operatorOrValue;\r\n actualValue = value;\r\n }\r\n\r\n this.whereConditions.push({ \r\n field: fieldOrConditions, \r\n operator, \r\n value: actualValue \r\n });\r\n \r\n return this;\r\n }\r\n\r\n whereEquals(field: string, value: any): QueryBuilder {\r\n return this.where(field, '=', value);\r\n }\r\n\r\n whereNot(field: string, value: any): QueryBuilder {\r\n return this.where(field, '!=', value);\r\n }\r\n\r\n whereLike(field: string, value: string): QueryBuilder {\r\n return this.where(field, 'LIKE', value);\r\n }\r\n\r\n whereNotLike(field: string, value: string): QueryBuilder {\r\n return this.where(field, 'NOT LIKE', value);\r\n }\r\n\r\n whereIn(field: string, values: any[]): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IN', value: values });\r\n return this;\r\n }\r\n\r\n whereNotIn(field: string, values: any[]): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'NOT IN', value: values });\r\n return this;\r\n }\r\n\r\n whereBetween(field: string, min: any, max: any): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'BETWEEN', value: [min, max] });\r\n return this;\r\n }\r\n\r\n whereNotBetween(field: string, min: any, max: any): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'NOT BETWEEN', value: [min, max] });\r\n return this;\r\n }\r\n\r\n whereNull(field: string): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IS NULL', value: null });\r\n return this;\r\n }\r\n\r\n whereNotNull(field: string): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IS NOT NULL', value: null });\r\n return this;\r\n }\r\n\r\n whereExists(subquery: QueryBuilder): QueryBuilder {\r\n this.whereConditions.push({ \r\n field: '', \r\n operator: 'EXISTS', \r\n value: subquery \r\n });\r\n return this;\r\n }\r\n\r\n whereNotExists(subquery: QueryBuilder): QueryBuilder {\r\n this.whereConditions.push({ \r\n field: '', \r\n operator: 'NOT EXISTS', \r\n value: subquery \r\n });\r\n return this;\r\n }\r\n\r\n // OR WHERE conditions\r\n orWhere(field: string, operator: string, value?: any): QueryBuilder;\r\n orWhere(field: string, value: any): QueryBuilder;\r\n orWhere(field: string, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n // Implementation similar to where() but with OR logic\r\n // This would require refactoring the condition structure to support AND/OR\r\n return this.where(field, operatorOrValue as string, value);\r\n }\r\n\r\n // GROUP BY and HAVING\r\n groupBy(fields: string | string[]): QueryBuilder {\r\n this.groupByFields = Array.isArray(fields) ? fields : [fields];\r\n return this;\r\n }\r\n\r\n having(field: string, operator: string, value?: any): QueryBuilder {\r\n let actualOperator = '=';\r\n let actualValue = operator;\r\n\r\n if (arguments.length === 3) {\r\n actualOperator = operator;\r\n actualValue = value;\r\n }\r\n\r\n this.havingConditions.push({ \r\n field, \r\n operator: actualOperator, \r\n value: actualValue \r\n });\r\n return this;\r\n }\r\n\r\n havingCount(field: string, operator: string, value: number): QueryBuilder {\r\n return this.having(`COUNT(${field})`, operator, value);\r\n }\r\n\r\n // ORDER BY\r\n orderBy(field: string, direction: 'ASC' | 'DESC' = 'ASC'): QueryBuilder {\r\n this.orderByFields.push(`${field} ${direction}`);\r\n return this;\r\n }\r\n\r\n orderByDesc(field: string): QueryBuilder {\r\n return this.orderBy(field, 'DESC');\r\n }\r\n\r\n orderByRaw(raw: string): QueryBuilder {\r\n this.orderByFields.push(raw);\r\n return this;\r\n }\r\n\r\n latest(field: string = 'created_at'): QueryBuilder {\r\n return this.orderByDesc(field);\r\n }\r\n\r\n oldest(field: string = 'created_at'): QueryBuilder {\r\n return this.orderBy(field, 'ASC');\r\n }\r\n\r\n // LIMIT and OFFSET\r\n limit(count: number): QueryBuilder {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n offset(count: number): QueryBuilder {\r\n this.offsetValue = count;\r\n return this;\r\n }\r\n\r\n skip(count: number): QueryBuilder {\r\n return this.offset(count);\r\n }\r\n\r\n take(count: number): QueryBuilder {\r\n return this.limit(count);\r\n }\r\n\r\n firstRow(): QueryBuilder {\r\n return this.limit(1);\r\n }\r\n\r\n paginate(page: number, perPage: number): QueryBuilder {\r\n this.limitValue = perPage;\r\n this.offsetValue = (page - 1) * perPage;\r\n return this;\r\n }\r\n\r\n // UNION operations\r\n union(query: QueryBuilder): QueryBuilder {\r\n this.unionQueries.push(query);\r\n return this;\r\n }\r\n\r\n unionAll(query: QueryBuilder): QueryBuilder {\r\n // Note: SQLite doesn't differentiate UNION and UNION ALL like other databases\r\n return this.union(query);\r\n }\r\n\r\n // CTE (Common Table Expressions)\r\n with(alias: string, query: QueryBuilder): QueryBuilder {\r\n this.cteQueries.set(alias, query);\r\n return this;\r\n }\r\n\r\n // Subqueries\r\n whereSubQuery(field: string, operator: string, subquery: QueryBuilder): QueryBuilder {\r\n this.subQueries.push({ query: subquery, alias: '' });\r\n this.whereConditions.push({ field, operator, value: subquery });\r\n return this;\r\n }\r\n\r\n // Aggregation functions\r\n count(field: string = '*'): QueryBuilder {\r\n this.selectFields = [`COUNT(${field}) as count`];\r\n return this;\r\n }\r\n\r\n sum(field: string): QueryBuilder {\r\n this.selectFields = [`SUM(${field}) as sum`];\r\n return this;\r\n }\r\n\r\n avg(field: string): QueryBuilder {\r\n this.selectFields = [`AVG(${field}) as avg`];\r\n return this;\r\n }\r\n\r\n max(field: string): QueryBuilder {\r\n this.selectFields = [`MAX(${field}) as max`];\r\n return this;\r\n }\r\n\r\n min(field: string): QueryBuilder {\r\n this.selectFields = [`MIN(${field}) as min`];\r\n return this;\r\n }\r\n\r\n // SQL Generation\r\n toSQL(): { sql: string; params: any[] } {\r\n let sql = '';\r\n const params: any[] = [];\r\n\r\n // CTE queries\r\n if (this.cteQueries.size > 0) {\r\n const cteList: string[] = [];\r\n this.cteQueries.forEach((query, alias) => {\r\n const { sql: cteSql, params: cteParams } = query.toSQL();\r\n cteList.push(`${alias} AS (${cteSql})`);\r\n params.push(...cteParams);\r\n });\r\n sql += `WITH ${cteList.join(', ')} `;\r\n }\r\n\r\n // Main SELECT\r\n sql += `SELECT ${this.selectFields.join(', ')} FROM ${this.tableName}`;\r\n\r\n // JOINs\r\n if (this.joinClauses.length > 0) {\r\n this.joinClauses.forEach(join => {\r\n sql += ` ${join.type} JOIN ${join.table} ON ${join.condition}`;\r\n });\r\n }\r\n\r\n // WHERE conditions\r\n if (this.whereConditions.length > 0) {\r\n const conditions: string[] = [];\r\n this.whereConditions.forEach(condition => {\r\n const { clause, conditionParams } = this.buildCondition(condition);\r\n conditions.push(clause);\r\n params.push(...conditionParams);\r\n });\r\n sql += ` WHERE ${conditions.join(' AND ')}`;\r\n }\r\n\r\n // GROUP BY\r\n if (this.groupByFields.length > 0) {\r\n sql += ` GROUP BY ${this.groupByFields.join(', ')}`;\r\n }\r\n\r\n // HAVING\r\n if (this.havingConditions.length > 0) {\r\n const conditions: string[] = [];\r\n this.havingConditions.forEach(condition => {\r\n const { clause, conditionParams } = this.buildCondition(condition);\r\n conditions.push(clause);\r\n params.push(...conditionParams);\r\n });\r\n sql += ` HAVING ${conditions.join(' AND ')}`;\r\n }\r\n\r\n // ORDER BY\r\n if (this.orderByFields.length > 0) {\r\n sql += ` ORDER BY ${this.orderByFields.join(', ')}`;\r\n }\r\n\r\n // LIMIT\r\n if (this.limitValue !== null) {\r\n sql += ` LIMIT ${this.limitValue}`;\r\n }\r\n\r\n // OFFSET\r\n if (this.offsetValue !== null) {\r\n sql += ` OFFSET ${this.offsetValue}`;\r\n }\r\n\r\n // UNION queries\r\n if (this.unionQueries.length > 0) {\r\n this.unionQueries.forEach(unionQuery => {\r\n const { sql: unionSql, params: unionParams } = unionQuery.toSQL();\r\n sql += ` UNION ${unionSql}`;\r\n params.push(...unionParams);\r\n });\r\n }\r\n\r\n return { sql, params };\r\n }\r\n\r\n private buildCondition(condition: QueryCondition): { clause: string; conditionParams: any[] } {\r\n const { field, operator, value } = condition;\r\n const params: any[] = [];\r\n\r\n switch (operator.toUpperCase()) {\r\n case 'IN':\r\n case 'NOT IN':\r\n const placeholders = (value as any[]).map(() => '?').join(', ');\r\n params.push(...(value as any[]));\r\n return { \r\n clause: `${field} ${operator} (${placeholders})`, \r\n conditionParams: params \r\n };\r\n\r\n case 'BETWEEN':\r\n case 'NOT BETWEEN':\r\n params.push(value[0], value[1]);\r\n return { \r\n clause: `${field} ${operator} ? AND ?`, \r\n conditionParams: params \r\n };\r\n\r\n case 'IS NULL':\r\n case 'IS NOT NULL':\r\n return { \r\n clause: `${field} ${operator}`, \r\n conditionParams: [] \r\n };\r\n\r\n case 'EXISTS':\r\n case 'NOT EXISTS':\r\n const { sql: subSql, params: subParams } = (value as QueryBuilder).toSQL();\r\n params.push(...subParams);\r\n return { \r\n clause: `${operator} (${subSql})`, \r\n conditionParams: params \r\n };\r\n\r\n default:\r\n if (value instanceof QueryBuilder) {\r\n const { sql: subSql, params: subParams } = value.toSQL();\r\n params.push(...subParams);\r\n return { \r\n clause: `${field} ${operator} (${subSql})`, \r\n conditionParams: params \r\n };\r\n }\r\n params.push(value);\r\n return { \r\n clause: `${field} ${operator} ?`, \r\n conditionParams: params \r\n };\r\n }\r\n }\r\n\r\n // Execution methods (require DAO)\r\n async get(): Promise<SQLiteRow[]> {\r\n if (!this.dao) {\r\n throw new Error('DAO instance required for query execution');\r\n }\r\n const { sql, params } = this.toSQL();\r\n const result = await this.dao.execute(sql, params);\r\n return result.rows;\r\n }\r\n\r\n async first(): Promise<SQLiteRow | null> {\r\n this.limit(1);\r\n const results = await this.get(); // This will apply the limit(1) set by firstRow()\r\n return results.length > 0 ? results[0] : null;\r\n }\r\n\r\n async pluck(column: string): Promise<any[]> {\r\n this.select(column);\r\n const results = await this.get();\r\n return results.map(row => row[column]);\r\n }\r\n\r\n async exists(): Promise<boolean> {\r\n this.select('1').limit(1);\r\n const results = await this.get();\r\n return results.length > 0;\r\n }\r\n\r\n async countResult(): Promise<number> {\r\n this.count();\r\n const result = await this.first();\r\n return result ? result.count : 0;\r\n }\r\n\r\n // Static helper methods for DML operations\r\n static insert(tableName: string, data: Record<string, any>): { sql: string; params: any[] } {\r\n const fields = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = values.map(() => '?').join(', ');\r\n\r\n return {\r\n sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`,\r\n params: values\r\n };\r\n }\r\n\r\n static insertMany(tableName: string, dataArray: Record<string, any>[]): { sql: string; params: any[] } {\r\n if (dataArray.length === 0) {\r\n throw new Error('Data array cannot be empty');\r\n }\r\n\r\n const fields = Object.keys(dataArray[0]);\r\n const placeholders = fields.map(() => '?').join(', ');\r\n const valueGroups = dataArray.map(() => `(${placeholders})`).join(', ');\r\n\r\n const allValues = dataArray.flatMap(data => Object.values(data));\r\n\r\n return {\r\n sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES ${valueGroups}`,\r\n params: allValues\r\n };\r\n }\r\n\r\n static update(tableName: string, data: Record<string, any>, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n const sets = Object.keys(data).map(key => `${key} = ?`).join(', ');\r\n const params = [...Object.values(data), ...whereParams];\r\n\r\n return {\r\n sql: `UPDATE ${tableName} SET ${sets} WHERE ${where}`,\r\n params\r\n };\r\n }\r\n\r\n static delete(tableName: string, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n return {\r\n sql: `DELETE FROM ${tableName} WHERE ${where}`,\r\n params: whereParams\r\n };\r\n }\r\n\r\n static upsert(tableName: string, data: Record<string, any>, conflictColumns: string[]): { sql: string; params: any[] } {\r\n const fields = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = values.map(() => '?').join(', ');\r\n\r\n const updateColumns = fields.filter(field => !conflictColumns.includes(field));\r\n const updateClause = updateColumns.length > 0\r\n ? updateColumns.map(col => `${col} = excluded.${col}`).join(', ')\r\n : '';\r\n\r\n let sql = `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`;\r\n\r\n if (updateColumns.length > 0) {\r\n sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO UPDATE SET ${updateClause}`;\r\n } else {\r\n sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO NOTHING`;\r\n }\r\n\r\n return { sql, params: values };\r\n }\r\n\r\n // Utility methods\r\n clone(): QueryBuilder {\r\n if (!this.dao) throw new Error('DAO instance required for cloning QueryBuilder');\r\n const cloned = new QueryBuilder(this.dao);\r\n cloned.tableName = this.tableName;\r\n cloned.selectFields = [...this.selectFields];\r\n cloned.joinClauses = [...this.joinClauses];\r\n cloned.whereConditions = [...this.whereConditions];\r\n cloned.groupByFields = [...this.groupByFields];\r\n cloned.havingConditions = [...this.havingConditions];\r\n cloned.orderByFields = [...this.orderByFields];\r\n cloned.limitValue = this.limitValue;\r\n cloned.offsetValue = this.offsetValue;\r\n cloned.unionQueries = [...this.unionQueries];\r\n cloned.subQueries = [...this.subQueries];\r\n cloned.cteQueries = new Map(this.cteQueries);\r\n return cloned;\r\n }\r\n\r\n toRawSQL(): string {\r\n const { sql, params } = this.toSQL();\r\n let rawSql = sql;\r\n params.forEach(param => {\r\n if (typeof param === 'string') {\r\n rawSql = rawSql.replace('?', `'${param.replace(/'/g, \"''\")}'`);\r\n } else if (param === null || param === undefined) {\r\n rawSql = rawSql.replace('?', 'NULL');\r\n } else {\r\n rawSql = rawSql.replace('?', String(param));\r\n }\r\n });\r\n return rawSql;\r\n }\r\n\r\n explain(): QueryBuilder {\r\n this.selectFields = ['EXPLAIN QUERY PLAN ' + this.selectFields.join(', ')];\r\n return this;\r\n }\r\n}","// src/core/service-manager.ts\r\nimport { BaseService } from \"./base-service\";\r\nimport { ServiceStatus, HealthCheckResult } from \"../types\";\r\n\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.SERVICE_MANAGER);\r\n\r\n// Concrete service class mặc định\r\nexport class DefaultService extends BaseService {\r\n // BaseService đã cung cấp đầy đủ functionality\r\n}\r\n\r\n// Interface cho cấu hình service\r\nexport interface ServiceConfig {\r\n schemaName: string;\r\n tableName: string;\r\n primaryKeyFields?: string[];\r\n serviceClass?: new (schemaName: string, tableName: string) => BaseService;\r\n}\r\n\r\n// Interface cho trạng thái service\r\nexport interface ServiceInfo {\r\n key: string;\r\n schemaName: string;\r\n tableName: string;\r\n status: ServiceStatus;\r\n isRegistered: boolean;\r\n createdAt: string;\r\n lastAccessed?: string;\r\n}\r\n\r\n// Interface cho báo cáo sức khỏe\r\nexport interface HealthReport {\r\n totalServices: number;\r\n healthyServices: number;\r\n unhealthyServices: number;\r\n services: Array<HealthCheckResult & { serviceKey: string }>;\r\n timestamp: string;\r\n overallHealth: boolean;\r\n}\r\n\r\n// Event types cho ServiceManager\r\nexport interface ServiceManagerEvent {\r\n type:\r\n | \"SERVICE_CREATED\"\r\n | \"SERVICE_DESTROYED\"\r\n | \"SERVICE_ERROR\"\r\n | \"HEALTH_CHECK_COMPLETED\";\r\n serviceKey: string;\r\n schemaName: string;\r\n tableName: string;\r\n timestamp: string;\r\n data?: any;\r\n error?: Error;\r\n}\r\n\r\nexport type ServiceManagerEventHandler = (event: ServiceManagerEvent) => void;\r\n\r\n/**\r\n * ServiceManager - Quản lý vòng đời các service con kế thừa từ BaseService\r\n * Không can thiệp vào DatabaseManager, chỉ tập trung quản lý service instances\r\n */\r\nexport class ServiceManager {\r\n private static instance: ServiceManager | null = null;\r\n\r\n // Service registry\r\n private services: Map<string, BaseService> = new Map();\r\n private serviceConfigs: Map<string, ServiceConfig> = new Map();\r\n private serviceMetadata: Map<\r\n string,\r\n { createdAt: string; lastAccessed?: string }\r\n > = new Map();\r\n\r\n // Event system\r\n private eventHandlers: Map<string, ServiceManagerEventHandler[]> = new Map();\r\n\r\n // Lifecycle management\r\n private isShuttingDown = false;\r\n private cleanupInterval: NodeJS.Timeout | null = null;\r\n\r\n private constructor() {\r\n logger.info(\"ServiceManager instance created\");\r\n this.bindMethods();\r\n this.startPeriodicCleanup();\r\n }\r\n\r\n /**\r\n * Singleton instance\r\n */\r\n public static getInstance(): ServiceManager {\r\n if (!ServiceManager.instance) {\r\n logger.debug(\"Creating new ServiceManager singleton instance\");\r\n ServiceManager.instance = new ServiceManager();\r\n } else {\r\n logger.trace(\"Returning existing ServiceManager singleton instance\");\r\n }\r\n return ServiceManager.instance;\r\n }\r\n\r\n /**\r\n * Reset singleton (chủ yếu cho testing)\r\n */\r\n public static resetInstance(): void {\r\n logger.warn(\"Resetting ServiceManager singleton instance\");\r\n if (ServiceManager.instance) {\r\n ServiceManager.instance.destroy();\r\n ServiceManager.instance = null;\r\n logger.info(\"ServiceManager singleton instance reset successfully\");\r\n } else {\r\n logger.debug(\"No ServiceManager instance to reset\");\r\n }\r\n }\r\n\r\n private bindMethods(): void {\r\n logger.trace(\"Binding ServiceManager methods\");\r\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n methods.forEach((method) => {\r\n if (\r\n typeof (this as any)[method] === \"function\" &&\r\n method !== \"constructor\"\r\n ) {\r\n (this as any)[method] = (this as any)[method].bind(this);\r\n }\r\n });\r\n logger.trace(\"ServiceManager methods bound successfully\", {\r\n methodCount: methods.length,\r\n });\r\n }\r\n\r\n /**\r\n * Tạo service key duy nhất\r\n */\r\n private createServiceKey(schemaName: string, tableName: string): string {\r\n const key = `${schemaName}:${tableName}`;\r\n logger.trace(\"Created service key\", { schemaName, tableName, key });\r\n return key;\r\n }\r\n\r\n /**\r\n * Validate service config\r\n */\r\n private validateServiceConfig(config: ServiceConfig): void {\r\n logger.trace(\"Validating service config\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n\r\n if (!config.schemaName?.trim()) {\r\n logger.error(\"Invalid service config: schema name missing\", { config });\r\n throw new Error(\"Schema name is required and cannot be empty\");\r\n }\r\n if (!config.tableName?.trim()) {\r\n logger.error(\"Invalid service config: table name missing\", { config });\r\n throw new Error(\"Table name is required and cannot be empty\");\r\n }\r\n\r\n logger.trace(\"Service config validation passed\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n }\r\n\r\n /**\r\n * Đăng ký cấu hình service\r\n */\r\n public registerService(config: ServiceConfig): this {\r\n logger.debug(\"Registering service\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n primaryKeyFields: config.primaryKeyFields,\r\n hasCustomServiceClass: !!config.serviceClass,\r\n });\r\n\r\n this.validateServiceConfig(config);\r\n\r\n const serviceKey = this.createServiceKey(\r\n config.schemaName,\r\n config.tableName\r\n );\r\n\r\n // Normalize config\r\n const normalizedConfig: ServiceConfig = {\r\n schemaName: config.schemaName.trim(),\r\n tableName: config.tableName.trim(),\r\n primaryKeyFields: config.primaryKeyFields || [\"id\"],\r\n serviceClass: config.serviceClass || DefaultService,\r\n };\r\n\r\n const wasAlreadyRegistered = this.serviceConfigs.has(serviceKey);\r\n this.serviceConfigs.set(serviceKey, normalizedConfig);\r\n\r\n if (wasAlreadyRegistered) {\r\n logger.info(\"Service configuration updated\", { serviceKey });\r\n } else {\r\n logger.info(\"Service registered successfully\", { serviceKey });\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Đăng ký nhiều services\r\n */\r\n public registerServices(configs: ServiceConfig[]): this {\r\n logger.debug(\"Registering multiple services\", { count: configs.length });\r\n\r\n configs.forEach((config, index) => {\r\n try {\r\n this.registerService(config);\r\n } catch (error) {\r\n logger.error(\"Failed to register service in batch\", {\r\n index,\r\n config,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n });\r\n\r\n logger.info(\"Multiple services registered successfully\", {\r\n count: configs.length,\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Tạo service instance từ config\r\n */\r\n private async createServiceInstance(\r\n config: ServiceConfig\r\n ): Promise<BaseService> {\r\n logger.debug(\"Creating service instance\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n serviceClassName: config.serviceClass?.name || \"DefaultService\",\r\n });\r\n\r\n const ServiceClass = config.serviceClass || DefaultService;\r\n const service = new ServiceClass(config.schemaName, config.tableName);\r\n\r\n if (config.primaryKeyFields) {\r\n logger.trace(\"Setting primary key fields\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n primaryKeyFields: config.primaryKeyFields,\r\n });\r\n service.setPrimaryKeyFields(config.primaryKeyFields);\r\n }\r\n\r\n logger.info(\"Service instance created successfully\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n\r\n return service;\r\n }\r\n\r\n /**\r\n * Lấy service (tự động tạo nếu chưa tồn tại)\r\n */\r\n public async getService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<BaseService> {\r\n if (this.isShuttingDown) {\r\n logger.error(\"ServiceManager is shutting down, cannot get service\", {\r\n schemaName,\r\n tableName,\r\n });\r\n throw new Error(\"ServiceManager is shutting down\");\r\n }\r\n\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Getting service\", { serviceKey });\r\n\r\n // Update access time\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n if (metadata) {\r\n metadata.lastAccessed = new Date().toISOString();\r\n logger.trace(\"Updated service access time\", { serviceKey });\r\n }\r\n\r\n // Return existing service\r\n if (this.services.has(serviceKey)) {\r\n logger.trace(\"Returning existing service\", { serviceKey });\r\n return this.services.get(serviceKey)!;\r\n }\r\n\r\n // Get or create default config\r\n let config = this.serviceConfigs.get(serviceKey);\r\n if (!config) {\r\n logger.debug(\"Creating default config for unregistered service\", {\r\n serviceKey,\r\n });\r\n config = {\r\n schemaName,\r\n tableName,\r\n primaryKeyFields: [\"id\"],\r\n serviceClass: DefaultService,\r\n };\r\n this.serviceConfigs.set(serviceKey, config);\r\n }\r\n\r\n try {\r\n const service = await this.createServiceInstance(config);\r\n this.services.set(serviceKey, service);\r\n\r\n // Track metadata\r\n this.serviceMetadata.set(serviceKey, {\r\n createdAt: new Date().toISOString(),\r\n lastAccessed: new Date().toISOString(),\r\n });\r\n\r\n this.emit(\"SERVICE_CREATED\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n });\r\n\r\n logger.info(\"Service created and cached successfully\", { serviceKey });\r\n return service;\r\n } catch (error) {\r\n logger.error(\"Failed to create service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n\r\n this.emit(\"SERVICE_ERROR\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n error: error as Error,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Lấy service đã tồn tại (không tự động tạo)\r\n */\r\n public getExistingService(\r\n schemaName: string,\r\n tableName: string\r\n ): BaseService | null {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.trace(\"Getting existing service\", { serviceKey });\r\n\r\n const service = this.services.get(serviceKey) || null;\r\n if (service) {\r\n logger.trace(\"Existing service found\", { serviceKey });\r\n } else {\r\n logger.trace(\"Existing service not found\", { serviceKey });\r\n }\r\n\r\n return service;\r\n }\r\n\r\n /**\r\n * Khởi tạo service\r\n */\r\n public async initializeService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<BaseService> {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Initializing service\", { serviceKey });\r\n\r\n try {\r\n const service = await this.getService(schemaName, tableName);\r\n await service.init();\r\n logger.info(\"Service initialized successfully\", { serviceKey });\r\n return service;\r\n } catch (error) {\r\n logger.error(\"Failed to initialize service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Hủy service instance\r\n */\r\n public async destroyService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<boolean> {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Destroying service\", { serviceKey });\r\n\r\n const service = this.services.get(serviceKey);\r\n\r\n if (!service) {\r\n logger.warn(\"Service not found for destruction\", { serviceKey });\r\n return false;\r\n }\r\n\r\n try {\r\n await service.close();\r\n service.destroy();\r\n\r\n this.services.delete(serviceKey);\r\n this.serviceMetadata.delete(serviceKey);\r\n\r\n this.emit(\"SERVICE_DESTROYED\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n });\r\n\r\n logger.info(\"Service destroyed successfully\", { serviceKey });\r\n return true;\r\n } catch (error) {\r\n logger.error(\"Failed to destroy service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n\r\n this.emit(\"SERVICE_ERROR\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n error: error as Error,\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Lấy danh sách services theo schema\r\n */\r\n public getServicesBySchema(schemaName: string): BaseService[] {\r\n logger.trace(\"Getting services by schema\", { schemaName });\r\n\r\n const services: BaseService[] = [];\r\n\r\n for (const [serviceKey, service] of this.services) {\r\n const [keySchema] = serviceKey.split(\":\");\r\n if (keySchema === schemaName) {\r\n services.push(service);\r\n }\r\n }\r\n\r\n logger.debug(\"Found services for schema\", {\r\n schemaName,\r\n count: services.length,\r\n });\r\n return services;\r\n }\r\n\r\n /**\r\n * Lấy danh sách service keys theo schema\r\n */\r\n public getServiceKeysBySchema(schemaName: string): string[] {\r\n logger.trace(\"Getting service keys by schema\", { schemaName });\r\n\r\n const keys: string[] = [];\r\n\r\n for (const serviceKey of this.services.keys()) {\r\n const [keySchema] = serviceKey.split(\":\");\r\n if (keySchema === schemaName) {\r\n keys.push(serviceKey);\r\n }\r\n }\r\n\r\n logger.debug(\"Found service keys for schema\", { schemaName, keys });\r\n return keys;\r\n }\r\n\r\n /**\r\n * Hủy tất cả services trong một schema\r\n */\r\n public async destroyServicesBySchema(schemaName: string): Promise<void> {\r\n const serviceKeys = this.getServiceKeysBySchema(schemaName);\r\n logger.debug(\"Destroying services by schema\", { schemaName, serviceKeys });\r\n\r\n if (serviceKeys.length === 0) {\r\n logger.debug(\"No services found to destroy for schema\", { schemaName });\r\n return;\r\n }\r\n\r\n const destroyPromises = serviceKeys.map(async (serviceKey) => {\r\n const [, tableName] = serviceKey.split(\":\");\r\n try {\r\n const result = await this.destroyService(schemaName, tableName);\r\n logger.trace(\"Service destroy result\", { serviceKey, result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error destroying service in schema cleanup\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n return false;\r\n }\r\n });\r\n\r\n const results = await Promise.all(destroyPromises);\r\n const successCount = results.filter(Boolean).length;\r\n\r\n logger.info(\"Schema services destruction completed\", {\r\n schemaName,\r\n totalServices: serviceKeys.length,\r\n successfulDestroys: successCount,\r\n });\r\n }\r\n\r\n /**\r\n * Lấy thông tin tất cả services\r\n */\r\n public getAllServiceInfo(): ServiceInfo[] {\r\n logger.trace(\"Getting all service info\");\r\n\r\n const infos: ServiceInfo[] = [];\r\n\r\n // Registered services\r\n for (const [serviceKey, config] of this.serviceConfigs) {\r\n const service = this.services.get(serviceKey);\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n infos.push({\r\n key: serviceKey,\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n status: service\r\n ? service.getStatus()\r\n : {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n isOpened: false,\r\n isInitialized: false,\r\n hasDao: false,\r\n },\r\n isRegistered: true,\r\n createdAt: metadata?.createdAt || \"N/A\",\r\n lastAccessed: metadata?.lastAccessed,\r\n });\r\n }\r\n\r\n // Unregistered services (created on-the-fly)\r\n for (const [serviceKey, service] of this.services) {\r\n if (!this.serviceConfigs.has(serviceKey)) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n infos.push({\r\n key: serviceKey,\r\n schemaName,\r\n tableName,\r\n status: service.getStatus(),\r\n isRegistered: false,\r\n createdAt: metadata?.createdAt || \"N/A\",\r\n lastAccessed: metadata?.lastAccessed,\r\n });\r\n }\r\n }\r\n\r\n return infos;\r\n }\r\n\r\n /**\r\n * Kiểm tra sức khỏe tất cả services\r\n */\r\n public async healthCheck(): Promise<HealthReport> {\r\n const services = Array.from(this.services.entries());\r\n const healthPromises = services.map(async ([serviceKey, service]) => {\r\n try {\r\n const health = await service.healthCheck();\r\n return { ...health, serviceKey };\r\n } catch (error) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n return {\r\n healthy: false,\r\n schemaName,\r\n error: (error as Error).message,\r\n timestamp: new Date().toISOString(),\r\n serviceKey,\r\n };\r\n }\r\n });\r\n\r\n const results = await Promise.all(healthPromises);\r\n const healthyCount = results.filter((r) => r.healthy).length;\r\n\r\n const report: HealthReport = {\r\n totalServices: results.length,\r\n healthyServices: healthyCount,\r\n unhealthyServices: results.length - healthyCount,\r\n services: results,\r\n timestamp: new Date().toISOString(),\r\n overallHealth: healthyCount === results.length,\r\n };\r\n\r\n this.emit(\"HEALTH_CHECK_COMPLETED\", {\r\n serviceKey: \"*\",\r\n schemaName: \"*\",\r\n tableName: \"*\",\r\n data: report,\r\n });\r\n\r\n return report;\r\n }\r\n\r\n /**\r\n * Thực hiện transaction trên nhiều services trong cùng schema\r\n * (Vì SQLite transaction chỉ hoạt động trong cùng database connection)\r\n */\r\n public async executeSchemaTransaction<T>(\r\n schemaName: string,\r\n callback: (services: BaseService[]) => Promise<T>\r\n ): Promise<T> {\r\n logger.trace(`Executing schema transaction for schema ${schemaName}`);\r\n const services = this.getServicesBySchema(schemaName);\r\n\r\n if (services.length === 0) {\r\n logger.error(\"No services found for schema\", { schemaName });\r\n throw new Error(`No services found for schema: ${schemaName}`);\r\n }\r\n\r\n // Ensure all services are initialized\r\n for (const service of services) {\r\n await service.init();\r\n }\r\n\r\n // Execute transaction on the first service (they share the same database)\r\n const primaryService = services[0];\r\n\r\n return await primaryService.executeTransaction(async () => {\r\n return await callback(services);\r\n });\r\n }\r\n\r\n /**\r\n * Periodic cleanup for unused services\r\n */\r\n private startPeriodicCleanup(): void {\r\n // Cleanup every 5 minutes\r\n this.cleanupInterval = setInterval(() => {\r\n this.cleanupUnusedServices();\r\n }, 5 * 60 * 1000);\r\n }\r\n\r\n /**\r\n * Cleanup services not accessed for a long time\r\n */\r\n private async cleanupUnusedServices(\r\n maxIdleTime: number = 30 * 60 * 1000\r\n ): Promise<void> {\r\n if (this.isShuttingDown) {\r\n return;\r\n }\r\n\r\n const now = Date.now();\r\n const servicesToDestroy: string[] = [];\r\n\r\n for (const [serviceKey, metadata] of this.serviceMetadata) {\r\n if (!metadata.lastAccessed) {\r\n continue;\r\n }\r\n\r\n const lastAccessTime = new Date(metadata.lastAccessed).getTime();\r\n if (now - lastAccessTime > maxIdleTime) {\r\n servicesToDestroy.push(serviceKey);\r\n }\r\n }\r\n\r\n for (const serviceKey of servicesToDestroy) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n await this.destroyService(schemaName, tableName);\r\n }\r\n }\r\n\r\n /**\r\n * Event system\r\n */\r\n public on(eventType: string, handler: ServiceManagerEventHandler): this {\r\n if (!this.eventHandlers.has(eventType)) {\r\n this.eventHandlers.set(eventType, []);\r\n }\r\n this.eventHandlers.get(eventType)!.push(handler);\r\n return this;\r\n }\r\n\r\n public off(eventType: string, handler: ServiceManagerEventHandler): this {\r\n const handlers = this.eventHandlers.get(eventType);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n private emit(\r\n type: ServiceManagerEvent[\"type\"],\r\n data: Omit<ServiceManagerEvent, \"type\" | \"timestamp\">\r\n ): void {\r\n const event: ServiceManagerEvent = {\r\n ...data,\r\n type,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n // Emit to specific event handlers\r\n const handlers = this.eventHandlers.get(type);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(event);\r\n } catch (error) {\r\n console.error(\r\n `ServiceManager: Error in ${type} event handler:`,\r\n error\r\n );\r\n }\r\n });\r\n }\r\n\r\n // Emit to global event handlers\r\n const globalHandlers = this.eventHandlers.get(\"*\");\r\n if (globalHandlers) {\r\n globalHandlers.forEach((handler) => {\r\n try {\r\n handler(event);\r\n } catch (error) {\r\n console.error(\r\n \"ServiceManager: Error in global event handler:\",\r\n error\r\n );\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Utility methods\r\n */\r\n public hasService(schemaName: string, tableName: string): boolean {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n return this.services.has(serviceKey);\r\n }\r\n\r\n public isRegistered(schemaName: string, tableName: string): boolean {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n return this.serviceConfigs.has(serviceKey);\r\n }\r\n\r\n public getServiceCount(): number {\r\n return this.services.size;\r\n }\r\n\r\n public getRegisteredCount(): number {\r\n return this.serviceConfigs.size;\r\n }\r\n\r\n public getSchemas(): string[] {\r\n const schemas = new Set<string>();\r\n\r\n for (const serviceKey of this.services.keys()) {\r\n const [schemaName] = serviceKey.split(\":\");\r\n schemas.add(schemaName);\r\n }\r\n\r\n return Array.from(schemas);\r\n }\r\n\r\n /**\r\n * Destroy all services and cleanup resources\r\n */\r\n public async destroy(): Promise<void> {\r\n this.isShuttingDown = true;\r\n\r\n // Clear cleanup interval\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n }\r\n\r\n // Destroy all services\r\n const destroyPromises = Array.from(this.services.entries()).map(\r\n async ([serviceKey, service]) => {\r\n try {\r\n await service.close();\r\n service.destroy();\r\n } catch (error) {\r\n console.error(`Error destroying service ${serviceKey}:`, error);\r\n }\r\n }\r\n );\r\n\r\n await Promise.all(destroyPromises);\r\n\r\n // Clear all data\r\n this.services.clear();\r\n this.serviceConfigs.clear();\r\n this.serviceMetadata.clear();\r\n this.eventHandlers.clear();\r\n\r\n this.isShuttingDown = false;\r\n }\r\n}\r\n\r\n// Export singleton instance\r\nexport const serviceManager = ServiceManager.getInstance();\r\n","// src/adapters/base-adapter.ts\r\nimport { SQLiteAdapter, SQLiteConnection } from '../types';\r\nexport abstract class BaseAdapter implements SQLiteAdapter {\r\n abstract connect(path: string): Promise<SQLiteConnection>;\r\n abstract isSupported(): boolean;\r\n\r\n protected sanitizeSQL(sql: string): string {\r\n return sql.trim();\r\n }\r\n\r\n protected bindParameters(sql: string, params?: any[]): string {\r\n if (!params || params.length === 0) {\r\n return sql;\r\n }\r\n\r\n let paramIndex = 0;\r\n return sql.replace(/\\?/g, () => {\r\n if (paramIndex < params.length) {\r\n const param = params[paramIndex++];\r\n if (typeof param === 'string') {\r\n return `'${param.replace(/'/g, \"''\")}'`;\r\n }\r\n if (param === null || param === undefined) {\r\n return 'NULL';\r\n }\r\n return String(param);\r\n }\r\n return '?';\r\n });\r\n }\r\n}","// src/index.ts - Main exports for UniversalSQLite Library with Logger Integration\r\nimport { DatabaseManager } from \"./core/database-manager\";\r\nimport { UniversalDAO } from \"./core/universal-dao\";\r\nimport { BaseService } from \"./core/base-service\";\r\nimport { DatabaseFactory } from \"./core/database-factory\";\r\nimport { QueryBuilder } from \"./query/query-builder\";\r\nimport {\r\n SQLiteAdapter,\r\n SQLiteResult,\r\n SQLiteRow,\r\n DatabaseSchema,\r\n DbFactoryOptions,\r\n ImportOptions,\r\n ImportResult,\r\n ColumnMapping,\r\n} from \"./types\";\r\n\r\n// ========================== LOGGER EXPORTS ==========================\r\nexport {\r\n SQLiteLoggerConfig,\r\n SQLiteModules,\r\n sqliteLogger,\r\n createModuleLogger,\r\n} from \"./logger/logger-config\";\r\n\r\n// ========================== CORE EXPORTS ==========================\r\nexport { UniversalDAO } from \"./core/universal-dao\";\r\nexport { DatabaseFactory } from \"./core/database-factory\";\r\nexport { DatabaseManager } from \"./core/database-manager\";\r\nexport { BaseService } from \"./core/base-service\";\r\nexport {\r\n ServiceManager,\r\n DefaultService,\r\n type ServiceConfig,\r\n type ServiceInfo,\r\n type HealthReport,\r\n type ServiceManagerEvent,\r\n type ServiceManagerEventHandler,\r\n} from \"./core/service-manager\";\r\n\r\n// ========================== QUERY & UTILITIES ==========================\r\nexport { QueryBuilder } from \"./query/query-builder\";\r\n\r\n// ========================== ADAPTERS ==========================\r\nexport { BaseAdapter } from \"./adapters/base-adapter\";\r\n\r\n// ========================== TYPE EXPORTS ==========================\r\nexport * from \"./types\";\r\n\r\n// Import logger configuration for internal use\r\nimport {\r\n SQLiteLoggerConfig,\r\n createModuleLogger,\r\n SQLiteModules,\r\n} from \"./logger/logger-config\";\r\n\r\n// ========================== UNIFIED INTERFACE ==========================\r\n\r\n/**\r\n * UniversalSQLite - The main unified interface providing a comprehensive\r\n * SQLite database management solution for all environments and platforms.\r\n *\r\n * Features:\r\n * - Cross-platform support (Browser, Node.js, Deno, Bun, React Native)\r\n * - Schema-based database management\r\n * - Role-based access control\r\n * - Advanced query building\r\n * - Data import/export capabilities\r\n * - Migration system\r\n * - Transaction management\r\n * - Connection pooling and lifecycle management\r\n * - Integrated logging and debugging\r\n */\r\nexport class UniversalSQLite {\r\n private static instance: UniversalSQLite | null = null;\r\n private currentSchema: string | null = null;\r\n private isInitialized: boolean = false;\r\n private initializationPromise: Promise<void> | null = null;\r\n private eventListeners: Map<string, Array<(...args: any[]) => void>> =\r\n new Map();\r\n\r\n // Module-specific logger\r\n private logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n\r\n constructor() {\r\n // Private constructor for singleton pattern\r\n if (UniversalSQLite.instance) {\r\n throw new Error(\r\n \"UniversalSQLite is a singleton. Use UniversalSQLite.getInstance() instead.\"\r\n );\r\n }\r\n this.logger.debug(\"UniversalSQLite instance created\");\r\n }\r\n\r\n /**\r\n * Get singleton instance of UniversalSQLite\r\n */\r\n static getInstance(): UniversalSQLite {\r\n if (!UniversalSQLite.instance) {\r\n UniversalSQLite.instance = new UniversalSQLite();\r\n }\r\n return UniversalSQLite.instance;\r\n }\r\n\r\n /**\r\n * Reset singleton instance (useful for testing)\r\n */\r\n static resetInstance(): void {\r\n if (UniversalSQLite.instance) {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Resetting UniversalSQLite instance\");\r\n UniversalSQLite.instance.closeAll().catch(() => {});\r\n }\r\n UniversalSQLite.instance = null;\r\n }\r\n\r\n // ========================== LOGGER CONFIGURATION METHODS ==========================\r\n\r\n /**\r\n * Configure logger for the entire library\r\n * @param config - Logger configuration object\r\n */\r\n static configureLogger(config: any): void {\r\n SQLiteLoggerConfig.updateConfiguration(config);\r\n }\r\n\r\n /**\r\n * Enable debug logging for development\r\n */\r\n static enableDebugLogging(): void {\r\n const debugConfig = SQLiteLoggerConfig.createDebugConfig();\r\n SQLiteLoggerConfig.updateConfiguration(debugConfig);\r\n }\r\n\r\n /**\r\n * Set production logging (errors and warnings only)\r\n */\r\n static setProductionLogging(): void {\r\n const prodConfig = SQLiteLoggerConfig.createProductionConfig();\r\n SQLiteLoggerConfig.updateConfiguration(prodConfig);\r\n }\r\n\r\n /**\r\n * Enable logging globally\r\n */\r\n static enableLogging(): void {\r\n SQLiteLoggerConfig.setEnabled(true);\r\n }\r\n\r\n /**\r\n * Disable logging globally\r\n */\r\n static disableLogging(): void {\r\n SQLiteLoggerConfig.setEnabled(false);\r\n }\r\n\r\n /**\r\n * Enable specific module logging\r\n */\r\n static enableModuleLogging(\r\n moduleName: string,\r\n levels?: string[],\r\n appenders?: string[]\r\n ): void {\r\n SQLiteLoggerConfig.enableModule(moduleName, levels, appenders);\r\n }\r\n\r\n /**\r\n * Disable specific module logging\r\n */\r\n static disableModuleLogging(moduleName: string): void {\r\n SQLiteLoggerConfig.disableModule(moduleName);\r\n }\r\n\r\n // ========================== INITIALIZATION METHODS ==========================\r\n\r\n /**\r\n * Initialize UniversalSQLite with schema configurations\r\n * @param schemas - Database schema configurations\r\n * @param options - Additional initialization options\r\n */\r\n async initialize(\r\n schemas: Record<string, DatabaseSchema>,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnectCore?: boolean;\r\n defaultRoles?: string[];\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any; // Logger configuration\r\n } = {}\r\n ): Promise<void> {\r\n this.logger.debug(\"Starting initialization\", {\r\n schemas: Object.keys(schemas),\r\n options,\r\n });\r\n\r\n if (this.isInitialized) {\r\n this.logger.debug(\"Already initialized, returning existing promise\");\r\n return this.initializationPromise || Promise.resolve();\r\n }\r\n\r\n if (this.initializationPromise) {\r\n this.logger.debug(\"Initialization in progress, waiting...\");\r\n return this.initializationPromise;\r\n }\r\n\r\n this.initializationPromise = this._performInitialization(schemas, options);\r\n return this.initializationPromise;\r\n }\r\n\r\n private async _performInitialization(\r\n schemas: Record<string, DatabaseSchema>,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnectCore?: boolean;\r\n defaultRoles?: string[];\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any;\r\n }\r\n ): Promise<void> {\r\n try {\r\n this.logger.info(\"Performing initialization\", {\r\n schemaCount: Object.keys(schemas).length,\r\n });\r\n\r\n // Configure logger if provided\r\n if (options.loggerConfig) {\r\n this.logger.debug(\"Configuring custom logger\");\r\n SQLiteLoggerConfig.updateConfiguration(options.loggerConfig);\r\n }\r\n\r\n // Register adapters if provided\r\n if (options.registerAdapters) {\r\n this.logger.debug(\"Registering adapters\", {\r\n count: options.registerAdapters.length,\r\n });\r\n options.registerAdapters.forEach((adapter) => {\r\n DatabaseFactory.registerAdapter(adapter);\r\n });\r\n }\r\n\r\n // Register global error handler\r\n if (options.globalErrorHandler) {\r\n this.logger.debug(\"Registering global error handler\");\r\n this.on(\"error\", options.globalErrorHandler);\r\n }\r\n\r\n // Register all schemas with DatabaseManager\r\n this.logger.debug(\"Registering schemas with DatabaseManager\");\r\n DatabaseManager.registerSchemas(schemas);\r\n\r\n // Initialize core connection if core schema exists and autoConnectCore is true\r\n if (schemas.core && options.autoConnectCore !== false) {\r\n this.logger.debug(\"Initializing core connection\");\r\n await DatabaseManager.initializeCoreConnection();\r\n }\r\n\r\n // Set default roles if provided\r\n if (options.defaultRoles && options.defaultRoles.length > 0) {\r\n this.logger.debug(\"Setting default roles\", {\r\n roles: options.defaultRoles,\r\n });\r\n await DatabaseManager.setCurrentUserRoles(options.defaultRoles);\r\n }\r\n\r\n this.isInitialized = true;\r\n this.logger.info(\"Initialization completed successfully\");\r\n this._emit(\"initialized\", { schemas: Object.keys(schemas) });\r\n } catch (error) {\r\n this.isInitialized = false;\r\n this.initializationPromise = null;\r\n this.logger.error(\"Initialization failed\", error);\r\n this._emit(\"error\", error as Error, \"initialization\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Initialize from a single schema configuration\r\n */\r\n async initializeFromSchema(\r\n schema: DatabaseSchema,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnect?: boolean;\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any;\r\n } = {}\r\n ): Promise<void> {\r\n this.logger.debug(\"Initializing from single schema\", {\r\n schemaName: schema.database_name,\r\n });\r\n const schemas = { [schema.database_name]: schema };\r\n return this.initialize(schemas, {\r\n ...options,\r\n autoConnectCore: options.autoConnect !== false,\r\n });\r\n }\r\n\r\n // ========================== CONNECTION MANAGEMENT ==========================\r\n\r\n /**\r\n * Connect to a specific database schema\r\n * @param schemaName - Name of the schema to connect to\r\n * @returns Promise resolving to UniversalDAO instance\r\n */\r\n async connect(schemaName: string): Promise<UniversalDAO> {\r\n this.logger.debug(\"Connecting to schema\", { schemaName });\r\n this.ensureInitialized();\r\n this.currentSchema = schemaName;\r\n\r\n try {\r\n const dao = await DatabaseManager.getLazyLoading(schemaName);\r\n this.logger.info(\"Successfully connected to schema\", { schemaName });\r\n this._emit(\"connected\", { schemaName });\r\n return dao;\r\n } catch (error) {\r\n this.logger.error(\"Failed to connect to schema\", { schemaName, error });\r\n this._emit(\"error\", error as Error, \"connection\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get DAO for a specific schema\r\n * @param schemaName - Optional schema name (uses current if not provided)\r\n */\r\n getDAO(schemaName?: string): UniversalDAO {\r\n this.ensureInitialized();\r\n const schema = schemaName || this.currentSchema;\r\n\r\n if (!schema) {\r\n const error = new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n this.logger.error(\"getDAO failed: No schema specified\");\r\n throw error;\r\n }\r\n\r\n try {\r\n this.logger.trace(\"Getting DAO for schema\", { schema });\r\n return DatabaseManager.get(schema);\r\n } catch (error) {\r\n this.logger.error(\"Failed to get DAO\", { schema, error });\r\n this._emit(\"error\", error as Error, \"getDAO\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current connected DAO\r\n */\r\n getCurrentDAO(): UniversalDAO {\r\n if (!this.currentSchema) {\r\n const error = new Error(\"No current connection. Call connect() first.\");\r\n this.logger.error(\"getCurrentDAO failed: No current connection\");\r\n throw error;\r\n }\r\n return this.getDAO(this.currentSchema);\r\n }\r\n\r\n /**\r\n * Ensure database connection exists and is active\r\n */\r\n async ensureDatabaseConnection(schemaName: string): Promise<UniversalDAO> {\r\n this.logger.debug(\"Ensuring database connection\", { schemaName });\r\n this.ensureInitialized();\r\n\r\n try {\r\n const dao = await DatabaseManager.ensureDatabaseConnection(schemaName);\r\n this.logger.debug(\"Database connection ensured\", { schemaName });\r\n return dao;\r\n } catch (error) {\r\n this.logger.error(\"Failed to ensure database connection\", {\r\n schemaName,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"ensureConnection\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== SERVICE CREATION ==========================\r\n\r\n /**\r\n * Create a service for a specific table\r\n * @param tableName - Name of the table\r\n * @param schemaName - Optional schema name (uses current if not provided)\r\n */\r\n createService<T = any>(\r\n tableName: string,\r\n schemaName?: string\r\n ): BaseService<T> {\r\n const schema = schemaName || this.currentSchema;\r\n if (!schema) {\r\n const error = new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n this.logger.error(\"createService failed: No schema specified\", {\r\n tableName,\r\n });\r\n throw error;\r\n }\r\n\r\n this.logger.debug(\"Creating service\", { tableName, schema });\r\n\r\n const ServiceClass = class extends BaseService<T> {\r\n constructor() {\r\n if (!schema) {\r\n throw new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n }\r\n super(schema, tableName);\r\n }\r\n };\r\n\r\n return new ServiceClass();\r\n }\r\n\r\n /**\r\n * Create multiple services at once\r\n */\r\n createServices<T = any>(\r\n tableNames: string[],\r\n schemaName?: string\r\n ): Record<string, BaseService<T>> {\r\n this.logger.debug(\"Creating multiple services\", { tableNames, schemaName });\r\n const services: Record<string, BaseService<T>> = {};\r\n\r\n tableNames.forEach((tableName) => {\r\n services[tableName] = this.createService<T>(tableName, schemaName);\r\n });\r\n\r\n this.logger.debug(\"Created services\", { count: tableNames.length });\r\n return services;\r\n }\r\n\r\n // ========================== QUERY BUILDING ==========================\r\n\r\n /**\r\n * Create query builder for current connection\r\n */\r\n query(tableName?: string, schemaName?: string): QueryBuilder {\r\n this.logger.trace(\"Creating query builder\", { tableName, schemaName });\r\n const dao = this.getDAO(schemaName);\r\n\r\n if (tableName) {\r\n return QueryBuilder.table(tableName, dao);\r\n }\r\n\r\n return new QueryBuilder(dao);\r\n }\r\n\r\n /**\r\n * Create query builder from table\r\n */\r\n table(tableName: string, schemaName?: string): QueryBuilder {\r\n return this.query(tableName, schemaName);\r\n }\r\n\r\n /**\r\n * Execute raw SQL on current connection\r\n */\r\n async execute(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteResult> {\r\n this.logger.debug(\"Executing SQL\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n paramsCount: params?.length,\r\n });\r\n\r\n try {\r\n const dao = this.getDAO(schemaName);\r\n const result = await dao.execute(sql, params);\r\n\r\n this.logger.debug(\"SQL executed successfully\", {\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowId: result.lastInsertRowId,\r\n });\r\n\r\n this._emit(\"queryExecuted\", {\r\n sql,\r\n params,\r\n rowCount: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"SQL execution failed\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"execute\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get first row from query\r\n */\r\n async getRst(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteRow> {\r\n this.logger.trace(\"Getting first row\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getRst(sql, params);\r\n }\r\n\r\n /**\r\n * Get all rows from query\r\n */\r\n async getRsts(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteRow[]> {\r\n this.logger.trace(\"Getting all rows\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getRsts(sql, params);\r\n }\r\n\r\n // ========================== SCHEMA MANAGEMENT ==========================\r\n\r\n /**\r\n * Initialize database from schema\r\n */\r\n async initializeSchema(\r\n schema: DatabaseSchema,\r\n forceRecreate: boolean = false\r\n ): Promise<void> {\r\n this.logger.info(\"Initializing schema\", {\r\n schemaName: schema.database_name,\r\n forceRecreate,\r\n });\r\n\r\n try {\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n forceRecreate\r\n );\r\n await dao.initializeFromSchema(schema);\r\n this.logger.info(\"Schema initialized successfully\", {\r\n schemaName: schema.database_name,\r\n });\r\n this._emit(\"schemaInitialized\", { schemaName: schema.database_name });\r\n } catch (error) {\r\n this.logger.error(\"Schema initialization failed\", {\r\n schemaName: schema.database_name,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"schemaInitialization\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get schema version for a database\r\n */\r\n async getSchemaVersion(schemaName?: string): Promise<string> {\r\n this.logger.debug(\"Getting schema version\", { schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getSchemaVersion();\r\n }\r\n\r\n /**\r\n * Get database information\r\n */\r\n async getDatabaseInfo(schemaName?: string): Promise<any> {\r\n this.logger.debug(\"Getting database info\", { schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getDatabaseInfo();\r\n }\r\n\r\n /**\r\n * Get table information\r\n */\r\n async getTableInfo(tableName: string, schemaName?: string): Promise<any[]> {\r\n this.logger.debug(\"Getting table info\", { tableName, schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getTableInfo(tableName);\r\n }\r\n\r\n // ========================== DATA IMPORT/EXPORT ==========================\r\n\r\n /**\r\n * Import data to a specific table\r\n */\r\n async importData(\r\n schemaName: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n options?: Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import\", {\r\n schemaName,\r\n tableName,\r\n recordCount: data.length,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importDataToTable(\r\n schemaName,\r\n tableName,\r\n data,\r\n options\r\n );\r\n\r\n this.logger.info(\"Data import completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n errors: result.errors.length,\r\n });\r\n\r\n this._emit(\"dataImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Data import failed\", { schemaName, tableName, error });\r\n this._emit(\"error\", error as Error, \"dataImport\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n async importDataWithMapping(\r\n schemaName: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options?: Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import with mapping\", {\r\n schemaName,\r\n tableName,\r\n recordCount: data.length,\r\n mappingCount: columnMappings.length,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importDataWithMapping(\r\n schemaName,\r\n tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n\r\n this.logger.info(\"Data import with mapping completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n });\r\n\r\n this._emit(\"dataImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Data import with mapping failed\", {\r\n schemaName,\r\n tableName,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"dataImportWithMapping\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import from CSV\r\n */\r\n async importFromCSV(\r\n schemaName: string,\r\n tableName: string,\r\n csvData: string,\r\n options?: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting CSV import\", {\r\n schemaName,\r\n tableName,\r\n csvLength: csvData.length,\r\n delimiter: options?.delimiter,\r\n hasHeader: options?.hasHeader,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importFromCSV(\r\n schemaName,\r\n tableName,\r\n csvData,\r\n options\r\n );\r\n\r\n this.logger.info(\"CSV import completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n });\r\n\r\n this._emit(\"csvImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"CSV import failed\", { schemaName, tableName, error });\r\n this._emit(\"error\", error as Error, \"csvImport\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== ROLE & ACCESS MANAGEMENT ==========================\r\n\r\n /**\r\n * Set user roles and initialize role-based connections\r\n */\r\n async setUserRoles(roles: string[], primaryRole?: string): Promise<void> {\r\n this.logger.info(\"Setting user roles\", { roles, primaryRole });\r\n this.ensureInitialized();\r\n\r\n try {\r\n await DatabaseManager.setCurrentUserRoles(roles, primaryRole);\r\n this.logger.info(\"User roles set successfully\", { roles, primaryRole });\r\n this._emit(\"userRolesSet\", { roles, primaryRole });\r\n } catch (error) {\r\n this.logger.error(\"Failed to set user roles\", {\r\n roles,\r\n primaryRole,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"setUserRoles\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current user roles\r\n */\r\n getCurrentUserRoles(): string[] {\r\n const roles = DatabaseManager.getCurrentUserRoles();\r\n this.logger.trace(\"Getting current user roles\", { roles });\r\n return roles;\r\n }\r\n\r\n /**\r\n * Get current primary role\r\n */\r\n getCurrentRole(): string | null {\r\n const role = DatabaseManager.getCurrentRole();\r\n this.logger.trace(\"Getting current role\", { role });\r\n return role;\r\n }\r\n\r\n /**\r\n * Check if user has access to database\r\n */\r\n hasAccessToDatabase(dbKey: string): boolean {\r\n const hasAccess = DatabaseManager.hasAccessToDatabase(dbKey);\r\n this.logger.trace(\"Checking database access\", { dbKey, hasAccess });\r\n return hasAccess;\r\n }\r\n\r\n // ========================== TRANSACTION MANAGEMENT ==========================\r\n\r\n /**\r\n * Execute cross-schema transaction\r\n */\r\n async executeTransaction(\r\n schemas: string[],\r\n callback: (daos: Record<string, UniversalDAO>) => Promise<void>\r\n ): Promise<void> {\r\n this.logger.info(\"Starting cross-schema transaction\", { schemas });\r\n\r\n try {\r\n await DatabaseManager.executeCrossSchemaTransaction(schemas, callback);\r\n this.logger.info(\"Cross-schema transaction completed successfully\", {\r\n schemas,\r\n });\r\n this._emit(\"transactionCompleted\", { schemas });\r\n } catch (error) {\r\n this.logger.error(\"Cross-schema transaction failed\", { schemas, error });\r\n this._emit(\"error\", error as Error, \"transaction\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute transaction on current connection\r\n */\r\n async executeTransactionOnCurrent<T>(\r\n callback: (dao: UniversalDAO) => Promise<T>\r\n ): Promise<T> {\r\n this.logger.debug(\"Starting transaction on current connection\");\r\n const dao = this.getCurrentDAO();\r\n\r\n try {\r\n await dao.beginTransaction();\r\n this.logger.trace(\"Transaction begun\");\r\n\r\n const result = await callback(dao);\r\n\r\n await dao.commitTransaction();\r\n this.logger.debug(\"Transaction committed successfully\");\r\n return result;\r\n } catch (error) {\r\n this.logger.warn(\"Transaction failed, rolling back\", { error });\r\n await dao.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== UTILITY & STATUS METHODS ==========================\r\n\r\n /**\r\n * Get environment information\r\n */\r\n getEnvironment(): string {\r\n const env = DatabaseFactory.getEnvironmentInfo();\r\n this.logger.trace(\"Getting environment info\", { env });\r\n return env;\r\n }\r\n\r\n /**\r\n * Get connection status\r\n */\r\n getConnectionStatus(): {\r\n isInitialized: boolean;\r\n currentSchema: string | null;\r\n activeConnections: string[];\r\n connectionCount: number;\r\n userRoles: string[];\r\n primaryRole: string | null;\r\n } {\r\n const status = {\r\n isInitialized: this.isInitialized,\r\n currentSchema: this.currentSchema,\r\n activeConnections: DatabaseManager.listConnections(),\r\n connectionCount: DatabaseManager.getConnectionCount(),\r\n userRoles: this.getCurrentUserRoles(),\r\n primaryRole: this.getCurrentRole(),\r\n };\r\n\r\n this.logger.trace(\"Getting connection status\", status);\r\n return status;\r\n }\r\n\r\n /**\r\n * Get list of available schemas\r\n */\r\n getAvailableSchemas(): string[] {\r\n const schemas = DatabaseManager.getAvailableSchemas();\r\n this.logger.trace(\"Getting available schemas\", { schemas });\r\n return schemas;\r\n }\r\n\r\n /**\r\n * Health check for all connections\r\n */\r\n async healthCheck(): Promise<\r\n Record<string, { healthy: boolean; error?: string }>\r\n > {\r\n this.logger.debug(\"Starting health check for all connections\");\r\n const connections = DatabaseManager.getConnections();\r\n const healthStatus: Record<string, { healthy: boolean; error?: string }> =\r\n {};\r\n\r\n for (const [schemaName, dao] of Object.entries(connections)) {\r\n try {\r\n await dao.execute(\"SELECT 1\");\r\n healthStatus[schemaName] = { healthy: true };\r\n this.logger.trace(\"Health check passed\", { schemaName });\r\n } catch (error) {\r\n healthStatus[schemaName] = {\r\n healthy: false,\r\n error: (error as Error).message,\r\n };\r\n this.logger.warn(\"Health check failed\", { schemaName, error });\r\n }\r\n }\r\n\r\n this.logger.debug(\"Health check completed\", {\r\n totalConnections: Object.keys(healthStatus).length,\r\n healthyConnections: Object.values(healthStatus).filter((s) => s.healthy)\r\n .length,\r\n });\r\n\r\n return healthStatus;\r\n }\r\n\r\n // ========================== EVENT SYSTEM ==========================\r\n\r\n /**\r\n * Add event listener\r\n */\r\n on(event: string, handler: (...args: any[]) => void): this {\r\n this.logger.trace(\"Adding event listener\", { event });\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, []);\r\n }\r\n this.eventListeners.get(event)!.push(handler);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove event listener\r\n */\r\n off(event: string, handler: (...args: any[]) => void): this {\r\n this.logger.trace(\"Removing event listener\", { event });\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Emit event\r\n */\r\n private _emit(event: string, ...args: any[]): void {\r\n this.logger.trace(\"Emitting event\", { event, argsCount: args.length });\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(...args);\r\n } catch (error) {\r\n // Handle event handler errors gracefully\r\n this.logger.error(\"Error in event handler\", { event, error });\r\n }\r\n });\r\n }\r\n }\r\n\r\n // ========================== CONNECTION LIFECYCLE ==========================\r\n\r\n /**\r\n * Close specific connection\r\n */\r\n async closeConnection(schemaName: string): Promise<void> {\r\n this.logger.info(\"Closing connection\", { schemaName });\r\n\r\n try {\r\n await DatabaseManager.closeConnection(schemaName);\r\n\r\n if (this.currentSchema === schemaName) {\r\n this.currentSchema = null;\r\n this.logger.debug(\"Current schema reset due to connection close\");\r\n }\r\n\r\n this.logger.info(\"Connection closed successfully\", { schemaName });\r\n this._emit(\"connectionClosed\", { schemaName });\r\n } catch (error) {\r\n this.logger.error(\"Failed to close connection\", { schemaName, error });\r\n this._emit(\"error\", error as Error, \"closeConnection\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections\r\n */\r\n async closeAll(): Promise<void> {\r\n this.logger.info(\"Closing all connections\");\r\n\r\n try {\r\n await DatabaseManager.closeAll();\r\n this.currentSchema = null;\r\n this.isInitialized = false;\r\n this.initializationPromise = null;\r\n this.eventListeners.clear();\r\n\r\n this.logger.info(\"All connections closed successfully\");\r\n this._emit(\"allConnectionsClosed\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to close all connections\", { error });\r\n this._emit(\"error\", error as Error, \"closeAll\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Logout user and close role-specific connections\r\n */\r\n async logout(): Promise<void> {\r\n this.logger.info(\"User logout initiated\");\r\n\r\n try {\r\n await DatabaseManager.logout();\r\n this.currentSchema = null;\r\n this.logger.info(\"User logout completed successfully\");\r\n this._emit(\"userLoggedOut\");\r\n } catch (error) {\r\n this.logger.error(\"User logout failed\", { error });\r\n this._emit(\"error\", error as Error, \"logout\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== STATIC UTILITY METHODS ==========================\r\n\r\n /**\r\n * Register adapter with DatabaseFactory\r\n */\r\n static registerAdapter(adapter: SQLiteAdapter): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering adapter\", {\r\n adapterName: adapter.name,\r\n adapterVersion: adapter.version,\r\n });\r\n DatabaseFactory.registerAdapter(adapter);\r\n }\r\n\r\n /**\r\n * Register role configuration\r\n */\r\n static registerRole(roleConfig: {\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n }): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering role\", { roleConfig });\r\n DatabaseManager.registerRole(roleConfig);\r\n }\r\n\r\n /**\r\n * Register multiple roles\r\n */\r\n static registerRoles(\r\n roleConfigs: Array<{\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n }>\r\n ): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering multiple roles\", {\r\n roleCount: roleConfigs.length,\r\n });\r\n DatabaseManager.registerRoles(roleConfigs);\r\n }\r\n\r\n // ========================== PRIVATE HELPERS ==========================\r\n\r\n private ensureInitialized(): void {\r\n if (!this.isInitialized) {\r\n const error = new Error(\r\n \"UniversalSQLite not initialized. Call initialize() first.\"\r\n );\r\n this.logger.error(\"Operation attempted on uninitialized instance\");\r\n throw error;\r\n }\r\n }\r\n}\r\n\r\n// ========================== FACTORY FUNCTIONS ==========================\r\n\r\n/**\r\n * Create UniversalDAO instance\r\n */\r\nexport const createUniversalDAO = (\r\n dbPath: string,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n createIfNotExists?: boolean;\r\n forceRecreate?: boolean;\r\n }\r\n): UniversalDAO => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Creating UniversalDAO\", { dbPath, options });\r\n return DatabaseFactory.createDAO(dbPath, options);\r\n};\r\n\r\n/**\r\n * Create database from schema configuration\r\n */\r\nexport const createDatabaseFromSchema = async (\r\n schema: DatabaseSchema,\r\n options?: Omit<DbFactoryOptions, \"config\">\r\n): Promise<UniversalDAO> => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Creating database from schema\", {\r\n schemaName: schema.database_name,\r\n });\r\n return await DatabaseFactory.createFromConfig(schema, options);\r\n};\r\n\r\n/**\r\n * Open existing database\r\n */\r\nexport const openExistingDatabase = async (\r\n dbName: string,\r\n options?: Omit<DbFactoryOptions, \"config\" | \"configAsset\">\r\n): Promise<UniversalDAO> => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Opening existing database\", { dbName });\r\n return await DatabaseFactory.openExisting(dbName, options);\r\n};\r\n\r\n/**\r\n * Create query builder\r\n */\r\nexport const createQueryBuilder = (dao?: UniversalDAO): QueryBuilder => {\r\n const logger = createModuleLogger(SQLiteModules.QUERY_BUILDER);\r\n logger.trace(\"Creating query builder\");\r\n return new QueryBuilder(dao);\r\n};\r\n\r\n/**\r\n * Create base service\r\n */\r\nexport const createBaseService = <T = any>(\r\n schemaName: string,\r\n tableName?: string\r\n): BaseService<T> => {\r\n const logger = createModuleLogger(SQLiteModules.BASE_SERVICE);\r\n logger.debug(\"Creating base service\", { schemaName, tableName });\r\n return new (class extends BaseService<T> {\r\n constructor() {\r\n super(schemaName, tableName);\r\n }\r\n })();\r\n};\r\n\r\n// ========================== CONVENIENCE EXPORTS ==========================\r\n\r\n/**\r\n * Quick setup function for common use cases\r\n */\r\nexport const setupUniversalSQLite = async (config: {\r\n schemas: Record<string, DatabaseSchema>;\r\n adapters?: SQLiteAdapter[];\r\n defaultRoles?: string[];\r\n autoConnect?: string; // schema name to auto-connect to\r\n loggerConfig?: any; // logger configuration\r\n enableDebugLogging?: boolean;\r\n}): Promise<UniversalSQLite> => {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.info(\"Setting up UniversalSQLite\", {\r\n schemaCount: Object.keys(config.schemas).length,\r\n autoConnect: config.autoConnect,\r\n enableDebugLogging: config.enableDebugLogging,\r\n });\r\n\r\n const sqlite = UniversalSQLite.getInstance();\r\n\r\n // Configure debug logging if requested\r\n if (config.enableDebugLogging) {\r\n UniversalSQLite.enableDebugLogging();\r\n }\r\n\r\n await sqlite.initialize(config.schemas, {\r\n registerAdapters: config.adapters,\r\n defaultRoles: config.defaultRoles,\r\n loggerConfig: config.loggerConfig,\r\n });\r\n\r\n if (config.autoConnect) {\r\n await sqlite.connect(config.autoConnect);\r\n }\r\n\r\n logger.info(\"UniversalSQLite setup completed\");\r\n return sqlite;\r\n};\r\n\r\n/**\r\n * Quick database creation from single schema\r\n */\r\nexport const createSingleDatabase = async (\r\n schema: DatabaseSchema,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n autoConnect?: boolean;\r\n loggerConfig?: any;\r\n enableDebugLogging?: boolean;\r\n }\r\n): Promise<{ sqlite: UniversalSQLite; dao: UniversalDAO }> => {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.info(\"Creating single database\", {\r\n schemaName: schema.database_name,\r\n enableDebugLogging: options?.enableDebugLogging,\r\n });\r\n\r\n const sqlite = UniversalSQLite.getInstance();\r\n\r\n // Configure debug logging if requested\r\n if (options?.enableDebugLogging) {\r\n UniversalSQLite.enableDebugLogging();\r\n }\r\n\r\n await sqlite.initializeFromSchema(schema, {\r\n registerAdapters: options?.adapter ? [options.adapter] : undefined,\r\n autoConnect: options?.autoConnect,\r\n loggerConfig: options?.loggerConfig,\r\n });\r\n\r\n const dao =\r\n options?.autoConnect !== false\r\n ? await sqlite.connect(schema.database_name)\r\n : sqlite.getDAO(schema.database_name);\r\n\r\n logger.info(\"Single database creation completed\");\r\n return { sqlite, dao };\r\n};\r\n\r\n// ========================== DEFAULT EXPORT ==========================\r\n\r\n/**\r\n * Default export is the singleton instance\r\n */\r\nconst defaultInstance = UniversalSQLite.getInstance();\r\nexport default defaultInstance;\r\n"],"names":["h","a","y","o","r","i","l","b","p","w","m","N","SQLiteModules","SQLiteLoggerConfig","LoggerConfigBuilder","customConfig","config","createLogger","newConfig","enabled","moduleName","levels","appenders","sqliteLogger","createModuleLogger","logger","message","args","UniversalDAO","adapter","dbPath","options","_a","_b","error","genericType","defaultType","mappedType","col","processedCol","constraints","defaultIndex","defaultValue","schema","hasExistingSchema","result","tableName","tableConfig","tableDefinition","tables","table","columnDefs","foreignKeyDefs","fk","fkSql","allDefs","sql","indexes","index","columns","isUnique","version","insertTable","validCols","columnNames","placeholders","params","updateTable","setCols","setClause","whereClause","deleteTable","selectTable","row","suffix","orderBy","wheres","clause","conditions","where","operator","json","idFields","queryTable","key","value","startTime","tableInfo","columnMap","batchSize","processedCount","skipAutoIncrementPK","batch","j","rowIndex","rowData","processedData","errorInfo","data","columnMappings","transformedData","newRow","mapping","csvData","delimiter","hasHeader","lines","line","headers","dataStartIndex","firstRowCols","_","values","v","header","processedRow","columnName","columnInfo","isRequired","isAutoIncrementPK","lowerColumnName","columnType","type","num","lower","date","conflictColumns","updateColumns","whereColumns","updateValues","whereValues","allValues","info","t","isOpen","DatabaseFactory","environment","dao","dbInfo","errorMsg","_c","_d","dbName","dbFileName","closeError","isForceInit","isForceDelete","schemaError","configAsset","DatabaseManager","maxConnections","currentConnectionCount","manager","schemas","schemaKeys","internalKeys","externalKeys","allKeys","roleConfig","roleConfigs","roleName","databases","allDatabases","db","coreSchema","userRoles","primaryRole","previousRoles","requiredDatabases","failedInitializations","initPromises","dbKey","err","errorSummary","f","previousDatabases","currentDatabases","databasesToClose","hasAccess","schemaName","callback","listeners","currentActiveDb","closePromises","activeDbArray","databaseKeys","failedOpens","invalidKeys","newConnectionsCount","currentConnectionsCount","availableSchemas","daos","acc","databaseKey","importConfigs","c","configKey","importResult","count","connections","connectionsToClose","BaseService","newDao","method","fields","createdRecord","primaryKeyValue","findError","id","updateData","success","record","allWheres","name","results","whereConditions","exists","items","dataArray","rollbackError","obj","event","handler","handlers","errorType","handlerError","status","QueryBuilder","builder","raw","fieldList","condition","fieldOrConditions","operatorOrValue","field","val","actualValue","min","max","subquery","actualOperator","direction","page","perPage","query","alias","cteList","cteSql","cteParams","join","conditionParams","unionQuery","unionSql","unionParams","subSql","subParams","column","valueGroups","whereParams","sets","updateClause","cloned","rawSql","param","DefaultService","ServiceManager","methods","serviceKey","normalizedConfig","wasAlreadyRegistered","configs","ServiceClass","service","metadata","services","keySchema","keys","serviceKeys","destroyPromises","successCount","infos","healthPromises","health","healthyCount","report","maxIdleTime","now","servicesToDestroy","lastAccessTime","eventType","globalHandlers","BaseAdapter","paramIndex","UniversalSQLite","debugConfig","prodConfig","tableNames","forceRecreate","roles","role","env","healthStatus","s","createUniversalDAO","createDatabaseFromSchema","openExistingDatabase","createQueryBuilder","createBaseService","setupUniversalSQLite","sqlite","createSingleDatabase","defaultInstance"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../node_modules/@dqcai/logger/lib/index.mjs","../src/logger/logger-config.ts","../src/core/universal-dao.ts","../src/core/database-factory.ts","../src/core/database-manager.ts","../src/core/base-service.ts","../src/query/query-builder.ts","../src/core/service-manager.ts","../src/adapters/base-adapter.ts","../src/index.ts"],"sourcesContent":["const h=(...a)=>a.map(e=>typeof e==\"object\"?JSON.stringify(e,null,2):String(e)).join(\" \");class y{constructor(e){this.transports=new Map,this.transportFactory=null,this.config=e,this.sessionId=e.sessionId||this.generateSessionId()}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}getSessionId(){return this.sessionId}renewSession(){return this.sessionId=this.generateSessionId(),this.sessionId}setTransportFactory(e){this.transportFactory=e}addTransport(e){this.transports.set(e.name,e)}removeTransport(e){return this.transports.delete(e)}getTransport(e){return this.transports.get(e)}listTransports(){return Array.from(this.transports.keys())}setModuleConfig(e,t){this.config.modules[e]=t}getModuleConfig(e){return this.config.modules[e]}setGlobalEnabled(e){this.config.enabled=e}isGlobalEnabled(){return this.config.enabled}setDefaultLevel(e){this.config.defaultLevel=e}getConfig(){return JSON.parse(JSON.stringify(this.config))}setMetadata(e){this.config.metadata=Object.assign(Object.assign({},this.config.metadata),e)}shouldLog(e,t){if(!this.config.enabled)return!1;const o=this.config.modules[e];return o?o.enabled&&o.levels.includes(t):this.isLevelEnabled(t,this.config.defaultLevel)}isLevelEnabled(e,t){const o=[\"trace\",\"debug\",\"info\",\"warn\",\"error\"],r=o.indexOf(e),i=o.indexOf(t);return r===-1||i===-1?!1:r>=i}getTransportsForModule(e){const t=this.config.modules[e];return((t==null?void 0:t.transports)||[\"console\"]).map(o=>this.transports.get(o)).filter(o=>o!==void 0)}async sendToTransports(e,t){if(t.length===0)return;const o=t.map(async r=>{try{await r.log(e)}catch(i){console.error(`[UniversalLogger] Transport ${r.name} failed:`,i)}});await Promise.allSettled(o)}async log(e,t,o,r){if(!this.shouldLog(e,t))return;const i={timestamp:new Date().toISOString(),level:t,module:e,message:o,data:r,metadata:this.config.metadata,sessionId:this.sessionId},l=this.getTransportsForModule(e);await this.sendToTransports(i,l)}async trace(e,...t){const o=h(...t);await this.log(e,\"trace\",o)}async debug(e,...t){const o=h(...t);await this.log(e,\"debug\",o)}async info(e,...t){const o=h(...t);await this.log(e,\"info\",o)}async warn(e,...t){const o=h(...t);await this.log(e,\"warn\",o)}async error(e,...t){const o=h(...t);await this.log(e,\"error\",o)}async flush(){const e=Array.from(this.transports.values()).filter(t=>typeof t.flush==\"function\").map(t=>t.flush());await Promise.allSettled(e)}async cleanup(){const e=Array.from(this.transports.values()).filter(t=>typeof t.cleanup==\"function\").map(t=>t.cleanup());await Promise.allSettled(e)}createModuleLogger(e){return new b(e,this)}}class b{constructor(e,t){this.module=e,this.logger=t}async flush(){await this.logger.flush()}async trace(...e){const t=h(...e);await this.logger.trace(this.module,t)}async debug(...e){const t=h(...e);await this.logger.debug(this.module,t)}async info(...e){const t=h(...e);await this.logger.info(this.module,t)}async warn(...e){const t=h(...e);await this.logger.warn(this.module,t)}async error(...e){const t=h(...e);await this.logger.error(this.module,t)}getModuleName(){return this.module}}const d=(...a)=>a.map(e=>typeof e==\"object\"?JSON.stringify(e,null,2):String(e)).join(\" \");class ${constructor(e,t){this.moduleName=e,this.logger=t.createModuleLogger(e),this.logger.info(`${e} initialized`).catch(o=>{console.error(`Failed to log initialization for ${e}:`,o)})}logTrace(...e){const t=d(...e);this.logger.trace(t).catch(o=>{console.error(`Failed to log trace [${this.moduleName}]:`,o)})}logDebug(...e){const t=d(...e);this.logger.debug(t).catch(o=>{console.error(`Failed to log debug [${this.moduleName}]:`,o)})}logInfo(...e){const t=d(...e);this.logger.info(t).catch(o=>{console.error(`Failed to log info [${this.moduleName}]:`,o)})}logWarn(...e){const t=d(...e);this.logger.warn(t).catch(o=>{console.error(`Failed to log warn [${this.moduleName}]:`,o)})}logError(...e){const t=d(...e);this.logger.error(t).catch(o=>{console.error(`Failed to log error [${this.moduleName}]:`,o)})}async logTraceAsync(...e){const t=d(...e);await this.logger.trace(t)}async logDebugAsync(...e){const t=d(...e);await this.logger.debug(t)}async logInfoAsync(...e){const t=d(...e);await this.logger.info(t)}async logWarnAsync(...e){const t=d(...e);await this.logger.warn(t)}async logErrorAsync(...e){const t=d(...e);await this.logger.error(t)}async flushLogs(){typeof this.logger.flush==\"function\"&&await this.logger.flush()}getModuleName(){return this.moduleName}}class p{constructor(e={}){this.name=\"console\",this.config=Object.assign({colorize:!0,timestamp:!0,prefix:\"\"},e)}log(e){const t=[];this.config.timestamp&&t.push(`[${e.timestamp}]`),this.config.prefix&&t.push(`[${this.config.prefix}]`),t.push(`[${e.module}]`,`[${e.level.toUpperCase()}]`,e.message);const o=t.join(\" \"),r=e.data?[e.data]:[];this.config.colorize?this.logWithColor(e.level,o,r):this.logWithoutColor(e.level,o,r)}logWithColor(e,t,o){const r={trace:\"#999999\",debug:\"#0066cc\",info:\"#00cc66\",warn:\"#ff9900\",error:\"#cc0000\"}[e];console.log(`%c${t}`,`color: ${r}`,...o)}logWithoutColor(e,t,o){switch(e){case\"error\":console.error(t,...o);break;case\"warn\":console.warn(t,...o);break;case\"info\":console.info(t,...o);break;default:console.log(t,...o)}}}class v{constructor(){this.transportCreators=new Map,this.registerTransport(\"console\",e=>new p(e))}registerTransport(e,t){this.transportCreators.set(e,t)}create(e,t){const o=this.transportCreators.get(e);return o?o(t):null}getAvailableTransports(){return Array.from(this.transportCreators.keys())}}class w{constructor(){this.config={enabled:!0,defaultLevel:\"info\",modules:{}}}setEnabled(e){return this.config.enabled=e,this}setDefaultLevel(e){return this.config.defaultLevel=e,this}setSessionId(e){return this.config.sessionId=e,this}setMetadata(e){return this.config.metadata=e,this}addModule(e,t=!0,o=[\"info\",\"warn\",\"error\"],r=[\"console\"]){return this.config.modules[e]={enabled:t,levels:o,transports:r},this}build(){return JSON.parse(JSON.stringify(this.config))}}class m{static createDevelopmentConfig(){return new w().setEnabled(!0).setDefaultLevel(\"debug\").addModule(\"DatabaseManager\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"info\",\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!0,[\"debug\",\"info\",\"warn\",\"error\"],[\"console\"]).build()}static createProductionConfig(){return new w().setEnabled(!0).setDefaultLevel(\"warn\").addModule(\"DatabaseManager\",!0,[\"error\"],[\"console\"]).addModule(\"ApiClient\",!0,[\"warn\",\"error\"],[\"console\"]).addModule(\"Cache\",!1,[],[]).build()}static createCustomConfig(e=!1){return e?m.createDevelopmentConfig():m.createProductionConfig()}}function L(a,e,t){const o=t.value;t.value=async function(...r){this.moduleName||this.constructor.name;const i=this.logger;if(i)try{await i.debug(`Calling method: ${e}`,{args:r.length,argTypes:r.map(s=>typeof s)});const l=Date.now();try{const s=await o.apply(this,r),c=Date.now()-l;return await i.debug(`Method ${e} completed in ${c}ms`),s}catch(s){const c=Date.now()-l;throw await i.error(`Method ${e} failed after ${c}ms`,{error:s instanceof Error?s.message:String(s),stack:s instanceof Error?s.stack:void 0}),s}}catch(l){return console.warn(`[LogMethod] Logging failed for ${e}:`,l),await o.apply(this,r)}else return await o.apply(this,r)}}function M(a=1e3){return function(e,t,o){const r=o.value;o.value=async function(...i){const l=Date.now();try{const s=await r.apply(this,i),c=Date.now()-l,n=this.logger;if(n&&c>a)try{await n.warn(`Slow method detected: ${t} took ${c}ms`,{threshold:a,duration:c,methodName:t,className:this.constructor.name,args:i.length,timestamp:new Date().toISOString()})}catch(g){console.warn(`[LogPerformance] Logging failed for ${t}:`,g)}return s}catch(s){const c=Date.now()-l,n=this.logger;if(n)try{await n.error(`Method ${t} failed after ${c}ms`,{threshold:a,duration:c,methodName:t,className:this.constructor.name,error:s instanceof Error?s.message:String(s)})}catch(g){console.warn(`[LogPerformance] Logging failed for ${t}:`,g)}throw s}}}}function S(a=\"debug\"){return function(e,t,o){const r=o.value;o.value=async function(...i){const l=this.logger,s=`${this.constructor.name}.${t}`;if(l){const c=Date.now();try{await l[a](`\\u2192 Entering ${s}`,{args:i.map((u,f)=>({index:f,type:typeof u,value:typeof u==\"object\"?\"[Object]\":String(u).slice(0,100)}))});const n=await r.apply(this,i),g=Date.now()-c;return await l[a](`\\u2190 Exiting ${s} (${g}ms)`,{duration:g,resultType:typeof n,hasResult:n!==void 0}),n}catch(n){const g=Date.now()-c;throw await l.error(`\\u2717 ${s} threw error (${g}ms)`,{duration:g,error:n instanceof Error?n.message:String(n)}),n}}else return await r.apply(this,i)}}}function C(a=6e4){const e=new Map;return function(t,o,r){const i=r.value;r.value=async function(...l){const s=`${this.constructor.name}.${o}.${JSON.stringify(l)}`,c=Date.now(),n=e.get(s),g=this.logger;if(n&&n.expires>c){if(g)try{await g.debug(`Cache HIT for ${o}`,{cacheKey:s})}catch(f){console.warn(\"[LogCache] Logging failed:\",f)}return n.value}if(g)try{await g.debug(`Cache MISS for ${o}`,{cacheKey:s})}catch(f){console.warn(\"[LogCache] Logging failed:\",f)}const u=await i.apply(this,l);return e.set(s,{value:u,expires:c+a}),u}}}function D(a=3,e=1e3){return function(t,o,r){const i=r.value;r.value=async function(...l){const s=this.logger;let c;for(let n=1;n<=a;n++)try{return s&&n>1&&await s.info(`Retry attempt ${n}/${a} for ${o}`),await i.apply(this,l)}catch(g){if(c=g,s)try{await s.warn(`Attempt ${n}/${a} failed for ${o}`,{attempt:n,maxRetries:a,error:g instanceof Error?g.message:String(g),willRetry:n<a})}catch(u){console.warn(\"[LogRetry] Logging failed:\",u)}if(n<a){const u=e*Math.pow(2,n-1);await new Promise(f=>setTimeout(f,u))}}if(s)try{await s.error(`All ${a} attempts failed for ${o}`,{maxRetries:a,finalError:c instanceof Error?c.message:String(c)})}catch(n){console.warn(\"[LogRetry] Final logging failed:\",n)}throw c}}}function T(a,e=\"debug\"){return function(t){return class extends t{constructor(...o){super(...o);const r=o.find(i=>i&&typeof i==\"object\"&&typeof i.createModuleLogger==\"function\");if(r&&!this.logger){const i=a||t.name;this.logger=r.createModuleLogger(i),this.moduleName=i}}}}}const N=a=>{const e=a||m.createDevelopmentConfig(),t=new y(e);return t.addTransport(new p),t};export{$ as BaseModule,p as ConsoleTransport,v as DefaultTransportFactory,T as EnableLogging,C as LogCache,L as LogMethod,S as LogMethodFlow,M as LogPerformance,D as LogRetry,w as LoggerConfigBuilder,m as LoggerUtils,b as ModuleLogger,y as UniversalLogger,N as createLogger};\n//# sourceMappingURL=index.mjs.map\n","// src/logger/logger-config.ts - Logger configuration for UniversalSQLite\r\nimport {\r\n BaseModule,\r\n LoggerConfigBuilder,\r\n createLogger,\r\n UniversalLogger,\r\n} from \"@dqcai/logger\";\r\n\r\n// export lại module thư viện cho các module con sử dụng\r\nexport { BaseModule };\r\n\r\n/**\r\n * Predefined modules for UniversalSQLite library\r\n */\r\nexport enum SQLiteModules {\r\n // Core modules\r\n DATABASE_MANAGER = \"DatabaseManager\",\r\n DATABASE_FACTORY = \"DatabaseFactory\",\r\n UNIVERSAL_DAO = \"UniversalDAO\",\r\n BASE_SERVICE = \"BaseService\",\r\n SERVICE_MANAGER = \"ServiceManager\",\r\n\r\n // Query modules\r\n QUERY_BUILDER = \"QueryBuilder\",\r\n\r\n // Adapter modules\r\n BASE_ADAPTER = \"BaseAdapter\",\r\n\r\n // Main interface\r\n UNIVERSAL_SQLITE = \"UniversalSQLite\",\r\n\r\n // Transaction & Connection\r\n TRANSACTION = \"Transaction\",\r\n CONNECTION = \"Connection\",\r\n}\r\n\r\n/**\r\n * Default logger configuration for UniversalSQLite\r\n */\r\nexport class SQLiteLoggerConfig {\r\n private static instance: UniversalLogger | null = null;\r\n private static currentConfig: any = null;\r\n\r\n /**\r\n * Create default logger configuration\r\n */\r\n static createDefaultConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(true) // Default: disabled for production\r\n .setDefaultLevel(\"warn\") // Default level\r\n\r\n // Core modules - usually important\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_SQLITE,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // DAO and Services - detailed debugging\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_DAO,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_SERVICE,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.SERVICE_MANAGER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // Query building - can be verbose\r\n .addModule(\r\n SQLiteModules.QUERY_BUILDER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n // Adapters - platform specific\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Initialize logger with default or custom configuration\r\n */\r\n static initialize(customConfig?: any): UniversalLogger {\r\n const config = customConfig || SQLiteLoggerConfig.createDefaultConfig();\r\n SQLiteLoggerConfig.currentConfig = config;\r\n if (config.enabled) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.initialize()\",\r\n JSON.stringify(config, null, 2)\r\n );\r\n }\r\n SQLiteLoggerConfig.instance = createLogger(config);\r\n return SQLiteLoggerConfig.instance;\r\n }\r\n\r\n /**\r\n * Get current logger instance\r\n */\r\n static getInstance(): UniversalLogger {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.enabled &&\r\n (SQLiteLoggerConfig.currentConfig.defaultLevel === \"trace\" ||\r\n SQLiteLoggerConfig.currentConfig.defaultLevel === \"debug\")\r\n ) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.getInstance()\",\r\n JSON.stringify(SQLiteLoggerConfig.currentConfig, null, 2)\r\n );\r\n }\r\n if (!SQLiteLoggerConfig.instance) {\r\n return SQLiteLoggerConfig.initialize();\r\n }\r\n return SQLiteLoggerConfig.instance;\r\n }\r\n\r\n /**\r\n * Update logger configuration at runtime\r\n */\r\n static updateConfiguration(newConfig: any): void {\r\n if (\r\n newConfig &&\r\n newConfig.enabled &&\r\n (newConfig.defaultLevel === \"trace\" || newConfig.defaultLevel === \"debug\")\r\n ) {\r\n console.debug(\r\n \"SQLiteLoggerConfig.updateConfiguration()\",\r\n JSON.stringify(newConfig, null, 2)\r\n );\r\n }\r\n SQLiteLoggerConfig.currentConfig = newConfig;\r\n SQLiteLoggerConfig.instance = createLogger(newConfig);\r\n if (\r\n newConfig &&\r\n newConfig.enabled &&\r\n (newConfig.defaultLevel === \"trace\" ||\r\n newConfig.defaultLevel === \"debug\" ||\r\n newConfig.defaultLevel === \"info\")\r\n ) {\r\n console.log(\r\n \"SQLiteLoggerConfig.updateConfiguration()\",\r\n JSON.stringify(SQLiteLoggerConfig.instance, null, 2)\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Enable/disable logging globally\r\n */\r\n static setEnabled(enabled: boolean): void {\r\n if (SQLiteLoggerConfig.currentConfig) {\r\n SQLiteLoggerConfig.currentConfig.enabled = enabled;\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Enable specific module\r\n */\r\n static enableModule(\r\n moduleName: string,\r\n levels?: string[],\r\n appenders?: string[]\r\n ): void {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.modules\r\n ) {\r\n SQLiteLoggerConfig.currentConfig.modules[moduleName] = {\r\n enabled: true,\r\n levels: levels || [\"debug\", \"info\", \"warn\", \"error\"],\r\n appenders: appenders || [\"console\"],\r\n };\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Disable specific module\r\n */\r\n static disableModule(moduleName: string): void {\r\n if (\r\n SQLiteLoggerConfig.currentConfig &&\r\n SQLiteLoggerConfig.currentConfig.modules\r\n ) {\r\n SQLiteLoggerConfig.currentConfig.modules[moduleName] = {\r\n enabled: false,\r\n };\r\n SQLiteLoggerConfig.updateConfiguration(SQLiteLoggerConfig.currentConfig);\r\n }\r\n }\r\n\r\n /**\r\n * Create debug-only configuration\r\n */\r\n static createDebugConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(true)\r\n .setDefaultLevel(\"trace\")\r\n\r\n // Enable all modules for debugging\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_SQLITE,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.UNIVERSAL_DAO,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_SERVICE,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.SERVICE_MANAGER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.QUERY_BUILDER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n true,\r\n [\"trace\", \"debug\", \"info\", \"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Create production-safe configuration (errors and warnings only)\r\n */\r\n static createProductionConfig() {\r\n return (\r\n new LoggerConfigBuilder()\r\n .setEnabled(true)\r\n .setDefaultLevel(\"warn\")\r\n\r\n // Only critical errors in production\r\n .addModule(SQLiteModules.UNIVERSAL_SQLITE, true, [\"error\"], [\"console\"])\r\n .addModule(\r\n SQLiteModules.DATABASE_MANAGER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(\r\n SQLiteModules.DATABASE_FACTORY,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n .addModule(SQLiteModules.UNIVERSAL_DAO, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.BASE_SERVICE, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.SERVICE_MANAGER, true, [\"error\"], [\"console\"])\r\n .addModule(SQLiteModules.QUERY_BUILDER, true, [\"error\"], [\"console\"])\r\n .addModule(\r\n SQLiteModules.BASE_ADAPTER,\r\n true,\r\n [\"warn\", \"error\"],\r\n [\"console\"]\r\n )\r\n\r\n .build()\r\n );\r\n }\r\n\r\n /**\r\n * Reset to default configuration\r\n */\r\n static reset(): UniversalLogger {\r\n return SQLiteLoggerConfig.initialize();\r\n }\r\n}\r\n\r\n/**\r\n * Export logger instance for use throughout the library\r\n */\r\nexport const sqliteLogger = SQLiteLoggerConfig.getInstance();\r\n\r\n/**\r\n * Helper function to create module-specific logger\r\n */\r\nexport const createModuleLogger = (moduleName: string) => {\r\n const logger = SQLiteLoggerConfig.getInstance();\r\n return {\r\n trace: (message: string, ...args: any[]) =>\r\n logger.trace(moduleName, message, ...args),\r\n debug: (message: string, ...args: any[]) =>\r\n logger.debug(moduleName, message, ...args),\r\n info: (message: string, ...args: any[]) =>\r\n logger.info(moduleName, message, ...args),\r\n warn: (message: string, ...args: any[]) =>\r\n logger.warn(moduleName, message, ...args),\r\n error: (message: string, ...args: any[]) =>\r\n logger.error(moduleName, message, ...args),\r\n };\r\n};\r\n","// src/core/universal-dao.ts\r\nimport {\r\n ColumnDefinition,\r\n DatabaseSchema,\r\n ImportOptions,\r\n ImportResult,\r\n IndexDefinition,\r\n QueryTable,\r\n SQLiteAdapter,\r\n SQLiteConnection,\r\n SQLiteResult,\r\n SQLiteRow,\r\n TableDefinition,\r\n TypeMappingConfig,\r\n WhereClause,\r\n ColumnMapping,\r\n} from \"../types\";\r\n\r\n// Import logger configuration for internal use\r\nimport { SQLiteModules, createModuleLogger } from \"../logger/logger-config\";\r\n\r\nexport class UniversalDAO {\r\n private connection: SQLiteConnection | null = null;\r\n private isConnected: boolean = false;\r\n private inTransaction: boolean = false;\r\n private typeMappingConfig: TypeMappingConfig[\"type_mapping\"] | null = null;\r\n private createIfNotExists: boolean = false;\r\n private forceRecreate: boolean = false;\r\n private logger = createModuleLogger(SQLiteModules.UNIVERSAL_DAO);\r\n\r\n constructor(\r\n private adapter: SQLiteAdapter,\r\n private dbPath: string,\r\n private options?: {\r\n createIfNotExists?: boolean; // Mặc định false - không tạo mới nếu đã tồn tại\r\n forceRecreate?: boolean; // Mặc định false - ép tạo lại = true\r\n }\r\n ) {\r\n this.createIfNotExists = options?.createIfNotExists ?? false;\r\n this.forceRecreate = options?.forceRecreate ?? false;\r\n\r\n this.logger.trace(\"UniversalDAO constructor initialized\", {\r\n dbPath: this.dbPath,\r\n createIfNotExists: this.createIfNotExists,\r\n forceRecreate: this.forceRecreate,\r\n });\r\n }\r\n\r\n async connect(): Promise<void> {\r\n this.logger.trace(\"Attempting to connect to database\", {\r\n dbPath: this.dbPath,\r\n });\r\n\r\n if (this.isConnected) {\r\n this.logger.debug(\"Already connected to database, skipping connection\");\r\n return;\r\n }\r\n\r\n try {\r\n this.connection = await this.adapter.connect(this.dbPath);\r\n this.isConnected = true;\r\n this.logger.info(\"Successfully connected to database\", {\r\n dbPath: this.dbPath,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to connect to database\", {\r\n dbPath: this.dbPath,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n this.logger.trace(\"Attempting to disconnect from database\");\r\n\r\n if (this.connection && this.isConnected) {\r\n try {\r\n await this.connection.close();\r\n this.connection = null;\r\n this.isConnected = false;\r\n this.logger.info(\"Successfully disconnected from database\");\r\n } catch (error) {\r\n this.logger.error(\"Error during database disconnection\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n } else {\r\n this.logger.debug(\"Database was not connected, nothing to disconnect\");\r\n }\r\n }\r\n\r\n async close(): Promise<void> {\r\n this.logger.trace(\"Closing database connection\");\r\n await this.disconnect();\r\n }\r\n\r\n // Type mapping utilities\r\n setTypeMappingConfig(config: TypeMappingConfig[\"type_mapping\"]): void {\r\n this.logger.trace(\"Setting type mapping configuration\", { config });\r\n this.typeMappingConfig = config;\r\n this.logger.debug(\"Type mapping configuration updated\");\r\n }\r\n\r\n private convertToSQLiteType(genericType: string): string {\r\n this.logger.trace(\"Converting generic type to SQLite type\", {\r\n genericType,\r\n });\r\n\r\n if (!this.typeMappingConfig || !this.typeMappingConfig.sqlite) {\r\n const defaultType = this.getDefaultSQLiteType(genericType);\r\n this.logger.debug(\"Using default type mapping\", {\r\n genericType,\r\n sqliteType: defaultType,\r\n });\r\n return defaultType;\r\n }\r\n\r\n const sqliteMapping = this.typeMappingConfig.sqlite;\r\n const mappedType = sqliteMapping[genericType.toLowerCase()] || \"TEXT\";\r\n this.logger.debug(\"Using custom type mapping\", {\r\n genericType,\r\n sqliteType: mappedType,\r\n });\r\n return mappedType;\r\n }\r\n\r\n private getDefaultSQLiteType(genericType: string): string {\r\n const defaultMapping: Record<string, string> = {\r\n string: \"TEXT\",\r\n varchar: \"TEXT\",\r\n char: \"TEXT\",\r\n email: \"TEXT\",\r\n url: \"TEXT\",\r\n uuid: \"TEXT\",\r\n integer: \"INTEGER\",\r\n bigint: \"INTEGER\",\r\n smallint: \"INTEGER\",\r\n tinyint: \"INTEGER\",\r\n decimal: \"REAL\",\r\n numeric: \"REAL\",\r\n float: \"REAL\",\r\n double: \"REAL\",\r\n boolean: \"INTEGER\",\r\n timestamp: \"TEXT\",\r\n datetime: \"TEXT\",\r\n date: \"TEXT\",\r\n time: \"TEXT\",\r\n json: \"TEXT\",\r\n array: \"TEXT\",\r\n blob: \"BLOB\",\r\n binary: \"BLOB\",\r\n };\r\n return defaultMapping[genericType.toLowerCase()] || \"TEXT\";\r\n }\r\n\r\n private processColumnDefinition(col: ColumnDefinition): ColumnDefinition {\r\n this.logger.trace(\"Processing column definition\", {\r\n columnName: col.name,\r\n originalType: col.type,\r\n });\r\n\r\n const processedCol: ColumnDefinition = { ...col };\r\n processedCol.type = this.convertToSQLiteType(col.type);\r\n\r\n const options: string[] = [];\r\n if (col.constraints) {\r\n this.logger.trace(\"Processing column constraints\", {\r\n columnName: col.name,\r\n constraints: col.constraints,\r\n });\r\n\r\n const constraints = col.constraints.toUpperCase().split(\" \");\r\n if (constraints.includes(\"PRIMARY\")) {\r\n options.push(\"PRIMARY KEY\");\r\n processedCol.primary_key = true;\r\n }\r\n if (\r\n constraints.includes(\"AUTO_INCREMENT\") ||\r\n constraints.includes(\"AUTOINCREMENT\")\r\n ) {\r\n if (processedCol.primary_key) options.push(\"AUTOINCREMENT\");\r\n processedCol.auto_increment = true;\r\n }\r\n if (constraints.includes(\"NOT\") && constraints.includes(\"NULL\")) {\r\n options.push(\"NOT NULL\");\r\n processedCol.nullable = false;\r\n }\r\n if (constraints.includes(\"UNIQUE\")) {\r\n if (!processedCol.primary_key) options.push(\"UNIQUE\");\r\n processedCol.unique = true;\r\n }\r\n // Handle DEFAULT values\r\n const defaultIndex = constraints.indexOf(\"DEFAULT\");\r\n if (defaultIndex !== -1 && constraints.length > defaultIndex + 1) {\r\n const defaultValue = constraints[defaultIndex + 1];\r\n options.push(`DEFAULT ${defaultValue}`);\r\n processedCol.default = defaultValue;\r\n }\r\n }\r\n\r\n processedCol.option_key = options.join(\" \").trim();\r\n this.logger.debug(\"Column definition processed\", {\r\n columnName: col.name,\r\n finalType: processedCol.type,\r\n options: processedCol.option_key,\r\n });\r\n\r\n return processedCol;\r\n }\r\n\r\n // Schema initialization with enhanced options\r\n async initializeFromSchema(schema: DatabaseSchema): Promise<void> {\r\n this.logger.info(\"Initializing database schema\", {\r\n schemaVersion: schema.version,\r\n tableCount: Object.keys(schema.schemas).length,\r\n });\r\n\r\n this.ensureConnected();\r\n\r\n // Check if schema already exists\r\n let hasExistingSchema = false;\r\n try {\r\n const result = await this.execute(\r\n \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n );\r\n hasExistingSchema = result.rows.length > 0;\r\n if (hasExistingSchema) {\r\n this.logger.debug(\"Existing schema detected\", {\r\n currentVersion: result.rows[0]?.version,\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.debug(\r\n \"No existing schema found or schema info table missing\"\r\n );\r\n hasExistingSchema = false;\r\n }\r\n\r\n // Handle existing schema based on options\r\n if (hasExistingSchema && !this.createIfNotExists && !this.forceRecreate) {\r\n this.logger.info(\r\n \"Schema exists and no recreation options set, using existing schema\"\r\n );\r\n if (schema.type_mapping) {\r\n this.setTypeMappingConfig(schema.type_mapping);\r\n }\r\n return;\r\n }\r\n\r\n if (hasExistingSchema && this.forceRecreate) {\r\n this.logger.warn(\r\n \"Force recreate option enabled, dropping all existing tables\"\r\n );\r\n await this.dropAllTables();\r\n }\r\n\r\n if (schema.type_mapping) {\r\n this.setTypeMappingConfig(schema.type_mapping);\r\n }\r\n\r\n try {\r\n this.logger.debug(\"Enabling foreign key constraints\");\r\n await this.execute(\"PRAGMA foreign_keys = ON\");\r\n } catch (error) {\r\n this.logger.warn(\"Failed to enable foreign key constraints\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n\r\n await this.beginTransaction();\r\n\r\n try {\r\n this.logger.info(\"Creating tables from schema\");\r\n for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n this.logger.debug(\"Creating table\", {\r\n tableName,\r\n columnCount: tableConfig.cols.length,\r\n });\r\n\r\n const tableDefinition: TableDefinition = {\r\n name: tableName,\r\n cols: tableConfig.cols.map((col) =>\r\n this.processColumnDefinition(col)\r\n ),\r\n description: tableConfig.description,\r\n indexes: tableConfig.indexes,\r\n foreign_keys: tableConfig.foreign_keys,\r\n };\r\n await this.createTableWithForeignKeys(tableDefinition);\r\n }\r\n\r\n this.logger.info(\"Creating indexes for tables\");\r\n for (const [tableName, tableConfig] of Object.entries(schema.schemas)) {\r\n if (tableConfig.indexes?.length) {\r\n this.logger.debug(\"Creating indexes for table\", {\r\n tableName,\r\n indexCount: tableConfig.indexes.length,\r\n });\r\n await this.createIndexesForTable(tableName, tableConfig.indexes);\r\n }\r\n }\r\n\r\n await this.setSchemaVersion(schema.version);\r\n await this.commitTransaction();\r\n this.logger.info(\"Schema initialization completed successfully\", {\r\n version: schema.version,\r\n });\r\n } catch (error) {\r\n this.logger.error(\r\n \"Schema initialization failed, rolling back transaction\",\r\n {\r\n error: error instanceof Error ? error.message : String(error),\r\n }\r\n );\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n private async dropAllTables(): Promise<void> {\r\n this.logger.info(\"Dropping all existing tables\");\r\n\r\n const tables = await this.execute(\r\n \"SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\r\n );\r\n\r\n this.logger.debug(\"Found tables to drop\", {\r\n tableCount: tables.rows.length,\r\n });\r\n\r\n await this.beginTransaction();\r\n\r\n try {\r\n for (const table of tables.rows) {\r\n this.logger.trace(\"Dropping table\", { tableName: table.name });\r\n await this.execute(`DROP TABLE IF EXISTS ${table.name}`);\r\n }\r\n await this.commitTransaction();\r\n this.logger.info(\"All tables dropped successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to drop tables, rolling back\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n private async createTableWithForeignKeys(\r\n table: TableDefinition\r\n ): Promise<void> {\r\n this.logger.trace(\"Creating table with foreign keys\", {\r\n tableName: table.name,\r\n });\r\n\r\n const columnDefs = table.cols.map((col) =>\r\n `${col.name} ${col.type} ${col.option_key || \"\"}`.trim()\r\n );\r\n\r\n const foreignKeyDefs: string[] = [];\r\n if (table.foreign_keys) {\r\n this.logger.debug(\"Processing foreign keys\", {\r\n tableName: table.name,\r\n fkCount: table.foreign_keys.length,\r\n });\r\n for (const fk of table.foreign_keys) {\r\n let fkSql = `FOREIGN KEY (${fk.column}) REFERENCES ${fk.references.table}(${fk.references.column})`;\r\n if (fk.on_delete) fkSql += ` ON DELETE ${fk.on_delete}`;\r\n if (fk.on_update) fkSql += ` ON UPDATE ${fk.on_update}`;\r\n foreignKeyDefs.push(fkSql);\r\n }\r\n }\r\n\r\n const allDefs = [...columnDefs, ...foreignKeyDefs];\r\n const sql = `CREATE TABLE IF NOT EXISTS ${table.name} (${allDefs.join(\r\n \", \"\r\n )})`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.debug(\"Table created successfully\", {\r\n tableName: table.name,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to create table\", {\r\n tableName: table.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private async createIndexesForTable(\r\n tableName: string,\r\n indexes: IndexDefinition[]\r\n ): Promise<void> {\r\n this.logger.trace(\"Creating indexes for table\", {\r\n tableName,\r\n indexCount: indexes.length,\r\n });\r\n\r\n for (const index of indexes) {\r\n const columns = index.columns.join(\", \");\r\n const isUnique = index.unique || false;\r\n const sql = `CREATE ${isUnique ? \"UNIQUE\" : \"\"} INDEX IF NOT EXISTS ${\r\n index.name\r\n } ON ${tableName} (${columns})`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.debug(\"Index created successfully\", {\r\n indexName: index.name,\r\n tableName,\r\n columns: index.columns,\r\n unique: isUnique,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Failed to create index\", {\r\n indexName: index.name,\r\n tableName,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n // Transaction management\r\n async beginTransaction(): Promise<void> {\r\n this.logger.trace(\"Beginning transaction\");\r\n\r\n if (this.inTransaction) {\r\n const error = new Error(\"Transaction already in progress\");\r\n this.logger.error(\"Cannot begin transaction\", { error: error.message });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"BEGIN TRANSACTION\");\r\n this.inTransaction = true;\r\n this.logger.debug(\"Transaction started successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to begin transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async commitTransaction(): Promise<void> {\r\n this.logger.trace(\"Committing transaction\");\r\n\r\n if (!this.inTransaction) {\r\n const error = new Error(\"No transaction in progress\");\r\n this.logger.error(\"Cannot commit transaction\", { error: error.message });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"COMMIT\");\r\n this.inTransaction = false;\r\n this.logger.debug(\"Transaction committed successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to commit transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async rollbackTransaction(): Promise<void> {\r\n this.logger.trace(\"Rolling back transaction\");\r\n\r\n if (!this.inTransaction) {\r\n const error = new Error(\"No transaction in progress\");\r\n this.logger.error(\"Cannot rollback transaction\", {\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n try {\r\n await this.execute(\"ROLLBACK\");\r\n this.inTransaction = false;\r\n this.logger.debug(\"Transaction rolled back successfully\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to rollback transaction\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Schema management\r\n async getSchemaVersion(): Promise<string> {\r\n this.logger.trace(\"Getting schema version\");\r\n\r\n try {\r\n const result = await this.getRst(\r\n \"SELECT version FROM _schema_info ORDER BY applied_at DESC LIMIT 1\"\r\n );\r\n const version = result.version || \"0\";\r\n this.logger.debug(\"Schema version retrieved\", { version });\r\n return version;\r\n } catch (error) {\r\n this.logger.debug(\"No schema version found, returning default\", {\r\n defaultVersion: \"0\",\r\n });\r\n return \"0\";\r\n }\r\n }\r\n\r\n async setSchemaVersion(version: string): Promise<void> {\r\n this.logger.trace(\"Setting schema version\", { version });\r\n\r\n try {\r\n await this.execute(`CREATE TABLE IF NOT EXISTS _schema_info (\r\n version TEXT NOT NULL,\r\n applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\r\n )`);\r\n await this.execute(`INSERT INTO _schema_info (version) VALUES (?)`, [\r\n version,\r\n ]);\r\n this.logger.info(\"Schema version set successfully\", { version });\r\n } catch (error) {\r\n this.logger.error(\"Failed to set schema version\", {\r\n version,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // CRUD Operations\r\n async insert(insertTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing insert operation\", {\r\n tableName: insertTable.name,\r\n });\r\n\r\n const validCols = insertTable.cols.filter(\r\n (col) => col.value !== undefined && col.value !== null\r\n );\r\n\r\n if (validCols.length === 0) {\r\n const error = new Error(\"No valid columns to insert\");\r\n this.logger.error(\"Insert operation failed\", {\r\n tableName: insertTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n const columnNames = validCols.map((col) => col.name).join(\", \");\r\n const placeholders = validCols.map(() => \"?\").join(\", \");\r\n const params = validCols.map((col) =>\r\n typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n );\r\n\r\n const sql = `INSERT INTO ${insertTable.name} (${columnNames}) VALUES (${placeholders})`;\r\n\r\n this.logger.debug(\"Executing insert query\", {\r\n tableName: insertTable.name,\r\n columnCount: validCols.length,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.info(\"Insert operation completed successfully\", {\r\n tableName: insertTable.name,\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowid: result.lastInsertRowId,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Insert operation failed\", {\r\n tableName: insertTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async update(updateTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing update operation\", {\r\n tableName: updateTable.name,\r\n });\r\n\r\n const setCols = updateTable.cols.filter(\r\n (col) =>\r\n col.value !== undefined &&\r\n !updateTable.wheres?.some((w) => w.name === col.name)\r\n );\r\n\r\n if (setCols.length === 0) {\r\n const error = new Error(\"No columns to update\");\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n const setClause = setCols.map((col) => `${col.name} = ?`).join(\", \");\r\n const params = setCols.map((col) =>\r\n typeof col.value === \"object\" ? JSON.stringify(col.value) : col.value\r\n );\r\n\r\n let sql = `UPDATE ${updateTable.name} SET ${setClause}`;\r\n const whereClause = this.buildWhereClause(updateTable.wheres);\r\n\r\n if (!whereClause.sql) {\r\n const error = new Error(\"WHERE clause is required for UPDATE operation\");\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n sql += whereClause.sql;\r\n params.push(...whereClause.params);\r\n\r\n this.logger.debug(\"Executing update query\", {\r\n tableName: updateTable.name,\r\n updateColumnCount: setCols.length,\r\n whereConditions: updateTable.wheres?.length || 0,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.info(\"Update operation completed successfully\", {\r\n tableName: updateTable.name,\r\n rowsAffected: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Update operation failed\", {\r\n tableName: updateTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async delete(deleteTable: QueryTable): Promise<SQLiteResult> {\r\n this.logger.trace(\"Performing delete operation\", {\r\n tableName: deleteTable.name,\r\n });\r\n\r\n let sql = `DELETE FROM ${deleteTable.name}`;\r\n const whereClause = this.buildWhereClause(deleteTable.wheres);\r\n\r\n if (!whereClause.sql) {\r\n const error = new Error(\"WHERE clause is required for DELETE operation\");\r\n this.logger.error(\"Delete operation failed\", {\r\n tableName: deleteTable.name,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n sql += whereClause.sql;\r\n\r\n this.logger.debug(\"Executing delete query\", {\r\n tableName: deleteTable.name,\r\n whereConditions: deleteTable.wheres?.length || 0,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, whereClause.params);\r\n this.logger.info(\"Delete operation completed successfully\", {\r\n tableName: deleteTable.name,\r\n rowsAffected: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Delete operation failed\", {\r\n tableName: deleteTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async select(selectTable: QueryTable): Promise<SQLiteRow> {\r\n this.logger.trace(\"Performing select single operation\", {\r\n tableName: selectTable.name,\r\n });\r\n\r\n const { sql, params } = this.buildSelectQuery(selectTable, \" LIMIT 1\");\r\n\r\n this.logger.debug(\"Executing select single query\", {\r\n tableName: selectTable.name,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n const row = result.rows[0] || {};\r\n this.logger.debug(\"Select single operation completed\", {\r\n tableName: selectTable.name,\r\n hasResult: !!result.rows[0],\r\n });\r\n return row;\r\n } catch (error) {\r\n this.logger.error(\"Select single operation failed\", {\r\n tableName: selectTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async selectAll(selectTable: QueryTable): Promise<SQLiteRow[]> {\r\n this.logger.trace(\"Performing select all operation\", {\r\n tableName: selectTable.name,\r\n });\r\n\r\n const { sql, params } = this.buildSelectQuery(selectTable);\r\n\r\n this.logger.debug(\"Executing select all query\", {\r\n tableName: selectTable.name,\r\n sql,\r\n });\r\n\r\n try {\r\n const result = await this.execute(sql, params);\r\n this.logger.debug(\"Select all operation completed\", {\r\n tableName: selectTable.name,\r\n rowCount: result.rows.length,\r\n });\r\n return result.rows;\r\n } catch (error) {\r\n this.logger.error(\"Select all operation failed\", {\r\n tableName: selectTable.name,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Utility methods\r\n private buildSelectQuery(\r\n selectTable: QueryTable,\r\n suffix: string = \"\"\r\n ): { sql: string; params: any[] } {\r\n const columns =\r\n selectTable.cols.length > 0\r\n ? selectTable.cols.map((col) => col.name).join(\", \")\r\n : \"*\";\r\n\r\n let sql = `SELECT ${columns} FROM ${selectTable.name}`;\r\n const whereClause = this.buildWhereClause(selectTable.wheres);\r\n sql += whereClause.sql;\r\n\r\n if (selectTable.orderbys?.length) {\r\n const orderBy = selectTable.orderbys\r\n .map((o) => `${o.name} ${o.direction || \"ASC\"}`)\r\n .join(\", \");\r\n sql += ` ORDER BY ${orderBy}`;\r\n }\r\n\r\n if (selectTable.limitOffset) {\r\n if (selectTable.limitOffset.limit)\r\n sql += ` LIMIT ${selectTable.limitOffset.limit}`;\r\n if (selectTable.limitOffset.offset)\r\n sql += ` OFFSET ${selectTable.limitOffset.offset}`;\r\n }\r\n\r\n sql += suffix;\r\n return { sql, params: whereClause.params };\r\n }\r\n\r\n private buildWhereClause(\r\n wheres?: WhereClause[],\r\n clause: string = \"WHERE\"\r\n ): { sql: string; params: any[] } {\r\n if (!wheres || wheres.length === 0) {\r\n return { sql: \"\", params: [] };\r\n }\r\n\r\n const conditions: string[] = [];\r\n const params: any[] = [];\r\n\r\n for (const where of wheres) {\r\n const operator = where.operator || \"=\";\r\n conditions.push(`${where.name} ${operator} ?`);\r\n params.push(where.value);\r\n }\r\n\r\n return { sql: ` ${clause} ${conditions.join(\" AND \")}`, params };\r\n }\r\n\r\n convertJsonToQueryTable(\r\n tableName: string,\r\n json: Record<string, any>,\r\n idFields: string[] = [\"id\"]\r\n ): QueryTable {\r\n this.logger.trace(\"Converting JSON to QueryTable\", {\r\n tableName,\r\n fieldCount: Object.keys(json).length,\r\n idFields,\r\n });\r\n\r\n const queryTable: QueryTable = { name: tableName, cols: [], wheres: [] };\r\n\r\n for (const [key, value] of Object.entries(json)) {\r\n queryTable.cols.push({ name: key, value });\r\n if (idFields.includes(key) && value !== undefined) {\r\n queryTable.wheres?.push({ name: key, value });\r\n }\r\n }\r\n\r\n this.logger.debug(\"JSON converted to QueryTable\", {\r\n tableName,\r\n columnCount: queryTable.cols.length,\r\n whereCount: queryTable.wheres?.length || 0,\r\n });\r\n\r\n return queryTable;\r\n }\r\n\r\n // Enhanced Data Import functionality\r\n async importData(options: ImportOptions): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import operation\", {\r\n tableName: options.tableName,\r\n totalRows: options.data.length,\r\n batchSize: options.batchSize || 1000,\r\n validateData: options.validateData,\r\n updateOnConflict: options.updateOnConflict,\r\n skipErrors: options.skipErrors,\r\n });\r\n\r\n const startTime = Date.now();\r\n const result: ImportResult = {\r\n totalRows: options.data.length,\r\n successRows: 0,\r\n errorRows: 0,\r\n errors: [],\r\n executionTime: 0,\r\n };\r\n\r\n if (!this.isConnected) {\r\n const error = new Error(\"Database is not connected\");\r\n this.logger.error(\"Import failed - database not connected\");\r\n throw error;\r\n }\r\n\r\n if (!options.data || options.data.length === 0) {\r\n this.logger.warn(\"No data provided for import, returning empty result\");\r\n result.executionTime = Date.now() - startTime;\r\n return result;\r\n }\r\n\r\n const tableInfo = await this.getTableInfo(options.tableName);\r\n if (tableInfo.length === 0) {\r\n const error = new Error(`Table '${options.tableName}' does not exist`);\r\n this.logger.error(\"Import failed - table does not exist\", {\r\n tableName: options.tableName,\r\n });\r\n throw error;\r\n }\r\n\r\n this.logger.debug(\"Table info retrieved for import\", {\r\n tableName: options.tableName,\r\n columnCount: tableInfo.length,\r\n });\r\n\r\n const columnMap = new Map(\r\n tableInfo.map((col) => [col.name.toLowerCase(), col])\r\n );\r\n const batchSize = options.batchSize || 1000;\r\n let processedCount = 0;\r\n const skipAutoIncrementPK = !options.includeAutoIncrementPK;\r\n\r\n try {\r\n await this.beginTransaction();\r\n\r\n for (let i = 0; i < options.data.length; i += batchSize) {\r\n const batch = options.data.slice(i, i + batchSize);\r\n this.logger.debug(\"Processing import batch\", {\r\n batchNumber: Math.floor(i / batchSize) + 1,\r\n batchSize: batch.length,\r\n totalBatches: Math.ceil(options.data.length / batchSize),\r\n });\r\n\r\n for (let j = 0; j < batch.length; j++) {\r\n const rowIndex = i + j;\r\n const rowData = batch[j];\r\n\r\n try {\r\n const processedData = options.validateData\r\n ? this.validateAndTransformRow(\r\n rowData,\r\n columnMap,\r\n options.tableName,\r\n skipAutoIncrementPK\r\n )\r\n : this.transformRowData(rowData, columnMap, skipAutoIncrementPK);\r\n\r\n if (options.updateOnConflict && options.conflictColumns) {\r\n await this.insertOrUpdate(\r\n options.tableName,\r\n processedData,\r\n options.conflictColumns\r\n );\r\n } else {\r\n await this.insertRow(options.tableName, processedData);\r\n }\r\n\r\n result.successRows++;\r\n } catch (error) {\r\n result.errorRows++;\r\n const errorInfo = {\r\n rowIndex,\r\n error: error instanceof Error ? error.message : String(error),\r\n rowData,\r\n };\r\n result.errors.push(errorInfo);\r\n\r\n this.logger.warn(\"Row import failed\", {\r\n rowIndex,\r\n tableName: options.tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n\r\n if (options.onError) {\r\n options.onError(\r\n error instanceof Error ? error : new Error(String(error)),\r\n rowIndex,\r\n rowData\r\n );\r\n }\r\n\r\n if (!options.skipErrors) {\r\n this.logger.error(\r\n \"Import operation stopped due to error and skipErrors=false\"\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n processedCount++;\r\n if (options.onProgress && processedCount % 100 === 0) {\r\n options.onProgress(processedCount, options.data.length);\r\n }\r\n }\r\n }\r\n\r\n await this.commitTransaction();\r\n this.logger.info(\"Data import completed successfully\", {\r\n tableName: options.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows,\r\n executionTime: Date.now() - startTime,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Import operation failed, rolling back transaction\", {\r\n tableName: options.tableName,\r\n processedCount,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n await this.rollbackTransaction();\r\n throw error;\r\n }\r\n\r\n if (options.onProgress) {\r\n options.onProgress(processedCount, options.data.length);\r\n }\r\n\r\n result.executionTime = Date.now() - startTime;\r\n return result;\r\n }\r\n\r\n // Import with column mapping\r\n async importDataWithMapping(\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import with column mapping\", {\r\n tableName,\r\n dataRows: data.length,\r\n mappingCount: columnMappings.length,\r\n });\r\n\r\n const transformedData = data.map((row, index) => {\r\n this.logger.trace(\"Transforming row with column mappings\", {\r\n rowIndex: index,\r\n });\r\n const newRow: Record<string, any> = {};\r\n\r\n columnMappings.forEach((mapping) => {\r\n if (row.hasOwnProperty(mapping.sourceColumn)) {\r\n let value = row[mapping.sourceColumn];\r\n\r\n if (mapping.transform) {\r\n try {\r\n value = mapping.transform(value);\r\n } catch (error) {\r\n this.logger.warn(\"Column transformation failed\", {\r\n rowIndex: index,\r\n sourceColumn: mapping.sourceColumn,\r\n targetColumn: mapping.targetColumn,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n }\r\n }\r\n\r\n newRow[mapping.targetColumn] = value;\r\n }\r\n });\r\n\r\n return newRow;\r\n });\r\n\r\n this.logger.debug(\"Data transformation completed\", {\r\n originalRowCount: data.length,\r\n transformedRowCount: transformedData.length,\r\n });\r\n\r\n return await this.importData({\r\n tableName,\r\n data: transformedData,\r\n ...options,\r\n });\r\n }\r\n\r\n // Import from CSV\r\n async importFromCSV(\r\n tableName: string,\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting CSV import\", {\r\n tableName,\r\n csvLength: csvData.length,\r\n delimiter: options.delimiter || \",\",\r\n hasHeader: options.hasHeader !== false,\r\n });\r\n\r\n const delimiter = options.delimiter || \",\";\r\n const hasHeader = options.hasHeader !== false;\r\n\r\n const lines = csvData.split(\"\\n\").filter((line) => line.trim());\r\n if (lines.length === 0) {\r\n const error = new Error(\"CSV data is empty\");\r\n this.logger.error(\"CSV import failed - empty data\");\r\n throw error;\r\n }\r\n\r\n let headers: string[] = [];\r\n let dataStartIndex = 0;\r\n\r\n if (hasHeader) {\r\n headers = lines[0]\r\n .split(delimiter)\r\n .map((h) => h.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n dataStartIndex = 1;\r\n this.logger.debug(\"CSV headers extracted\", {\r\n headers,\r\n headerCount: headers.length,\r\n });\r\n } else {\r\n const firstRowCols = lines[0].split(delimiter).length;\r\n headers = Array.from(\r\n { length: firstRowCols },\r\n (_, i) => `column_${i + 1}`\r\n );\r\n this.logger.debug(\"Generated column headers for headerless CSV\", {\r\n columnCount: firstRowCols,\r\n headers,\r\n });\r\n }\r\n\r\n const data: Record<string, any>[] = [];\r\n for (let i = dataStartIndex; i < lines.length; i++) {\r\n const values = lines[i]\r\n .split(delimiter)\r\n .map((v) => v.trim().replace(/^[\"']|[\"']$/g, \"\"));\r\n const row: Record<string, any> = {};\r\n\r\n headers.forEach((header, index) => {\r\n row[header] = values[index] || null;\r\n });\r\n\r\n data.push(row);\r\n }\r\n\r\n this.logger.debug(\"CSV data parsed\", {\r\n totalLines: lines.length,\r\n dataRows: data.length,\r\n skipHeader: hasHeader,\r\n });\r\n\r\n if (options.columnMappings) {\r\n this.logger.debug(\"Using column mappings for CSV import\");\r\n return await this.importDataWithMapping(\r\n tableName,\r\n data,\r\n options.columnMappings,\r\n options\r\n );\r\n } else {\r\n return await this.importData({\r\n tableName,\r\n data,\r\n ...options,\r\n });\r\n }\r\n }\r\n\r\n private validateAndTransformRow(\r\n rowData: Record<string, any>,\r\n columnMap: Map<string, any>,\r\n tableName: string,\r\n skipAutoIncrementPK: boolean = true\r\n ): Record<string, any> {\r\n this.logger.trace(\"Validating and transforming row data\", { tableName });\r\n\r\n const processedRow: Record<string, any> = {};\r\n\r\n for (const [columnName, columnInfo] of columnMap.entries()) {\r\n const isRequired = columnInfo.notnull === 1 && !columnInfo.dflt_value;\r\n const isPrimaryKey = columnInfo.pk === 1;\r\n const isAutoIncrementPK =\r\n isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n continue;\r\n }\r\n\r\n const value = this.findValueForColumn(rowData, columnName);\r\n\r\n if (isRequired && (value === null || value === undefined)) {\r\n const error = new Error(\r\n `Required column '${columnName}' is missing or null in table '${tableName}'`\r\n );\r\n this.logger.error(\"Row validation failed\", {\r\n tableName,\r\n columnName,\r\n error: error.message,\r\n });\r\n throw error;\r\n }\r\n\r\n if (value !== null && value !== undefined) {\r\n try {\r\n processedRow[columnName] = this.convertValueToColumnType(\r\n value,\r\n columnInfo.type\r\n );\r\n } catch (error) {\r\n this.logger.error(\"Value conversion failed during validation\", {\r\n tableName,\r\n columnName,\r\n value,\r\n columnType: columnInfo.type,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n return processedRow;\r\n }\r\n\r\n private transformRowData(\r\n rowData: Record<string, any>,\r\n columnMap: Map<string, any>,\r\n skipAutoIncrementPK: boolean = true\r\n ): Record<string, any> {\r\n this.logger.trace(\"Transforming row data without validation\");\r\n\r\n const processedRow: Record<string, any> = {};\r\n\r\n for (const [key, value] of Object.entries(rowData)) {\r\n const columnName = key.toLowerCase();\r\n const columnInfo = columnMap.get(columnName);\r\n\r\n if (!columnInfo) {\r\n this.logger.trace(\"Column not found in table schema, skipping\", {\r\n columnName: key,\r\n });\r\n continue;\r\n }\r\n\r\n const isPrimaryKey = columnInfo.pk === 1;\r\n const isAutoIncrementPK =\r\n isPrimaryKey && columnInfo.type.toLowerCase().includes(\"integer\");\r\n\r\n if (skipAutoIncrementPK && isAutoIncrementPK) {\r\n continue;\r\n }\r\n\r\n if (value !== null && value !== undefined) {\r\n try {\r\n processedRow[key] = this.convertValueToColumnType(\r\n value,\r\n columnInfo.type\r\n );\r\n } catch (error) {\r\n this.logger.warn(\"Value conversion failed during transformation\", {\r\n columnName: key,\r\n value,\r\n columnType: columnInfo.type,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n // Continue processing other columns\r\n }\r\n }\r\n }\r\n\r\n return processedRow;\r\n }\r\n\r\n private findValueForColumn(\r\n rowData: Record<string, any>,\r\n columnName: string\r\n ): any {\r\n if (rowData.hasOwnProperty(columnName)) {\r\n return rowData[columnName];\r\n }\r\n\r\n const lowerColumnName = columnName.toLowerCase();\r\n for (const [key, value] of Object.entries(rowData)) {\r\n if (key.toLowerCase() === lowerColumnName) {\r\n return value;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private convertValueToColumnType(value: any, columnType: string): any {\r\n if (value === null || value === undefined) {\r\n return null;\r\n }\r\n\r\n const type = columnType.toLowerCase();\r\n\r\n try {\r\n if (type.includes(\"integer\") || type.includes(\"int\")) {\r\n if (typeof value === \"boolean\") {\r\n return value ? 1 : 0;\r\n }\r\n const num = parseInt(String(value));\r\n return isNaN(num) ? null : num;\r\n }\r\n\r\n if (\r\n type.includes(\"real\") ||\r\n type.includes(\"float\") ||\r\n type.includes(\"decimal\")\r\n ) {\r\n const num = parseFloat(String(value));\r\n return isNaN(num) ? null : num;\r\n }\r\n\r\n if (type.includes(\"boolean\")) {\r\n if (typeof value === \"boolean\") {\r\n return value ? 1 : 0;\r\n }\r\n if (typeof value === \"string\") {\r\n const lower = value.toLowerCase();\r\n return lower === \"true\" || lower === \"1\" || lower === \"yes\" ? 1 : 0;\r\n }\r\n return value ? 1 : 0;\r\n }\r\n\r\n if (type.includes(\"json\")) {\r\n if (typeof value === \"object\") {\r\n return JSON.stringify(value);\r\n }\r\n if (typeof value === \"string\") {\r\n try {\r\n JSON.parse(value);\r\n return value;\r\n } catch {\r\n throw new Error(\r\n `Invalid JSON format for column type '${columnType}'`\r\n );\r\n }\r\n }\r\n return JSON.stringify(value);\r\n }\r\n\r\n if (type.includes(\"timestamp\") || type.includes(\"datetime\")) {\r\n if (value instanceof Date) {\r\n return value.toISOString();\r\n }\r\n if (typeof value === \"string\" || typeof value === \"number\") {\r\n const date = new Date(value);\r\n return isNaN(date.getTime()) ? value : date.toISOString();\r\n }\r\n return String(value);\r\n }\r\n\r\n return String(value);\r\n } catch (error) {\r\n throw new Error(\r\n `Cannot convert value '${value}' to column type '${columnType}'`\r\n );\r\n }\r\n }\r\n\r\n private async insertRow(\r\n tableName: string,\r\n data: Record<string, any>\r\n ): Promise<void> {\r\n const columns = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = columns.map(() => \"?\").join(\", \");\r\n\r\n const sql = `INSERT INTO ${tableName} (${columns.join(\r\n \", \"\r\n )}) VALUES (${placeholders})`;\r\n\r\n try {\r\n await this.execute(sql, values);\r\n } catch (error) {\r\n this.logger.trace(\"Insert row failed\", {\r\n tableName,\r\n columns,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private async insertOrUpdate(\r\n tableName: string,\r\n data: Record<string, any>,\r\n conflictColumns: string[]\r\n ): Promise<void> {\r\n this.logger.trace(\"Attempting insert or update\", {\r\n tableName,\r\n conflictColumns,\r\n });\r\n\r\n try {\r\n await this.insertRow(tableName, data);\r\n } catch (error) {\r\n if (this.isConflictError(error)) {\r\n this.logger.debug(\"Insert conflict detected, attempting update\", {\r\n tableName,\r\n });\r\n await this.updateRowByColumns(tableName, data, conflictColumns);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n private async updateRowByColumns(\r\n tableName: string,\r\n data: Record<string, any>,\r\n conflictColumns: string[]\r\n ): Promise<void> {\r\n const allColumns = Object.keys(data);\r\n const updateColumns = allColumns.filter(\r\n (col) => !conflictColumns.includes(col)\r\n );\r\n const whereColumns = conflictColumns;\r\n\r\n if (updateColumns.length === 0) {\r\n this.logger.debug(\"No columns to update, skipping update operation\", {\r\n tableName,\r\n });\r\n return;\r\n }\r\n\r\n const setClause = updateColumns.map((col) => `${col} = ?`).join(\", \");\r\n const whereClause = whereColumns.map((col) => `${col} = ?`).join(\" AND \");\r\n\r\n const updateValues = updateColumns.map((col) => data[col]);\r\n const whereValues = whereColumns.map((col) => data[col]);\r\n const allValues = [...updateValues, ...whereValues];\r\n\r\n const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`;\r\n\r\n try {\r\n await this.execute(sql, allValues);\r\n this.logger.trace(\"Update by columns completed\", {\r\n tableName,\r\n updateColumns,\r\n whereColumns,\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Update by columns failed\", {\r\n tableName,\r\n sql,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n private isConflictError(error: any): boolean {\r\n return (\r\n error.code === \"SQLITE_CONSTRAINT_UNIQUE\" ||\r\n error.code === \"SQLITE_CONSTRAINT_PRIMARYKEY\" ||\r\n (error.message && error.message.includes(\"UNIQUE constraint failed\"))\r\n );\r\n }\r\n\r\n // Database info methods\r\n async getDatabaseInfo(): Promise<any> {\r\n this.logger.trace(\"Getting database information\");\r\n\r\n try {\r\n const tables = await this.execute(\r\n \"SELECT name FROM sqlite_master WHERE type='table'\"\r\n );\r\n const version = await this.getSchemaVersion();\r\n\r\n const info = {\r\n name: this.dbPath,\r\n tables: tables.rows.map((t) => t.name),\r\n isConnected: this.isConnected,\r\n version,\r\n };\r\n\r\n this.logger.debug(\"Database information retrieved\", {\r\n tableCount: info.tables.length,\r\n isConnected: info.isConnected,\r\n version: info.version,\r\n });\r\n\r\n return info;\r\n } catch (error) {\r\n this.logger.error(\"Failed to get database information\", {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async getTableInfo(tableName: string): Promise<any[]> {\r\n this.logger.trace(\"Getting table information\", { tableName });\r\n\r\n try {\r\n const result = await this.execute(`PRAGMA table_info(${tableName})`);\r\n this.logger.debug(\"Table information retrieved\", {\r\n tableName,\r\n columnCount: result.rows.length,\r\n });\r\n return result.rows;\r\n } catch (error) {\r\n this.logger.error(\"Failed to get table information\", {\r\n tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async dropTable(tableName: string): Promise<void> {\r\n this.logger.info(\"Dropping table\", { tableName });\r\n\r\n const sql = `DROP TABLE IF EXISTS ${tableName}`;\r\n\r\n try {\r\n await this.execute(sql);\r\n this.logger.info(\"Table dropped successfully\", { tableName });\r\n } catch (error) {\r\n this.logger.error(\"Failed to drop table\", {\r\n tableName,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // Connection check method\r\n isConnectionOpen(): boolean {\r\n const isOpen = this.isConnected && !!this.connection;\r\n this.logger.trace(\"Connection status checked\", { isOpen });\r\n return isOpen;\r\n }\r\n\r\n async ensureConnected(): Promise<void> {\r\n if (!this.isConnectionOpen()) {\r\n this.logger.debug(\"Connection not open, attempting to connect\");\r\n await this.connect();\r\n }\r\n }\r\n\r\n async execute(sql: string, params: any[] = []): Promise<SQLiteResult> {\r\n this.logger.trace(\"Executing SQL query\", {\r\n sql: sql.substring(0, 100) + (sql.length > 100 ? \"...\" : \"\"),\r\n paramCount: params.length,\r\n });\r\n\r\n this.ensureConnected();\r\n\r\n try {\r\n const result = await this.connection!.execute(sql, params);\r\n this.logger.trace(\"SQL query executed successfully\", {\r\n rowsAffected: result.rowsAffected,\r\n rowsReturned: result.rows?.length || 0,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"SQL query execution failed\", {\r\n sql: sql.substring(0, 200) + (sql.length > 200 ? \"...\" : \"\"),\r\n paramCount: params.length,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n async getRst(sql: string, params: any[] = []): Promise<SQLiteRow> {\r\n const result = await this.execute(sql, params);\r\n return result.rows[0] || {};\r\n }\r\n\r\n async getRsts(sql: string, params: any[] = []): Promise<SQLiteRow[]> {\r\n const result = await this.execute(sql, params);\r\n return result.rows;\r\n }\r\n}\r\n","// src/core/database-factory.ts\r\nimport { SQLiteAdapter, DatabaseSchema, DbFactoryOptions } from \"../types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n\r\n/**\r\n * Universal DatabaseFactory - A powerful utility class designed to create and manage\r\n * UniversalDAO instances from JSON schema across all operating systems and frameworks\r\n * using TypeScript and JavaScript. It provides methods for creating new, opening existing\r\n * databases, checking integrity, and managing database lifecycle.\r\n */\r\nexport class DatabaseFactory {\r\n private static adapters: SQLiteAdapter[] = [];\r\n\r\n /**\r\n * Register a SQLite adapter for use by the factory\r\n * @param adapter The SQLite adapter to register\r\n */\r\n static registerAdapter(adapter: SQLiteAdapter): void {\r\n logger.info(`Registering SQLite adapter: ${adapter.constructor.name}`, {\r\n adapterName: adapter.constructor.name,\r\n totalAdapters: this.adapters.length + 1,\r\n });\r\n\r\n this.adapters.push(adapter);\r\n\r\n logger.debug(\r\n `Successfully registered adapter. Total adapters: ${this.adapters.length}`\r\n );\r\n }\r\n\r\n /**\r\n * Get information about the current runtime environment\r\n * @returns A string describing the current environment\r\n */\r\n static getEnvironmentInfo(): string {\r\n logger.trace(\"Detecting runtime environment\");\r\n\r\n let environment: string;\r\n\r\n if (\r\n typeof navigator !== \"undefined\" &&\r\n navigator.product === \"ReactNative\"\r\n ) {\r\n environment = \"React Native\";\r\n } else if (typeof globalThis.Bun !== \"undefined\") {\r\n environment = \"Bun\";\r\n } else if (typeof globalThis.Deno !== \"undefined\") {\r\n environment = \"Deno\";\r\n } else if (typeof window !== \"undefined\") {\r\n environment = \"Browser\";\r\n } else if (typeof process !== \"undefined\") {\r\n environment = \"Node.js\";\r\n } else {\r\n environment = \"Unknown\";\r\n }\r\n\r\n logger.debug(`Detected runtime environment: ${environment}`);\r\n return environment;\r\n }\r\n\r\n /**\r\n * Detect the best available SQLite adapter for the current environment\r\n * @returns The best available SQLite adapter\r\n * @throws Error if no supported adapter is found\r\n */\r\n private static detectBestAdapter(): SQLiteAdapter {\r\n logger.trace(\"Detecting best available SQLite adapter\", {\r\n totalAdapters: this.adapters.length,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n\r\n for (const adapter of this.adapters) {\r\n logger.trace(`Testing adapter: ${adapter.constructor.name}`);\r\n\r\n if (adapter.isSupported()) {\r\n logger.info(`Selected adapter: ${adapter.constructor.name}`, {\r\n adapterName: adapter.constructor.name,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n return adapter;\r\n }\r\n\r\n logger.debug(\r\n `Adapter ${adapter.constructor.name} is not supported in current environment`\r\n );\r\n }\r\n\r\n logger.error(\"No supported SQLite adapter found\", {\r\n totalAdapters: this.adapters.length,\r\n environment: this.getEnvironmentInfo(),\r\n });\r\n\r\n throw new Error(\"No supported SQLite adapter found\");\r\n }\r\n\r\n /**\r\n * Validate schema version compatibility between database and config\r\n * @param dao The UniversalDAO instance\r\n * @param schema The database schema configuration\r\n */\r\n private static async validateSchemaVersion(\r\n dao: UniversalDAO,\r\n schema: DatabaseSchema\r\n ): Promise<void> {\r\n logger.trace(\"Validating schema version compatibility\", {\r\n databaseName: schema.database_name,\r\n configVersion: schema.version,\r\n });\r\n\r\n try {\r\n const dbInfo = await dao.getDatabaseInfo();\r\n logger.debug(\"Retrieved database info\", {\r\n databaseVersion: dbInfo.version,\r\n configVersion: schema.version,\r\n });\r\n\r\n if (dbInfo.version !== schema.version) {\r\n const errorMsg = `Schema version mismatch: database (${dbInfo.version}) vs config (${schema.version})`;\r\n logger.error(\"Schema version mismatch\", {\r\n databaseName: schema.database_name,\r\n databaseVersion: dbInfo.version,\r\n configVersion: schema.version,\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Schema version validation successful\", {\r\n databaseName: schema.database_name,\r\n version: schema.version,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error during schema version validation\", {\r\n databaseName: schema.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error validating schema version for ${schema.database_name}: ${\r\n (error as Error).message\r\n }`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate the provided schema object to ensure it has minimum required properties\r\n * @param schema The schema object to validate\r\n * @returns True if the schema is valid, otherwise throws an error\r\n */\r\n private static validateSchema(schema: any): schema is DatabaseSchema {\r\n logger.trace(\"Validating database schema configuration\");\r\n\r\n if (!schema) {\r\n logger.error(\"Schema validation failed: null or undefined schema\");\r\n throw new Error(\"Schema configuration is null or undefined.\");\r\n }\r\n\r\n if (\r\n typeof schema.database_name !== \"string\" ||\r\n schema.database_name.trim() === \"\"\r\n ) {\r\n logger.error(\"Schema validation failed: invalid database_name\", {\r\n databaseName: schema.database_name,\r\n type: typeof schema.database_name,\r\n });\r\n throw new Error(\r\n \"Invalid or missing 'database_name' in schema. This is required to name the database file.\"\r\n );\r\n }\r\n\r\n if (\r\n typeof schema.schemas !== \"object\" ||\r\n schema.schemas === null ||\r\n Object.keys(schema.schemas).length === 0\r\n ) {\r\n logger.error(\"Schema validation failed: invalid schemas object\", {\r\n databaseName: schema.database_name,\r\n schemasType: typeof schema.schemas,\r\n schemasCount: schema.schemas ? Object.keys(schema.schemas).length : 0,\r\n });\r\n throw new Error(\r\n \"Invalid or missing 'schemas' object in schema. At least one table definition is required.\"\r\n );\r\n }\r\n\r\n logger.debug(\"Schema validation successful\", {\r\n databaseName: schema.database_name,\r\n tablesCount: Object.keys(schema.schemas).length,\r\n version: schema.version,\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Create a new UniversalDAO instance (equivalent to SQLiteDAO)\r\n * @param dbPath Path to the database file\r\n * @param options Configuration options\r\n * @returns A new UniversalDAO instance\r\n */\r\n static createDAO(\r\n dbPath: string,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n createIfNotExists?: boolean;\r\n forceRecreate?: boolean;\r\n }\r\n ): UniversalDAO {\r\n logger.info(\"Creating new UniversalDAO instance\", {\r\n dbPath,\r\n hasCustomAdapter: !!options?.adapter,\r\n createIfNotExists: options?.createIfNotExists ?? false,\r\n forceRecreate: options?.forceRecreate ?? false,\r\n });\r\n\r\n let adapter: SQLiteAdapter;\r\n\r\n if (options?.adapter) {\r\n logger.debug(\"Using provided custom adapter\", {\r\n adapterName: options.adapter.constructor.name,\r\n });\r\n adapter = options.adapter;\r\n } else {\r\n logger.debug(\"Detecting best adapter automatically\");\r\n adapter = this.detectBestAdapter();\r\n }\r\n\r\n const dao = new UniversalDAO(adapter, dbPath, {\r\n createIfNotExists: options?.createIfNotExists ?? false,\r\n forceRecreate: options?.forceRecreate ?? false,\r\n });\r\n\r\n logger.debug(\"UniversalDAO instance created successfully\", {\r\n dbPath,\r\n adapterName: adapter.constructor.name,\r\n });\r\n\r\n return dao;\r\n }\r\n\r\n /**\r\n * Opens an existing database without initializing its schema.\r\n * Includes integrity check to detect corrupted files.\r\n * @param dbName The name of the database (e.g., 'core.db' or 'core').\r\n * @param options Additional options for database connection.\r\n * @returns A promise that resolves to a connected UniversalDAO instance.\r\n */\r\n public static async openExisting(\r\n dbName: string,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Opening existing database\", { dbName, options });\r\n\r\n // Determine the database file path\r\n const dbFileName = dbName.endsWith(\".db\") ? dbName : `${dbName}.db`;\r\n logger.debug(\"Resolved database filename\", {\r\n originalName: dbName,\r\n resolvedName: dbFileName,\r\n });\r\n\r\n // Create and connect DAO instance\r\n const dao = this.createDAO(dbFileName, options);\r\n\r\n try {\r\n logger.debug(\"Connecting to database\", { dbFileName });\r\n await dao.connect();\r\n\r\n logger.debug(\"Running integrity check\", { dbFileName });\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n\r\n logger.info(\"Database opened successfully\", { dbFileName });\r\n return dao;\r\n } catch (error) {\r\n logger.error(\"Error opening database\", {\r\n dbFileName,\r\n error: (error as Error).message,\r\n });\r\n\r\n try {\r\n await dao.close();\r\n } catch (closeError) {\r\n logger.warn(\"Error closing DAO after failed open\", {\r\n dbFileName,\r\n closeError: (closeError as Error).message,\r\n });\r\n }\r\n\r\n throw new Error(\r\n `Error opening database '${dbFileName}': ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Internal method to create or open database with various options\r\n * @param options Configuration options\r\n * @param isForceInit Allow re-initialization of existing database\r\n * @param isForceDelete Force delete and recreate database\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n private static async createOrOpenInternal(\r\n options: DbFactoryOptions,\r\n isForceInit: boolean = false,\r\n isForceDelete: boolean = false\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating or opening database internally\", {\r\n isForceInit,\r\n isForceDelete,\r\n hasConfig: !!options.config,\r\n hasConfigAsset: !!options.configAsset,\r\n });\r\n\r\n let schema: DatabaseSchema;\r\n\r\n // Step 1: Load schema\r\n logger.trace(\"Loading database schema\");\r\n if (options.config) {\r\n logger.debug(\"Using provided config object\");\r\n schema = options.config;\r\n } else if (options.configAsset) {\r\n logger.debug(\"Using provided config asset\");\r\n schema = options.configAsset;\r\n } else {\r\n logger.error(\"No database schema configuration provided\");\r\n throw new Error(\r\n \"Either 'config', 'configAsset', or 'configPath' must be provided to the factory.\"\r\n );\r\n }\r\n\r\n // Step 2: Validate schema\r\n logger.trace(\"Validating schema configuration\");\r\n this.validateSchema(schema);\r\n\r\n // Step 3: Determine database path\r\n const dbFileName = schema.database_name.endsWith(\".db\")\r\n ? schema.database_name\r\n : `${schema.database_name}.db`;\r\n\r\n logger.debug(\"Database filename resolved\", {\r\n originalName: schema.database_name,\r\n resolvedName: dbFileName,\r\n });\r\n\r\n // Step 4: Create DAO instance\r\n logger.debug(\"Creating DAO instance\", {\r\n dbFileName,\r\n hasCustomAdapter: !!options.adapter,\r\n createIfNotExists: isForceInit,\r\n forceRecreate: isForceDelete,\r\n });\r\n\r\n const dao = this.createDAO(dbFileName, {\r\n adapter: options.adapter,\r\n createIfNotExists: isForceInit,\r\n forceRecreate: isForceDelete,\r\n });\r\n\r\n try {\r\n // Step 5: Connect to database\r\n logger.debug(\"Connecting to database\", { dbFileName });\r\n await dao.connect();\r\n\r\n // Step 6: Initialize schema if needed\r\n logger.debug(\"Initializing database schema\", { dbFileName });\r\n await dao.initializeFromSchema(schema);\r\n\r\n // Step 7: Validate schema version compatibility\r\n logger.debug(\"Validating schema version compatibility\");\r\n try {\r\n await this.validateSchemaVersion(dao, schema);\r\n } catch (schemaError: any) {\r\n logger.error(\"Schema version validation failed\", {\r\n dbFileName,\r\n error: schemaError.message,\r\n });\r\n\r\n await dao.close();\r\n throw new Error(\r\n `Schema mismatch in existing database. Use forceRecreate=true to recreate with updated schema. Error: ${schemaError.message}`\r\n );\r\n }\r\n\r\n logger.info(\"Database created/opened successfully\", {\r\n dbFileName,\r\n databaseName: schema.database_name,\r\n version: schema.version,\r\n });\r\n\r\n return dao;\r\n } catch (error) {\r\n logger.error(\"Error during database creation/opening\", {\r\n dbFileName,\r\n error: (error as Error).message,\r\n });\r\n\r\n if (dao.isConnectionOpen()) {\r\n try {\r\n await dao.close();\r\n } catch (closeError) {\r\n logger.warn(\"Error closing DAO after failed operation\", {\r\n dbFileName,\r\n closeError: (closeError as Error).message,\r\n });\r\n }\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new database (DANGEROUS - will delete existing database)\r\n * Only use this for migrations or development, not in production\r\n * @param options Configuration options\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async create(options: DbFactoryOptions): Promise<UniversalDAO> {\r\n logger.warn(\r\n \"Creating database with force recreate - this will delete existing database\",\r\n {\r\n databaseName:\r\n options.config?.database_name || options.configAsset?.database_name,\r\n }\r\n );\r\n\r\n return this.createOrOpenInternal(options, true, true);\r\n }\r\n\r\n /**\r\n * Smart method to create or open database\r\n * Only creates new tables if they don't exist and initializes file initially\r\n * Will check if file exists and is valid before deciding to create new or open existing\r\n * @param options Database configuration options\r\n * @param isForceInit Force re-initialization of tables even if they exist (default: false)\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createOrOpen(\r\n options: DbFactoryOptions,\r\n isForceInit: boolean = false\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Smart create or open database\", {\r\n databaseName:\r\n options.config?.database_name || options.configAsset?.database_name,\r\n isForceInit,\r\n });\r\n\r\n return this.createOrOpenInternal(options, isForceInit);\r\n }\r\n\r\n /**\r\n * Convenience method to create a database from a JSON asset\r\n * @param configAsset The imported/required JSON configuration\r\n * @param options Additional options for database creation\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createFromAsset(\r\n configAsset: DatabaseSchema,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating database from asset\", {\r\n databaseName: configAsset.database_name,\r\n version: configAsset.version,\r\n });\r\n\r\n try {\r\n return await this.create({\r\n ...options,\r\n configAsset,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error creating database from asset\", {\r\n databaseName: configAsset.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error creating database from asset: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Convenience method to create a database from a configuration object\r\n * @param config The database schema configuration object\r\n * @param options Additional options for database creation\r\n * @returns Promise that resolves to initialized UniversalDAO\r\n */\r\n public static async createFromConfig(\r\n config: DatabaseSchema,\r\n options: Omit<\r\n DbFactoryOptions,\r\n \"config\" | \"configAsset\" | \"configPath\"\r\n > = {}\r\n ): Promise<UniversalDAO> {\r\n logger.info(\"Creating database from config\", {\r\n databaseName: config.database_name,\r\n version: config.version,\r\n });\r\n\r\n try {\r\n return await this.create({\r\n ...options,\r\n config,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error creating database from config\", {\r\n databaseName: config.database_name,\r\n error: (error as Error).message,\r\n });\r\n\r\n throw new Error(\r\n `Error creating database from config: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n}\r\n\r\nexport default DatabaseFactory;\r\n","// src/core/database-manager.ts\r\n\r\nimport {\r\n DatabaseSchema,\r\n ImportOptions,\r\n ImportResult,\r\n ColumnMapping,\r\n} from \"../types\";\r\nimport { DatabaseFactory } from \"./database-factory\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.DATABASE_MANAGER);\r\n\r\nexport type DatabaseConnections = {\r\n [key: string]: UniversalDAO;\r\n};\r\n\r\nexport interface RoleConfig {\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n}\r\n\r\nexport type RoleRegistry = {\r\n [roleName: string]: RoleConfig;\r\n};\r\n\r\nexport interface DatabaseImportConfig {\r\n databaseKey: string;\r\n tableName: string;\r\n data: Record<string, any>[];\r\n options?: Partial<ImportOptions>;\r\n columnMappings?: ColumnMapping[];\r\n}\r\n\r\nexport interface BulkImportResult {\r\n totalDatabases: number;\r\n successDatabases: number;\r\n results: Record<string, ImportResult>;\r\n errors: Record<string, Error>;\r\n executionTime: number;\r\n}\r\n\r\nexport interface SchemaManager {\r\n getSchema(key: string): DatabaseSchema | undefined;\r\n registerSchema(key: string, schema: DatabaseSchema): void;\r\n getAllSchemaKeys(): string[];\r\n hasSchema(key: string): boolean;\r\n}\r\n\r\nexport class DatabaseManager {\r\n private static maxConnections = 10;\r\n private static connections: DatabaseConnections = {};\r\n private static isInitialized = false;\r\n private static roleRegistry: RoleRegistry = {};\r\n private static currentRole: string | null = null;\r\n private static currentUserRoles: string[] = [];\r\n private static activeDatabases: Set<string> = new Set();\r\n private static isClosingConnections = false;\r\n\r\n // Schema management - support dynamic schemas\r\n private static schemaConfigurations: Record<string, DatabaseSchema> = {};\r\n private static schemaManager: SchemaManager | null = null;\r\n\r\n // Event system for database reconnection\r\n private static eventListeners: Map<\r\n string,\r\n Array<(dao: UniversalDAO) => void>\r\n > = new Map();\r\n\r\n /**\r\n * Get the maximum number of allowed database connections\r\n */\r\n public static getMaxConnections(): number {\r\n logger.trace(\"Getting max connections\", {\r\n maxConnections: this.maxConnections,\r\n });\r\n return this.maxConnections;\r\n }\r\n\r\n /**\r\n * Set the maximum number of allowed database connections\r\n * @param maxConnections - The maximum number of connections (must be positive)\r\n * @throws Error if maxConnections is not positive or if current connections exceed the new limit\r\n */\r\n public static setMaxConnections(maxConnections: number): void {\r\n logger.debug(\"Setting max connections\", {\r\n newMaxConnections: maxConnections,\r\n currentMax: this.maxConnections,\r\n });\r\n\r\n if (maxConnections <= 0) {\r\n logger.error(\"Invalid max connections value\", { maxConnections });\r\n throw new Error(\"Maximum connections must be a positive number\");\r\n }\r\n\r\n const currentConnectionCount = Object.keys(this.connections).length;\r\n if (currentConnectionCount > maxConnections) {\r\n logger.error(\r\n \"Cannot set max connections - would exceed current active connections\",\r\n {\r\n requestedMax: maxConnections,\r\n currentActiveConnections: currentConnectionCount,\r\n activeConnectionKeys: Object.keys(this.connections),\r\n }\r\n );\r\n throw new Error(\r\n `Cannot set maximum connections to ${maxConnections}. ` +\r\n `Current active connections (${currentConnectionCount}) exceed the new limit. ` +\r\n `Please close some connections first.`\r\n );\r\n }\r\n\r\n this.maxConnections = maxConnections;\r\n logger.info(\"Max connections updated successfully\", {\r\n newMaxConnections: maxConnections,\r\n currentActiveConnections: currentConnectionCount,\r\n });\r\n }\r\n\r\n /**\r\n * Set a schema manager for dynamic schema handling\r\n */\r\n public static setSchemaManager(manager: SchemaManager): void {\r\n logger.debug(\"Setting schema manager\", {\r\n hadPreviousManager: this.schemaManager !== null,\r\n });\r\n this.schemaManager = manager;\r\n logger.info(\"Schema manager set successfully\");\r\n }\r\n\r\n /**\r\n * Register a schema configuration dynamically\r\n */\r\n public static registerSchema(key: string, schema: DatabaseSchema): void {\r\n logger.debug(\"Registering schema\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n this.schemaConfigurations[key] = schema;\r\n logger.info(\"Schema registered successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n }\r\n\r\n /**\r\n * Register multiple schemas at once\r\n */\r\n public static registerSchemas(schemas: Record<string, DatabaseSchema>): void {\r\n const schemaKeys = Object.keys(schemas);\r\n logger.debug(\"Registering multiple schemas\", {\r\n count: schemaKeys.length,\r\n keys: schemaKeys,\r\n });\r\n\r\n Object.entries(schemas).forEach(([key, schema]) => {\r\n this.registerSchema(key, schema);\r\n });\r\n\r\n logger.info(\"Multiple schemas registered successfully\", {\r\n count: schemaKeys.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get schema from internal store or external manager\r\n */\r\n private static getSchema(key: string): DatabaseSchema | undefined {\r\n logger.trace(\"Getting schema\", { key });\r\n\r\n // Try internal schemas first\r\n if (this.schemaConfigurations[key]) {\r\n logger.trace(\"Schema found in internal configurations\", { key });\r\n return this.schemaConfigurations[key];\r\n }\r\n\r\n // Try external schema manager\r\n if (this.schemaManager) {\r\n logger.trace(\"Checking external schema manager\", { key });\r\n const schema = this.schemaManager.getSchema(key);\r\n if (schema) {\r\n logger.trace(\"Schema found in external manager\", { key });\r\n return schema;\r\n }\r\n }\r\n\r\n logger.warn(\"Schema not found\", { key });\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Get all available schema keys\r\n */\r\n public static getAvailableSchemas(): string[] {\r\n const internalKeys = Object.keys(this.schemaConfigurations);\r\n const externalKeys = this.schemaManager?.getAllSchemaKeys() || [];\r\n const allKeys = [...new Set([...internalKeys, ...externalKeys])];\r\n\r\n logger.trace(\"Getting available schemas\", {\r\n internalCount: internalKeys.length,\r\n externalCount: externalKeys.length,\r\n totalUnique: allKeys.length,\r\n });\r\n\r\n return allKeys;\r\n }\r\n\r\n /**\r\n * Register a role configuration\r\n */\r\n public static registerRole(roleConfig: RoleConfig): void {\r\n logger.debug(\"Registering role\", {\r\n roleName: roleConfig.roleName,\r\n requiredDatabases: roleConfig.requiredDatabases,\r\n optionalDatabases: roleConfig.optionalDatabases,\r\n priority: roleConfig.priority,\r\n });\r\n\r\n this.roleRegistry[roleConfig.roleName] = roleConfig;\r\n logger.info(\"Role registered successfully\", {\r\n roleName: roleConfig.roleName,\r\n });\r\n }\r\n\r\n /**\r\n * Register multiple roles\r\n */\r\n public static registerRoles(roleConfigs: RoleConfig[]): void {\r\n logger.debug(\"Registering multiple roles\", { count: roleConfigs.length });\r\n roleConfigs.forEach((config) => this.registerRole(config));\r\n logger.info(\"Multiple roles registered successfully\", {\r\n count: roleConfigs.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get all registered roles\r\n */\r\n public static getRegisteredRoles(): RoleRegistry {\r\n logger.trace(\"Getting registered roles\", {\r\n count: Object.keys(this.roleRegistry).length,\r\n });\r\n return { ...this.roleRegistry };\r\n }\r\n\r\n /**\r\n * Get databases for a specific role\r\n */\r\n public static getRoleDatabases(roleName: string): string[] {\r\n logger.trace(\"Getting role databases\", { roleName });\r\n\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (!roleConfig) {\r\n logger.error(\"Role not found in registry\", {\r\n roleName,\r\n availableRoles: Object.keys(this.roleRegistry),\r\n });\r\n throw new Error(`Role '${roleName}' is not registered.`);\r\n }\r\n\r\n const databases = [\r\n ...roleConfig.requiredDatabases,\r\n ...(roleConfig.optionalDatabases || []),\r\n ];\r\n\r\n logger.trace(\"Role databases retrieved\", { roleName, databases });\r\n return databases;\r\n }\r\n\r\n /**\r\n * Get databases for current user roles\r\n */\r\n public static getCurrentUserDatabases(): string[] {\r\n logger.trace(\"Getting current user databases\", {\r\n currentUserRoles: this.currentUserRoles,\r\n });\r\n\r\n const allDatabases = new Set<string>();\r\n allDatabases.add(\"core\"); // Core database is always included\r\n\r\n for (const roleName of this.currentUserRoles) {\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (roleConfig) {\r\n roleConfig.requiredDatabases.forEach((db) => allDatabases.add(db));\r\n if (roleConfig.optionalDatabases) {\r\n roleConfig.optionalDatabases.forEach((db) => allDatabases.add(db));\r\n }\r\n } else {\r\n logger.warn(\"Role config not found for current user role\", {\r\n roleName,\r\n });\r\n }\r\n }\r\n\r\n const result = Array.from(allDatabases);\r\n logger.debug(\"Current user databases calculated\", {\r\n userRoles: this.currentUserRoles,\r\n databases: result,\r\n });\r\n return result;\r\n }\r\n\r\n /**\r\n * Initialize core database connection\r\n */\r\n public static async initializeCoreConnection(): Promise<void> {\r\n logger.debug(\"Initializing core database connection\");\r\n\r\n if (this.connections[\"core\"]) {\r\n logger.debug(\"Core connection already exists\");\r\n return;\r\n }\r\n\r\n try {\r\n const coreSchema = this.getSchema(\"core\");\r\n if (!coreSchema) {\r\n logger.error(\"Core database schema not found\");\r\n throw new Error(\"Core database schema not found.\");\r\n }\r\n\r\n logger.debug(\"Creating core database connection\", {\r\n schemaName: coreSchema.database_name,\r\n });\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: coreSchema },\r\n false\r\n );\r\n\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[\"core\"] = dao;\r\n logger.info(\"Core database connection initialized successfully\");\r\n } catch (error) {\r\n logger.error(\"Error initializing core database\", {\r\n error: (error as Error).message,\r\n });\r\n throw new Error(\r\n `Error initializing core database: ${(error as Error).message}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Set current user roles and initialize connections\r\n */\r\n public static async setCurrentUserRoles(\r\n userRoles: string[],\r\n primaryRole?: string\r\n ): Promise<void> {\r\n logger.debug(\"Setting current user roles\", { userRoles, primaryRole });\r\n\r\n // Validate roles exist\r\n for (const roleName of userRoles) {\r\n if (!this.roleRegistry[roleName]) {\r\n logger.error(\"Role not registered\", {\r\n roleName,\r\n availableRoles: Object.keys(this.roleRegistry),\r\n });\r\n throw new Error(\r\n `Role '${roleName}' is not registered. Please register it first.`\r\n );\r\n }\r\n }\r\n\r\n const previousRoles = [...this.currentUserRoles];\r\n this.currentUserRoles = userRoles;\r\n this.currentRole = primaryRole || userRoles[0] || null;\r\n\r\n logger.info(\"User roles updated\", {\r\n previousRoles,\r\n newRoles: userRoles,\r\n primaryRole: this.currentRole,\r\n });\r\n\r\n try {\r\n await this.initializeUserRoleConnections();\r\n await this.cleanupUnusedConnections(previousRoles);\r\n logger.info(\"User role connections initialized successfully\");\r\n } catch (error) {\r\n logger.error(\"Failed to initialize user role connections\", {\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current user roles\r\n */\r\n public static getCurrentUserRoles(): string[] {\r\n logger.trace(\"Getting current user roles\", {\r\n roles: this.currentUserRoles,\r\n });\r\n return [...this.currentUserRoles];\r\n }\r\n\r\n /**\r\n * Get current primary role\r\n */\r\n public static getCurrentRole(): string | null {\r\n logger.trace(\"Getting current primary role\", { role: this.currentRole });\r\n return this.currentRole;\r\n }\r\n\r\n /**\r\n * Initialize connections for current user roles\r\n */\r\n private static async initializeUserRoleConnections(): Promise<void> {\r\n const requiredDatabases = this.getCurrentUserDatabases();\r\n logger.debug(\"Initializing user role connections\", { requiredDatabases });\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n const initPromises = requiredDatabases.map(async (dbKey) => {\r\n if (this.connections[dbKey]) {\r\n logger.trace(\"Database already connected\", { dbKey });\r\n return; // Already connected\r\n }\r\n\r\n try {\r\n logger.debug(\"Initializing database connection\", { dbKey });\r\n const schema = this.getSchema(dbKey);\r\n if (!schema) {\r\n throw new Error(\r\n `Database key '${dbKey}' not found in schema configurations.`\r\n );\r\n }\r\n\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[dbKey] = dao;\r\n logger.info(\"Database connection initialized\", {\r\n dbKey,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize database connection\", {\r\n dbKey,\r\n error: err.message,\r\n });\r\n\r\n // Check if database is required for any role\r\n const isRequired = this.currentUserRoles.some((roleName) => {\r\n const roleConfig = this.roleRegistry[roleName];\r\n return roleConfig && roleConfig.requiredDatabases.includes(dbKey);\r\n });\r\n\r\n if (isRequired) {\r\n failedInitializations.push({ key: dbKey, error: err });\r\n } else {\r\n logger.warn(\"Optional database initialization failed\", {\r\n dbKey,\r\n error: err.message,\r\n });\r\n }\r\n // Optional databases that fail are ignored\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize required databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize required databases for user roles:\\n${errorSummary}`\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup unused connections\r\n */\r\n private static async cleanupUnusedConnections(\r\n previousRoles: string[]\r\n ): Promise<void> {\r\n logger.debug(\"Cleaning up unused connections\", { previousRoles });\r\n\r\n const previousDatabases = new Set<string>();\r\n previousDatabases.add(\"core\");\r\n\r\n for (const roleName of previousRoles) {\r\n const roleConfig = this.roleRegistry[roleName];\r\n if (roleConfig) {\r\n roleConfig.requiredDatabases.forEach((db) => previousDatabases.add(db));\r\n if (roleConfig.optionalDatabases) {\r\n roleConfig.optionalDatabases.forEach((db) =>\r\n previousDatabases.add(db)\r\n );\r\n }\r\n }\r\n }\r\n\r\n const currentDatabases = new Set(this.getCurrentUserDatabases());\r\n const databasesToClose = Array.from(previousDatabases).filter(\r\n (db) => !currentDatabases.has(db)\r\n );\r\n\r\n logger.debug(\"Databases to cleanup\", {\r\n databasesToClose,\r\n previousDatabaseCount: previousDatabases.size,\r\n currentDatabaseCount: currentDatabases.size,\r\n });\r\n\r\n if (databasesToClose.length > 0) {\r\n for (const dbKey of databasesToClose) {\r\n if (this.connections[dbKey]) {\r\n try {\r\n logger.debug(\"Closing unused database connection\", { dbKey });\r\n await this.connections[dbKey].close();\r\n delete this.connections[dbKey];\r\n logger.info(\"Database connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection during cleanup\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue cleanup\r\n }\r\n }\r\n }\r\n logger.info(\"Cleanup completed\", { closedConnections: databasesToClose });\r\n } else {\r\n logger.debug(\"No connections to cleanup\");\r\n }\r\n }\r\n\r\n /**\r\n * Check if current user has access to database\r\n */\r\n public static hasAccessToDatabase(dbKey: string): boolean {\r\n const hasAccess = this.getSchema(dbKey) !== undefined;\r\n logger.trace(\"Checking database access\", { dbKey, hasAccess });\r\n return hasAccess;\r\n }\r\n\r\n /**\r\n * Get database connection\r\n */\r\n public static get(key: string): UniversalDAO {\r\n logger.trace(\"Getting database connection\", { key });\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied to database\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n const dao = this.connections[key];\r\n if (!dao) {\r\n logger.error(\"Database not connected\", {\r\n key,\r\n availableConnections: Object.keys(this.connections),\r\n });\r\n throw new Error(\r\n `Database '${key}' is not connected. Please ensure it's initialized.`\r\n );\r\n }\r\n\r\n logger.trace(\"Database connection retrieved successfully\", { key });\r\n return dao;\r\n }\r\n\r\n /**\r\n * Register event listener for database reconnection\r\n */\r\n public static onDatabaseReconnect(\r\n schemaName: string,\r\n callback: (dao: UniversalDAO) => void\r\n ): void {\r\n logger.debug(\"Registering database reconnect listener\", { schemaName });\r\n\r\n if (!this.eventListeners.has(schemaName)) {\r\n this.eventListeners.set(schemaName, []);\r\n }\r\n this.eventListeners.get(schemaName)!.push(callback);\r\n\r\n logger.trace(\"Database reconnect listener registered\", {\r\n schemaName,\r\n listenerCount: this.eventListeners.get(schemaName)!.length,\r\n });\r\n }\r\n\r\n /**\r\n * Remove event listener for database reconnection\r\n */\r\n public static offDatabaseReconnect(\r\n schemaName: string,\r\n callback: (dao: UniversalDAO) => void\r\n ): void {\r\n logger.debug(\"Removing database reconnect listener\", { schemaName });\r\n\r\n const listeners = this.eventListeners.get(schemaName);\r\n if (listeners) {\r\n const index = listeners.indexOf(callback);\r\n if (index > -1) {\r\n listeners.splice(index, 1);\r\n logger.trace(\"Database reconnect listener removed\", {\r\n schemaName,\r\n remainingListeners: listeners.length,\r\n });\r\n } else {\r\n logger.warn(\"Database reconnect listener not found for removal\", {\r\n schemaName,\r\n });\r\n }\r\n } else {\r\n logger.warn(\"No listeners found for schema\", { schemaName });\r\n }\r\n }\r\n\r\n /**\r\n * Notify listeners of database reconnection\r\n */\r\n private static notifyDatabaseReconnect(\r\n schemaName: string,\r\n dao: UniversalDAO\r\n ): void {\r\n const listeners = this.eventListeners.get(schemaName);\r\n if (listeners) {\r\n logger.debug(\"Notifying database reconnect listeners\", {\r\n schemaName,\r\n listenerCount: listeners.length,\r\n });\r\n\r\n listeners.forEach((callback, index) => {\r\n try {\r\n callback(dao);\r\n logger.trace(\"Database reconnect listener notified\", {\r\n schemaName,\r\n listenerIndex: index,\r\n });\r\n } catch (error) {\r\n logger.error(\"Error in database reconnect listener\", {\r\n schemaName,\r\n listenerIndex: index,\r\n error: (error as Error).message,\r\n });\r\n // Handle callback errors gracefully\r\n }\r\n });\r\n } else {\r\n logger.trace(\"No listeners to notify for database reconnection\", {\r\n schemaName,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections\r\n */\r\n private static async closeAllConnections(): Promise<void> {\r\n if (this.isClosingConnections) {\r\n logger.debug(\"Already closing connections, skipping\");\r\n return;\r\n }\r\n\r\n logger.info(\"Closing all database connections\", {\r\n connectionCount: Object.keys(this.connections).length,\r\n });\r\n\r\n this.isClosingConnections = true;\r\n try {\r\n // Save active databases\r\n const currentActiveDb = Object.keys(this.connections);\r\n currentActiveDb.forEach((dbKey) => this.activeDatabases.add(dbKey));\r\n\r\n logger.debug(\"Saving active database list for potential reconnection\", {\r\n activeDatabases: currentActiveDb,\r\n });\r\n\r\n const closePromises = Object.entries(this.connections).map(\r\n async ([dbKey, dao]) => {\r\n try {\r\n logger.debug(\"Closing database connection\", { dbKey });\r\n await dao.close();\r\n logger.trace(\"Database connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue closing\r\n }\r\n }\r\n );\r\n\r\n await Promise.all(closePromises);\r\n this.connections = {};\r\n logger.info(\"All database connections closed successfully\");\r\n } finally {\r\n this.isClosingConnections = false;\r\n }\r\n }\r\n\r\n /**\r\n * Reopen connections\r\n */\r\n public static async reopenConnections(): Promise<void> {\r\n logger.info(\"Reopening database connections\");\r\n\r\n try {\r\n await this.initializeCoreConnection();\r\n\r\n if (this.currentUserRoles.length > 0) {\r\n await this.initializeUserRoleConnections();\r\n }\r\n\r\n // Reinitialize previously active databases\r\n const activeDbArray = Array.from(this.activeDatabases);\r\n logger.debug(\"Reinitializing previously active databases\", {\r\n activeDatabases: activeDbArray,\r\n });\r\n\r\n if (activeDbArray.length > 0) {\r\n for (const dbKey of activeDbArray) {\r\n if (!this.connections[dbKey]) {\r\n const schema = this.getSchema(dbKey);\r\n if (schema) {\r\n try {\r\n logger.debug(\"Reopening database connection\", { dbKey });\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.connect();\r\n this.connections[dbKey] = dao;\r\n this.notifyDatabaseReconnect(dbKey, dao);\r\n logger.info(\"Database connection reopened\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Failed to reopen database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue\r\n }\r\n } else {\r\n logger.warn(\"Schema not found for previously active database\", {\r\n dbKey,\r\n });\r\n }\r\n } else if (this.connections[dbKey]) {\r\n // Database exists, notify services\r\n logger.trace(\"Database already connected, notifying listeners\", {\r\n dbKey,\r\n });\r\n this.notifyDatabaseReconnect(dbKey, this.connections[dbKey]);\r\n }\r\n }\r\n }\r\n\r\n logger.info(\"Database connections reopened successfully\");\r\n } catch (error) {\r\n logger.error(\"Failed to reopen database connections\", {\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Ensure database connection exists and is active\r\n */\r\n public static async ensureDatabaseConnection(\r\n key: string\r\n ): Promise<UniversalDAO> {\r\n logger.debug(\"Ensuring database connection\", { key });\r\n this.activeDatabases.add(key);\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied when ensuring database connection\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n if (this.connections[key]) {\r\n try {\r\n const isConnected = this.connections[key].isConnectionOpen();\r\n if (isConnected) {\r\n logger.trace(\"Database connection already active\", { key });\r\n return this.connections[key];\r\n } else {\r\n // Clean up inactive connection\r\n logger.warn(\"Database connection inactive, cleaning up\", { key });\r\n try {\r\n await this.connections[key].close().catch(() => {});\r\n } catch (error) {\r\n logger.debug(\"Error during connection cleanup\", {\r\n key,\r\n error: (error as Error).message,\r\n });\r\n // Ignore cleanup errors\r\n }\r\n delete this.connections[key];\r\n }\r\n } catch (error) {\r\n logger.error(\"Error checking connection status\", {\r\n key,\r\n error: (error as Error).message,\r\n });\r\n delete this.connections[key];\r\n }\r\n }\r\n\r\n // Create new connection\r\n logger.debug(\"Creating new database connection\", { key });\r\n return await this.getLazyLoading(key);\r\n }\r\n\r\n /**\r\n * Get all connections\r\n */\r\n public static getConnections(): DatabaseConnections {\r\n logger.trace(\"Getting all connections\", {\r\n count: Object.keys(this.connections).length,\r\n });\r\n return { ...this.connections };\r\n }\r\n\r\n /**\r\n * Open all existing databases\r\n */\r\n public static async openAllExisting(\r\n databaseKeys: string[]\r\n ): Promise<boolean> {\r\n logger.info(\"Opening all existing databases\", { databaseKeys });\r\n const failedOpens: { key: string; error: Error }[] = [];\r\n\r\n for (const key of databaseKeys) {\r\n try {\r\n logger.debug(\"Opening database\", { key });\r\n const schema = this.getSchema(key);\r\n if (!schema) {\r\n throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n }\r\n\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[key] = dao;\r\n logger.info(\"Database opened successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to open database\", { key, error: err.message });\r\n failedOpens.push({ key, error: err });\r\n }\r\n }\r\n\r\n if (failedOpens.length > 0) {\r\n const errorSummary = failedOpens\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to open one or more databases\", {\r\n failedDatabases: failedOpens.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(`Failed to open one or more databases:\\n${errorSummary}`);\r\n }\r\n\r\n this.isInitialized = true;\r\n logger.info(\"All databases opened successfully\", {\r\n count: databaseKeys.length,\r\n });\r\n return true;\r\n }\r\n\r\n /**\r\n * Initialize databases lazily\r\n */\r\n public static async initLazySchema(databaseKeys: string[]): Promise<boolean> {\r\n logger.debug(\"Initializing databases lazily\", { databaseKeys });\r\n\r\n const invalidKeys = databaseKeys.filter((key) => !this.getSchema(key));\r\n if (invalidKeys.length > 0) {\r\n logger.error(\"Invalid database keys found\", { invalidKeys });\r\n throw new Error(\r\n `Invalid database keys: ${invalidKeys.join(\", \")}. Schemas not found.`\r\n );\r\n }\r\n\r\n const newConnectionsCount = databaseKeys.filter(\r\n (key) => !this.connections[key]\r\n ).length;\r\n const currentConnectionsCount = Object.keys(this.connections).length;\r\n\r\n if (currentConnectionsCount + newConnectionsCount > this.maxConnections) {\r\n logger.error(\"Would exceed maximum connections\", {\r\n currentConnections: currentConnectionsCount,\r\n newConnections: newConnectionsCount,\r\n maxConnections: this.maxConnections,\r\n });\r\n throw new Error(\r\n `Cannot initialize ${newConnectionsCount} new connections. Would exceed maximum of ${this.maxConnections} connections. Current: ${currentConnectionsCount}`\r\n );\r\n }\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n const initPromises = databaseKeys.map(async (key) => {\r\n if (this.connections[key]) {\r\n logger.trace(\"Database already initialized\", { key });\r\n return; // Already initialized\r\n }\r\n\r\n try {\r\n logger.debug(\"Initializing database\", { key });\r\n const schema = this.getSchema(key)!;\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n await dao.execute(\"PRAGMA integrity_check\");\r\n this.connections[key] = dao;\r\n logger.info(\"Database initialized successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize database\", {\r\n key,\r\n error: err.message,\r\n });\r\n failedInitializations.push({ key, error: err });\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize one or more databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize one or more databases:\\n${errorSummary}`\r\n );\r\n }\r\n\r\n if (Object.keys(this.connections).length > 0) {\r\n this.isInitialized = true;\r\n logger.info(\"Lazy schema initialization completed\", {\r\n initializedCount: databaseKeys.length - failedInitializations.length,\r\n });\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Initialize all available databases\r\n */\r\n public static async initializeAll(): Promise<void> {\r\n if (this.isInitialized) {\r\n logger.debug(\"Database manager already initialized\");\r\n return;\r\n }\r\n\r\n const availableSchemas = this.getAvailableSchemas();\r\n logger.info(\"Initializing all available databases\", {\r\n schemaCount: availableSchemas.length,\r\n schemas: availableSchemas,\r\n });\r\n\r\n const failedInitializations: { key: string; error: Error }[] = [];\r\n\r\n const initPromises = availableSchemas.map(async (key) => {\r\n try {\r\n logger.debug(\"Initializing schema\", { key });\r\n const schema = this.getSchema(key)!;\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n false\r\n );\r\n this.connections[key] = dao;\r\n logger.info(\"Schema initialized successfully\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Failed to initialize schema\", {\r\n key,\r\n error: err.message,\r\n });\r\n failedInitializations.push({ key, error: err });\r\n }\r\n });\r\n\r\n await Promise.all(initPromises);\r\n\r\n if (failedInitializations.length > 0) {\r\n this.isInitialized = false;\r\n const errorSummary = failedInitializations\r\n .map((f) => ` - ${f.key}: ${f.error.message}`)\r\n .join(\"\\n\");\r\n logger.error(\"Failed to initialize one or more databases\", {\r\n failedDatabases: failedInitializations.map((f) => f.key),\r\n errorSummary,\r\n });\r\n throw new Error(\r\n `Failed to initialize one or more databases:\\n${errorSummary}`\r\n );\r\n }\r\n\r\n this.isInitialized = true;\r\n logger.info(\"All databases initialized successfully\", {\r\n totalSchemas: availableSchemas.length,\r\n });\r\n }\r\n\r\n /**\r\n * Get database with lazy loading\r\n */\r\n public static async getLazyLoading(key: string): Promise<UniversalDAO> {\r\n logger.debug(\"Getting database with lazy loading\", { key });\r\n this.activeDatabases.add(key);\r\n\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied for lazy loading\", { key });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n\r\n if (!this.connections[key]) {\r\n const schema = this.getSchema(key);\r\n if (!schema) {\r\n logger.error(\"Schema not found for lazy loading\", { key });\r\n throw new Error(`Invalid database key: ${key}. Schema not found.`);\r\n }\r\n\r\n if (Object.keys(this.connections).length >= this.maxConnections) {\r\n logger.error(\"Maximum connections reached\", {\r\n currentConnections: Object.keys(this.connections).length,\r\n maxConnections: this.maxConnections,\r\n });\r\n throw new Error(\"Maximum number of database connections reached\");\r\n }\r\n\r\n logger.debug(\"Creating new connection for lazy loading\", {\r\n key,\r\n schemaName: schema.database_name,\r\n });\r\n const dao = await DatabaseFactory.createOrOpen({ config: schema }, false);\r\n await dao.connect();\r\n this.connections[key] = dao;\r\n logger.info(\"Database connection created via lazy loading\", { key });\r\n }\r\n\r\n this.isInitialized = true;\r\n return this.connections[key];\r\n }\r\n\r\n /**\r\n * Execute cross-schema transaction\r\n */\r\n public static async executeCrossSchemaTransaction(\r\n schemas: string[],\r\n callback: (daos: Record<string, UniversalDAO>) => Promise<void>\r\n ): Promise<void> {\r\n logger.debug(\"Executing cross-schema transaction\", { schemas });\r\n\r\n for (const key of schemas) {\r\n if (!this.hasAccessToDatabase(key)) {\r\n logger.error(\"Access denied for cross-schema transaction\", {\r\n key,\r\n schemas,\r\n });\r\n throw new Error(`Access denied: Database '${key}' is not accessible.`);\r\n }\r\n }\r\n\r\n const daos = schemas.reduce((acc, key) => {\r\n acc[key] = this.get(key);\r\n return acc;\r\n }, {} as Record<string, UniversalDAO>);\r\n\r\n logger.debug(\"Starting cross-schema transaction\", { schemas });\r\n\r\n try {\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.beginTransaction())\r\n );\r\n logger.trace(\"All transactions started successfully\");\r\n\r\n await callback(daos);\r\n logger.trace(\"Transaction callback completed successfully\");\r\n\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.commitTransaction())\r\n );\r\n logger.info(\"Cross-schema transaction completed successfully\", {\r\n schemas,\r\n });\r\n } catch (error) {\r\n logger.error(\"Cross-schema transaction failed, rolling back\", {\r\n schemas,\r\n error: (error as Error).message,\r\n });\r\n\r\n await Promise.all(\r\n Object.values(daos).map((dao) => dao.rollbackTransaction())\r\n );\r\n logger.debug(\"Cross-schema transaction rolled back\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data to table\r\n */\r\n public static async importDataToTable(\r\n databaseKey: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing data to table\", {\r\n databaseKey,\r\n tableName,\r\n recordCount: data.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for data import\", { databaseKey, tableName });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importData({\r\n tableName,\r\n data,\r\n ...options,\r\n });\r\n logger.info(\"Data import completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Data import failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n public static async importDataWithMapping(\r\n databaseKey: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing data with column mapping\", {\r\n databaseKey,\r\n tableName,\r\n recordCount: data.length,\r\n mappingCount: columnMappings.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for data import with mapping\", {\r\n databaseKey,\r\n tableName,\r\n });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importDataWithMapping(\r\n tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n logger.info(\"Data import with mapping completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Data import with mapping failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk import data\r\n */\r\n public static async bulkImport(\r\n importConfigs: DatabaseImportConfig[]\r\n ): Promise<BulkImportResult> {\r\n const startTime = Date.now();\r\n logger.info(\"Starting bulk import\", {\r\n configCount: importConfigs.length,\r\n configs: importConfigs.map((c) => ({\r\n databaseKey: c.databaseKey,\r\n tableName: c.tableName,\r\n recordCount: c.data.length,\r\n })),\r\n });\r\n\r\n const result: BulkImportResult = {\r\n totalDatabases: importConfigs.length,\r\n successDatabases: 0,\r\n results: {},\r\n errors: {},\r\n executionTime: 0,\r\n };\r\n\r\n for (const config of importConfigs) {\r\n const configKey = `${config.databaseKey}.${config.tableName}`;\r\n logger.debug(\"Processing bulk import config\", { configKey });\r\n\r\n try {\r\n if (!this.hasAccessToDatabase(config.databaseKey)) {\r\n throw new Error(\r\n `Access denied: Database '${config.databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(config.databaseKey);\r\n let importResult: ImportResult;\r\n\r\n if (config.columnMappings) {\r\n logger.trace(\"Using column mappings for import\", { configKey });\r\n importResult = await dao.importDataWithMapping(\r\n config.tableName,\r\n config.data,\r\n config.columnMappings,\r\n config.options\r\n );\r\n } else {\r\n logger.trace(\"Using direct import\", { configKey });\r\n importResult = await dao.importData({\r\n tableName: config.tableName,\r\n data: config.data,\r\n ...config.options,\r\n });\r\n }\r\n\r\n result.results[configKey] = importResult;\r\n result.successDatabases++;\r\n logger.info(\"Bulk import config completed successfully\", {\r\n configKey,\r\n importedRows: importResult.successRows,\r\n skippedRows: importResult.errorRows,\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error(\"Bulk import config failed\", {\r\n configKey,\r\n error: err.message,\r\n });\r\n result.errors[configKey] = err;\r\n }\r\n }\r\n\r\n result.executionTime = Date.now() - startTime;\r\n logger.info(\"Bulk import completed\", {\r\n totalConfigs: result.totalDatabases,\r\n successfulConfigs: result.successDatabases,\r\n failedConfigs: Object.keys(result.errors).length,\r\n executionTimeMs: result.executionTime,\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Import from CSV\r\n */\r\n public static async importFromCSV(\r\n databaseKey: string,\r\n tableName: string,\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.debug(\"Importing from CSV\", {\r\n databaseKey,\r\n tableName,\r\n csvSize: csvData.length,\r\n options,\r\n });\r\n\r\n if (!this.hasAccessToDatabase(databaseKey)) {\r\n logger.error(\"Access denied for CSV import\", { databaseKey, tableName });\r\n throw new Error(\r\n `Access denied: Database '${databaseKey}' is not accessible.`\r\n );\r\n }\r\n\r\n const dao = this.get(databaseKey);\r\n try {\r\n const result = await dao.importFromCSV(tableName, csvData, options);\r\n logger.info(\"CSV import completed successfully\", {\r\n databaseKey,\r\n tableName,\r\n importedRows: result.successRows,\r\n skippedRows: result.errorRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"CSV import failed\", {\r\n databaseKey,\r\n tableName,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get connection count\r\n */\r\n public static getConnectionCount(): number {\r\n const count = Object.keys(this.connections).length;\r\n logger.trace(\"Getting connection count\", { count });\r\n return count;\r\n }\r\n\r\n /**\r\n * List all active connections\r\n */\r\n public static listConnections(): string[] {\r\n const connections = Object.keys(this.connections);\r\n logger.trace(\"Listing connections\", { connections });\r\n return connections;\r\n }\r\n\r\n /**\r\n * Close specific connection\r\n */\r\n public static async closeConnection(dbKey: string): Promise<void> {\r\n logger.debug(\"Closing specific connection\", { dbKey });\r\n\r\n const dao = this.connections[dbKey];\r\n if (dao) {\r\n try {\r\n await dao.disconnect();\r\n delete this.connections[dbKey];\r\n logger.info(\"Database connection closed successfully\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing database connection\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n } else {\r\n logger.warn(\"Attempted to close non-existent connection\", { dbKey });\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections and reset state\r\n */\r\n public static async closeAll(): Promise<void> {\r\n logger.info(\"Closing all connections and resetting state\");\r\n\r\n await this.closeAllConnections();\r\n\r\n this.currentUserRoles = [];\r\n this.currentRole = null;\r\n this.isInitialized = false;\r\n this.activeDatabases.clear();\r\n this.eventListeners.clear();\r\n this.isClosingConnections = false;\r\n\r\n logger.info(\"All connections closed and state reset successfully\");\r\n }\r\n\r\n /**\r\n * Logout user - close role-specific connections\r\n */\r\n public static async logout(): Promise<void> {\r\n logger.info(\"Logging out user\", {\r\n currentUserRoles: this.currentUserRoles,\r\n });\r\n\r\n const connectionsToClose = Object.keys(this.connections).filter(\r\n (key) => key !== \"core\"\r\n );\r\n\r\n logger.debug(\"Closing role-specific connections\", { connectionsToClose });\r\n\r\n for (const dbKey of connectionsToClose) {\r\n try {\r\n await this.connections[dbKey].close();\r\n delete this.connections[dbKey];\r\n logger.debug(\"Role-specific connection closed\", { dbKey });\r\n } catch (error) {\r\n logger.error(\"Error closing connection during logout\", {\r\n dbKey,\r\n error: (error as Error).message,\r\n });\r\n // Log error but continue cleanup\r\n }\r\n }\r\n\r\n this.currentUserRoles = [];\r\n this.currentRole = null;\r\n\r\n logger.info(\"User logout completed successfully\", {\r\n closedConnections: connectionsToClose.length,\r\n });\r\n }\r\n}\r\n","// src/core/base-service.ts\r\nimport {\r\n QueryTable,\r\n WhereClause,\r\n OrderByClause,\r\n ImportResult,\r\n ColumnMapping,\r\n ImportOptions,\r\n ServiceStatus,\r\n HealthCheckResult,\r\n} from \"../types\";\r\nimport { UniversalDAO } from \"./universal-dao\";\r\nimport { DatabaseManager } from \"./database-manager\";\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.BASE_SERVICE);\r\n\r\nexport interface FindOptions {\r\n where?: WhereClause[];\r\n orderBy?: OrderByClause[];\r\n limit?: number;\r\n offset?: number;\r\n columns?: string[];\r\n}\r\n\r\nexport type ErrorHandler = (error: Error) => void;\r\nexport type EventHandler = (data: any) => void;\r\n\r\n/**\r\n * Universal BaseService - An enhanced abstract base class designed to provide\r\n * comprehensive CRUD operations and database management features across all\r\n * operating systems and frameworks using TypeScript and JavaScript.\r\n */\r\nexport abstract class BaseService<T = any> {\r\n protected dao: UniversalDAO | null = null;\r\n protected schemaName: string;\r\n protected tableName: string;\r\n protected isOpened: boolean = false;\r\n protected isInitialized: boolean = false;\r\n protected errorHandlers: Map<string, ErrorHandler> = new Map();\r\n protected eventListeners: Map<string, EventHandler[]> = new Map();\r\n protected primaryKeyFields: string[] = [\"id\"];\r\n private cache: Map<string, any> = new Map();\r\n private reconnectHandler: (dao: UniversalDAO) => void;\r\n\r\n constructor(schemaName: string, tableName?: string) {\r\n this.schemaName = schemaName;\r\n this.tableName = tableName || schemaName;\r\n\r\n logger.debug(\"Creating BaseService instance\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n primaryKeyFields: this.primaryKeyFields\r\n });\r\n\r\n // Register reconnect listener for database reconnection\r\n this.reconnectHandler = (newDao: UniversalDAO) => {\r\n logger.info(\"Database reconnected for service\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n \r\n this.dao = newDao;\r\n this._emit(\"daoReconnected\", { schemaName: this.schemaName });\r\n };\r\n\r\n DatabaseManager.onDatabaseReconnect(schemaName, this.reconnectHandler);\r\n this.bindMethods();\r\n \r\n logger.trace(\"BaseService instance created successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n }\r\n\r\n private bindMethods(): void {\r\n logger.trace(\"Binding service methods\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n methods.forEach((method) => {\r\n if (\r\n typeof (this as any)[method] === \"function\" &&\r\n method !== \"constructor\"\r\n ) {\r\n (this as any)[method] = (this as any)[method].bind(this);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Set primary key fields for the service\r\n */\r\n setPrimaryKeyFields(fields: string[]): this {\r\n logger.debug(\"Setting primary key fields\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n previousFields: this.primaryKeyFields,\r\n newFields: fields\r\n });\r\n\r\n this.primaryKeyFields = fields;\r\n return this;\r\n }\r\n\r\n /**\r\n * Initialize the service and establish database connection\r\n */\r\n async init(): Promise<this> {\r\n logger.info(\"Initializing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n try {\r\n if (this.isInitialized) {\r\n logger.debug(\"Service already initialized, skipping\", {\r\n schemaName: this.schemaName\r\n });\r\n return this;\r\n }\r\n\r\n logger.debug(\"Getting DAO from DatabaseManager\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n this.dao = await DatabaseManager.getLazyLoading(this.schemaName);\r\n\r\n if (!this.dao) {\r\n const errorMsg = `Failed to initialize DAO for schema: ${this.schemaName}`;\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n if (!this.dao.isConnectionOpen()) {\r\n logger.debug(\"DAO connection not open, connecting\", {\r\n schemaName: this.schemaName\r\n });\r\n await this.dao.connect();\r\n }\r\n\r\n this.isOpened = true;\r\n this.isInitialized = true;\r\n \r\n logger.info(\"BaseService initialized successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n this._emit(\"initialized\", { schemaName: this.schemaName });\r\n\r\n return this;\r\n } catch (error) {\r\n logger.error(\"Error initializing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"INIT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new record - Safe version với comprehensive error handling\r\n */\r\n async create(data: Partial<T>): Promise<T | null> {\r\n logger.debug(\"Creating new record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n hasData: !!data,\r\n dataKeys: data ? Object.keys(data) : []\r\n });\r\n\r\n await this._ensureInitialized();\r\n await this.ensureValidConnection();\r\n \r\n try {\r\n this._validateData(data);\r\n \r\n logger.trace(\"Building data table for insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const queryTable = this.buildDataTable(data as Record<string, any>);\r\n const result = await this.dao!.insert(queryTable);\r\n \r\n if (result.rowsAffected === 0) {\r\n const errorMsg = \"Insert operation failed - no rows affected\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n result\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Insert operation successful\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowId: result.lastInsertRowId\r\n });\r\n\r\n let createdRecord: T | null = null;\r\n const primaryKeyValue = data[this.primaryKeyFields[0] as keyof T];\r\n \r\n try {\r\n if (primaryKeyValue !== undefined && primaryKeyValue !== null) {\r\n logger.trace(\"Retrieving created record by primary key\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n primaryKeyField: this.primaryKeyFields[0],\r\n primaryKeyValue\r\n });\r\n createdRecord = await this.findById(primaryKeyValue as any);\r\n } else if (result.lastInsertRowId) {\r\n logger.trace(\"Retrieving created record by last insert ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n lastInsertRowId: result.lastInsertRowId\r\n });\r\n createdRecord = await this.findById(result.lastInsertRowId);\r\n }\r\n } catch (findError) {\r\n logger.warn(\"Could not retrieve created record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n findError: (findError as Error).message\r\n });\r\n }\r\n\r\n if (!createdRecord) {\r\n logger.debug(\"Using original data as created record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n createdRecord = data as T;\r\n }\r\n\r\n logger.info(\"Record created successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordRetrieved: !!createdRecord\r\n });\r\n\r\n this._emit(\"dataCreated\", { operation: \"create\", data: createdRecord });\r\n return createdRecord;\r\n } catch (error) {\r\n logger.error(\"Error creating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"CREATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Update an existing record\r\n */\r\n async update(id: any, data: Partial<T>): Promise<T | null> {\r\n logger.debug(\"Updating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n hasData: !!data,\r\n dataKeys: data ? Object.keys(data) : []\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required for update\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n this._validateData(data);\r\n \r\n const updateData = {\r\n ...data,\r\n [this.primaryKeyFields[0]]: id,\r\n };\r\n\r\n logger.trace(\"Building update query table\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const queryTable = this.buildDataTable(updateData as Record<string, any>);\r\n await this.dao!.update(queryTable);\r\n\r\n logger.debug(\"Update operation completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const result = await this.findById(id);\r\n \r\n logger.info(\"Record updated successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n recordFound: !!result\r\n });\r\n\r\n this._emit(\"dataUpdated\", { operation: \"update\", id, data: result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error updating record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"UPDATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Delete a record by ID\r\n */\r\n async delete(id: any): Promise<boolean> {\r\n logger.debug(\"Deleting record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required for delete\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [],\r\n wheres: [{ name: this.primaryKeyFields[0], value: id }],\r\n };\r\n\r\n logger.trace(\"Executing delete operation\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n primaryKeyField: this.primaryKeyFields[0]\r\n });\r\n\r\n const result = await this.dao!.delete(queryTable);\r\n const success = result.rowsAffected > 0;\r\n\r\n if (success) {\r\n logger.info(\"Record deleted successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n rowsAffected: result.rowsAffected\r\n });\r\n this._emit(\"dataDeleted\", { operation: \"delete\", id });\r\n } else {\r\n logger.warn(\"Delete operation completed but no rows affected\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n }\r\n\r\n return success;\r\n } catch (error) {\r\n logger.error(\"Error deleting record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"DELETE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find a record by ID\r\n */\r\n async findById(id: any): Promise<T | null> {\r\n logger.debug(\"Finding record by ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!id) {\r\n const errorMsg = \"ID is required\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const conditions = { [this.primaryKeyFields[0]]: id };\r\n \r\n logger.trace(\"Building select query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions\r\n });\r\n\r\n const queryTable = this.buildSelectTable(conditions);\r\n const result = await this.dao!.select(queryTable);\r\n\r\n const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n \r\n logger.debug(\"Find by ID completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n recordFound: !!record\r\n });\r\n\r\n this._emit(\"dataFetched\", { operation: \"findById\", id });\r\n return record;\r\n } catch (error) {\r\n logger.error(\"Error finding record by ID\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_BY_ID_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find the first record matching conditions\r\n */\r\n async findFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n logger.debug(\"Finding first record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n conditions\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.trace(\"Building select query for findFirst\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n const queryTable = this.buildSelectTable(conditions);\r\n const result = await this.dao!.select(queryTable);\r\n\r\n const record = Object.keys(result).length > 0 ? (result as T) : null;\r\n \r\n logger.debug(\"Find first completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordFound: !!record\r\n });\r\n\r\n this._emit(\"dataFetched\", { operation: \"findFirst\" });\r\n return record;\r\n } catch (error) {\r\n logger.error(\"Error finding first record\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_FIRST_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Find all records matching conditions\r\n */\r\n async findAll(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): Promise<T[]> {\r\n logger.debug(\"Finding all records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n hasLimit: !!options.limit,\r\n hasOffset: !!options.offset,\r\n hasOrderBy: !!(options.orderBy && options.orderBy.length > 0),\r\n limit: options.limit,\r\n offset: options.offset\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n // Build where clauses from conditions\r\n const whereFromConditions = this.buildWhereFromObject(conditions);\r\n const allWheres = [...whereFromConditions, ...(options.where || [])];\r\n\r\n logger.trace(\"Building query for findAll\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalWheres: allWheres.length,\r\n hasColumns: !!(options.columns && options.columns.length > 0)\r\n });\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: options.columns ? options.columns.map((name) => ({ name })) : [],\r\n wheres: allWheres,\r\n orderbys: options.orderBy,\r\n limitOffset: {\r\n limit: options.limit,\r\n offset: options.offset,\r\n },\r\n };\r\n\r\n const results = await this.dao!.selectAll(queryTable);\r\n \r\n logger.info(\"Find all completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordsFound: results.length,\r\n conditionsCount: Object.keys(conditions).length\r\n });\r\n\r\n this._emit(\"dataFetched\", {\r\n operation: \"findAll\",\r\n count: results.length,\r\n });\r\n return results as T[];\r\n } catch (error) {\r\n logger.error(\"Error finding all records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditions,\r\n options,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"FIND_ALL_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Count records matching conditions\r\n */\r\n async count(where?: WhereClause[] | Record<string, any>): Promise<number> {\r\n logger.debug(\"Counting records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n hasWhere: !!where,\r\n whereType: where ? (Array.isArray(where) ? 'array' : 'object') : 'none'\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n let whereConditions: WhereClause[] = [];\r\n\r\n if (Array.isArray(where)) {\r\n whereConditions = where;\r\n logger.trace(\"Using array where conditions\", {\r\n schemaName: this.schemaName,\r\n whereCount: whereConditions.length\r\n });\r\n } else if (where && typeof where === \"object\") {\r\n whereConditions = this.buildWhereFromObject(where);\r\n logger.trace(\"Built where conditions from object\", {\r\n schemaName: this.schemaName,\r\n whereCount: whereConditions.length\r\n });\r\n }\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [{ name: \"COUNT(*) as count\" }],\r\n wheres: whereConditions,\r\n };\r\n\r\n const result = await this.dao!.select(queryTable);\r\n const count = result.count || 0;\r\n \r\n logger.debug(\"Count completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n count\r\n });\r\n\r\n return count;\r\n } catch (error) {\r\n logger.error(\"Error counting records\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n where,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"COUNT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a record exists by ID\r\n */\r\n async exists(id: any): Promise<boolean> {\r\n logger.debug(\"Checking if record exists\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n\r\n const item = await this.findById(id);\r\n const exists = item !== null;\r\n \r\n logger.debug(\"Existence check completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id,\r\n exists\r\n });\r\n\r\n return exists;\r\n }\r\n\r\n /**\r\n * Truncate table (delete all records and reset auto-increment)\r\n */\r\n async truncate(): Promise<void> {\r\n logger.warn(\"Truncating table - this will delete all data\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.debug(\"Executing truncate operations\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this.dao!.execute(`DELETE FROM ${this.tableName}`);\r\n await this.dao!.execute(\r\n `DELETE FROM sqlite_sequence WHERE name='${this.tableName}'`\r\n );\r\n \r\n logger.info(\"Table truncated successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"tableTruncated\", { tableName: this.tableName });\r\n } catch (error) {\r\n logger.error(\"Error truncating table\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"TRUNCATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk insert records\r\n */\r\n async bulkInsert(items: Partial<T>[]): Promise<ImportResult> {\r\n logger.info(\"Starting bulk insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!Array.isArray(items) || items.length === 0) {\r\n const errorMsg = \"Items must be a non-empty array\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsType: typeof items,\r\n itemsLength: Array.isArray(items) ? items.length : 'N/A'\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n logger.debug(\"Executing bulk insert operation\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length\r\n });\r\n\r\n const result = await this.dao!.importData({\r\n tableName: this.tableName,\r\n data: items as Record<string, any>[],\r\n batchSize: 1000,\r\n skipErrors: false,\r\n validateData: true,\r\n });\r\n\r\n logger.info(\"Bulk insert completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataBulkCreated\", {\r\n operation: \"bulkInsert\",\r\n count: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during bulk insert\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: items.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"BULK_INSERT_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Bulk create records with transaction support\r\n */\r\n async bulkCreate(dataArray: Record<string, any>[]): Promise<T[]> {\r\n logger.info(\"Starting bulk create with transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n if (!Array.isArray(dataArray) || dataArray.length === 0) {\r\n const errorMsg = \"Data must be a non-empty array\";\r\n logger.error(errorMsg, {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataType: typeof dataArray,\r\n dataLength: Array.isArray(dataArray) ? dataArray.length : 'N/A'\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n\r\n const results: T[] = [];\r\n \r\n logger.debug(\"Executing bulk create in transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length\r\n });\r\n\r\n await this.executeTransaction(async () => {\r\n for (let i = 0; i < dataArray.length; i++) {\r\n const data = dataArray[i];\r\n \r\n if (i % 100 === 0) {\r\n logger.trace(\"Bulk create progress\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n processed: i,\r\n total: dataArray.length\r\n });\r\n }\r\n\r\n this._validateData(data);\r\n const queryTable = this.buildDataTable(data);\r\n await this.dao!.insert(queryTable);\r\n results.push(data as T);\r\n }\r\n });\r\n\r\n logger.info(\"Bulk create completed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordsCreated: results.length\r\n });\r\n\r\n this._emit(\"dataBulkCreated\", {\r\n operation: \"bulkCreate\",\r\n count: results.length,\r\n });\r\n return results;\r\n } catch (error) {\r\n logger.error(\"Error during bulk create\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n itemsCount: dataArray.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"BULK_CREATE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute operations within a transaction\r\n */\r\n async executeTransaction(callback: () => Promise<any>): Promise<any> {\r\n logger.debug(\"Starting transaction\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n logger.trace(\"Beginning database transaction\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n await this.dao!.beginTransaction();\r\n const result = await callback();\r\n \r\n logger.trace(\"Committing transaction\", {\r\n schemaName: this.schemaName\r\n });\r\n\r\n await this.dao!.commitTransaction();\r\n \r\n logger.info(\"Transaction completed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"transactionCompleted\", { operation: \"transaction\" });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Transaction failed, rolling back\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n try {\r\n await this.dao!.rollbackTransaction();\r\n logger.debug(\"Transaction rollback successful\", {\r\n schemaName: this.schemaName\r\n });\r\n } catch (rollbackError) {\r\n logger.error(\"Error during transaction rollback\", {\r\n schemaName: this.schemaName,\r\n rollbackError: (rollbackError as Error).message\r\n });\r\n this._handleError(\"ROLLBACK_ERROR\", rollbackError as Error);\r\n }\r\n \r\n this._handleError(\"TRANSACTION_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data from CSV\r\n */\r\n async importFromCSV(\r\n csvData: string,\r\n options: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.info(\"Starting CSV import\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n csvDataLength: csvData.length,\r\n delimiter: options.delimiter,\r\n hasHeader: options.hasHeader,\r\n hasMappings: !!(options.columnMappings && options.columnMappings.length > 0)\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n const result = await this.dao!.importFromCSV(\r\n this.tableName,\r\n csvData,\r\n options\r\n );\r\n\r\n logger.info(\"CSV import completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataImported\", { operation: \"importFromCSV\", result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during CSV import\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n csvDataLength: csvData.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"IMPORT_CSV_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n async importDataWithMapping(\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options: Partial<ImportOptions> = {}\r\n ): Promise<ImportResult> {\r\n logger.info(\"Starting import with column mapping\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataCount: data.length,\r\n mappingsCount: columnMappings.length\r\n });\r\n\r\n await this._ensureInitialized();\r\n\r\n try {\r\n const result = await this.dao!.importDataWithMapping(\r\n this.tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n\r\n logger.info(\"Import with mapping completed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n totalRows: result.totalRows,\r\n successRows: result.successRows,\r\n errorRows: result.errorRows\r\n });\r\n\r\n this._emit(\"dataImported\", { operation: \"importWithMapping\", result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error during import with mapping\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataCount: data.length,\r\n mappingsCount: columnMappings.length,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"IMPORT_MAPPING_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n // Utility methods\r\n protected buildSelectTable(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): QueryTable {\r\n logger.trace(\"Building select table query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n conditionsCount: Object.keys(conditions).length,\r\n hasOptions: Object.keys(options).length > 0\r\n });\r\n\r\n const queryTable: QueryTable = {\r\n name: this.tableName,\r\n cols: [],\r\n wheres: [],\r\n orderbys: options.orderBy || [],\r\n limitOffset: {},\r\n };\r\n\r\n if (options.columns && options.columns.length > 0) {\r\n queryTable.cols = options.columns.map((name) => ({ name }));\r\n }\r\n\r\n if (conditions && Object.keys(conditions).length > 0) {\r\n queryTable.wheres = Object.entries(conditions).map(([key, value]) => ({\r\n name: key,\r\n value,\r\n operator: \"=\",\r\n }));\r\n }\r\n\r\n if (options.limit !== undefined) {\r\n queryTable.limitOffset!.limit = options.limit;\r\n }\r\n if (options.offset !== undefined) {\r\n queryTable.limitOffset!.offset = options.offset;\r\n }\r\n\r\n return queryTable;\r\n }\r\n\r\n protected buildDataTable(data: Record<string, any>): QueryTable {\r\n logger.trace(\"Building data table for query\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataKeys: Object.keys(data)\r\n });\r\n\r\n return this.dao!.convertJsonToQueryTable(\r\n this.tableName,\r\n data,\r\n this.primaryKeyFields\r\n );\r\n }\r\n\r\n protected buildWhereFromObject(obj: Record<string, any>): WhereClause[] {\r\n const wheres = Object.entries(obj)\r\n .filter(([_, value]) => value !== undefined)\r\n .map(([key, value]) => ({ name: key, value }));\r\n\r\n logger.trace(\"Built where clauses from object\", {\r\n schemaName: this.schemaName,\r\n originalKeys: Object.keys(obj).length,\r\n filteredWheres: wheres.length\r\n });\r\n\r\n return wheres;\r\n }\r\n\r\n // Event system\r\n on(event: string, handler: EventHandler): this {\r\n logger.trace(\"Adding event listener\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event\r\n });\r\n\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, []);\r\n }\r\n this.eventListeners.get(event)!.push(handler);\r\n return this;\r\n }\r\n\r\n off(event: string, handler: EventHandler): this {\r\n logger.trace(\"Removing event listener\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event\r\n });\r\n\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n protected _emit(event: string, data: any): void {\r\n logger.trace(\"Emitting event\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event,\r\n hasData: !!data\r\n });\r\n\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(data);\r\n } catch (error) {\r\n logger.error(\"Error in event handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n event,\r\n error: (error as Error).message\r\n });\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Error handling\r\n setErrorHandler(errorType: string, handler: ErrorHandler): this {\r\n logger.debug(\"Setting error handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType\r\n });\r\n\r\n this.errorHandlers.set(errorType, handler);\r\n return this;\r\n }\r\n\r\n protected _handleError(errorType: string, error: Error): void {\r\n logger.error(\"Handling service error\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType,\r\n error: error.message\r\n });\r\n\r\n const handler = this.errorHandlers.get(errorType);\r\n if (handler) {\r\n try {\r\n handler(error);\r\n } catch (handlerError) {\r\n logger.error(\"Error in error handler\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n errorType,\r\n handlerError: (handlerError as Error).message\r\n });\r\n }\r\n }\r\n this._emit(\"error\", { errorType, error });\r\n }\r\n\r\n protected _validateData(data: any): void {\r\n if (!data || typeof data !== \"object\") {\r\n const errorMsg = \"Data must be a valid object\";\r\n logger.error(\"Data validation failed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n dataType: typeof data,\r\n isNull: data === null\r\n });\r\n throw new Error(errorMsg);\r\n }\r\n }\r\n\r\n protected async _ensureInitialized(): Promise<void> {\r\n if (!this.isInitialized) {\r\n logger.debug(\"Service not initialized, initializing now\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n await this.init();\r\n }\r\n }\r\n\r\n private async ensureValidConnection(): Promise<void> {\r\n logger.trace(\"Ensuring valid database connection\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n try {\r\n const isConnected = this.dao?.isConnectionOpen();\r\n if (!isConnected) {\r\n logger.debug(\"Connection not valid, getting new connection\", {\r\n schemaName: this.schemaName\r\n });\r\n this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n this.schemaName\r\n );\r\n }\r\n } catch (error) {\r\n logger.warn(\"Error checking connection, getting new connection\", {\r\n schemaName: this.schemaName,\r\n error: (error as Error).message\r\n });\r\n this.dao = await DatabaseManager.ensureDatabaseConnection(\r\n this.schemaName\r\n );\r\n }\r\n }\r\n\r\n // Information and status methods\r\n async getDatabaseInfo(): Promise<any> {\r\n logger.trace(\"Getting database info\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n return await this.dao!.getDatabaseInfo();\r\n }\r\n\r\n async getTableInfo(): Promise<any[]> {\r\n logger.trace(\"Getting table info\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n await this._ensureInitialized();\r\n return await this.dao!.getTableInfo(this.tableName);\r\n }\r\n\r\n getStatus(): ServiceStatus {\r\n const status = {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized,\r\n hasDao: !!this.dao,\r\n };\r\n\r\n logger.trace(\"Getting service status\", status);\r\n return status;\r\n }\r\n\r\n async healthCheck(): Promise<HealthCheckResult> {\r\n logger.debug(\"Performing health check\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n try {\r\n await this._ensureInitialized();\r\n const count = await this.count();\r\n \r\n const result = {\r\n healthy: true,\r\n schemaName: this.schemaName,\r\n recordCount: count,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n logger.info(\"Health check passed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n recordCount: count\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n const result = {\r\n healthy: false,\r\n schemaName: this.schemaName,\r\n error: (error as Error).message,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n logger.error(\"Health check failed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n return result;\r\n }\r\n }\r\n\r\n // Lifecycle management\r\n async close(): Promise<boolean> {\r\n logger.info(\"Closing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n isOpened: this.isOpened,\r\n isInitialized: this.isInitialized\r\n });\r\n\r\n try {\r\n if (this.dao) {\r\n await this.dao.close();\r\n logger.debug(\"DAO closed successfully\", {\r\n schemaName: this.schemaName\r\n });\r\n }\r\n\r\n this.isOpened = false;\r\n this.isInitialized = false;\r\n this.eventListeners.clear();\r\n this.errorHandlers.clear();\r\n this.cache.clear();\r\n\r\n logger.info(\"BaseService closed successfully\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n this._emit(\"closed\", { schemaName: this.schemaName });\r\n return true;\r\n } catch (error) {\r\n logger.error(\"Error closing BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n error: (error as Error).message\r\n });\r\n\r\n this._handleError(\"CLOSE_ERROR\", error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n public destroy(): void {\r\n logger.debug(\"Destroying BaseService\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n\r\n // Remove reconnect listener\r\n DatabaseManager.offDatabaseReconnect(\r\n this.schemaName,\r\n this.reconnectHandler\r\n );\r\n\r\n // Clear all resources\r\n this.eventListeners.clear();\r\n this.errorHandlers.clear();\r\n this.cache.clear();\r\n\r\n logger.trace(\"BaseService destroyed\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n }\r\n\r\n // Alias methods for backward compatibility\r\n async getAll(\r\n conditions: Record<string, any> = {},\r\n options: FindOptions = {}\r\n ): Promise<T[]> {\r\n logger.trace(\"Using getAll alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n return this.findAll(conditions, options);\r\n }\r\n\r\n async getById(id: string | number): Promise<T | null> {\r\n logger.trace(\"Using getById alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName,\r\n id\r\n });\r\n return this.findById(id);\r\n }\r\n\r\n async getFirst(conditions: Record<string, any> = {}): Promise<T | null> {\r\n logger.trace(\"Using getFirst alias\", {\r\n schemaName: this.schemaName,\r\n tableName: this.tableName\r\n });\r\n return this.findFirst(conditions);\r\n }\r\n}","// src/query/query-builder.ts\r\nimport { UniversalDAO } from '../core/universal-dao';\r\nimport { SQLiteResult, SQLiteRow } from '../types';\r\n\r\nexport interface QueryCondition {\r\n field: string;\r\n operator: string;\r\n value: any;\r\n}\r\n\r\nexport interface JoinClause {\r\n type: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL OUTER';\r\n table: string;\r\n condition: string;\r\n}\r\n\r\nexport interface SubQuery {\r\n query: QueryBuilder;\r\n alias: string;\r\n}\r\n\r\n/**\r\n * Enhanced QueryBuilder with advanced SQL query construction capabilities\r\n */\r\nexport class QueryBuilder {\r\n private tableName = '';\r\n private selectFields: string[] = ['*'];\r\n private joinClauses: JoinClause[] = [];\r\n private whereConditions: QueryCondition[] = [];\r\n private groupByFields: string[] = [];\r\n private havingConditions: QueryCondition[] = [];\r\n private orderByFields: string[] = [];\r\n private limitValue: number | null = null;\r\n private offsetValue: number | null = null;\r\n private params: any[] = [];\r\n private unionQueries: QueryBuilder[] = [];\r\n private subQueries: SubQuery[] = [];\r\n private cteQueries: Map<string, QueryBuilder> = new Map();\r\n private dao: UniversalDAO | null = null;\r\n\r\n constructor(dao?: UniversalDAO) {\r\n this.dao = dao || null;\r\n }\r\n\r\n static table(name: string, dao?: UniversalDAO): QueryBuilder {\r\n const builder = new QueryBuilder(dao);\r\n builder.tableName = name;\r\n return builder;\r\n }\r\n\r\n static from(name: string, dao?: UniversalDAO): QueryBuilder {\r\n return QueryBuilder.table(name, dao);\r\n }\r\n\r\n // SELECT operations\r\n select(fields: string | string[]): QueryBuilder {\r\n this.selectFields = Array.isArray(fields) ? fields : [fields];\r\n return this;\r\n }\r\n\r\n selectRaw(raw: string): QueryBuilder {\r\n this.selectFields = [raw];\r\n return this;\r\n }\r\n\r\n selectDistinct(fields: string | string[]): QueryBuilder {\r\n const fieldList = Array.isArray(fields) ? fields.join(', ') : fields;\r\n this.selectFields = [`DISTINCT ${fieldList}`];\r\n return this;\r\n }\r\n\r\n // JOIN operations\r\n join(table: string, condition: string, type: JoinClause['type'] = 'INNER'): QueryBuilder {\r\n this.joinClauses.push({ type, table, condition });\r\n return this;\r\n }\r\n\r\n innerJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'INNER');\r\n }\r\n\r\n leftJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'LEFT');\r\n }\r\n\r\n rightJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'RIGHT');\r\n }\r\n\r\n fullOuterJoin(table: string, condition: string): QueryBuilder {\r\n return this.join(table, condition, 'FULL OUTER');\r\n }\r\n\r\n // WHERE conditions\r\n where(field: string, operator: string, value?: any): QueryBuilder;\r\n where(field: string, value: any): QueryBuilder;\r\n where(conditions: Record<string, any>): QueryBuilder;\r\n where(fieldOrConditions: string | Record<string, any>, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n if (typeof fieldOrConditions === 'object') {\r\n // Handle object of conditions\r\n Object.entries(fieldOrConditions).forEach(([field, val]) => {\r\n this.whereConditions.push({ field, operator: '=', value: val });\r\n });\r\n return this;\r\n }\r\n\r\n let operator = '=';\r\n let actualValue = operatorOrValue;\r\n\r\n if (arguments.length === 3) {\r\n operator = operatorOrValue;\r\n actualValue = value;\r\n }\r\n\r\n this.whereConditions.push({ \r\n field: fieldOrConditions, \r\n operator, \r\n value: actualValue \r\n });\r\n \r\n return this;\r\n }\r\n\r\n whereEquals(field: string, value: any): QueryBuilder {\r\n return this.where(field, '=', value);\r\n }\r\n\r\n whereNot(field: string, value: any): QueryBuilder {\r\n return this.where(field, '!=', value);\r\n }\r\n\r\n whereLike(field: string, value: string): QueryBuilder {\r\n return this.where(field, 'LIKE', value);\r\n }\r\n\r\n whereNotLike(field: string, value: string): QueryBuilder {\r\n return this.where(field, 'NOT LIKE', value);\r\n }\r\n\r\n whereIn(field: string, values: any[]): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IN', value: values });\r\n return this;\r\n }\r\n\r\n whereNotIn(field: string, values: any[]): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'NOT IN', value: values });\r\n return this;\r\n }\r\n\r\n whereBetween(field: string, min: any, max: any): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'BETWEEN', value: [min, max] });\r\n return this;\r\n }\r\n\r\n whereNotBetween(field: string, min: any, max: any): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'NOT BETWEEN', value: [min, max] });\r\n return this;\r\n }\r\n\r\n whereNull(field: string): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IS NULL', value: null });\r\n return this;\r\n }\r\n\r\n whereNotNull(field: string): QueryBuilder {\r\n this.whereConditions.push({ field, operator: 'IS NOT NULL', value: null });\r\n return this;\r\n }\r\n\r\n whereExists(subquery: QueryBuilder): QueryBuilder {\r\n this.whereConditions.push({ \r\n field: '', \r\n operator: 'EXISTS', \r\n value: subquery \r\n });\r\n return this;\r\n }\r\n\r\n whereNotExists(subquery: QueryBuilder): QueryBuilder {\r\n this.whereConditions.push({ \r\n field: '', \r\n operator: 'NOT EXISTS', \r\n value: subquery \r\n });\r\n return this;\r\n }\r\n\r\n // OR WHERE conditions\r\n orWhere(field: string, operator: string, value?: any): QueryBuilder;\r\n orWhere(field: string, value: any): QueryBuilder;\r\n orWhere(field: string, operatorOrValue?: string | any, value?: any): QueryBuilder {\r\n // Implementation similar to where() but with OR logic\r\n // This would require refactoring the condition structure to support AND/OR\r\n return this.where(field, operatorOrValue as string, value);\r\n }\r\n\r\n // GROUP BY and HAVING\r\n groupBy(fields: string | string[]): QueryBuilder {\r\n this.groupByFields = Array.isArray(fields) ? fields : [fields];\r\n return this;\r\n }\r\n\r\n having(field: string, operator: string, value?: any): QueryBuilder {\r\n let actualOperator = '=';\r\n let actualValue = operator;\r\n\r\n if (arguments.length === 3) {\r\n actualOperator = operator;\r\n actualValue = value;\r\n }\r\n\r\n this.havingConditions.push({ \r\n field, \r\n operator: actualOperator, \r\n value: actualValue \r\n });\r\n return this;\r\n }\r\n\r\n havingCount(field: string, operator: string, value: number): QueryBuilder {\r\n return this.having(`COUNT(${field})`, operator, value);\r\n }\r\n\r\n // ORDER BY\r\n orderBy(field: string, direction: 'ASC' | 'DESC' = 'ASC'): QueryBuilder {\r\n this.orderByFields.push(`${field} ${direction}`);\r\n return this;\r\n }\r\n\r\n orderByDesc(field: string): QueryBuilder {\r\n return this.orderBy(field, 'DESC');\r\n }\r\n\r\n orderByRaw(raw: string): QueryBuilder {\r\n this.orderByFields.push(raw);\r\n return this;\r\n }\r\n\r\n latest(field: string = 'created_at'): QueryBuilder {\r\n return this.orderByDesc(field);\r\n }\r\n\r\n oldest(field: string = 'created_at'): QueryBuilder {\r\n return this.orderBy(field, 'ASC');\r\n }\r\n\r\n // LIMIT and OFFSET\r\n limit(count: number): QueryBuilder {\r\n this.limitValue = count;\r\n return this;\r\n }\r\n\r\n offset(count: number): QueryBuilder {\r\n this.offsetValue = count;\r\n return this;\r\n }\r\n\r\n skip(count: number): QueryBuilder {\r\n return this.offset(count);\r\n }\r\n\r\n take(count: number): QueryBuilder {\r\n return this.limit(count);\r\n }\r\n\r\n firstRow(): QueryBuilder {\r\n return this.limit(1);\r\n }\r\n\r\n paginate(page: number, perPage: number): QueryBuilder {\r\n this.limitValue = perPage;\r\n this.offsetValue = (page - 1) * perPage;\r\n return this;\r\n }\r\n\r\n // UNION operations\r\n union(query: QueryBuilder): QueryBuilder {\r\n this.unionQueries.push(query);\r\n return this;\r\n }\r\n\r\n unionAll(query: QueryBuilder): QueryBuilder {\r\n // Note: SQLite doesn't differentiate UNION and UNION ALL like other databases\r\n return this.union(query);\r\n }\r\n\r\n // CTE (Common Table Expressions)\r\n with(alias: string, query: QueryBuilder): QueryBuilder {\r\n this.cteQueries.set(alias, query);\r\n return this;\r\n }\r\n\r\n // Subqueries\r\n whereSubQuery(field: string, operator: string, subquery: QueryBuilder): QueryBuilder {\r\n this.subQueries.push({ query: subquery, alias: '' });\r\n this.whereConditions.push({ field, operator, value: subquery });\r\n return this;\r\n }\r\n\r\n // Aggregation functions\r\n count(field: string = '*'): QueryBuilder {\r\n this.selectFields = [`COUNT(${field}) as count`];\r\n return this;\r\n }\r\n\r\n sum(field: string): QueryBuilder {\r\n this.selectFields = [`SUM(${field}) as sum`];\r\n return this;\r\n }\r\n\r\n avg(field: string): QueryBuilder {\r\n this.selectFields = [`AVG(${field}) as avg`];\r\n return this;\r\n }\r\n\r\n max(field: string): QueryBuilder {\r\n this.selectFields = [`MAX(${field}) as max`];\r\n return this;\r\n }\r\n\r\n min(field: string): QueryBuilder {\r\n this.selectFields = [`MIN(${field}) as min`];\r\n return this;\r\n }\r\n\r\n // SQL Generation\r\n toSQL(): { sql: string; params: any[] } {\r\n let sql = '';\r\n const params: any[] = [];\r\n\r\n // CTE queries\r\n if (this.cteQueries.size > 0) {\r\n const cteList: string[] = [];\r\n this.cteQueries.forEach((query, alias) => {\r\n const { sql: cteSql, params: cteParams } = query.toSQL();\r\n cteList.push(`${alias} AS (${cteSql})`);\r\n params.push(...cteParams);\r\n });\r\n sql += `WITH ${cteList.join(', ')} `;\r\n }\r\n\r\n // Main SELECT\r\n sql += `SELECT ${this.selectFields.join(', ')} FROM ${this.tableName}`;\r\n\r\n // JOINs\r\n if (this.joinClauses.length > 0) {\r\n this.joinClauses.forEach(join => {\r\n sql += ` ${join.type} JOIN ${join.table} ON ${join.condition}`;\r\n });\r\n }\r\n\r\n // WHERE conditions\r\n if (this.whereConditions.length > 0) {\r\n const conditions: string[] = [];\r\n this.whereConditions.forEach(condition => {\r\n const { clause, conditionParams } = this.buildCondition(condition);\r\n conditions.push(clause);\r\n params.push(...conditionParams);\r\n });\r\n sql += ` WHERE ${conditions.join(' AND ')}`;\r\n }\r\n\r\n // GROUP BY\r\n if (this.groupByFields.length > 0) {\r\n sql += ` GROUP BY ${this.groupByFields.join(', ')}`;\r\n }\r\n\r\n // HAVING\r\n if (this.havingConditions.length > 0) {\r\n const conditions: string[] = [];\r\n this.havingConditions.forEach(condition => {\r\n const { clause, conditionParams } = this.buildCondition(condition);\r\n conditions.push(clause);\r\n params.push(...conditionParams);\r\n });\r\n sql += ` HAVING ${conditions.join(' AND ')}`;\r\n }\r\n\r\n // ORDER BY\r\n if (this.orderByFields.length > 0) {\r\n sql += ` ORDER BY ${this.orderByFields.join(', ')}`;\r\n }\r\n\r\n // LIMIT\r\n if (this.limitValue !== null) {\r\n sql += ` LIMIT ${this.limitValue}`;\r\n }\r\n\r\n // OFFSET\r\n if (this.offsetValue !== null) {\r\n sql += ` OFFSET ${this.offsetValue}`;\r\n }\r\n\r\n // UNION queries\r\n if (this.unionQueries.length > 0) {\r\n this.unionQueries.forEach(unionQuery => {\r\n const { sql: unionSql, params: unionParams } = unionQuery.toSQL();\r\n sql += ` UNION ${unionSql}`;\r\n params.push(...unionParams);\r\n });\r\n }\r\n\r\n return { sql, params };\r\n }\r\n\r\n private buildCondition(condition: QueryCondition): { clause: string; conditionParams: any[] } {\r\n const { field, operator, value } = condition;\r\n const params: any[] = [];\r\n\r\n switch (operator.toUpperCase()) {\r\n case 'IN':\r\n case 'NOT IN':\r\n const placeholders = (value as any[]).map(() => '?').join(', ');\r\n params.push(...(value as any[]));\r\n return { \r\n clause: `${field} ${operator} (${placeholders})`, \r\n conditionParams: params \r\n };\r\n\r\n case 'BETWEEN':\r\n case 'NOT BETWEEN':\r\n params.push(value[0], value[1]);\r\n return { \r\n clause: `${field} ${operator} ? AND ?`, \r\n conditionParams: params \r\n };\r\n\r\n case 'IS NULL':\r\n case 'IS NOT NULL':\r\n return { \r\n clause: `${field} ${operator}`, \r\n conditionParams: [] \r\n };\r\n\r\n case 'EXISTS':\r\n case 'NOT EXISTS':\r\n const { sql: subSql, params: subParams } = (value as QueryBuilder).toSQL();\r\n params.push(...subParams);\r\n return { \r\n clause: `${operator} (${subSql})`, \r\n conditionParams: params \r\n };\r\n\r\n default:\r\n if (value instanceof QueryBuilder) {\r\n const { sql: subSql, params: subParams } = value.toSQL();\r\n params.push(...subParams);\r\n return { \r\n clause: `${field} ${operator} (${subSql})`, \r\n conditionParams: params \r\n };\r\n }\r\n params.push(value);\r\n return { \r\n clause: `${field} ${operator} ?`, \r\n conditionParams: params \r\n };\r\n }\r\n }\r\n\r\n // Execution methods (require DAO)\r\n async get(): Promise<SQLiteRow[]> {\r\n if (!this.dao) {\r\n throw new Error('DAO instance required for query execution');\r\n }\r\n const { sql, params } = this.toSQL();\r\n const result = await this.dao.execute(sql, params);\r\n return result.rows;\r\n }\r\n\r\n async first(): Promise<SQLiteRow | null> {\r\n this.limit(1);\r\n const results = await this.get(); // This will apply the limit(1) set by firstRow()\r\n return results.length > 0 ? results[0] : null;\r\n }\r\n\r\n async pluck(column: string): Promise<any[]> {\r\n this.select(column);\r\n const results = await this.get();\r\n return results.map(row => row[column]);\r\n }\r\n\r\n async exists(): Promise<boolean> {\r\n this.select('1').limit(1);\r\n const results = await this.get();\r\n return results.length > 0;\r\n }\r\n\r\n async countResult(): Promise<number> {\r\n this.count();\r\n const result = await this.first();\r\n return result ? result.count : 0;\r\n }\r\n\r\n // Static helper methods for DML operations\r\n static insert(tableName: string, data: Record<string, any>): { sql: string; params: any[] } {\r\n const fields = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = values.map(() => '?').join(', ');\r\n\r\n return {\r\n sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`,\r\n params: values\r\n };\r\n }\r\n\r\n static insertMany(tableName: string, dataArray: Record<string, any>[]): { sql: string; params: any[] } {\r\n if (dataArray.length === 0) {\r\n throw new Error('Data array cannot be empty');\r\n }\r\n\r\n const fields = Object.keys(dataArray[0]);\r\n const placeholders = fields.map(() => '?').join(', ');\r\n const valueGroups = dataArray.map(() => `(${placeholders})`).join(', ');\r\n\r\n const allValues = dataArray.flatMap(data => Object.values(data));\r\n\r\n return {\r\n sql: `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES ${valueGroups}`,\r\n params: allValues\r\n };\r\n }\r\n\r\n static update(tableName: string, data: Record<string, any>, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n const sets = Object.keys(data).map(key => `${key} = ?`).join(', ');\r\n const params = [...Object.values(data), ...whereParams];\r\n\r\n return {\r\n sql: `UPDATE ${tableName} SET ${sets} WHERE ${where}`,\r\n params\r\n };\r\n }\r\n\r\n static delete(tableName: string, where: string, whereParams: any[] = []): { sql: string; params: any[] } {\r\n return {\r\n sql: `DELETE FROM ${tableName} WHERE ${where}`,\r\n params: whereParams\r\n };\r\n }\r\n\r\n static upsert(tableName: string, data: Record<string, any>, conflictColumns: string[]): { sql: string; params: any[] } {\r\n const fields = Object.keys(data);\r\n const values = Object.values(data);\r\n const placeholders = values.map(() => '?').join(', ');\r\n\r\n const updateColumns = fields.filter(field => !conflictColumns.includes(field));\r\n const updateClause = updateColumns.length > 0\r\n ? updateColumns.map(col => `${col} = excluded.${col}`).join(', ')\r\n : '';\r\n\r\n let sql = `INSERT INTO ${tableName} (${fields.join(', ')}) VALUES (${placeholders})`;\r\n\r\n if (updateColumns.length > 0) {\r\n sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO UPDATE SET ${updateClause}`;\r\n } else {\r\n sql += ` ON CONFLICT(${conflictColumns.join(', ')}) DO NOTHING`;\r\n }\r\n\r\n return { sql, params: values };\r\n }\r\n\r\n // Utility methods\r\n clone(): QueryBuilder {\r\n if (!this.dao) throw new Error('DAO instance required for cloning QueryBuilder');\r\n const cloned = new QueryBuilder(this.dao);\r\n cloned.tableName = this.tableName;\r\n cloned.selectFields = [...this.selectFields];\r\n cloned.joinClauses = [...this.joinClauses];\r\n cloned.whereConditions = [...this.whereConditions];\r\n cloned.groupByFields = [...this.groupByFields];\r\n cloned.havingConditions = [...this.havingConditions];\r\n cloned.orderByFields = [...this.orderByFields];\r\n cloned.limitValue = this.limitValue;\r\n cloned.offsetValue = this.offsetValue;\r\n cloned.unionQueries = [...this.unionQueries];\r\n cloned.subQueries = [...this.subQueries];\r\n cloned.cteQueries = new Map(this.cteQueries);\r\n return cloned;\r\n }\r\n\r\n toRawSQL(): string {\r\n const { sql, params } = this.toSQL();\r\n let rawSql = sql;\r\n params.forEach(param => {\r\n if (typeof param === 'string') {\r\n rawSql = rawSql.replace('?', `'${param.replace(/'/g, \"''\")}'`);\r\n } else if (param === null || param === undefined) {\r\n rawSql = rawSql.replace('?', 'NULL');\r\n } else {\r\n rawSql = rawSql.replace('?', String(param));\r\n }\r\n });\r\n return rawSql;\r\n }\r\n\r\n explain(): QueryBuilder {\r\n this.selectFields = ['EXPLAIN QUERY PLAN ' + this.selectFields.join(', ')];\r\n return this;\r\n }\r\n}","// src/core/service-manager.ts\r\nimport { BaseService } from \"./base-service\";\r\nimport { ServiceStatus, HealthCheckResult } from \"../types\";\r\n\r\nimport { createModuleLogger, SQLiteModules } from \"../logger/logger-config\";\r\n\r\nconst logger = createModuleLogger(SQLiteModules.SERVICE_MANAGER);\r\n\r\n// Concrete service class mặc định\r\nexport class DefaultService extends BaseService {\r\n // BaseService đã cung cấp đầy đủ functionality\r\n}\r\n\r\n// Interface cho cấu hình service\r\nexport interface ServiceConfig {\r\n schemaName: string;\r\n tableName: string;\r\n primaryKeyFields?: string[];\r\n serviceClass?: new (schemaName: string, tableName: string) => BaseService;\r\n}\r\n\r\n// Interface cho trạng thái service\r\nexport interface ServiceInfo {\r\n key: string;\r\n schemaName: string;\r\n tableName: string;\r\n status: ServiceStatus;\r\n isRegistered: boolean;\r\n createdAt: string;\r\n lastAccessed?: string;\r\n}\r\n\r\n// Interface cho báo cáo sức khỏe\r\nexport interface HealthReport {\r\n totalServices: number;\r\n healthyServices: number;\r\n unhealthyServices: number;\r\n services: Array<HealthCheckResult & { serviceKey: string }>;\r\n timestamp: string;\r\n overallHealth: boolean;\r\n}\r\n\r\n// Event types cho ServiceManager\r\nexport interface ServiceManagerEvent {\r\n type:\r\n | \"SERVICE_CREATED\"\r\n | \"SERVICE_DESTROYED\"\r\n | \"SERVICE_ERROR\"\r\n | \"HEALTH_CHECK_COMPLETED\";\r\n serviceKey: string;\r\n schemaName: string;\r\n tableName: string;\r\n timestamp: string;\r\n data?: any;\r\n error?: Error;\r\n}\r\n\r\nexport type ServiceManagerEventHandler = (event: ServiceManagerEvent) => void;\r\n\r\n/**\r\n * ServiceManager - Quản lý vòng đời các service con kế thừa từ BaseService\r\n * Không can thiệp vào DatabaseManager, chỉ tập trung quản lý service instances\r\n */\r\nexport class ServiceManager {\r\n private static instance: ServiceManager | null = null;\r\n\r\n // Service registry\r\n private services: Map<string, BaseService> = new Map();\r\n private serviceConfigs: Map<string, ServiceConfig> = new Map();\r\n private serviceMetadata: Map<\r\n string,\r\n { createdAt: string; lastAccessed?: string }\r\n > = new Map();\r\n\r\n // Event system\r\n private eventHandlers: Map<string, ServiceManagerEventHandler[]> = new Map();\r\n\r\n // Lifecycle management\r\n private isShuttingDown = false;\r\n private cleanupInterval: NodeJS.Timeout | null = null;\r\n\r\n private constructor() {\r\n logger.info(\"ServiceManager instance created\");\r\n this.bindMethods();\r\n this.startPeriodicCleanup();\r\n }\r\n\r\n /**\r\n * Singleton instance\r\n */\r\n public static getInstance(): ServiceManager {\r\n if (!ServiceManager.instance) {\r\n logger.debug(\"Creating new ServiceManager singleton instance\");\r\n ServiceManager.instance = new ServiceManager();\r\n } else {\r\n logger.trace(\"Returning existing ServiceManager singleton instance\");\r\n }\r\n return ServiceManager.instance;\r\n }\r\n\r\n /**\r\n * Reset singleton (chủ yếu cho testing)\r\n */\r\n public static resetInstance(): void {\r\n logger.warn(\"Resetting ServiceManager singleton instance\");\r\n if (ServiceManager.instance) {\r\n ServiceManager.instance.destroy();\r\n ServiceManager.instance = null;\r\n logger.info(\"ServiceManager singleton instance reset successfully\");\r\n } else {\r\n logger.debug(\"No ServiceManager instance to reset\");\r\n }\r\n }\r\n\r\n private bindMethods(): void {\r\n logger.trace(\"Binding ServiceManager methods\");\r\n const methods = Object.getOwnPropertyNames(Object.getPrototypeOf(this));\r\n methods.forEach((method) => {\r\n if (\r\n typeof (this as any)[method] === \"function\" &&\r\n method !== \"constructor\"\r\n ) {\r\n (this as any)[method] = (this as any)[method].bind(this);\r\n }\r\n });\r\n logger.trace(\"ServiceManager methods bound successfully\", {\r\n methodCount: methods.length,\r\n });\r\n }\r\n\r\n /**\r\n * Tạo service key duy nhất\r\n */\r\n private createServiceKey(schemaName: string, tableName: string): string {\r\n const key = `${schemaName}:${tableName}`;\r\n logger.trace(\"Created service key\", { schemaName, tableName, key });\r\n return key;\r\n }\r\n\r\n /**\r\n * Validate service config\r\n */\r\n private validateServiceConfig(config: ServiceConfig): void {\r\n logger.trace(\"Validating service config\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n\r\n if (!config.schemaName?.trim()) {\r\n logger.error(\"Invalid service config: schema name missing\", { config });\r\n throw new Error(\"Schema name is required and cannot be empty\");\r\n }\r\n if (!config.tableName?.trim()) {\r\n logger.error(\"Invalid service config: table name missing\", { config });\r\n throw new Error(\"Table name is required and cannot be empty\");\r\n }\r\n\r\n logger.trace(\"Service config validation passed\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n }\r\n\r\n /**\r\n * Đăng ký cấu hình service\r\n */\r\n public registerService(config: ServiceConfig): this {\r\n logger.debug(\"Registering service\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n primaryKeyFields: config.primaryKeyFields,\r\n hasCustomServiceClass: !!config.serviceClass,\r\n });\r\n\r\n this.validateServiceConfig(config);\r\n\r\n const serviceKey = this.createServiceKey(\r\n config.schemaName,\r\n config.tableName\r\n );\r\n\r\n // Normalize config\r\n const normalizedConfig: ServiceConfig = {\r\n schemaName: config.schemaName.trim(),\r\n tableName: config.tableName.trim(),\r\n primaryKeyFields: config.primaryKeyFields || [\"id\"],\r\n serviceClass: config.serviceClass || DefaultService,\r\n };\r\n\r\n const wasAlreadyRegistered = this.serviceConfigs.has(serviceKey);\r\n this.serviceConfigs.set(serviceKey, normalizedConfig);\r\n\r\n if (wasAlreadyRegistered) {\r\n logger.info(\"Service configuration updated\", { serviceKey });\r\n } else {\r\n logger.info(\"Service registered successfully\", { serviceKey });\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Đăng ký nhiều services\r\n */\r\n public registerServices(configs: ServiceConfig[]): this {\r\n logger.debug(\"Registering multiple services\", { count: configs.length });\r\n\r\n configs.forEach((config, index) => {\r\n try {\r\n this.registerService(config);\r\n } catch (error) {\r\n logger.error(\"Failed to register service in batch\", {\r\n index,\r\n config,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n });\r\n\r\n logger.info(\"Multiple services registered successfully\", {\r\n count: configs.length,\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Tạo service instance từ config\r\n */\r\n private async createServiceInstance(\r\n config: ServiceConfig\r\n ): Promise<BaseService> {\r\n logger.debug(\"Creating service instance\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n serviceClassName: config.serviceClass?.name || \"DefaultService\",\r\n });\r\n\r\n const ServiceClass = config.serviceClass || DefaultService;\r\n const service = new ServiceClass(config.schemaName, config.tableName);\r\n\r\n if (config.primaryKeyFields) {\r\n logger.trace(\"Setting primary key fields\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n primaryKeyFields: config.primaryKeyFields,\r\n });\r\n service.setPrimaryKeyFields(config.primaryKeyFields);\r\n }\r\n\r\n logger.info(\"Service instance created successfully\", {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n });\r\n\r\n return service;\r\n }\r\n\r\n /**\r\n * Lấy service (tự động tạo nếu chưa tồn tại)\r\n */\r\n public async getService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<BaseService> {\r\n if (this.isShuttingDown) {\r\n logger.error(\"ServiceManager is shutting down, cannot get service\", {\r\n schemaName,\r\n tableName,\r\n });\r\n throw new Error(\"ServiceManager is shutting down\");\r\n }\r\n\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Getting service\", { serviceKey });\r\n\r\n // Update access time\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n if (metadata) {\r\n metadata.lastAccessed = new Date().toISOString();\r\n logger.trace(\"Updated service access time\", { serviceKey });\r\n }\r\n\r\n // Return existing service\r\n if (this.services.has(serviceKey)) {\r\n logger.trace(\"Returning existing service\", { serviceKey });\r\n return this.services.get(serviceKey)!;\r\n }\r\n\r\n // Get or create default config\r\n let config = this.serviceConfigs.get(serviceKey);\r\n if (!config) {\r\n logger.debug(\"Creating default config for unregistered service\", {\r\n serviceKey,\r\n });\r\n config = {\r\n schemaName,\r\n tableName,\r\n primaryKeyFields: [\"id\"],\r\n serviceClass: DefaultService,\r\n };\r\n this.serviceConfigs.set(serviceKey, config);\r\n }\r\n\r\n try {\r\n const service = await this.createServiceInstance(config);\r\n this.services.set(serviceKey, service);\r\n\r\n // Track metadata\r\n this.serviceMetadata.set(serviceKey, {\r\n createdAt: new Date().toISOString(),\r\n lastAccessed: new Date().toISOString(),\r\n });\r\n\r\n this.emit(\"SERVICE_CREATED\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n });\r\n\r\n logger.info(\"Service created and cached successfully\", { serviceKey });\r\n return service;\r\n } catch (error) {\r\n logger.error(\"Failed to create service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n\r\n this.emit(\"SERVICE_ERROR\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n error: error as Error,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Lấy service đã tồn tại (không tự động tạo)\r\n */\r\n public getExistingService(\r\n schemaName: string,\r\n tableName: string\r\n ): BaseService | null {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.trace(\"Getting existing service\", { serviceKey });\r\n\r\n const service = this.services.get(serviceKey) || null;\r\n if (service) {\r\n logger.trace(\"Existing service found\", { serviceKey });\r\n } else {\r\n logger.trace(\"Existing service not found\", { serviceKey });\r\n }\r\n\r\n return service;\r\n }\r\n\r\n /**\r\n * Khởi tạo service\r\n */\r\n public async initializeService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<BaseService> {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Initializing service\", { serviceKey });\r\n\r\n try {\r\n const service = await this.getService(schemaName, tableName);\r\n await service.init();\r\n logger.info(\"Service initialized successfully\", { serviceKey });\r\n return service;\r\n } catch (error) {\r\n logger.error(\"Failed to initialize service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Hủy service instance\r\n */\r\n public async destroyService(\r\n schemaName: string,\r\n tableName: string\r\n ): Promise<boolean> {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n logger.debug(\"Destroying service\", { serviceKey });\r\n\r\n const service = this.services.get(serviceKey);\r\n\r\n if (!service) {\r\n logger.warn(\"Service not found for destruction\", { serviceKey });\r\n return false;\r\n }\r\n\r\n try {\r\n await service.close();\r\n service.destroy();\r\n\r\n this.services.delete(serviceKey);\r\n this.serviceMetadata.delete(serviceKey);\r\n\r\n this.emit(\"SERVICE_DESTROYED\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n });\r\n\r\n logger.info(\"Service destroyed successfully\", { serviceKey });\r\n return true;\r\n } catch (error) {\r\n logger.error(\"Failed to destroy service\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n\r\n this.emit(\"SERVICE_ERROR\", {\r\n serviceKey,\r\n schemaName,\r\n tableName,\r\n error: error as Error,\r\n });\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Lấy danh sách services theo schema\r\n */\r\n public getServicesBySchema(schemaName: string): BaseService[] {\r\n logger.trace(\"Getting services by schema\", { schemaName });\r\n\r\n const services: BaseService[] = [];\r\n\r\n for (const [serviceKey, service] of this.services) {\r\n const [keySchema] = serviceKey.split(\":\");\r\n if (keySchema === schemaName) {\r\n services.push(service);\r\n }\r\n }\r\n\r\n logger.debug(\"Found services for schema\", {\r\n schemaName,\r\n count: services.length,\r\n });\r\n return services;\r\n }\r\n\r\n /**\r\n * Lấy danh sách service keys theo schema\r\n */\r\n public getServiceKeysBySchema(schemaName: string): string[] {\r\n logger.trace(\"Getting service keys by schema\", { schemaName });\r\n\r\n const keys: string[] = [];\r\n\r\n for (const serviceKey of this.services.keys()) {\r\n const [keySchema] = serviceKey.split(\":\");\r\n if (keySchema === schemaName) {\r\n keys.push(serviceKey);\r\n }\r\n }\r\n\r\n logger.debug(\"Found service keys for schema\", { schemaName, keys });\r\n return keys;\r\n }\r\n\r\n /**\r\n * Hủy tất cả services trong một schema\r\n */\r\n public async destroyServicesBySchema(schemaName: string): Promise<void> {\r\n const serviceKeys = this.getServiceKeysBySchema(schemaName);\r\n logger.debug(\"Destroying services by schema\", { schemaName, serviceKeys });\r\n\r\n if (serviceKeys.length === 0) {\r\n logger.debug(\"No services found to destroy for schema\", { schemaName });\r\n return;\r\n }\r\n\r\n const destroyPromises = serviceKeys.map(async (serviceKey) => {\r\n const [, tableName] = serviceKey.split(\":\");\r\n try {\r\n const result = await this.destroyService(schemaName, tableName);\r\n logger.trace(\"Service destroy result\", { serviceKey, result });\r\n return result;\r\n } catch (error) {\r\n logger.error(\"Error destroying service in schema cleanup\", {\r\n serviceKey,\r\n error: (error as Error).message,\r\n });\r\n return false;\r\n }\r\n });\r\n\r\n const results = await Promise.all(destroyPromises);\r\n const successCount = results.filter(Boolean).length;\r\n\r\n logger.info(\"Schema services destruction completed\", {\r\n schemaName,\r\n totalServices: serviceKeys.length,\r\n successfulDestroys: successCount,\r\n });\r\n }\r\n\r\n /**\r\n * Lấy thông tin tất cả services\r\n */\r\n public getAllServiceInfo(): ServiceInfo[] {\r\n logger.trace(\"Getting all service info\");\r\n\r\n const infos: ServiceInfo[] = [];\r\n\r\n // Registered services\r\n for (const [serviceKey, config] of this.serviceConfigs) {\r\n const service = this.services.get(serviceKey);\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n infos.push({\r\n key: serviceKey,\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n status: service\r\n ? service.getStatus()\r\n : {\r\n schemaName: config.schemaName,\r\n tableName: config.tableName,\r\n isOpened: false,\r\n isInitialized: false,\r\n hasDao: false,\r\n },\r\n isRegistered: true,\r\n createdAt: metadata?.createdAt || \"N/A\",\r\n lastAccessed: metadata?.lastAccessed,\r\n });\r\n }\r\n\r\n // Unregistered services (created on-the-fly)\r\n for (const [serviceKey, service] of this.services) {\r\n if (!this.serviceConfigs.has(serviceKey)) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n const metadata = this.serviceMetadata.get(serviceKey);\r\n\r\n infos.push({\r\n key: serviceKey,\r\n schemaName,\r\n tableName,\r\n status: service.getStatus(),\r\n isRegistered: false,\r\n createdAt: metadata?.createdAt || \"N/A\",\r\n lastAccessed: metadata?.lastAccessed,\r\n });\r\n }\r\n }\r\n\r\n return infos;\r\n }\r\n\r\n /**\r\n * Kiểm tra sức khỏe tất cả services\r\n */\r\n public async healthCheck(): Promise<HealthReport> {\r\n const services = Array.from(this.services.entries());\r\n const healthPromises = services.map(async ([serviceKey, service]) => {\r\n try {\r\n const health = await service.healthCheck();\r\n return { ...health, serviceKey };\r\n } catch (error) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n return {\r\n healthy: false,\r\n schemaName,\r\n error: (error as Error).message,\r\n timestamp: new Date().toISOString(),\r\n serviceKey,\r\n };\r\n }\r\n });\r\n\r\n const results = await Promise.all(healthPromises);\r\n const healthyCount = results.filter((r) => r.healthy).length;\r\n\r\n const report: HealthReport = {\r\n totalServices: results.length,\r\n healthyServices: healthyCount,\r\n unhealthyServices: results.length - healthyCount,\r\n services: results,\r\n timestamp: new Date().toISOString(),\r\n overallHealth: healthyCount === results.length,\r\n };\r\n\r\n this.emit(\"HEALTH_CHECK_COMPLETED\", {\r\n serviceKey: \"*\",\r\n schemaName: \"*\",\r\n tableName: \"*\",\r\n data: report,\r\n });\r\n\r\n return report;\r\n }\r\n\r\n /**\r\n * Thực hiện transaction trên nhiều services trong cùng schema\r\n * (Vì SQLite transaction chỉ hoạt động trong cùng database connection)\r\n */\r\n public async executeSchemaTransaction<T>(\r\n schemaName: string,\r\n callback: (services: BaseService[]) => Promise<T>\r\n ): Promise<T> {\r\n logger.trace(`Executing schema transaction for schema ${schemaName}`);\r\n const services = this.getServicesBySchema(schemaName);\r\n\r\n if (services.length === 0) {\r\n logger.error(\"No services found for schema\", { schemaName });\r\n throw new Error(`No services found for schema: ${schemaName}`);\r\n }\r\n\r\n // Ensure all services are initialized\r\n for (const service of services) {\r\n await service.init();\r\n }\r\n\r\n // Execute transaction on the first service (they share the same database)\r\n const primaryService = services[0];\r\n\r\n return await primaryService.executeTransaction(async () => {\r\n return await callback(services);\r\n });\r\n }\r\n\r\n /**\r\n * Periodic cleanup for unused services\r\n */\r\n private startPeriodicCleanup(): void {\r\n // Cleanup every 5 minutes\r\n this.cleanupInterval = setInterval(() => {\r\n this.cleanupUnusedServices();\r\n }, 5 * 60 * 1000);\r\n }\r\n\r\n /**\r\n * Cleanup services not accessed for a long time\r\n */\r\n private async cleanupUnusedServices(\r\n maxIdleTime: number = 30 * 60 * 1000\r\n ): Promise<void> {\r\n if (this.isShuttingDown) {\r\n return;\r\n }\r\n\r\n const now = Date.now();\r\n const servicesToDestroy: string[] = [];\r\n\r\n for (const [serviceKey, metadata] of this.serviceMetadata) {\r\n if (!metadata.lastAccessed) {\r\n continue;\r\n }\r\n\r\n const lastAccessTime = new Date(metadata.lastAccessed).getTime();\r\n if (now - lastAccessTime > maxIdleTime) {\r\n servicesToDestroy.push(serviceKey);\r\n }\r\n }\r\n\r\n for (const serviceKey of servicesToDestroy) {\r\n const [schemaName, tableName] = serviceKey.split(\":\");\r\n await this.destroyService(schemaName, tableName);\r\n }\r\n }\r\n\r\n /**\r\n * Event system\r\n */\r\n public on(eventType: string, handler: ServiceManagerEventHandler): this {\r\n if (!this.eventHandlers.has(eventType)) {\r\n this.eventHandlers.set(eventType, []);\r\n }\r\n this.eventHandlers.get(eventType)!.push(handler);\r\n return this;\r\n }\r\n\r\n public off(eventType: string, handler: ServiceManagerEventHandler): this {\r\n const handlers = this.eventHandlers.get(eventType);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n private emit(\r\n type: ServiceManagerEvent[\"type\"],\r\n data: Omit<ServiceManagerEvent, \"type\" | \"timestamp\">\r\n ): void {\r\n const event: ServiceManagerEvent = {\r\n ...data,\r\n type,\r\n timestamp: new Date().toISOString(),\r\n };\r\n\r\n // Emit to specific event handlers\r\n const handlers = this.eventHandlers.get(type);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(event);\r\n } catch (error) {\r\n console.error(\r\n `ServiceManager: Error in ${type} event handler:`,\r\n error\r\n );\r\n }\r\n });\r\n }\r\n\r\n // Emit to global event handlers\r\n const globalHandlers = this.eventHandlers.get(\"*\");\r\n if (globalHandlers) {\r\n globalHandlers.forEach((handler) => {\r\n try {\r\n handler(event);\r\n } catch (error) {\r\n console.error(\r\n \"ServiceManager: Error in global event handler:\",\r\n error\r\n );\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Utility methods\r\n */\r\n public hasService(schemaName: string, tableName: string): boolean {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n return this.services.has(serviceKey);\r\n }\r\n\r\n public isRegistered(schemaName: string, tableName: string): boolean {\r\n const serviceKey = this.createServiceKey(schemaName, tableName);\r\n return this.serviceConfigs.has(serviceKey);\r\n }\r\n\r\n public getServiceCount(): number {\r\n return this.services.size;\r\n }\r\n\r\n public getRegisteredCount(): number {\r\n return this.serviceConfigs.size;\r\n }\r\n\r\n public getSchemas(): string[] {\r\n const schemas = new Set<string>();\r\n\r\n for (const serviceKey of this.services.keys()) {\r\n const [schemaName] = serviceKey.split(\":\");\r\n schemas.add(schemaName);\r\n }\r\n\r\n return Array.from(schemas);\r\n }\r\n\r\n /**\r\n * Destroy all services and cleanup resources\r\n */\r\n public async destroy(): Promise<void> {\r\n this.isShuttingDown = true;\r\n\r\n // Clear cleanup interval\r\n if (this.cleanupInterval) {\r\n clearInterval(this.cleanupInterval);\r\n this.cleanupInterval = null;\r\n }\r\n\r\n // Destroy all services\r\n const destroyPromises = Array.from(this.services.entries()).map(\r\n async ([serviceKey, service]) => {\r\n try {\r\n await service.close();\r\n service.destroy();\r\n } catch (error) {\r\n console.error(`Error destroying service ${serviceKey}:`, error);\r\n }\r\n }\r\n );\r\n\r\n await Promise.all(destroyPromises);\r\n\r\n // Clear all data\r\n this.services.clear();\r\n this.serviceConfigs.clear();\r\n this.serviceMetadata.clear();\r\n this.eventHandlers.clear();\r\n\r\n this.isShuttingDown = false;\r\n }\r\n}\r\n\r\n// Export singleton instance\r\nexport const serviceManager = ServiceManager.getInstance();\r\n","// src/adapters/base-adapter.ts\r\nimport { SQLiteAdapter, SQLiteConnection } from '../types';\r\nexport abstract class BaseAdapter implements SQLiteAdapter {\r\n abstract connect(path: string): Promise<SQLiteConnection>;\r\n abstract isSupported(): boolean;\r\n\r\n protected sanitizeSQL(sql: string): string {\r\n return sql.trim();\r\n }\r\n\r\n protected bindParameters(sql: string, params?: any[]): string {\r\n if (!params || params.length === 0) {\r\n return sql;\r\n }\r\n\r\n let paramIndex = 0;\r\n return sql.replace(/\\?/g, () => {\r\n if (paramIndex < params.length) {\r\n const param = params[paramIndex++];\r\n if (typeof param === 'string') {\r\n return `'${param.replace(/'/g, \"''\")}'`;\r\n }\r\n if (param === null || param === undefined) {\r\n return 'NULL';\r\n }\r\n return String(param);\r\n }\r\n return '?';\r\n });\r\n }\r\n}","// src/index.ts - Main exports for UniversalSQLite Library with Logger Integration\r\nimport { DatabaseManager } from \"./core/database-manager\";\r\nimport { UniversalDAO } from \"./core/universal-dao\";\r\nimport { BaseService } from \"./core/base-service\";\r\nimport { DatabaseFactory } from \"./core/database-factory\";\r\nimport { QueryBuilder } from \"./query/query-builder\";\r\nimport {\r\n SQLiteAdapter,\r\n SQLiteResult,\r\n SQLiteRow,\r\n DatabaseSchema,\r\n DbFactoryOptions,\r\n ImportOptions,\r\n ImportResult,\r\n ColumnMapping,\r\n} from \"./types\";\r\n\r\n// ========================== LOGGER EXPORTS ==========================\r\nexport {\r\n SQLiteLoggerConfig,\r\n SQLiteModules,\r\n sqliteLogger,\r\n createModuleLogger,\r\n} from \"./logger/logger-config\";\r\n\r\n// ========================== CORE EXPORTS ==========================\r\nexport { UniversalDAO } from \"./core/universal-dao\";\r\nexport { DatabaseFactory } from \"./core/database-factory\";\r\nexport { DatabaseManager } from \"./core/database-manager\";\r\nexport { BaseService } from \"./core/base-service\";\r\nexport {\r\n ServiceManager,\r\n DefaultService,\r\n type ServiceConfig,\r\n type ServiceInfo,\r\n type HealthReport,\r\n type ServiceManagerEvent,\r\n type ServiceManagerEventHandler,\r\n} from \"./core/service-manager\";\r\n\r\n// ========================== QUERY & UTILITIES ==========================\r\nexport { QueryBuilder } from \"./query/query-builder\";\r\n\r\n// ========================== ADAPTERS ==========================\r\nexport { BaseAdapter } from \"./adapters/base-adapter\";\r\n\r\n// ========================== TYPE EXPORTS ==========================\r\nexport * from \"./types\";\r\n\r\n// Import logger configuration for internal use\r\nimport {\r\n SQLiteLoggerConfig,\r\n createModuleLogger,\r\n SQLiteModules,\r\n} from \"./logger/logger-config\";\r\n\r\n// ========================== UNIFIED INTERFACE ==========================\r\n\r\n/**\r\n * UniversalSQLite - The main unified interface providing a comprehensive\r\n * SQLite database management solution for all environments and platforms.\r\n *\r\n * Features:\r\n * - Cross-platform support (Browser, Node.js, Deno, Bun, React Native)\r\n * - Schema-based database management\r\n * - Role-based access control\r\n * - Advanced query building\r\n * - Data import/export capabilities\r\n * - Migration system\r\n * - Transaction management\r\n * - Connection pooling and lifecycle management\r\n * - Integrated logging and debugging\r\n */\r\nexport class UniversalSQLite {\r\n private static instance: UniversalSQLite | null = null;\r\n private currentSchema: string | null = null;\r\n private isInitialized: boolean = false;\r\n private initializationPromise: Promise<void> | null = null;\r\n private eventListeners: Map<string, Array<(...args: any[]) => void>> =\r\n new Map();\r\n\r\n // Module-specific logger\r\n private logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n\r\n constructor() {\r\n // Private constructor for singleton pattern\r\n if (UniversalSQLite.instance) {\r\n throw new Error(\r\n \"UniversalSQLite is a singleton. Use UniversalSQLite.getInstance() instead.\"\r\n );\r\n }\r\n this.logger.debug(\"UniversalSQLite instance created\");\r\n }\r\n\r\n /**\r\n * Get singleton instance of UniversalSQLite\r\n */\r\n static getInstance(): UniversalSQLite {\r\n if (!UniversalSQLite.instance) {\r\n UniversalSQLite.instance = new UniversalSQLite();\r\n }\r\n return UniversalSQLite.instance;\r\n }\r\n\r\n /**\r\n * Reset singleton instance (useful for testing)\r\n */\r\n static resetInstance(): void {\r\n if (UniversalSQLite.instance) {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Resetting UniversalSQLite instance\");\r\n UniversalSQLite.instance.closeAll().catch(() => {});\r\n }\r\n UniversalSQLite.instance = null;\r\n }\r\n\r\n // ========================== LOGGER CONFIGURATION METHODS ==========================\r\n\r\n /**\r\n * Configure logger for the entire library\r\n * @param config - Logger configuration object\r\n */\r\n static configureLogger(config: any): void {\r\n SQLiteLoggerConfig.updateConfiguration(config);\r\n }\r\n\r\n /**\r\n * Enable debug logging for development\r\n */\r\n static enableDebugLogging(): void {\r\n const debugConfig = SQLiteLoggerConfig.createDebugConfig();\r\n SQLiteLoggerConfig.updateConfiguration(debugConfig);\r\n }\r\n\r\n /**\r\n * Set production logging (errors and warnings only)\r\n */\r\n static setProductionLogging(): void {\r\n const prodConfig = SQLiteLoggerConfig.createProductionConfig();\r\n SQLiteLoggerConfig.updateConfiguration(prodConfig);\r\n }\r\n\r\n /**\r\n * Enable logging globally\r\n */\r\n static enableLogging(): void {\r\n SQLiteLoggerConfig.setEnabled(true);\r\n }\r\n\r\n /**\r\n * Disable logging globally\r\n */\r\n static disableLogging(): void {\r\n SQLiteLoggerConfig.setEnabled(false);\r\n }\r\n\r\n /**\r\n * Enable specific module logging\r\n */\r\n static enableModuleLogging(\r\n moduleName: string,\r\n levels?: string[],\r\n appenders?: string[]\r\n ): void {\r\n SQLiteLoggerConfig.enableModule(moduleName, levels, appenders);\r\n }\r\n\r\n /**\r\n * Disable specific module logging\r\n */\r\n static disableModuleLogging(moduleName: string): void {\r\n SQLiteLoggerConfig.disableModule(moduleName);\r\n }\r\n\r\n // ========================== INITIALIZATION METHODS ==========================\r\n\r\n /**\r\n * Initialize UniversalSQLite with schema configurations\r\n * @param schemas - Database schema configurations\r\n * @param options - Additional initialization options\r\n */\r\n async initialize(\r\n schemas: Record<string, DatabaseSchema>,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnectCore?: boolean;\r\n defaultRoles?: string[];\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any; // Logger configuration\r\n } = {}\r\n ): Promise<void> {\r\n this.logger.debug(\"Starting initialization\", {\r\n schemas: Object.keys(schemas),\r\n options,\r\n });\r\n\r\n if (this.isInitialized) {\r\n this.logger.debug(\"Already initialized, returning existing promise\");\r\n return this.initializationPromise || Promise.resolve();\r\n }\r\n\r\n if (this.initializationPromise) {\r\n this.logger.debug(\"Initialization in progress, waiting...\");\r\n return this.initializationPromise;\r\n }\r\n\r\n this.initializationPromise = this._performInitialization(schemas, options);\r\n return this.initializationPromise;\r\n }\r\n\r\n private async _performInitialization(\r\n schemas: Record<string, DatabaseSchema>,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnectCore?: boolean;\r\n defaultRoles?: string[];\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any;\r\n }\r\n ): Promise<void> {\r\n try {\r\n this.logger.info(\"Performing initialization\", {\r\n schemaCount: Object.keys(schemas).length,\r\n });\r\n\r\n // Configure logger if provided\r\n if (options.loggerConfig) {\r\n this.logger.debug(\"Configuring custom logger\");\r\n SQLiteLoggerConfig.updateConfiguration(options.loggerConfig);\r\n }\r\n\r\n // Register adapters if provided\r\n if (options.registerAdapters) {\r\n this.logger.debug(\"Registering adapters\", {\r\n count: options.registerAdapters.length,\r\n });\r\n options.registerAdapters.forEach((adapter) => {\r\n DatabaseFactory.registerAdapter(adapter);\r\n });\r\n }\r\n\r\n // Register global error handler\r\n if (options.globalErrorHandler) {\r\n this.logger.debug(\"Registering global error handler\");\r\n this.on(\"error\", options.globalErrorHandler);\r\n }\r\n\r\n // Register all schemas with DatabaseManager\r\n this.logger.debug(\"Registering schemas with DatabaseManager\");\r\n DatabaseManager.registerSchemas(schemas);\r\n\r\n // Initialize core connection if core schema exists and autoConnectCore is true\r\n if (schemas.core && options.autoConnectCore !== false) {\r\n this.logger.debug(\"Initializing core connection\");\r\n await DatabaseManager.initializeCoreConnection();\r\n }\r\n\r\n // Set default roles if provided\r\n if (options.defaultRoles && options.defaultRoles.length > 0) {\r\n this.logger.debug(\"Setting default roles\", {\r\n roles: options.defaultRoles,\r\n });\r\n await DatabaseManager.setCurrentUserRoles(options.defaultRoles);\r\n }\r\n\r\n this.isInitialized = true;\r\n this.logger.info(\"Initialization completed successfully\");\r\n this._emit(\"initialized\", { schemas: Object.keys(schemas) });\r\n } catch (error) {\r\n this.isInitialized = false;\r\n this.initializationPromise = null;\r\n this.logger.error(\"Initialization failed\", error);\r\n this._emit(\"error\", error as Error, \"initialization\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Initialize from a single schema configuration\r\n */\r\n async initializeFromSchema(\r\n schema: DatabaseSchema,\r\n options: {\r\n registerAdapters?: SQLiteAdapter[];\r\n autoConnect?: boolean;\r\n globalErrorHandler?: (error: Error, context: string) => void;\r\n loggerConfig?: any;\r\n } = {}\r\n ): Promise<void> {\r\n this.logger.debug(\"Initializing from single schema\", {\r\n schemaName: schema.database_name,\r\n });\r\n const schemas = { [schema.database_name]: schema };\r\n return this.initialize(schemas, {\r\n ...options,\r\n autoConnectCore: options.autoConnect !== false,\r\n });\r\n }\r\n\r\n // ========================== CONNECTION MANAGEMENT ==========================\r\n\r\n /**\r\n * Connect to a specific database schema\r\n * @param schemaName - Name of the schema to connect to\r\n * @returns Promise resolving to UniversalDAO instance\r\n */\r\n async connect(schemaName: string): Promise<UniversalDAO> {\r\n this.logger.debug(\"Connecting to schema\", { schemaName });\r\n this.ensureInitialized();\r\n this.currentSchema = schemaName;\r\n\r\n try {\r\n const dao = await DatabaseManager.getLazyLoading(schemaName);\r\n this.logger.info(\"Successfully connected to schema\", { schemaName });\r\n this._emit(\"connected\", { schemaName });\r\n return dao;\r\n } catch (error) {\r\n this.logger.error(\"Failed to connect to schema\", { schemaName, error });\r\n this._emit(\"error\", error as Error, \"connection\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get DAO for a specific schema\r\n * @param schemaName - Optional schema name (uses current if not provided)\r\n */\r\n getDAO(schemaName?: string): UniversalDAO {\r\n this.ensureInitialized();\r\n const schema = schemaName || this.currentSchema;\r\n\r\n if (!schema) {\r\n const error = new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n this.logger.error(\"getDAO failed: No schema specified\");\r\n throw error;\r\n }\r\n\r\n try {\r\n this.logger.trace(\"Getting DAO for schema\", { schema });\r\n return DatabaseManager.get(schema);\r\n } catch (error) {\r\n this.logger.error(\"Failed to get DAO\", { schema, error });\r\n this._emit(\"error\", error as Error, \"getDAO\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current connected DAO\r\n */\r\n getCurrentDAO(): UniversalDAO {\r\n if (!this.currentSchema) {\r\n const error = new Error(\"No current connection. Call connect() first.\");\r\n this.logger.error(\"getCurrentDAO failed: No current connection\");\r\n throw error;\r\n }\r\n return this.getDAO(this.currentSchema);\r\n }\r\n\r\n /**\r\n * Ensure database connection exists and is active\r\n */\r\n async ensureDatabaseConnection(schemaName: string): Promise<UniversalDAO> {\r\n this.logger.debug(\"Ensuring database connection\", { schemaName });\r\n this.ensureInitialized();\r\n\r\n try {\r\n const dao = await DatabaseManager.ensureDatabaseConnection(schemaName);\r\n this.logger.debug(\"Database connection ensured\", { schemaName });\r\n return dao;\r\n } catch (error) {\r\n this.logger.error(\"Failed to ensure database connection\", {\r\n schemaName,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"ensureConnection\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== SERVICE CREATION ==========================\r\n\r\n /**\r\n * Create a service for a specific table\r\n * @param tableName - Name of the table\r\n * @param schemaName - Optional schema name (uses current if not provided)\r\n */\r\n createService<T = any>(\r\n tableName: string,\r\n schemaName?: string\r\n ): BaseService<T> {\r\n const schema = schemaName || this.currentSchema;\r\n if (!schema) {\r\n const error = new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n this.logger.error(\"createService failed: No schema specified\", {\r\n tableName,\r\n });\r\n throw error;\r\n }\r\n\r\n this.logger.debug(\"Creating service\", { tableName, schema });\r\n\r\n const ServiceClass = class extends BaseService<T> {\r\n constructor() {\r\n if (!schema) {\r\n throw new Error(\r\n \"No schema specified. Use connect() first or provide schemaName parameter.\"\r\n );\r\n }\r\n super(schema, tableName);\r\n }\r\n };\r\n\r\n return new ServiceClass();\r\n }\r\n\r\n /**\r\n * Create multiple services at once\r\n */\r\n createServices<T = any>(\r\n tableNames: string[],\r\n schemaName?: string\r\n ): Record<string, BaseService<T>> {\r\n this.logger.debug(\"Creating multiple services\", { tableNames, schemaName });\r\n const services: Record<string, BaseService<T>> = {};\r\n\r\n tableNames.forEach((tableName) => {\r\n services[tableName] = this.createService<T>(tableName, schemaName);\r\n });\r\n\r\n this.logger.debug(\"Created services\", { count: tableNames.length });\r\n return services;\r\n }\r\n\r\n // ========================== QUERY BUILDING ==========================\r\n\r\n /**\r\n * Create query builder for current connection\r\n */\r\n query(tableName?: string, schemaName?: string): QueryBuilder {\r\n this.logger.trace(\"Creating query builder\", { tableName, schemaName });\r\n const dao = this.getDAO(schemaName);\r\n\r\n if (tableName) {\r\n return QueryBuilder.table(tableName, dao);\r\n }\r\n\r\n return new QueryBuilder(dao);\r\n }\r\n\r\n /**\r\n * Create query builder from table\r\n */\r\n table(tableName: string, schemaName?: string): QueryBuilder {\r\n return this.query(tableName, schemaName);\r\n }\r\n\r\n /**\r\n * Execute raw SQL on current connection\r\n */\r\n async execute(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteResult> {\r\n this.logger.debug(\"Executing SQL\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n paramsCount: params?.length,\r\n });\r\n\r\n try {\r\n const dao = this.getDAO(schemaName);\r\n const result = await dao.execute(sql, params);\r\n\r\n this.logger.debug(\"SQL executed successfully\", {\r\n rowsAffected: result.rowsAffected,\r\n lastInsertRowId: result.lastInsertRowId,\r\n });\r\n\r\n this._emit(\"queryExecuted\", {\r\n sql,\r\n params,\r\n rowCount: result.rowsAffected,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"SQL execution failed\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"execute\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get first row from query\r\n */\r\n async getRst(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteRow> {\r\n this.logger.trace(\"Getting first row\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getRst(sql, params);\r\n }\r\n\r\n /**\r\n * Get all rows from query\r\n */\r\n async getRsts(\r\n sql: string,\r\n params?: any[],\r\n schemaName?: string\r\n ): Promise<SQLiteRow[]> {\r\n this.logger.trace(\"Getting all rows\", {\r\n sql: sql.substring(0, 100) + \"...\",\r\n });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getRsts(sql, params);\r\n }\r\n\r\n // ========================== SCHEMA MANAGEMENT ==========================\r\n\r\n /**\r\n * Initialize database from schema\r\n */\r\n async initializeSchema(\r\n schema: DatabaseSchema,\r\n forceRecreate: boolean = false\r\n ): Promise<void> {\r\n this.logger.info(\"Initializing schema\", {\r\n schemaName: schema.database_name,\r\n forceRecreate,\r\n });\r\n\r\n try {\r\n const dao = await DatabaseFactory.createOrOpen(\r\n { config: schema },\r\n forceRecreate\r\n );\r\n await dao.initializeFromSchema(schema);\r\n this.logger.info(\"Schema initialized successfully\", {\r\n schemaName: schema.database_name,\r\n });\r\n this._emit(\"schemaInitialized\", { schemaName: schema.database_name });\r\n } catch (error) {\r\n this.logger.error(\"Schema initialization failed\", {\r\n schemaName: schema.database_name,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"schemaInitialization\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get schema version for a database\r\n */\r\n async getSchemaVersion(schemaName?: string): Promise<string> {\r\n this.logger.debug(\"Getting schema version\", { schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getSchemaVersion();\r\n }\r\n\r\n /**\r\n * Get database information\r\n */\r\n async getDatabaseInfo(schemaName?: string): Promise<any> {\r\n this.logger.debug(\"Getting database info\", { schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getDatabaseInfo();\r\n }\r\n\r\n /**\r\n * Get table information\r\n */\r\n async getTableInfo(tableName: string, schemaName?: string): Promise<any[]> {\r\n this.logger.debug(\"Getting table info\", { tableName, schemaName });\r\n const dao = this.getDAO(schemaName);\r\n return await dao.getTableInfo(tableName);\r\n }\r\n\r\n // ========================== DATA IMPORT/EXPORT ==========================\r\n\r\n /**\r\n * Import data to a specific table\r\n */\r\n async importData(\r\n schemaName: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n options?: Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import\", {\r\n schemaName,\r\n tableName,\r\n recordCount: data.length,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importDataToTable(\r\n schemaName,\r\n tableName,\r\n data,\r\n options\r\n );\r\n\r\n this.logger.info(\"Data import completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n errors: result.errors.length,\r\n });\r\n\r\n this._emit(\"dataImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Data import failed\", { schemaName, tableName, error });\r\n this._emit(\"error\", error as Error, \"dataImport\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import data with column mapping\r\n */\r\n async importDataWithMapping(\r\n schemaName: string,\r\n tableName: string,\r\n data: Record<string, any>[],\r\n columnMappings: ColumnMapping[],\r\n options?: Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting data import with mapping\", {\r\n schemaName,\r\n tableName,\r\n recordCount: data.length,\r\n mappingCount: columnMappings.length,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importDataWithMapping(\r\n schemaName,\r\n tableName,\r\n data,\r\n columnMappings,\r\n options\r\n );\r\n\r\n this.logger.info(\"Data import with mapping completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n });\r\n\r\n this._emit(\"dataImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"Data import with mapping failed\", {\r\n schemaName,\r\n tableName,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"dataImportWithMapping\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Import from CSV\r\n */\r\n async importFromCSV(\r\n schemaName: string,\r\n tableName: string,\r\n csvData: string,\r\n options?: {\r\n delimiter?: string;\r\n hasHeader?: boolean;\r\n columnMappings?: ColumnMapping[];\r\n } & Partial<ImportOptions>\r\n ): Promise<ImportResult> {\r\n this.logger.info(\"Starting CSV import\", {\r\n schemaName,\r\n tableName,\r\n csvLength: csvData.length,\r\n delimiter: options?.delimiter,\r\n hasHeader: options?.hasHeader,\r\n });\r\n\r\n try {\r\n const result = await DatabaseManager.importFromCSV(\r\n schemaName,\r\n tableName,\r\n csvData,\r\n options\r\n );\r\n\r\n this.logger.info(\"CSV import completed\", {\r\n schemaName,\r\n tableName,\r\n successRows: result.successRows,\r\n failedRows: result.errorRows,\r\n });\r\n\r\n this._emit(\"csvImported\", {\r\n schemaName,\r\n tableName,\r\n recordCount: result.successRows,\r\n });\r\n return result;\r\n } catch (error) {\r\n this.logger.error(\"CSV import failed\", { schemaName, tableName, error });\r\n this._emit(\"error\", error as Error, \"csvImport\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== ROLE & ACCESS MANAGEMENT ==========================\r\n\r\n /**\r\n * Set user roles and initialize role-based connections\r\n */\r\n async setUserRoles(roles: string[], primaryRole?: string): Promise<void> {\r\n this.logger.info(\"Setting user roles\", { roles, primaryRole });\r\n this.ensureInitialized();\r\n\r\n try {\r\n await DatabaseManager.setCurrentUserRoles(roles, primaryRole);\r\n this.logger.info(\"User roles set successfully\", { roles, primaryRole });\r\n this._emit(\"userRolesSet\", { roles, primaryRole });\r\n } catch (error) {\r\n this.logger.error(\"Failed to set user roles\", {\r\n roles,\r\n primaryRole,\r\n error,\r\n });\r\n this._emit(\"error\", error as Error, \"setUserRoles\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Get current user roles\r\n */\r\n getCurrentUserRoles(): string[] {\r\n const roles = DatabaseManager.getCurrentUserRoles();\r\n this.logger.trace(\"Getting current user roles\", { roles });\r\n return roles;\r\n }\r\n\r\n /**\r\n * Get current primary role\r\n */\r\n getCurrentRole(): string | null {\r\n const role = DatabaseManager.getCurrentRole();\r\n this.logger.trace(\"Getting current role\", { role });\r\n return role;\r\n }\r\n\r\n /**\r\n * Check if user has access to database\r\n */\r\n hasAccessToDatabase(dbKey: string): boolean {\r\n const hasAccess = DatabaseManager.hasAccessToDatabase(dbKey);\r\n this.logger.trace(\"Checking database access\", { dbKey, hasAccess });\r\n return hasAccess;\r\n }\r\n\r\n // ========================== TRANSACTION MANAGEMENT ==========================\r\n\r\n /**\r\n * Execute cross-schema transaction\r\n */\r\n async executeTransaction(\r\n schemas: string[],\r\n callback: (daos: Record<string, UniversalDAO>) => Promise<void>\r\n ): Promise<void> {\r\n this.logger.info(\"Starting cross-schema transaction\", { schemas });\r\n\r\n try {\r\n await DatabaseManager.executeCrossSchemaTransaction(schemas, callback);\r\n this.logger.info(\"Cross-schema transaction completed successfully\", {\r\n schemas,\r\n });\r\n this._emit(\"transactionCompleted\", { schemas });\r\n } catch (error) {\r\n this.logger.error(\"Cross-schema transaction failed\", { schemas, error });\r\n this._emit(\"error\", error as Error, \"transaction\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Execute transaction on current connection\r\n */\r\n async executeTransactionOnCurrent<T>(\r\n callback: (dao: UniversalDAO) => Promise<T>\r\n ): Promise<T> {\r\n this.logger.debug(\"Starting transaction on current connection\");\r\n const dao = this.getCurrentDAO();\r\n\r\n try {\r\n await dao.beginTransaction();\r\n this.logger.trace(\"Transaction begun\");\r\n\r\n const result = await callback(dao);\r\n\r\n await dao.commitTransaction();\r\n this.logger.debug(\"Transaction committed successfully\");\r\n return result;\r\n } catch (error) {\r\n this.logger.warn(\"Transaction failed, rolling back\", { error });\r\n await dao.rollbackTransaction();\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== UTILITY & STATUS METHODS ==========================\r\n\r\n /**\r\n * Get environment information\r\n */\r\n getEnvironment(): string {\r\n const env = DatabaseFactory.getEnvironmentInfo();\r\n this.logger.trace(\"Getting environment info\", { env });\r\n return env;\r\n }\r\n\r\n /**\r\n * Get connection status\r\n */\r\n getConnectionStatus(): {\r\n isInitialized: boolean;\r\n currentSchema: string | null;\r\n activeConnections: string[];\r\n connectionCount: number;\r\n userRoles: string[];\r\n primaryRole: string | null;\r\n } {\r\n const status = {\r\n isInitialized: this.isInitialized,\r\n currentSchema: this.currentSchema,\r\n activeConnections: DatabaseManager.listConnections(),\r\n connectionCount: DatabaseManager.getConnectionCount(),\r\n userRoles: this.getCurrentUserRoles(),\r\n primaryRole: this.getCurrentRole(),\r\n };\r\n\r\n this.logger.trace(\"Getting connection status\", status);\r\n return status;\r\n }\r\n\r\n /**\r\n * Get list of available schemas\r\n */\r\n getAvailableSchemas(): string[] {\r\n const schemas = DatabaseManager.getAvailableSchemas();\r\n this.logger.trace(\"Getting available schemas\", { schemas });\r\n return schemas;\r\n }\r\n\r\n /**\r\n * Health check for all connections\r\n */\r\n async healthCheck(): Promise<\r\n Record<string, { healthy: boolean; error?: string }>\r\n > {\r\n this.logger.debug(\"Starting health check for all connections\");\r\n const connections = DatabaseManager.getConnections();\r\n const healthStatus: Record<string, { healthy: boolean; error?: string }> =\r\n {};\r\n\r\n for (const [schemaName, dao] of Object.entries(connections)) {\r\n try {\r\n await dao.execute(\"SELECT 1\");\r\n healthStatus[schemaName] = { healthy: true };\r\n this.logger.trace(\"Health check passed\", { schemaName });\r\n } catch (error) {\r\n healthStatus[schemaName] = {\r\n healthy: false,\r\n error: (error as Error).message,\r\n };\r\n this.logger.warn(\"Health check failed\", { schemaName, error });\r\n }\r\n }\r\n\r\n this.logger.debug(\"Health check completed\", {\r\n totalConnections: Object.keys(healthStatus).length,\r\n healthyConnections: Object.values(healthStatus).filter((s) => s.healthy)\r\n .length,\r\n });\r\n\r\n return healthStatus;\r\n }\r\n\r\n // ========================== EVENT SYSTEM ==========================\r\n\r\n /**\r\n * Add event listener\r\n */\r\n on(event: string, handler: (...args: any[]) => void): this {\r\n this.logger.trace(\"Adding event listener\", { event });\r\n if (!this.eventListeners.has(event)) {\r\n this.eventListeners.set(event, []);\r\n }\r\n this.eventListeners.get(event)!.push(handler);\r\n return this;\r\n }\r\n\r\n /**\r\n * Remove event listener\r\n */\r\n off(event: string, handler: (...args: any[]) => void): this {\r\n this.logger.trace(\"Removing event listener\", { event });\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n const index = handlers.indexOf(handler);\r\n if (index > -1) {\r\n handlers.splice(index, 1);\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Emit event\r\n */\r\n private _emit(event: string, ...args: any[]): void {\r\n this.logger.trace(\"Emitting event\", { event, argsCount: args.length });\r\n const handlers = this.eventListeners.get(event);\r\n if (handlers) {\r\n handlers.forEach((handler) => {\r\n try {\r\n handler(...args);\r\n } catch (error) {\r\n // Handle event handler errors gracefully\r\n this.logger.error(\"Error in event handler\", { event, error });\r\n }\r\n });\r\n }\r\n }\r\n\r\n // ========================== CONNECTION LIFECYCLE ==========================\r\n\r\n /**\r\n * Close specific connection\r\n */\r\n async closeConnection(schemaName: string): Promise<void> {\r\n this.logger.info(\"Closing connection\", { schemaName });\r\n\r\n try {\r\n await DatabaseManager.closeConnection(schemaName);\r\n\r\n if (this.currentSchema === schemaName) {\r\n this.currentSchema = null;\r\n this.logger.debug(\"Current schema reset due to connection close\");\r\n }\r\n\r\n this.logger.info(\"Connection closed successfully\", { schemaName });\r\n this._emit(\"connectionClosed\", { schemaName });\r\n } catch (error) {\r\n this.logger.error(\"Failed to close connection\", { schemaName, error });\r\n this._emit(\"error\", error as Error, \"closeConnection\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Close all connections\r\n */\r\n async closeAll(): Promise<void> {\r\n this.logger.info(\"Closing all connections\");\r\n\r\n try {\r\n await DatabaseManager.closeAll();\r\n this.currentSchema = null;\r\n this.isInitialized = false;\r\n this.initializationPromise = null;\r\n this.eventListeners.clear();\r\n\r\n this.logger.info(\"All connections closed successfully\");\r\n this._emit(\"allConnectionsClosed\");\r\n } catch (error) {\r\n this.logger.error(\"Failed to close all connections\", { error });\r\n this._emit(\"error\", error as Error, \"closeAll\");\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Logout user and close role-specific connections\r\n */\r\n async logout(): Promise<void> {\r\n this.logger.info(\"User logout initiated\");\r\n\r\n try {\r\n await DatabaseManager.logout();\r\n this.currentSchema = null;\r\n this.logger.info(\"User logout completed successfully\");\r\n this._emit(\"userLoggedOut\");\r\n } catch (error) {\r\n this.logger.error(\"User logout failed\", { error });\r\n this._emit(\"error\", error as Error, \"logout\");\r\n throw error;\r\n }\r\n }\r\n\r\n // ========================== STATIC UTILITY METHODS ==========================\r\n\r\n /**\r\n * Register adapter with DatabaseFactory\r\n */\r\n static registerAdapter(adapter: SQLiteAdapter): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering adapter\", {\r\n adapterName: adapter.name,\r\n adapterVersion: adapter.version,\r\n });\r\n DatabaseFactory.registerAdapter(adapter);\r\n }\r\n\r\n /**\r\n * Register role configuration\r\n */\r\n static registerRole(roleConfig: {\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n }): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering role\", { roleConfig });\r\n DatabaseManager.registerRole(roleConfig);\r\n }\r\n\r\n /**\r\n * Register multiple roles\r\n */\r\n static registerRoles(\r\n roleConfigs: Array<{\r\n roleName: string;\r\n requiredDatabases: string[];\r\n optionalDatabases?: string[];\r\n priority?: number;\r\n }>\r\n ): void {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.debug(\"Registering multiple roles\", {\r\n roleCount: roleConfigs.length,\r\n });\r\n DatabaseManager.registerRoles(roleConfigs);\r\n }\r\n\r\n // ========================== PRIVATE HELPERS ==========================\r\n\r\n private ensureInitialized(): void {\r\n if (!this.isInitialized) {\r\n const error = new Error(\r\n \"UniversalSQLite not initialized. Call initialize() first.\"\r\n );\r\n this.logger.error(\"Operation attempted on uninitialized instance\");\r\n throw error;\r\n }\r\n }\r\n}\r\n\r\n// ========================== FACTORY FUNCTIONS ==========================\r\n\r\n/**\r\n * Create UniversalDAO instance\r\n */\r\nexport const createUniversalDAO = (\r\n dbPath: string,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n createIfNotExists?: boolean;\r\n forceRecreate?: boolean;\r\n }\r\n): UniversalDAO => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Creating UniversalDAO\", { dbPath, options });\r\n return DatabaseFactory.createDAO(dbPath, options);\r\n};\r\n\r\n/**\r\n * Create database from schema configuration\r\n */\r\nexport const createDatabaseFromSchema = async (\r\n schema: DatabaseSchema,\r\n options?: Omit<DbFactoryOptions, \"config\">\r\n): Promise<UniversalDAO> => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Creating database from schema\", {\r\n schemaName: schema.database_name,\r\n });\r\n return await DatabaseFactory.createFromConfig(schema, options);\r\n};\r\n\r\n/**\r\n * Open existing database\r\n */\r\nexport const openExistingDatabase = async (\r\n dbName: string,\r\n options?: Omit<DbFactoryOptions, \"config\" | \"configAsset\">\r\n): Promise<UniversalDAO> => {\r\n const logger = createModuleLogger(SQLiteModules.DATABASE_FACTORY);\r\n logger.debug(\"Opening existing database\", { dbName });\r\n return await DatabaseFactory.openExisting(dbName, options);\r\n};\r\n\r\n/**\r\n * Create query builder\r\n */\r\nexport const createQueryBuilder = (dao?: UniversalDAO): QueryBuilder => {\r\n const logger = createModuleLogger(SQLiteModules.QUERY_BUILDER);\r\n logger.trace(\"Creating query builder\");\r\n return new QueryBuilder(dao);\r\n};\r\n\r\n/**\r\n * Create base service\r\n */\r\nexport const createBaseService = <T = any>(\r\n schemaName: string,\r\n tableName?: string\r\n): BaseService<T> => {\r\n const logger = createModuleLogger(SQLiteModules.BASE_SERVICE);\r\n logger.debug(\"Creating base service\", { schemaName, tableName });\r\n return new (class extends BaseService<T> {\r\n constructor() {\r\n super(schemaName, tableName);\r\n }\r\n })();\r\n};\r\n\r\n// ========================== CONVENIENCE EXPORTS ==========================\r\n\r\n/**\r\n * Quick setup function for common use cases\r\n */\r\nexport const setupUniversalSQLite = async (config: {\r\n schemas: Record<string, DatabaseSchema>;\r\n adapters?: SQLiteAdapter[];\r\n defaultRoles?: string[];\r\n autoConnect?: string; // schema name to auto-connect to\r\n loggerConfig?: any; // logger configuration\r\n enableDebugLogging?: boolean;\r\n}): Promise<UniversalSQLite> => {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.info(\"Setting up UniversalSQLite\", {\r\n schemaCount: Object.keys(config.schemas).length,\r\n autoConnect: config.autoConnect,\r\n enableDebugLogging: config.enableDebugLogging,\r\n });\r\n\r\n const sqlite = UniversalSQLite.getInstance();\r\n\r\n // Configure debug logging if requested\r\n if (config.enableDebugLogging) {\r\n UniversalSQLite.enableDebugLogging();\r\n }\r\n\r\n await sqlite.initialize(config.schemas, {\r\n registerAdapters: config.adapters,\r\n defaultRoles: config.defaultRoles,\r\n loggerConfig: config.loggerConfig,\r\n });\r\n\r\n if (config.autoConnect) {\r\n await sqlite.connect(config.autoConnect);\r\n }\r\n\r\n logger.info(\"UniversalSQLite setup completed\");\r\n return sqlite;\r\n};\r\n\r\n/**\r\n * Quick database creation from single schema\r\n */\r\nexport const createSingleDatabase = async (\r\n schema: DatabaseSchema,\r\n options?: {\r\n adapter?: SQLiteAdapter;\r\n autoConnect?: boolean;\r\n loggerConfig?: any;\r\n enableDebugLogging?: boolean;\r\n }\r\n): Promise<{ sqlite: UniversalSQLite; dao: UniversalDAO }> => {\r\n const logger = createModuleLogger(SQLiteModules.UNIVERSAL_SQLITE);\r\n logger.info(\"Creating single database\", {\r\n schemaName: schema.database_name,\r\n enableDebugLogging: options?.enableDebugLogging,\r\n });\r\n\r\n const sqlite = UniversalSQLite.getInstance();\r\n\r\n // Configure debug logging if requested\r\n if (options?.enableDebugLogging) {\r\n UniversalSQLite.enableDebugLogging();\r\n }\r\n\r\n await sqlite.initializeFromSchema(schema, {\r\n registerAdapters: options?.adapter ? [options.adapter] : undefined,\r\n autoConnect: options?.autoConnect,\r\n loggerConfig: options?.loggerConfig,\r\n });\r\n\r\n const dao =\r\n options?.autoConnect !== false\r\n ? await sqlite.connect(schema.database_name)\r\n : sqlite.getDAO(schema.database_name);\r\n\r\n logger.info(\"Single database creation completed\");\r\n return { sqlite, dao };\r\n};\r\n\r\n// ========================== DEFAULT EXPORT ==========================\r\n\r\n/**\r\n * Default export is the singleton instance\r\n */\r\nconst defaultInstance = UniversalSQLite.getInstance();\r\nexport default defaultInstance;\r\n"],"names":["h","a","y","o","r","i","l","b","p","w","m","N","SQLiteModules","SQLiteLoggerConfig","LoggerConfigBuilder","customConfig","config","createLogger","newConfig","enabled","moduleName","levels","appenders","sqliteLogger","createModuleLogger","logger","message","args","UniversalDAO","adapter","dbPath","options","_a","_b","error","genericType","defaultType","mappedType","col","processedCol","constraints","defaultIndex","defaultValue","schema","hasExistingSchema","result","tableName","tableConfig","tableDefinition","tables","table","columnDefs","foreignKeyDefs","fk","fkSql","allDefs","sql","indexes","index","columns","isUnique","version","insertTable","validCols","columnNames","placeholders","params","updateTable","setCols","setClause","whereClause","deleteTable","selectTable","row","suffix","orderBy","wheres","clause","conditions","where","operator","json","idFields","queryTable","key","value","startTime","tableInfo","columnMap","batchSize","processedCount","skipAutoIncrementPK","batch","j","rowIndex","rowData","processedData","errorInfo","data","columnMappings","transformedData","newRow","mapping","csvData","delimiter","hasHeader","lines","line","headers","dataStartIndex","firstRowCols","_","values","v","header","processedRow","columnName","columnInfo","isRequired","isAutoIncrementPK","lowerColumnName","columnType","type","num","lower","date","conflictColumns","updateColumns","whereColumns","updateValues","whereValues","allValues","info","t","isOpen","DatabaseFactory","environment","dao","dbInfo","errorMsg","_c","_d","dbName","dbFileName","closeError","isForceInit","isForceDelete","schemaError","configAsset","DatabaseManager","maxConnections","currentConnectionCount","manager","schemas","schemaKeys","internalKeys","externalKeys","allKeys","roleConfig","roleConfigs","roleName","databases","allDatabases","db","coreSchema","userRoles","primaryRole","previousRoles","requiredDatabases","failedInitializations","initPromises","dbKey","err","errorSummary","f","previousDatabases","currentDatabases","databasesToClose","hasAccess","schemaName","callback","listeners","currentActiveDb","closePromises","activeDbArray","databaseKeys","failedOpens","invalidKeys","newConnectionsCount","currentConnectionsCount","availableSchemas","daos","acc","databaseKey","importConfigs","c","configKey","importResult","count","connections","connectionsToClose","BaseService","newDao","method","fields","createdRecord","primaryKeyValue","findError","id","updateData","success","record","allWheres","name","results","whereConditions","exists","items","dataArray","rollbackError","obj","event","handler","handlers","errorType","handlerError","status","QueryBuilder","builder","raw","fieldList","condition","fieldOrConditions","operatorOrValue","field","val","actualValue","min","max","subquery","actualOperator","direction","page","perPage","query","alias","cteList","cteSql","cteParams","join","conditionParams","unionQuery","unionSql","unionParams","subSql","subParams","column","valueGroups","whereParams","sets","updateClause","cloned","rawSql","param","DefaultService","ServiceManager","methods","serviceKey","normalizedConfig","wasAlreadyRegistered","configs","ServiceClass","service","metadata","services","keySchema","keys","serviceKeys","destroyPromises","successCount","infos","healthPromises","health","healthyCount","report","maxIdleTime","now","servicesToDestroy","lastAccessTime","eventType","globalHandlers","BaseAdapter","paramIndex","UniversalSQLite","debugConfig","prodConfig","tableNames","forceRecreate","roles","role","env","healthStatus","s","createUniversalDAO","createDatabaseFromSchema","openExistingDatabase","createQueryBuilder","createBaseService","setupUniversalSQLite","sqlite","createSingleDatabase","defaultInstance"],"mappings":"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","x_google_ignoreList":[0]}
|