Skip to main content

QRepository

@quik/database


@quik/database / QRepository

Abstract Class: QRepository<TModel, TKeyType>

Defined in: database/src/repository/QRepository.ts:35

Abstract base repository class for database operations.

Extends

  • QObject

Type Parameters

TModel

TModel extends QModel

The model type

TKeyType

TKeyType = any

The type of the primary key (defaults to any)

Constructors

Constructor

protected new QRepository<TModel, TKeyType>(model): QRepository<TModel, TKeyType>

Defined in: database/src/repository/QRepository.ts:46

Creates an instance of QRepository.

Parameters

model

Constructor<TModel>

The model constructor

Returns

QRepository<TModel, TKeyType>

Overrides

QObject.constructor

Properties

_model

protected _model: Constructor<TModel>

Defined in: database/src/repository/QRepository.ts:83

The model constructor


_primaryKey

protected _primaryKey: string | string[] = "id"

Defined in: database/src/repository/QRepository.ts:57

The primary key field name or array of field names

Default

"id"

_sample

protected _sample: TModel

Defined in: database/src/repository/QRepository.ts:39

Sample instance of the model used for reflection and type operations

Accessors

isMysql

Get Signature

get protected isMysql(): boolean

Defined in: database/src/repository/QRepository.ts:109

Checks if the database is MySQL

Returns

boolean


knex

Get Signature

get protected knex(): Knex

Defined in: database/src/repository/QRepository.ts:95

Gets the Knex instance for database operations

Returns

Knex


logger

Get Signature

get protected logger(): IQLogger

Defined in: core/src/QObject.ts:15

The logger getter for the object.

Returns

IQLogger

Inherited from

QObject.logger


model

Get Signature

get protected model(): QueryBuilder<TModel>

Defined in: database/src/repository/QRepository.ts:88

Gets a query builder for the model

Returns

QueryBuilder<TModel>


modelConstructor

Get Signature

get protected modelConstructor(): Constructor<TModel>

Defined in: database/src/repository/QRepository.ts:76

Gets the model constructor

Returns

Constructor<TModel>


modelName

Get Signature

get protected modelName(): string

Defined in: database/src/repository/QRepository.ts:116

Gets the model name (entity name)

Returns

string


name

Get Signature

get name(): string

Defined in: core/src/QObject.ts:8

Returns

string

Inherited from

QObject.name


primaryKey

Get Signature

get primaryKey(): string | string[]

Defined in: database/src/repository/QRepository.ts:62

Gets the primary key field name or array of field names

Returns

string | string[]

Set Signature

set primaryKey(key): void

Defined in: database/src/repository/QRepository.ts:69

Sets the primary key field name or array of field names

Parameters
key

string | string[]

Returns

void


select

Get Signature

get protected select(): QueryBuilder<TModel>

Defined in: database/src/repository/QRepository.ts:102

Gets a query builder with columns selected based on the model's database mapping

Returns

QueryBuilder<TModel>

Methods

applyBulkIdsConstraint()

protected applyBulkIdsConstraint(queryBuilder, ids): QueryBuilder<TModel>

Defined in: database/src/repository/QRepository.ts:1600

Applies a primary-key filter for multiple ids to a query builder.

Uses whereIn for simple keys and grouped OR predicates for composite keys.

Parameters

queryBuilder

QueryBuilder<TModel>

Query builder to constrain

ids

(TModel | TKeyType)[]

Primary key values or entity instances

Returns

QueryBuilder<TModel>


bulkCreate()

bulkCreate(data): Promise<void>

Defined in: database/src/repository/QRepository.ts:689

Creates multiple entities in a single batch operation for improved performance.

This method efficiently handles bulk entity creation by:

  1. Processing input data (raw objects or existing model instances)
  2. Populating generated values that must exist before insert, such as UUID primary keys
  3. Validating all entities before database operations
  4. Performing a single database insert operation

Parameters

data

Partial<TModel>[]

Array of partial entity data or existing model instances to create. Each item can be either: - A plain object with entity properties - An existing QModel instance

Returns

Promise<void>

Throws

ValidationError If any entity fails validation

Throws

DatabaseError If the bulk insert operation fails

Example

// Create multiple users from plain objects
await userRepository.bulkCreate([
{ name: 'John Doe', email: 'john@example.com' },
{ name: 'Jane Smith', email: 'jane@example.com' }
]);

// Create from existing model instances
const users = [
userRepository.fill({ name: 'Alice', email: 'alice@example.com' }),
userRepository.fill({ name: 'Bob', email: 'bob@example.com' })
];
await userRepository.bulkCreate(users);

Performance

