RIK Database ORM

raw JSON →
1.4.5 verified Thu Apr 23 auth: no javascript

RIK Database is a TypeScript-first Object-Relational Mapper (ORM) designed specifically for a project named 'RIK'. It provides a structured, object-oriented interface for interacting with PostgreSQL databases, leveraging an underlying SQL query builder (likely Knex.js). The library offers models such as `Version`, `NetworkInterfaceSettings`, and `Plst`, along with associated interfaces, to manage database operations including querying, insertion, updating, and deletion. Currently at version 1.4.5, it appears to be actively maintained, offering type-safe interactions for its specific domain. Its key differentiator is its tailored design for the 'RIK' project, meaning it might come with predefined schema assumptions or conventions that align with that project's needs, distinguishing it from general-purpose ORMs.

error KnexTimeoutError: Knex: Timeout acquiring a connection. The pool is probably full. Are you missing a .transacting(trx) call?
cause The database connection pool is exhausted, often due to long-running queries, unreleased connections, or missing `await` for database operations within transactions.
fix
Increase the connection pool size in DbSettings.setConfig (e.g., { pool: { min: 2, max: 20 } }). Ensure all database queries are awaited, especially within Promise.all(). For transactions, make sure transacting(trx) is correctly applied to all queries within that transaction, and the transaction is explicitly committed or rolled back.
error Error: connect ECONNREFUSED
cause The application could not establish a connection with the PostgreSQL server, typically due to incorrect host, port, firewall, or the database server not running.
fix
Verify that DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, and DB_NAME in your .env or configuration are correct. Ensure the PostgreSQL server is running and accessible from the application's environment. Check firewall rules blocking the connection.
error SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "table_name" does not exist
cause The database table corresponding to a model (e.g., `Version` expecting a 'versions' table) does not exist in the connected database.
fix
Ensure your database schema has been created and migrated correctly. If using Knex migrations, run knex migrate:latest. If rik-database expects a specific schema, verify your database matches it.
error Undefined binding(s) detected when compiling UPDATE query. Set 'debug: true' in your Knex config to see the bindings.
cause A query is attempting to use a variable or object property that is `undefined` as a binding value in an update or insert operation, often due to typos or missing data.
fix
Inspect the data object being passed to insert, update, or patch methods. Ensure all properties intended for database columns have defined values and match the expected types. Add debug: true to the Knex configuration for more detailed error messages.
gotcha This library is explicitly designed for a 'specific project named RIK'. While it uses standard ORM patterns, its models and conventions might be tightly coupled to the RIK project's database schema, making it less suitable for general-purpose use without significant adaptation.
fix Review the source code and model definitions to understand the expected database schema. Be prepared to create a compatible schema or extend/modify the models for your specific project.
breaking As `rik-database` is built on top of Knex.js, major version updates of the underlying Knex library or PostgreSQL driver (`pg`) can introduce breaking changes. Although `rik-database` abstracts this, internal changes might manifest as unexpected behavior or errors.
fix Always check the release notes for `rik-database` for any mentions of underlying dependency updates. Pin exact versions of `rik-database`, `knex`, and `pg` to ensure stability and carefully test when upgrading.
gotcha Direct use of `Rik.raw()` for SQL expressions introduces a risk of SQL injection if user-provided input is not properly sanitized. This bypasses the ORM's built-in escaping mechanisms.
fix Only use `Rik.raw()` with static SQL strings or with values that are guaranteed to be safe (e.g., from an allow-list). For dynamic values, use Knex's parameter binding capabilities within `Rik.raw()` or, preferably, the ORM's query builder methods.
gotcha Improper transaction management can lead to data inconsistencies or deadlocks. While `setSettingsWithTransaction` is shown, fully robust error handling with `rollback` and `commit` for all paths is crucial but not fully demonstrated in the excerpt.
fix Always wrap database operations that need to be atomic within a transaction block. Ensure that `commit` is called on success and `rollback` is called in the event of any error (e.g., using `try...catch...finally` or `transaction.on('error')`). Consider using Knex's transaction helper for simpler transaction management.
npm install rik-database
yarn add rik-database
pnpm add rik-database

