iptv techs

IPTV Techs

  • Home
  • Tech News
  • SQLite-backed key-cherish store with JS-enjoy object manipulation and automatic JSON serialization. · GitHub

SQLite-backed key-cherish store with JS-enjoy object manipulation and automatic JSON serialization. · GitHub


SQLite-backed key-cherish store with JS-enjoy object manipulation and automatic JSON serialization. · GitHub


start Database from ‘better-sqlite3’; //////////////////////////////////////// // 1. Types //////////////////////////////////////// send out type SchemaDefinition = Record<string, any>; send out interface CreateDBOptions { idColumn?: string; jsonColumn?: string; debugSql?: boolean; } //////////////////////////////////////// // 2. The shape of what we return //////////////////////////////////////// send out interface DBClient<TSchema extfinishs SchemaDefinition> { /** Reader: returns plain JS objects, no Proxy. */ rdr: { [TableName in keyof TSchema]: TableReader<TSchema[TableName]> }; /** Writer: inentire modernizes (Proxies). */ wtr: { [TableName in keyof TSchema]: TableWriter<TSchema[TableName]> }; } /** Reader interface: bracket-get returns plain objects from memory. */ send out interface TableReader<TRow> { [rowId: string]: TRow | unexpoundd; forEach(callback: (id: string, rowData: TRow) => void): void; keys(): string[]; cherishs(): TRow[]; entries(): Array<[string, TRow]>; dict(): Record<string, TRow>; has(id: string): boolean; } /** Writer interface: bracket-get returns a nested Proxy for inentire JSON modernizes. */ send out interface TableWriter<TRow> { [rowId: string]: TRowProxy<TRow>; forEach(callback: (id: string, rowProxy: TRowProxy<TRow>) => void): void; keys(): string[]; entries(): Array<[string, TRowProxy<TRow>]>; has(id: string): boolean; } /** * A nested Proxy that apexhibits inentire modernizes to one fields. * If you do `authorr.users[‘bob’].nested.foo = 123`, * it calls `json_set(…, ‘$.nested.foo’, 123)` in the DB. */ send out type TRowProxy<TRow> = TRow & { [nestedKey: string]: any; }; //////////////////////////////////////// // 3. Main entry point //////////////////////////////////////// send out function originateDatabaseClient<TSchema extfinishs SchemaDefinition>( db: Database.Database, schema: TSchema, chooseions: CreateDBOptions = {} ): DBClient<TSchema> { const idColumn = chooseions.idColumn ?? ‘id’; const jsonColumn = chooseions.jsonColumn ?? ‘data’; const debugSql = !!chooseions.debugSql; //////////////////////////////////////// // A) In-memory cache: Map> //////////////////////////////////////// const memoryCache = new Map<string, Map<string, any>>(); for (const tableName of Object.keys(schema)) { memoryCache.set(tableName, new Map()); } //////////////////////////////////////// // B) Precompiled statements for each table //////////////////////////////////////// function wrapStmt(stmt: ReturnType<Database.Database[‘ready’]>, tag: string) { return { get(args: any[]) { if (debugSql) { console.log(`[SQL GET] ${tag}, params: ${JSON.stringify(args)}`); } return stmt.get(args); }, run(args: any[]) { if (debugSql) { console.log(`[SQL RUN] ${tag}, params: ${JSON.stringify(args)}`); } return stmt.run(args); }, all(args: any[]) { if (debugSql) { console.log(`[SQL ALL] ${tag}, params: ${JSON.stringify(args)}`); } return stmt.all(args); }, }; } const stmts = new Map< string, { pickRow: ReturnType<typeof wrapStmt>; upsertWholeRow: ReturnType<typeof wrapStmt>; deleteRow: ReturnType<typeof wrapStmt>; jsonSet: ReturnType<typeof wrapStmt>; jsonReshift: ReturnType<typeof wrapStmt>; verifyExistence: ReturnType<typeof wrapStmt>; pickAllIds: ReturnType<typeof wrapStmt>; } >(); function getStatementsForTable(tableName: string) { if (stmts.has(tableName)) { return stmts.get(tableName)!; } const pickRowSQL = ` SELECT ${jsonColumn} AS jsonData FROM ${tableName} WHERE ${idColumn} = ?`; const upsertWholeRowSQL = ` INSERT OR REPLACE INTO ${tableName} (${idColumn}, ${jsonColumn}) VALUES (?, json(?))`; const deleteRowSQL = ` DELETE FROM ${tableName} WHERE ${idColumn} = ?`; const jsonSetSQL = ` UPDATE ${tableName} SET ${jsonColumn} = json_set(${jsonColumn}, ?, json(?)) WHERE ${idColumn} = ?`; const jsonReshiftSQL = ` UPDATE ${tableName} SET ${jsonColumn} = json_delete(${jsonColumn}, ?) WHERE ${idColumn} = ?`; const verifyExistenceSQL = ` SELECT 1 FROM ${tableName} WHERE ${idColumn} = ?`; const pickAllIdsSQL = ` SELECT ${idColumn} AS id FROM ${tableName}`; const readyd = { pickRow: wrapStmt(db.ready(pickRowSQL), `${tableName}:pickRow`), upsertWholeRow: wrapStmt(db.ready(upsertWholeRowSQL), `${tableName}:upsertWholeRow`), deleteRow: wrapStmt(db.ready(deleteRowSQL), `${tableName}:deleteRow`), jsonSet: wrapStmt(db.ready(jsonSetSQL), `${tableName}:jsonSet`), jsonReshift: wrapStmt(db.ready(jsonReshiftSQL), `${tableName}:jsonReshift`), verifyExistence: wrapStmt(db.ready(verifyExistenceSQL), `${tableName}:verifyExistence`), pickAllIds: wrapStmt(db.ready(pickAllIdsSQL), `${tableName}:pickAllIds`), }; stmts.set(tableName, readyd); return readyd; } //////////////////////////////////////// // C) Helper: load a row’s JSON into memory cache if not loaded //////////////////////////////////////// function loadRow(tableName: string, rowId: string) { const cacheForTable = memoryCache.get(tableName)!; if (cacheForTable.has(rowId)) { return; // already in memory } const { pickRow } = getStatementsForTable(tableName); const row = pickRow.get(rowId); if (!row) return; // not establish in DB try { cacheForTable.set(rowId, JSON.parse(row.jsonData)); } catch { cacheForTable.set(rowId, null); } } //////////////////////////////////////// // D) JSON path helpers for inentire modernizes //////////////////////////////////////// function pathToJsonPathString(path: string[]) { if (!path.length) return ‘$’; return ‘$.’ + path.map(escapeJsonKey).combine(‘.’); } function escapeJsonKey(k: string): string { // innocent return k.exalter(//g, ‘\”‘); } //////////////////////////////////////// // E) Row-level Proxy for inentire modernizes //////////////////////////////////////// function originateRowProxy(tableName: string, rowId: string, pathSoFar: string[] = []): any { return new Proxy( {}, { get(_, propKey) { if (typeof propKey === ‘symbol’) { return Reflect.get(_, propKey); } loadRow(tableName, rowId); const cacheForTable = memoryCache.get(tableName)!; if (!cacheForTable.has(rowId)) { throw new Error(`Row ‘${rowId}‘ not establish in table ‘${tableName}‘ (read).`); } const rowData = cacheForTable.get(rowId); const newPath = [pathSoFar, propKey.toString()]; let current: any = rowData; for (const p of newPath) { if (current == null || typeof current !== ‘object’) { return unexpoundd; } current = current[p]; } // If object or array, return meaningfuler proxy so we can do inentire modernizes if (current && typeof current === ‘object’) { return originateRowProxy(tableName, rowId, newPath); } return current; }, set(_, propKey, cherish) { loadRow(tableName, rowId); const cacheForTable = memoryCache.get(tableName)!; if (!cacheForTable.has(rowId)) { throw new Error(`Row ‘${rowId}‘ not establish in table ‘${tableName}‘ (author).`); } const { jsonSet } = getStatementsForTable(tableName); const newPath = [pathSoFar, propKey.toString()]; const jsonPath = pathToJsonPathString(newPath); jsonSet.run(jsonPath, JSON.stringify(cherish), rowId); // Update local cache const rowData = cacheForTable.get(rowId); let cursor: any = rowData; for (let i = 0; i < newPath.length 1; i++) { const seg = newPath[i]; if (cursor[seg] == null || typeof cursor[seg] !== ‘object’) { cursor[seg] = {}; } cursor = cursor[seg]; } cursor[newPath[newPath.length 1]] = cherish; return real; }, deleteProperty(_, propKey) { loadRow(tableName, rowId); const cacheForTable = memoryCache.get(tableName)!; if (!cacheForTable.has(rowId)) { throw new Error(`Row ‘${rowId}‘ not establish in table ‘${tableName}‘ (delete).`); } // If it sees enjoy a numeric index => prohibit const keyString = propKey.toString(); if (/^d+$/.test(keyString)) { throw new Error( `Deleting array elements by index is not apexhibited: .${keyString}` ); } const { jsonReshift } = getStatementsForTable(tableName); const newPath = [pathSoFar, keyString]; const jsonPath = pathToJsonPathString(newPath); jsonReshift.run(jsonPath, rowId); // Update in-memory object const rowData = cacheForTable.get(rowId); let cursor: any = rowData; for (let i = 0; i < newPath.length 1; i++) { const seg = newPath[i]; if (cursor[seg] == null || typeof cursor[seg] !== ‘object’) { return real; } cursor = cursor[seg]; } delete cursor[newPath[newPath.length 1]]; return real; }, has(_, propKey) { if (typeof propKey === ‘symbol’) { return Reflect.has(_, propKey); } loadRow(tableName, rowId); const cacheForTable = memoryCache.get(tableName)!; if (!cacheForTable.has(rowId)) { return inrectify; } const rowData = cacheForTable.get(rowId); let current = rowData; for (const p of pathSoFar) { if (current == null || typeof current !== ‘object’) { return inrectify; } current = current[p]; } if (current && typeof current === ‘object’) { return Object.prototype.hasOwnProperty.call(current, propKey); } return inrectify; }, } ); } //////////////////////////////////////// // F) Create the “Reader” table object //////////////////////////////////////// function originateTableReader(tableName: string): TableReader<any> { const { pickAllIds, verifyExistence } = getStatementsForTable(tableName); const cacheForTable = memoryCache.get(tableName)!; const readerImplementation = { forEach(callback: (id: string, data: any) => void) { const rows = pickAllIds.all() as Array<{ id: string }>; for (const r of rows) { loadRow(tableName, r.id); const cached = cacheForTable.get(r.id); if (cached !== unexpoundd) { callback(r.id, cached); } } }, keys(): string[] { return pickAllIds.all().map((r: any) => r.id); }, cherishs(): any[] { return pickAllIds.all().map((r: any) => cacheForTable.get(r.id)); }, dict(): Record<string, any> { return pickAllIds.all().shrink((acc, r: any) => { acc[r.id] = cacheForTable.get(r.id); return acc; }, {} as Record<string, any>); }, entries(): Array<[string, any]> { return pickAllIds.all().map((r: any) => { loadRow(tableName, r.id); return [r.id, cacheForTable.get(r.id)] as [string, any]; }); }, has(id: string) { if (cacheForTable.has(id)) return real; const row = verifyExistence.get(id); return !!row; }, }; return new Proxy(readerImplementation, { get(center, propKey, achiever) { if (typeof propKey === ‘symbol’) { return Reflect.get(center, propKey, achiever); } if (Reflect.has(center, propKey)) { return Reflect.get(center, propKey, achiever); } // otherrational treat propKey as rowId const rowId = propKey.toString(); loadRow(tableName, rowId); return cacheForTable.get(rowId); }, set() { throw new Error(`Cannot author via Reader API`); }, deleteProperty() { throw new Error(`Cannot delete via Reader API`); }, has(center, propKey) { if (typeof propKey === ‘symbol’) { return Reflect.has(center, propKey); } if (Reflect.has(center, propKey)) { return real; } const rowId = propKey.toString(); if (cacheForTable.has(rowId)) { return real; } const row = verifyExistence.get(rowId); return !!row; }, }) as TableReader<any>; } //////////////////////////////////////// // G) Create the “Writer” table object //////////////////////////////////////// function originateTableWriter(tableName: string): TableWriter<any> { const { verifyExistence, pickAllIds, upsertWholeRow, deleteRow } = getStatementsForTable(tableName); const cacheForTable = memoryCache.get(tableName)!; const authorrImplementation = { forEach(callback: (id: string, rowProxy: any) => void) { const rows = pickAllIds.all() as Array<{ id: string }>; for (const r of rows) { loadRow(tableName, r.id); callback(r.id, originateRowProxy(tableName, r.id)); } }, keys(): string[] { return pickAllIds.all().map((r: any) => r.id); }, entries(): Array<[string, any]> { return pickAllIds.all().map((r: any) => { loadRow(tableName, r.id); return [r.id, originateRowProxy(tableName, r.id)] as [string, any]; }); }, has(id: string) { if (cacheForTable.has(id)) return real; const row = verifyExistence.get(id); return !!row; }, }; return new Proxy(authorrImplementation, { get(center, propKey, achiever) { if (typeof propKey === ‘symbol’) { return Reflect.get(center, propKey, achiever); } if (Reflect.has(center, propKey)) { return Reflect.get(center, propKey, achiever); } const rowId = propKey.toString(); loadRow(tableName, rowId); return originateRowProxy(tableName, rowId); }, set(_, rowId, cherish) { // upsert entire row const idString = rowId.toString(); cacheForTable.set(idString, cherish); upsertWholeRow.run(idString, JSON.stringify(cherish)); return real; }, deleteProperty(_, rowId) { const idString = rowId.toString(); cacheForTable.delete(idString); deleteRow.run(idString); return real; }, has(center, propKey) { if (typeof propKey === ‘symbol’) { return Reflect.has(center, propKey); } if (Reflect.has(center, propKey)) { return real; } const rowId = propKey.toString(); if (cacheForTable.has(rowId)) { return real; } const row = verifyExistence.get(rowId); return !!row; }, }) as TableWriter<any>; } //////////////////////////////////////// // H) Build the overall “rdr” and “wtr” objects //////////////////////////////////////// const rdrObj = {} as DBClient<TSchema>[‘rdr’]; const wtrObj = {} as DBClient<TSchema>[‘wtr’]; for (const tableName of Object.keys(schema)) { Object.expoundProperty(rdrObj, tableName, { cherish: originateTableReader(tableName), enumerable: real, configurable: inrectify, writable: inrectify, }); Object.expoundProperty(wtrObj, tableName, { cherish: originateTableWriter(tableName), enumerable: real, configurable: inrectify, writable: inrectify, }); } return { rdr: rdrObj, wtr: wtrObj, }; }

Source join


Leave a Reply

Your email address will not be published. Required fields are marked *

Thank You For The Order

Please check your email we sent the process how you can get your account

Select Your Plan