Use this method instead of multiple create() calls when inserting large datasets as it performs significantly better by reducing database round trips and transaction overhead.

See

  • create For creating single entities with return values
  • process For handling entities with different row states

bulkDelete()

bulkDelete(ids, force?): Promise<void>

Defined in: database/src/repository/QRepository.ts:809

Deletes multiple entities by primary key values or model instances.

Uses a single query for simple primary keys. Composite primary keys reuse the single-entity delete path to preserve query correctness.

Parameters

ids

(TModel | TKeyType)[]

Array of primary key values or existing entity instances

force?

boolean

Whether to force delete instead of soft delete

Returns

Promise<void>


bulkUpdate()

bulkUpdate(ids, data): Promise<void>

Defined in: database/src/repository/QRepository.ts:703

Updates multiple entities with the same partial data using a single SQL update.

Parameters

ids

(TModel | TKeyType)[]

Array of primary key values or existing entity instances

data

Partial<TModel>

Partial data applied to every matched row

Returns

Promise<void>


cleanEmptyKeys()

protected cleanEmptyKeys(data): Record<string, unknown>

Defined in: database/src/repository/QRepository.ts:1701

Removes null/undefined and empty object literals from an object graph.

Parameters

data

Record<string, unknown>

Returns

Record<string, unknown>


count()

count(findOptions?): Promise<number>

Defined in: database/src/repository/QRepository.ts:1062

Counts the number of entities matching the specified conditions.

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering entities to count

Returns

Promise<number>

Throws

DatabaseError If the count operation fails

Example

// Count all entities
const totalUsers = await userRepository.count();

// Count with conditions
const activeUserCount = await userRepository.count({
where: { status: 'active' }
});

// Count with complex conditions
const recentUserCount = await userRepository.count({
where: [{
field: 'createdAt',
operator: 'gt',
value: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // 7 days ago
}]
});

Performance

More efficient than retrieving entities and counting them in memory

See

  • get For retrieving entities matching conditions
  • paged For paginated results with total count

countBy()

Call Signature

countBy<TResult>(findOptions): Promise<TResult[]>

Defined in: database/src/repository/QRepository.ts:1096

Counts entities grouped by selected fields and returns raw aggregate rows.

Type Parameters
TResult

TResult extends Record<string, unknown> = Record<string, unknown>

Parameters
findOptions

QGroupedCountOptions<TModel>

Grouped count options

Returns

Promise<TResult[]>

Example
const rows = await requestRepository.countBy<{
date: string;
status: string;
count: number;
}>({
select: [
{ field: 'createdAt', as: 'date', transform: 'date' },
'status'
],
count: { field: 'id' },
sort: [{ field: 'date', direction: 'asc' }]
});

Call Signature

countBy<TEntity>(entity, findOptions): Promise<TEntity[]>

Defined in: database/src/repository/QRepository.ts:1099

Counts entities grouped by selected fields and returns raw aggregate rows.

Type Parameters
TEntity

TEntity extends QEntity

Parameters
entity

Constructor<TEntity>

findOptions

QGroupedCountOptions<TModel>

Grouped count options

Returns

Promise<TEntity[]>

Example
const rows = await requestRepository.countBy<{
date: string;
status: string;
count: number;
}>({
select: [
{ field: 'createdAt', as: 'date', transform: 'date' },
'status'
],
count: { field: 'id' },
sort: [{ field: 'date', direction: 'asc' }]
});

create()

create(data): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:616

Creates a single entity and returns the created instance with generated fields.

This method handles entity creation by:

  1. Processing input data (raw object or existing model instance)
  2. Populating generated values that must exist before insert, such as UUID primary keys
  3. Validating the entity before database operations
  4. Inserting into database and retrieving generated fields (like auto-increment IDs) while preserving application-generated UUID values when the database returns scalar insert results
  5. Returning the complete entity instance

Parameters

data

Partial<TModel>

The entity data or existing model instance to create. Can be either: - A plain object with entity properties - An existing QModel instance

Returns

Promise<TModel>

Throws

ValidationError If the entity fails validation

Throws

DatabaseError If the insert operation fails

Example

// Create from plain object
const user = await userRepository.create({
name: 'John Doe',
email: 'john@example.com'
});
console.log(user.id); // Auto-generated ID

// Create from existing model instance
const userModel = userRepository.fill({ name: 'Jane', email: 'jane@example.com' });
const created = await userRepository.create(userModel);

Performance

For bulk operations, consider using bulkCreate() instead

See

  • bulkCreate For creating multiple entities efficiently
  • update For modifying existing entities

delete()

delete(id, force?): Promise<void>

Defined in: database/src/repository/QRepository.ts:785

Deletes an entity from the database, with support for soft delete.