This quickstart demonstrates basic CRUD (Create, Read, Update, Delete) operations using the `rik-database` ORM, including configuring the database connection, interacting with `Version` and `NetworkInterfaceSettings` models, and handling multiple inserts. It shows how to use named imports and instantiate models for data insertion.

import { DbSettings, Version, IVersion, NetworkInterfaceSettings } from 'rik-database';
import { createRequire } from 'module';

// Emulate CommonJS require for .env support in ESM context, or use dotenv directly
const require = createRequire(import.meta.url);
require('dotenv').config();

const dbConfig = {
    client: process.env.DB_CLIENT || 'pg',
    connection: {
        host: process.env.DB_HOST || 'localhost',
        user: process.env.DB_USER || 'user',
        password: process.env.DB_PASSWORD || 'password',
        database: process.env.DB_NAME || 'databaseName',
        port: process.env.DB_PORT ? parseInt(process.env.DB_PORT, 10) : 5432
    },
    pool: {
        min: 2,
        max: 10
    }
};

// Initialize database settings
DbSettings.setConfig(dbConfig);

class DatabaseOperations {
    public async demonstrateOperations(): Promise<void> {
        console.log('--- Demonstrating RIK Database ORM Operations ---');

        // Get current version data
        let currentVersion = await Version.query().orderBy('id', 'desc').first();
        console.log('\n+------- Current Version -------+');
        if (currentVersion) {
            console.log(currentVersion);
        } else {
            console.log('Version table is empty. Adding initial version.');
            const initialVersion: IVersion = { id: 1, name: 'Initial Version', number: '1.0.0', date: new Date().toISOString() };
            await Version.query().insert(initialVersion);
            currentVersion = await Version.query().orderBy('id', 'desc').first();
            console.log(currentVersion);
        }

        // Add a new version
        const newVersionData: IVersion = { name: 'Feature Update', number: '1.1.0', date: new Date().toISOString() };
        const newVersion = await Version.query().insert(newVersionData);
        console.log('\nNew version has been added. Version ID:', newVersion.id);

        // Update a version
        if (currentVersion) {
            const updatedVersionData: Partial<IVersion> = { name: 'Patched Feature Update' };
            const updatedVersion = await Version.query().patchAndFetchById(newVersion.id, updatedVersionData);
            console.log('\nVersion has been updated. Version:', updatedVersion);
        }

        // Insert multiple network settings with model instantiation
        try {
            const settingsToInsert = [
                new NetworkInterfaceSettings({
                    name: 'eth0', method_name: 'dhcp', ip_address: '0.0.0.0', gateway: '0.0.0.0'
                }),
                new NetworkInterfaceSettings({
                    name: 'eth1', method_name: 'static', ip_address: '192.168.1.100', gateway: '192.168.1.1'
                })
            ];
            const insertedSettings = await NetworkInterfaceSettings.query().insert(settingsToInsert);
            console.log('\nInserted Network Settings:', insertedSettings);
        } catch (error) {
            console.error('[DatabaseOperations:demonstrateOperations]: Error inserting settings:', error);
        }

        // Delete a version
        if (newVersion) {
            const deletedCount = await Version.query().deleteById(newVersion.id);
            console.log(`\nDeleted ${deletedCount} version(s) with ID ${newVersion.id}.`);
        }

        console.log('\n--- RIK Database ORM Operations Complete ---');
    }
}

// To run this example, ensure you have a .env file with DB_CLIENT, DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT.
// Example .env:
// DB_CLIENT=pg
// DB_HOST=localhost
// DB_USER=myuser
// DB_PASSWORD=mypassword
// DB_NAME=mydb
// DB_PORT=5432

const app = new DatabaseOperations();
app.demonstrateOperations().catch(console.error);