UNPKG

forge-sql-orm

Version:

Drizzle ORM integration for Atlassian @forge/sql. Provides a custom driver, schema migration, two levels of caching (local and global via @forge/kvs), optimistic locking, and query analysis.

172 lines 7.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ForgeSQLCacheOperations = void 0; const cacheUtils_1 = require("../utils/cacheUtils"); const table_1 = require("drizzle-orm/table"); /** * Implementation of cache operations for ForgeSQL ORM. * Provides methods for cacheable database operations with automatic cache management. * * ⚠️ **IMPORTANT**: All modification methods in this class use optimistic locking/versioning * through `modifyWithVersioning()` internally. This ensures data consistency and prevents * concurrent modification conflicts. */ class ForgeSQLCacheOperations { options; forgeOperations; /** * Creates a new instance of ForgeSQLCacheOperations. * * @param options - Configuration options for the ORM * @param forgeOperations - The ForgeSQL operations instance */ constructor(options, forgeOperations) { this.options = options; this.forgeOperations = forgeOperations; } /** * Evicts cache for multiple tables using Drizzle table objects. * * @param tables - Array of Drizzle table objects to clear cache for * @returns Promise that resolves when cache eviction is complete * @throws Error if cacheEntityName is not configured */ async evictCacheEntities(tables) { if (!this.options.cacheEntityName) { throw new Error("cacheEntityName is not configured"); } await this.evictCache(tables.map((t) => (0, table_1.getTableName)(t))); } /** * Evicts cache for multiple tables by their names. * * @param tables - Array of table names to clear cache for * @returns Promise that resolves when cache eviction is complete * @throws Error if cacheEntityName is not configured */ async evictCache(tables) { if (!this.options.cacheEntityName) { throw new Error("cacheEntityName is not configured"); } await (0, cacheUtils_1.clearTablesCache)(tables, this.options); } /** * Inserts records with optimistic locking/versioning and automatically evicts cache. * * This method uses `modifyWithVersioning().insert()` internally, providing: * - Automatic version field initialization * - Optimistic locking support * - Cache eviction after successful operation * * @param schema - The table schema * @param models - Array of entities to insert * @param updateIfExists - Whether to update existing records * @returns Promise that resolves to the number of inserted rows * @throws Error if cacheEntityName is not configured * @throws Error if optimistic locking check fails */ async insert(schema, models, updateIfExists) { this.validateCacheConfiguration(); const number = await this.forgeOperations .modifyWithVersioning() .insert(schema, models, updateIfExists); await (0, cacheUtils_1.clearCache)(schema, this.options); return number; } /** * Deletes a record by ID with optimistic locking/versioning and automatically evicts cache. * * This method uses `modifyWithVersioning().deleteById()` internally, providing: * - Optimistic locking checks before deletion * - Version field validation * - Cache eviction after successful operation * * @param id - The ID of the record to delete * @param schema - The table schema * @returns Promise that resolves to the number of affected rows * @throws Error if cacheEntityName is not configured * @throws Error if optimistic locking check fails */ async deleteById(id, schema) { this.validateCacheConfiguration(); const number = await this.forgeOperations.modifyWithVersioning().deleteById(id, schema); await (0, cacheUtils_1.clearCache)(schema, this.options); return number; } /** * Updates a record by ID with optimistic locking/versioning and automatically evicts cache. * * This method uses `modifyWithVersioning().updateById()` internally, providing: * - Optimistic locking checks before update * - Version field incrementation * - Cache eviction after successful operation * * @param entity - The entity with updated values (must include primary key) * @param schema - The table schema * @returns Promise that resolves to the number of affected rows * @throws Error if cacheEntityName is not configured * @throws Error if optimistic locking check fails */ async updateById(entity, schema) { this.validateCacheConfiguration(); const number = await this.forgeOperations.modifyWithVersioning().updateById(entity, schema); await (0, cacheUtils_1.clearCache)(schema, this.options); return number; } /** * Updates fields based on conditions with optimistic locking/versioning and automatically evicts cache. * * This method uses `modifyWithVersioning().updateFields()` internally, providing: * - Optimistic locking support (if version field is configured) * - Version field validation and incrementation * - Cache eviction after successful operation * * @param updateData - The data to update * @param schema - The table schema * @param where - Optional WHERE conditions * @returns Promise that resolves to the number of affected rows * @throws Error if cacheEntityName is not configured * @throws Error if optimistic locking check fails */ async updateFields(updateData, schema, where) { this.validateCacheConfiguration(); const number = await this.forgeOperations .modifyWithVersioning() .updateFields(updateData, schema, where); await (0, cacheUtils_1.clearCache)(schema, this.options); return number; } /** * Executes a query with caching support. * First checks cache, if not found executes query and stores result in cache. * * @param query - The Drizzle query to execute * @param cacheTtl - Optional cache TTL override * @returns Promise that resolves to the query results * @throws Error if cacheEntityName is not configured */ async executeQuery(query, cacheTtl) { this.validateCacheConfiguration(); const sqlQuery = query; const cacheResult = await (0, cacheUtils_1.getFromCache)(sqlQuery, this.options); if (cacheResult) { return cacheResult; } const results = await query; await (0, cacheUtils_1.setCacheResult)(sqlQuery, this.options, results, cacheTtl ?? this.options.cacheTTL ?? 60); return results; } /** * Validates that cache configuration is properly set up. * * @throws Error if cacheEntityName is not configured * @private */ validateCacheConfiguration() { if (!this.options.cacheEntityName) { throw new Error("cacheEntityName is not configured"); } } } exports.ForgeSQLCacheOperations = ForgeSQLCacheOperations; //# sourceMappingURL=ForgeSQLCacheOperations.js.map