This method handles entity deletion by:

  1. Retrieving the entity (if ID provided) or using provided instance
  2. Checking soft delete support and force parameter
  3. Either soft deleting (updating delete timestamp) or hard deleting

Parameters

id

TModel | TKeyType

The primary key value of the entity to delete, or an existing entity instance

force?

boolean

Whether to force delete (ignore soft delete), defaults to false

Returns

Promise<void>

Throws

ItemNotFoundError If no entity is found with the given id

Throws

DatabaseError If the delete operation fails

Example

// Soft delete (if supported by model)
await userRepository.delete(123);

// Force hard delete
await userRepository.delete(123, true);

// Delete existing entity instance
const user = await userRepository.findById(123);
await userRepository.delete(user);

See

  • deleteBy For bulk deletion with conditions
  • restore For restoring soft-deleted entities

deleteBy()

deleteBy(where, force?): Promise<void>

Defined in: database/src/repository/QRepository.ts:865

Deletes multiple entities that match the specified conditions.

This method efficiently performs bulk deletion by:

  1. Building a query with the provided where conditions
  2. Checking soft delete support and force parameter
  3. Either updating the soft delete timestamp or performing hard deletion

Parameters

where

QWhereCondition | QWhereBuilder | QWhereCondition[] | Partial<{ [k in string | number | symbol]: TModel[k] }>

Conditions to match entities for deletion, can be: - A QWhereBuilder instance for complex conditions - A single QWhereCondition object - An array of QWhereCondition objects - A partial entity object with field values to match

force?

boolean

Whether to force delete (ignore soft delete), defaults to false

Returns

Promise<void>

Throws

DatabaseError If the delete operation fails

Example

// Delete all inactive users
await userRepository.deleteBy({ status: 'inactive' });

// Delete with complex conditions
await userRepository.deleteBy({
field: 'lastLoginDate',
operator: 'lt',
value: new Date(Date.now() - 90 * 24 * 60 * 60 * 1000) // 90 days ago
});

// Force hard delete (bypass soft delete)
await userRepository.deleteBy({ role: 'guest' }, true);

Performance

This is more efficient than finding and deleting entities individually

See

  • delete For deleting a single entity
  • restore For restoring soft-deleted entities

endSpan()

protected endSpan(span): void

Defined in: core/src/QObject.ts:35

End a span returned by startSpan.

Parameters

span

TelemetrySpan

The span to end.

Returns

void

Inherited from

QObject.endSpan


ensureGeneratedValues()

protected ensureGeneratedValues(item): void

Defined in: database/src/repository/QRepository.ts:1526

Populates generated fields that must exist before persistence.

UUID primary-generated columns are created in application code so inserts always receive a concrete identifier even when the database does not generate one automatically.

Parameters

item

TModel

Entity being prepared for persistence

Returns

void


fill()

protected fill(options?, initial?, fillOptions?): TModel

Defined in: database/src/repository/QRepository.ts:1509

Internal

Creates and fills a new entity instance with the provided data.

This factory method handles entity creation by:

  1. Getting the entity class from the store
  2. Instantiating a new entity instance
  3. Filling it with the provided data
  4. Properly setting the row state based on whether it's a new or existing entity

fill() does not validate the entity or enforce uniqueness constraints. Use create()/update() (or validate() directly) when you need validation.

Parameters

options?

Partial<ReferenceObject<TModel>>

The data to fill the entity with (properties and their values)

initial?

boolean = false

Whether this is an initial fill of an existing entity (affects row state)

fillOptions?
applyDefaults?

boolean

Returns

TModel

Example

// Create a new entity instance
const user = this.fill({ name: 'John', email: 'john@example.com' });

// Create from database (existing record)
const existingUser = this.fill(databaseRow, true);

Core method used throughout the repository for entity creation

See

  • create For publicly creating and persisting entities
  • modelBuilder For creating entities from database results

find()

