ORM
  • Introduction
  • Basics of Usage
    • Connecting to the Database
    • Creating a Model
    • Simple Queries
  • Configuration
  • Core Features
    • Models
    • CRUD Operations (Create, Read, Update, Delete): examples
    • Relationships
    • Transactions
  • Advanced Usage
    • Data Definition Language
    • Indexes
    • Triggers
    • Caching
  • Examples and templates
  • Security
    • Query parameterization and protection against SQL injections
    • Logging
    • Monitoring
    • Sanitization
  • ORM-CLI
    • Installing
    • Commands and usage
  • System architecture and implementation
    • Support of various databases
      • Implementation using a pattern strategy
      • Implementation using generics
      • Implementation using metaprogramming
    • Decorators
    • Migrations
      • Assignment of id in Tables and Columns
      • Assigning IDs to indexes and triggers
      • Working with migrations in ORM-CLI
        • Implementation of a pattern command for migration
    • QueryBuilder
    • Caching
    • File structure
  • API
    • Decorators
      • Column
      • ComputedColumn
      • Index
      • ForeignKey
      • PrimaryGeneratedColumn
      • Relations
      • Table
      • Trigger
      • Types decorators
        • Integer
        • Numeric
        • Float
        • Boolean
        • String
    • DDL
    • QueryBuilder
    • Additional API
Powered by GitBook
On this page
  1. System architecture and implementation

Caching

Реалізація кешування в ORM

PreviousQueryBuilderNextFile structure

Last updated 9 months ago

Architecture and Features

Caching in the ORM system is implemented using the "Factory" pattern, which provides the creation of specific cache implementations depending on the type. Currently, caching with Redis is supported, and additional caching mechanisms, such as Memcached, are planned for future integration.

Main Components:

  • CacheFactory: This is a factory class responsible for creating specific cache instances. It takes a cache type (CacheType) and corresponding settings (CacheOptions). Depending on the cache type, it creates and initializes the appropriate adapter, such as Redis.

  • RedisAdapter: An adapter for Redis that implements the CacheInterface. It provides basic cache operations: setting (set), retrieving (get), and deleting (delete) cached data. Initialization of the Redis client occurs through the init method, which connects to the Redis server and configures the client.

  • cache Method in QueryBuilder: This method is used for caching query results. It takes TTL (time-to-live) and cache key parameters. If data is already in the cache, it is returned without querying the database. Otherwise, the database query is executed, results are cached, and then returned.

Implementation Details:

  • CacheFactory: This class determines which specific cache to use and creates the corresponding object. For example, for Redis, the RedisAdapter class is used, which initializes and connects to the Redis server.

  • RedisAdapter: A class that handles interactions with Redis through a Redis client. It provides essential methods for cache management:

    • set(key: string, value: unknown, ttl?: number): stores a value in the cache with the specified key and optional time-to-live.

    • get(key: string): retrieves a value from the cache by key.

    • delete(key: string): removes a value from the cache by key.

  • QueryBuilder: The cache method in QueryBuilder integrates caching directly into the query execution process. It allows for reusing query results by storing them in the cache. This significantly improves performance, especially for frequently used queries.

Architecturally, caching is implemented flexibly and scalably, allowing for easy addition of new cache types and adaptation of the system to specific needs. Integrating caching with QueryBuilder greatly simplifies working with frequently used data, providing fast access and enhancing database performance.

Main Files Implementing Caching Logic:

And also the cache method in QueryBuilder:


//cache
async cache({ ttl, key }: CacheOptionsInterface, enableMonitoring: boolean = true): Promise<T> {
    if (!this._cache) {
       throw new Error('Cache not set!');
    }
    if (!key) {
       console.info('It is better to set the hashing key so it will be better in terms of performance!');
    }

    const queryExecute = async () => {
       const cacheKey = key || await Crypto.generateCacheKey(this.build());
       const cachedData = await this._cache.get(cacheKey);

       if (cachedData) {
          return JSON.parse(cachedData);
       }

       const dataFromDb = await this.execute(false);
       await this._cache.set(cacheKey, JSON.stringify(dataFromDb), ttl);
       return dataFromDb;
    };

    return this._monitoring && enableMonitoring
       ? await this._monitoring.measureExecutionTime(queryExecute, this.build(), this.parameters, MonitoringType.CacheQuery)
       : await queryExecute();
}
https://github.com/MyroslavShymon/ORM/tree/main/src/orm/context/cache