find(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:328

Finds a single entity based on find options, returning null if not found.

This method provides safe entity retrieval by:

  1. Building query with provided options (excluding relations initially)
  2. Retrieving the first matching record
  3. Loading relations if specified
  4. Returning null instead of throwing when no entity found

This method provides safe entity retrieval by:

  1. Building query with provided options (excluding relations initially)
  2. Retrieving the first matching record
  3. Loading relations if specified
  4. Returning null instead of throwing when no entity found

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Throws

DatabaseError If the query execution fails

Examples

// Find by condition
const user = await userRepository.find({
where: { email: 'user@example.com' }
});

if (user) {
console.log('User found:', user.name);
} else {
console.log('User not found');
}

// Find with relations
const userWithPosts = await userRepository.find({
where: { id: 123 },
relations: { posts: true }
});
// Find by condition
const user = await userRepository.find({
where: { email: 'user@example.com' }
});

if (user) {
console.log('User found:', user.name);
} else {
console.log('User not found');
}

// Find with relations
const userWithPosts = await userRepository.find({
where: { id: 123 },
relations: { posts: true }
});

See

  • findFirst For finding with exception on not found
  • findById For finding by primary key
  • findFirst For finding with exception on not found
  • findById For finding by primary key

findById()

findById(id, options?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:571

Finds an entity by its primary key with optional related data loading.

This method provides a convenient way to retrieve entities when you know their ID by:

  1. Creating a where condition based on the primary key
  2. Finding the entity using findFirst with that condition
  3. Loading any specified relations
  4. Throwing an error if the entity doesn't exist

Parameters

id

TKeyType

The primary key value (single value for simple keys, object for composite keys)

options?

QRelationFindOption

Relations to include in the result

Returns

Promise<TModel>

Throws

ItemNotFoundError If no entity is found with the given id

Throws

DatabaseError If the query execution fails

Example

// Find by ID without relations
const user = await userRepository.findById(123);

// Find by ID with relations
const userWithPosts = await userRepository.findById(123, {
relations: ['posts', 'profile']
});

// Find by composite key (if primaryKey is an array)
const orderItem = await orderItemRepository.findById({ orderId: 456, productId: 789 });

See

  • find For finding with custom conditions without throwing
  • findFirst For finding with custom conditions that throws

findDeleted()

findDeleted(findOptions?): Promise<TModel[]>

Defined in: database/src/repository/QRepository.ts:944

Retrieve only soft-deleted entities.

Parameters

findOptions?

QFindOptions<TModel>

Returns

Promise<TModel[]>

Throws

SoftDeleteUnsupportedError If the model does not support soft delete.

Example

const deletedUsers = await userRepository.findDeleted();

finder()

protected finder(item, findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:1141

Internal

Finds an entity with its relations loaded based on find options.

Parameters

item

TModel

The base entity data from the initial query

findOptions?

QFindOptions<TModel>

Options containing relation specifications

Returns

Promise<TModel>

Throws

DatabaseError If relation loading fails

Example

// This is an internal method used by find, findFirst, etc.
// Used internally like:
const baseUser = await query.first();
return this.finder(baseUser, { relations: ['posts', 'profile'] });

Used by public find methods to load relations

See

  • find For public API to find entities with relations
  • modelBuilder For creating model instances from data

findFirst()

findFirst(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:411

Finds the first entity matching the provided find options and throws if not found.

This method is similar to find() but ensures an entity exists by:

  1. Building query with provided options
  2. Retrieving the first matching record
  3. Throwing an error if no entity is found
  4. Loading relations if specified

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Throws

ItemNotFoundError If no entity is found

Throws

DatabaseError If the query execution fails

Example

try {
// Find first active admin user
const admin = await userRepository.findFirst({
where: { role: 'admin', status: 'active' }
});
// Admin is guaranteed to exist here
console.log(admin.name);
} catch (error) {
console.error('No admin user found');
}

See

  • find For finding without throwing exceptions
  • findLast For finding the last matching entity

findFirstOrNull()

findFirstOrNull(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:454

Finds the first entity matching the provided find options, returning null instead of throwing.

This method provides a safe way to use findFirst by:

  1. Attempting to retrieve the first matching entity
  2. Catching any exceptions, including ItemNotFoundError
  3. Always returning null in case of errors instead of propagating exceptions

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Example

// Safe retrieval of first matching entity
const admin = await userRepository.findFirstOrNull({
where: { role: 'admin', status: 'active' }
});

// Safe to use without try/catch
if (admin) {
console.log('Admin found:', admin.name);
} else {
console.log('No admin found or error occurred');
}

See

  • findFirst For finding with exception on not found
  • findOrNull For finding any matching entity without throwing

findLast()

findLast(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:492

Finds the last entity matching the provided find options and throws if not found.

This method retrieves the last entity (by primary key order) by:

  1. Building query with provided options
  2. Ordering by primary key in descending order
  3. Retrieving the first result (which is the last by primary key)
  4. Throwing an error if no entity is found
  5. Loading relations if specified

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Throws

ItemNotFoundError If no entity is found

Throws

DatabaseError If the query execution fails

Example

// Find the most recently created user (assuming id is auto-incremented)
const newestUser = await userRepository.findLast();

// Find the last active user by creation date
const lastActiveUser = await userRepository.findLast({
where: { status: 'active' },
sort: [{ field: 'createdAt', direction: 'desc' }]
});

See

  • findFirst For finding the first matching entity
  • find For finding without throwing exceptions

findLastOrNull()

findLastOrNull(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:531

Finds the last entity matching the provided find options, returning null instead of throwing.

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Example

const latestUser = await userRepository.findLastOrNull({
where: { status: 'active' }
});

See

findLast For finding the last matching entity with exceptions


findOrNull()

findOrNull(findOptions?): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:372

Finds a single entity based on find options, returning null if not found or on error.

This method provides a safe way to find entities by:

  1. Attempting to retrieve an entity using the find method
  2. Catching any exceptions that might occur during the process
  3. Always returning null in case of any errors instead of propagating exceptions

Parameters

findOptions?

QFindOptions<TModel>

Options for filtering and including relations

Returns

Promise<TModel>

Example

// Safe retrieval that never throws
const user = await userRepository.findOrNull({
where: { email: 'user@example.com' },
relations: ['profile']
});

// Safe to use without try/catch
if (user) {
console.log('User found:', user.name);
} else {
console.log('User not found or error occurred');
}

See

  • find For finding with null return but possible exceptions
  • findFirst For finding with exception on not found

findWithDeleted()

findWithDeleted(findOptions?): Promise<TModel[]>

Defined in: database/src/repository/QRepository.ts:964

Retrieve all entities, including soft-deleted ones.

Parameters

findOptions?

QFindOptions<TModel>

Returns

Promise<TModel[]>

Throws

SoftDeleteUnsupportedError If the model does not support soft delete.

Example

const allUsers = await userRepository.findWithDeleted();

get()

get(findOptions?): Promise<TModel[]>

Defined in: database/src/repository/QRepository.ts:255

Retrieves a list of entities based on flexible find options.

This method provides comprehensive querying capabilities including:

  1. Filtering with where conditions
  2. Sorting and ordering
  3. Pagination with offset/limit
  4. Including related entities
  5. Data transformation and model building

Parameters

findOptions?

QFindOptions<TModel>

Comprehensive options for filtering, sorting, pagination, and relations

Returns

Promise<TModel[]>

Throws

DatabaseError If the query execution fails

Example

// Simple query
const users = await userRepository.get();

// With filtering and sorting
const activeUsers = await userRepository.get({
where: { status: 'active' },
sort: { name: 'asc' },
limit: 10
});

// With relations
const usersWithPosts = await userRepository.get({
relations: { posts: true }
});

Performance

Consider using pagination for large datasets

See

  • find For retrieving a single entity
  • paged For paginated results with metadata

getEntityId()

protected getEntityId(item): TKeyType

Defined in: database/src/repository/QRepository.ts:1580

Internal

Extracts the primary key value from an entity for identification purposes.

This method retrieves ID values by:

  1. Checking if the primary key is single or composite
  2. For single keys, returning the value directly
  3. For composite keys, building an object with all key parts
  4. Maintaining the correct key structure for later operations

Parameters

item

TModel

The entity to extract the ID from

Returns

TKeyType

Examples

// For a simple primary key
const userId = this.getEntityId(user);
// Result: 123

// For a composite primary key
const orderLineId = this.getEntityId(orderLine);
// Result: { orderId: 456, lineId: 2 }

Used by various methods that need entity identification

// For a simple primary key
const userId = this.getEntityId(user);
// Result: 123

// For a composite primary key
const orderLineId = this.getEntityId(orderLine);
// Result: { orderId: 456, lineId: 2 }

Used by various methods that need entity identification

See


getFlaggedField()

protected getFlaggedField(flag): string

Defined in: database/src/repository/QRepository.ts:1381

Internal

Gets the first field name that has the specified flag in the model definition.

This utility method finds fields with specific metadata flags by:

  1. Searching through all model fields for a specific flag
  2. Returning the name of the first field with that flag
  3. Enabling generic operations based on field metadata

Parameters

flag

string

The flag name to search for (e.g., 'primary', 'generated', 'unique')

Returns

string

Example

// Find the primary key field
const pkField = this.getFlaggedField('primary');

// Find the auto-generated field
const generatedField = this.getFlaggedField('generated');

Used by various methods to work with flagged fields

See

QModel.getFlaggedField For the underlying implementation


getPrimaryKey()

protected getPrimaryKey(id): { [k in string | number | symbol]: TModel[k] }

Defined in: database/src/repository/QRepository.ts:1411

Internal

Converts a primary key value to a flattened where condition for queries.

This method handles both simple and composite primary keys by:

  1. Determining if the primary key is a single field or multiple fields
  2. Creating appropriate where conditions for each primary key component
  3. Formatting the conditions with table name qualification
  4. Supporting both simple values and complex objects for composite keys

Parameters

id

TKeyType

The primary key value (single value or object for composite keys)

Returns

{ [k in string | number | symbol]: TModel[k] }

Example

// For a simple primary key
const whereCondition = this.getPrimaryKey(123);
// Result: { 'User.id': 123 }

// For a composite primary key
const whereCondition = this.getPrimaryKey({ orderId: 456, lineId: 2 });
// Result: { 'OrderLine.orderId': 456, 'OrderLine.lineId': 2 }

Used by find and update operations to locate entities

See

getPrimaryKeyFromEntity For extracting keys from entity instances


getPrimaryKeyFromEntity()

protected getPrimaryKeyFromEntity(entity): { [k in string | number | symbol]: TModel[k] }

Defined in: database/src/repository/QRepository.ts:1460

Internal

Extracts the primary key values from an entity and formats them as a where condition.

This method extracts primary key data from an existing entity by:

  1. Determining if the primary key consists of one or multiple fields
  2. Extracting the primary key values from the entity
  3. Creating properly formatted where conditions with table qualification
  4. Supporting both simple and composite primary keys

Parameters

entity

TModel

The entity instance to extract primary key from

Returns

{ [k in string | number | symbol]: TModel[k] }

Example

// Extracting key from a user entity
const user = await userRepository.findById(123);
const whereCondition = this.getPrimaryKeyFromEntity(user);
// Result: { 'User.id': 123 }

// For an entity with composite key
const orderLine = await orderLineRepository.findById({orderId: 456, lineId: 2});
const whereCondition = this.getPrimaryKeyFromEntity(orderLine);
// Result: { 'OrderLine.orderId': 456, 'OrderLine.lineId': 2 }

Used for building where conditions from existing entities

See

  • getPrimaryKey For creating conditions from raw key values
  • getEntityId For extracting just the ID values without table qualification

joinQuery()

protected joinQuery<TResult>(resultEntity): QJoinQueryBuilder<TModel, TResult>

Defined in: database/src/repository/QRepository.ts:127

Starts a QJoinQueryBuilder for queries that join across tables not declared as @Relations on this model and return a custom result shape, instead of instances of TModel.

Type Parameters

TResult

TResult extends QEntity

Parameters

resultEntity

Constructor<TResult>

@Entity()-decorated class describing the shape rows are mapped into.

Returns

QJoinQueryBuilder<TModel, TResult>

See

QJoinQueryBuilder For the fluent join/where/select API and usage examples.


modelBuilder()

protected modelBuilder(flattened): TModel

Defined in: database/src/repository/QRepository.ts:1204

Internal

Builds a complete model instance from flattened database data.

This method handles data transformation by:

  1. Removing null values from the flattened data
  2. Unflattening the hierarchical structure
  3. Creating a properly typed model instance
  4. Marking the instance as an existing database record

This method handles data transformation by:

  1. Removing null values from the flattened data
  2. Unflattening the hierarchical structure
  3. Creating a properly typed model instance
  4. Marking the instance as an existing database record

Parameters

flattened

{ [k in string | number | symbol]: TModel[k] }

The flattened data from database query results

Returns

TModel

Examples

// Used internally to convert raw database rows to model instances
const rawRows = await database.query();
return rawRows.map(row => this.modelBuilder(row));

Used by query methods to convert database rows to model instances

// Used internally to convert raw database rows to model instances
const rawRows = await database.query();
return rawRows.map(row => this.modelBuilder(row));

Used by query methods to convert database rows to model instances

See

  • fill For creating new model instances
  • transformData For processing raw database results
  • fill For creating new model instances
  • transformData For processing raw database results

modelBuilderFromObject()

protected modelBuilderFromObject(data): TModel

Defined in: database/src/repository/QRepository.ts:1212

Builds a model instance from an already-unflattened object.

Parameters

data

Partial<TModel>

Returns

TModel


paged()

paged<TPagedEntity>(parameters?, relations?): Promise<TPagedEntity>

Defined in: database/src/repository/QRepository.ts:171

Retrieves a paginated list of entities with metadata about the pagination.

This method provides sophisticated pagination by:

  1. Calculating the total count of matching entities
  2. Determining correct page boundaries and navigation state
  3. Retrieving only the entities for the requested page
  4. Including pagination metadata like page counts and navigation flags

Type Parameters

TPagedEntity

TPagedEntity extends QPaginatedEntity<TModel> = QPaginatedEntity<TModel>

The paginated result type (defaults to QPaginatedEntity)

Parameters

parameters?

QPaginatedParameters

Pagination configuration including page number, page size, and filters

relations?

QRelationFindOption

Optional relations to include with the entities

Returns

Promise<TPagedEntity>

Throws

DatabaseError If any database operation fails

Example

// Basic pagination
const result = await userRepository.paged(
new QPaginatedParameters({ page: 2, size: 10 })
);
console.log(`Showing ${result.data.length} of ${result.count} results`);
console.log(`Page ${result.page} of ${Math.ceil(result.count / result.size)}`);

// Pagination with filtering and relations
const filteredResult = await userRepository.paged(
new QPaginatedParameters({
page: 1,
size: 25,
filter: { status: 'active' }
}),
{ relations: ['profile', 'posts'] }
);

Performance

Optimized for efficient data retrieval of large datasets

See

  • get For retrieving entities without pagination
  • count For just counting matching entities

process()

process(...items): Promise<TModel[]>

Defined in: database/src/repository/QRepository.ts:1010

Processes multiple entities based on their row state (created, modified, deleted).

This intelligent method handles mixed entity operations by:

  1. Examining each entity's row state flag
  2. Performing the appropriate operation (create, update, or delete)
  3. Collecting and returning the created/updated entities

Parameters

items

...TModel[]

The entities to process, each with an appropriate row state flag

Returns

Promise<TModel[]>

Throws

ValidationError If any entity fails validation

Throws

ItemNotFoundError If an entity to update/delete cannot be found

Throws

DatabaseError If any database operation fails

Example

// Create a mix of entities with different states
const newUser = userRepository.fill({ name: 'New User' });
newUser.rowState = QRowState.CREATED;

const existingUser = await userRepository.findById(123);
existingUser.name = 'Updated Name';
existingUser.rowState = QRowState.MODIFIED;

const userToDelete = await userRepository.findById(456);
userToDelete.rowState = QRowState.DELETED;

// Process all entities in a single call
const results = await userRepository.process(newUser, existingUser, userToDelete);
// results contains newUser and existingUser (not userToDelete as it was deleted)

Performance

More efficient than calling individual methods for each entity

See

  • create For creating single entities
  • update For updating single entities
  • delete For deleting single entities

recordSpanError()

protected recordSpanError(span, err): void

Defined in: core/src/QObject.ts:45

Record an exception on an active span.

Parameters

span

TelemetrySpan

The span to record the error on.

err

unknown

The error to record.

Returns

void

Inherited from

QObject.recordSpanError


restore()

restore(id): Promise<void>

Defined in: database/src/repository/QRepository.ts:921

Restores a previously soft-deleted entity by clearing its deletion timestamp.

Parameters

id

TKeyType

The primary key value of the entity to restore

Returns

Promise<void>

Throws

SoftDeleteUnsupportedError If the model doesn't support soft delete

Throws

ItemNotFoundError If no soft-deleted entity is found with the given id

Throws

DatabaseError If the restore operation fails

Example

try {
// Restore a previously deleted user
await userRepository.restore(123);
console.log('User restored successfully');
} catch (error) {
if (error instanceof SoftDeleteUnsupportedError) {
console.error('This model does not support soft delete');
} else if (error instanceof ItemNotFoundError) {
console.error('No deleted user found with that ID');
} else {
console.error('Failed to restore user:', error);
}
}

See

  • delete For soft-deleting entities
  • deleteBy For soft-deleting multiple entities

setSpanAttribute()

protected setSpanAttribute(span, key, value): void

Defined in: core/src/QObject.ts:64

Set a single attribute on an active span.

Parameters

span

TelemetrySpan

The span to update.

key

string

Attribute key.

value

string | number | boolean

Attribute value.

Returns

void

Inherited from

QObject.setSpanAttribute


skippableField()

protected skippableField(definition): boolean

Defined in: database/src/repository/QRepository.ts:1283

Parameters

definition

QEntityProperty

Returns

boolean


startSpan()

protected startSpan(spanName, options?): TelemetrySpan

Defined in: core/src/QObject.ts:26

Start a telemetry span for the given operation name. Returns undefined when no telemetry provider is active.

Parameters

spanName

string

Name of the span.

options?

TelemetrySpanOptions

Optional span attributes and kind.

Returns

TelemetrySpan

Inherited from

QObject.startSpan


toDatabaseFields()

protected toDatabaseFields(data): Record<string, unknown>

Defined in: database/src/repository/QRepository.ts:1258

Internal

Converts a model instance to a database field map for persistence operations.

This method prepares entity data for database operations by:

  1. Mapping model property names to database column names
  2. Transforming special data types (like dates) to database-compatible formats
  3. Including only defined fields from the model
  4. Handling data type conversions for the specific database dialect

This method prepares entity data for database operations by:

  1. Mapping model property names to database column names
  2. Transforming special data types (like dates) to database-compatible formats
  3. Including only defined fields from the model
  4. Handling data type conversions for the specific database dialect

Parameters

data

TModel

The model instance to convert to database fields

Returns

Record<string, unknown>

Examples

// Used internally during save operations
const dbFields = this.toDatabaseFields(userModel);
await database.table('users').insert(dbFields);

Used by persistence methods to prepare data for database operations

// Used internally during save operations
const dbFields = this.toDatabaseFields(userModel);
await database.table('users').insert(dbFields);

Used by persistence methods to prepare data for database operations

See


transformData()

protected transformData<T>(data): T

Defined in: database/src/repository/QRepository.ts:1663

Internal

Transforms raw database query results into structured entity data.

This complex method handles result transformation by:

  1. Converting flattened database rows to hierarchical objects
  2. Parsing and correctly formatting date/time fields
  3. Handling nested relations and many-to-many associations
  4. Building complete object graphs from joined query results

This complex method handles result transformation by:

  1. Converting flattened database rows to hierarchical objects
  2. Parsing and correctly formatting date/time fields
  3. Handling nested relations and many-to-many associations
  4. Building complete object graphs from joined query results
  5. Supporting both single entity and collection transformations

Type Parameters

T

T = Record<string, any>[]

The expected return type (typically an array of records)

Parameters

data

T

The raw data from database queries to transform

Returns

T

Examples

// Used internally after database queries
const rawResults = await knex('users').leftJoin('profiles', 'users.id', 'profiles.user_id');
const transformedData = this.transformData(rawResults);
// Result: Hierarchical user objects with nested profile objects

Core data transformation method used by query methods

// Used internally after database queries
const rawResults = await knex('users').leftJoin('profiles', 'users.id', 'profiles.user_id');
const transformedData = this.transformData(rawResults);
// Result: Hierarchical user objects with nested profile objects

Core data transformation method used by query methods

See

  • modelBuilder For converting transformed data to model instances
  • _parseDateItem For handling individual record parsing
  • modelBuilder For converting transformed data to model instances
  • _parseDateItem For handling individual record parsing

transformDataRaw()

protected transformDataRaw<T>(data): T

Defined in: database/src/repository/QRepository.ts:1682

Transforms raw database data into unflattened objects for relation-heavy queries.

Type Parameters

T

T = Record<string, any>[]

Parameters

data

T

Returns

T


transformDateTime()

protected transformDateTime(definition, value): any

Defined in: database/src/repository/QRepository.ts:1336

Internal

Transforms date and datetime fields to database-compatible formats.

This method handles date/time conversions by:

  1. Checking if the field is marked as a date or datetime type
  2. Converting JavaScript Date objects or ISO strings to SQL-compatible formats
  3. Ensuring proper formatting based on field type (date vs. datetime)
  4. Returning non-date values unchanged

This method handles date/time conversions by:

  1. Checking if the field is marked as a date or datetime type
  2. Converting JavaScript Date objects or ISO strings to SQL-compatible formats
  3. Ensuring proper formatting based on field type (date vs datetime)
  4. Returning non-date values unchanged

Parameters

definition

QEntityProperty

The field definition form the model

value

any

The value to transform

Returns

any

Examples

// Used internally during database field mapping
result['created_at'] = this.transformDateTime('createdAt', model.createdAt);
// For a date field: '2023-06-15'
// For a datetime field: '2023-06-15 14:30:00'

Used by toDatabaseFields to handle date conversions

// Used internally during database field mapping
result['created_at'] = this.transformDateTime('createdAt', model.createdAt);
// For a date field: '2023-06-15'
// For a datetime field: '2023-06-15 14:30:00'

Used by toDatabaseFields to handle date conversions

See


update()

update(id, data): Promise<TModel>

Defined in: database/src/repository/QRepository.ts:744

Updates an existing entity with new data and returns the updated instance.

This method handles entity updates by:

  1. Retrieving the existing entity (if ID provided) or using provided instance
  2. Applying the new data to the entity
  3. Validating the updated entity
  4. Persisting changes to the database

Parameters

id

TModel | TKeyType

The primary key value of the entity to update, or an existing entity instance

data

Partial<TModel>

The partial data to update the entity with

Returns

Promise<TModel>

Throws

ItemNotFoundError If no entity is found with the given id

Throws

ValidationError If the updated entity fails validation

Throws

DatabaseError If the update operation fails

Example

// Update by ID
const updatedUser = await userRepository.update(123, {
name: 'Updated Name',
email: 'new@example.com'
});

// Update existing entity instance
const user = await userRepository.findById(123);
const updated = await userRepository.update(user, { name: 'New Name' });

See

  • create For creating new entities
  • delete For removing entities