forge-sql-orm 1.0.23 → 1.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/dist/ForgeSQLORM.js +6 -5
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +6 -5
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts +2 -2
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +1 -1
- package/package.json +1 -1
- package/src/core/ForgeSQLORM.ts +7 -4
- package/src/core/ForgeSQLQueryBuilder.ts +1 -1
package/README.md
CHANGED
|
@@ -125,6 +125,8 @@ import ENTITIES from "./entities";
|
|
|
125
125
|
const forgeSQL = new ForgeSQL(ENTITIES);
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
+
|
|
129
|
+
|
|
128
130
|
- Fetch Data:
|
|
129
131
|
|
|
130
132
|
```js
|
|
@@ -495,6 +497,83 @@ console.log(results);
|
|
|
495
497
|
|
|
496
498
|
---
|
|
497
499
|
|
|
500
|
+
## ForgeSqlOrmOptions
|
|
501
|
+
|
|
502
|
+
The `ForgeSqlOrmOptions` object allows customization of ORM behavior. Currently, it supports the following options:
|
|
503
|
+
|
|
504
|
+
| Option | Type | Description |
|
|
505
|
+
|------------------|---------|-------------|
|
|
506
|
+
| `logRawSqlQuery` | `boolean` | Enables logging of SQL queries in the Atlassian Forge Developer Console. Useful for debugging and monitoring. Defaults to `false`. |
|
|
507
|
+
|
|
508
|
+
### Example: Initializing `ForgeSQL` with Options
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
import ForgeSQL from "forge-sql-orm";
|
|
512
|
+
import { Orders } from "./entities/Orders";
|
|
513
|
+
import { Users } from "./entities/Users";
|
|
514
|
+
import ENTITIES from "./entities";
|
|
515
|
+
|
|
516
|
+
const options = {
|
|
517
|
+
logRawSqlQuery: true, // Enable query logging for debugging purposes
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
const forgeSQL = new ForgeSQL(ENTITIES, options);
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
## Using `getKnex()` for Advanced SQL Queries
|
|
526
|
+
|
|
527
|
+
The `getKnex()` method allows direct interaction with Knex.js, enabling execution of raw SQL queries and complex query building.
|
|
528
|
+
|
|
529
|
+
### Example: Finding Duplicate Records in `UsersSchema`
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
const fields: string[] = ["name", "email"];
|
|
533
|
+
|
|
534
|
+
// Define selected fields, including a count of duplicate occurrences
|
|
535
|
+
const selectFields: Array<string | Knex.Raw> = [
|
|
536
|
+
...fields,
|
|
537
|
+
forgeSQL.getKnex().raw("COUNT(*) as count"),
|
|
538
|
+
];
|
|
539
|
+
|
|
540
|
+
// Create a QueryBuilder with grouping and filtering for duplicates
|
|
541
|
+
let selectQueryBuilder = forgeSQL
|
|
542
|
+
.createQueryBuilder(UsersSchema)
|
|
543
|
+
.select(selectFields as unknown as string[])
|
|
544
|
+
.groupBy(fields)
|
|
545
|
+
.having("COUNT(*) > 1");
|
|
546
|
+
|
|
547
|
+
// Generate the final SQL query with ordering by count
|
|
548
|
+
const query = selectQueryBuilder
|
|
549
|
+
.getKnexQuery()
|
|
550
|
+
.orderByRaw("count ASC")
|
|
551
|
+
.toSQL().sql;
|
|
552
|
+
|
|
553
|
+
/*
|
|
554
|
+
SQL Query:
|
|
555
|
+
SELECT `u0`.`name`, `u0`.`email`, COUNT(*) as count
|
|
556
|
+
FROM `users` AS `u0`
|
|
557
|
+
GROUP BY `u0`.`name`, `u0`.`email`
|
|
558
|
+
HAVING COUNT(*) > 1
|
|
559
|
+
ORDER BY count ASC;
|
|
560
|
+
*/
|
|
561
|
+
|
|
562
|
+
// Execute the SQL query and retrieve results
|
|
563
|
+
const duplicateResult = await forgeSQL
|
|
564
|
+
.fetch()
|
|
565
|
+
.executeSchemaSQL<DuplicateResult>(query, DuplicateSchema);
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
🔹 **What does this example do?**
|
|
569
|
+
1. Selects `name` and `email`, along with the count of duplicate occurrences (`COUNT(*) as count`).
|
|
570
|
+
2. Groups the data by `name` and `email` to identify duplicates.
|
|
571
|
+
3. Filters the results to include only groups with more than one record (`HAVING COUNT(*) > 1`).
|
|
572
|
+
4. Sorts the final results in ascending order by count (`ORDER BY count ASC`).
|
|
573
|
+
5. Executes the SQL query and returns the duplicate records.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
498
577
|
## Usage with MikroORM Generator
|
|
499
578
|
|
|
500
579
|
If you prefer to use MikroORM's default entity generator, then manually import your entities:
|
package/dist/ForgeSQLORM.js
CHANGED
|
@@ -265,11 +265,12 @@ class ForgeSQLORMImpl {
|
|
|
265
265
|
/**
|
|
266
266
|
* Returns the singleton instance of ForgeSQLORMImpl.
|
|
267
267
|
* @param entities - List of entities (required only on first initialization).
|
|
268
|
+
* @param options - Options for configuring ForgeSQL ORM behavior.
|
|
268
269
|
* @returns The singleton instance of ForgeSQLORMImpl.
|
|
269
270
|
*/
|
|
270
|
-
static getInstance(entities) {
|
|
271
|
+
static getInstance(entities, options) {
|
|
271
272
|
if (!ForgeSQLORMImpl.instance) {
|
|
272
|
-
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);
|
|
273
|
+
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities, options);
|
|
273
274
|
}
|
|
274
275
|
return ForgeSQLORMImpl.instance;
|
|
275
276
|
}
|
|
@@ -298,7 +299,7 @@ class ForgeSQLORMImpl {
|
|
|
298
299
|
return this.mikroORM.em.createQueryBuilder(entityName, alias, void 0, loggerContext);
|
|
299
300
|
}
|
|
300
301
|
/**
|
|
301
|
-
* Provides access to the underlying Knex instance for
|
|
302
|
+
* Provides access to the underlying Knex instance for building complex query parts.
|
|
302
303
|
* enabling advanced query customization and performance tuning.
|
|
303
304
|
* @returns The Knex instance, which can be used for query building.
|
|
304
305
|
*/
|
|
@@ -308,8 +309,8 @@ class ForgeSQLORMImpl {
|
|
|
308
309
|
}
|
|
309
310
|
class ForgeSQLORM {
|
|
310
311
|
ormInstance;
|
|
311
|
-
constructor(entities) {
|
|
312
|
-
this.ormInstance = ForgeSQLORMImpl.getInstance(entities);
|
|
312
|
+
constructor(entities, options) {
|
|
313
|
+
this.ormInstance = ForgeSQLORMImpl.getInstance(entities, options);
|
|
313
314
|
}
|
|
314
315
|
/**
|
|
315
316
|
* Proxies the `crud` method from `ForgeSQLORMImpl`.
|
package/dist/ForgeSQLORM.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForgeSQLORM.js","sources":["../src/utils/sqlUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/core/ForgeSQLORM.ts"],"sourcesContent":["import { types } from \"@mikro-orm/core/types\";\nimport moment from \"moment\";\nimport { AnyString } from \"@mikro-orm/core/typings\";\n\nexport const transformValue = (value: {\n type: keyof typeof types | AnyString;\n value: unknown;\n}): unknown => {\n switch (value.type) {\n case \"text\":\n case \"string\":\n return `'${value.value}'`;\n case \"datetime\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DDTHH:mm:ss.SSS\")}'`;\n case \"date\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DD\")}'`;\n case \"time\":\n return `'${moment(value.value as Date).format(\"HH:mm:ss.SSS\")}'`;\n default:\n return value.value;\n }\n};\nexport const parseDateTime = (value: string, format: string): Date => {\n return moment(value, format).toDate();\n};\n","import { UpdateQueryResponse, sql } from \"@forge/sql\";\nimport { EntityProperty, EntitySchema, ForgeSqlOrmOptions } from \"..\";\nimport type { types } from \"@mikro-orm/core/types\";\nimport { transformValue } from \"../utils/sqlUtils\";\nimport { CRUDForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLCrudOperations implements CRUDForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(forgeSqlOperations: ForgeSqlOperation, options: ForgeSqlOrmOptions) {\n this.forgeOperations = forgeSqlOperations;\n this.options = options;\n }\n\n /**\n * Generates an SQL insert query with values.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns An object containing the SQL query, fields, and values.\n */\n private async generateInsertScript<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean,\n ): Promise<{\n sql: string;\n fields: string[];\n values: { type: keyof typeof types; value: unknown }[];\n }> {\n const fieldNames: Set<string> = new Set();\n const fieldValueMaps: Record<string, { type: keyof typeof types; value: unknown }>[] = [];\n\n models.forEach((model) => {\n const fieldValueMap: Record<string, { type: keyof typeof types; value: unknown }> = {};\n schema.meta.props.forEach((p) => {\n const modelValue = model[p.name];\n if (p.kind === \"scalar\" && modelValue !== undefined) {\n fieldNames.add(p.fieldNames[0] || p.name);\n fieldValueMap[p.fieldNames[0]] = {\n type: p.type as keyof typeof types,\n value: modelValue,\n };\n }\n });\n fieldValueMaps.push(fieldValueMap);\n });\n\n const fields = Array.from(fieldNames);\n const values = fieldValueMaps.flatMap((fieldValueMap) =>\n fields.map(\n (f) =>\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n );\n\n return {\n sql: `INSERT INTO ${schema.meta.collection} (${fields.join(\",\")}) VALUES ${fieldValueMaps\n .map(\n (fieldValueMap) =>\n `(${fields\n .map((f) =>\n transformValue(\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n )\n .join(\",\")})`,\n )\n .join(\n \", \",\n )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(\",\")}` : \"\"}`,\n fields,\n values,\n };\n }\n\n /**\n * Inserts records into the database.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns The ID of the inserted row.\n */\n async insert<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models || models.length === 0) return 0;\n\n const query = await this.generateInsertScript(schema, models, updateIfExists);\n if (this.options?.logRawSqlQuery) {\n console.debug(\"INSERT SQL: \" + query.sql);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query.sql);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.insertId;\n }\n\n /**\n * Retrieves the primary keys for the given entity schema.\n * @param schema - The entity schema.\n * @returns An array of primary key properties.\n * @throws If no primary keys are found.\n */\n private getPrimaryKeys<T extends object>(schema: EntitySchema<T>): EntityProperty<T, unknown>[] {\n const primaryKeys = schema.meta.props.filter((p) => p.primary);\n if (!primaryKeys.length) {\n throw new Error(`No primary keys found for schema: ${schema.meta.className}`);\n }\n return primaryKeys;\n }\n\n /**\n * Deletes a record by its ID.\n * @param id - The ID of the record to delete.\n * @param schema - The entity schema.\n * @returns The number of rows affected.\n * @throws If the entity has more than one primary key.\n */\n async deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number> {\n const primaryKeys = this.getPrimaryKeys(schema);\n if (primaryKeys.length > 1) {\n throw new Error(\"Only one primary key is supported\");\n }\n\n const primaryKey = primaryKeys[0];\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();\n queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });\n\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"DELETE SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.affectedRows;\n }\n\n /**\n * Updates a record by its ID.\n * @param entity - The entity with updated values.\n * @param schema - The entity schema.\n * @throws If the primary key value is missing in the entity.\n */\n async updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void> {\n const primaryKeys = this.getPrimaryKeys(schema);\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);\n\n primaryKeys.forEach((pk) => {\n const value = entity[pk.name];\n if (value === null || value === undefined) {\n throw new Error(`Primary Key ${pk.name} must exist in the model`);\n }\n queryBuilder.andWhere({ [pk.name]: { $eq: value } });\n });\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"UPDATE SQL: \" + query);\n }\n await this.forgeOperations.fetch().executeRawUpdateSQL(query);\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport { parseDateTime } from \"../utils/sqlUtils\";\nimport { ForgeSqlOrmOptions, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(options: ForgeSqlOrmOptions) {\n this.options = options;\n }\n\n /**\n * Executes a schema-based SQL query and maps the result to the entity schema.\n * @param query - The SQL query to execute.\n * @param schema - The entity schema defining the structure.\n * @returns A list of mapped entity objects.\n */\n async executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]> {\n const datas = await this.executeRawSQL<unknown>(query);\n if (!datas.length) return [];\n\n return datas.map((r) => {\n const rawModel = r as Record<string, unknown>;\n const newModel: Record<string, unknown> = {};\n\n schema.meta.props\n .filter((p) => p.kind === \"scalar\")\n .forEach((p) => {\n const fieldName = p.name;\n const fieldNames = p.fieldNames;\n const rawFieldName = fieldNames && Array.isArray(fieldNames) ? fieldNames[0] : p.name;\n\n switch (p.type) {\n case \"datetime\":\n newModel[fieldName] = parseDateTime(\n rawModel[rawFieldName] as string,\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n );\n break;\n case \"date\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"YYYY-MM-DD\");\n break;\n case \"time\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"HH:mm:ss.SSS\");\n break;\n default:\n newModel[fieldName] = rawModel[rawFieldName];\n }\n });\n return newModel as T;\n });\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * @param query - The raw SQL query to execute.\n * @returns A list of results as objects.\n */\n async executeRawSQL<T extends object | unknown>(query: string): Promise<T[]> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing raw SQL: \" + query);\n }\n const sqlStatement = await sql.prepare<T>(query).execute();\n return sqlStatement.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param query - The raw SQL update query.\n * @returns The update response containing affected rows.\n */\n async executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing update SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import type { EntityName, LoggingOptions } from \"@mikro-orm/core\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport type { AnyEntity, EntityClass, EntityClassGroup } from \"@mikro-orm/core/typings\";\nimport type { QueryBuilder } from \"@mikro-orm/knex/query\";\nimport { MemoryCacheAdapter, MikroORM, NullCacheAdapter } from \"@mikro-orm/mysql\";\nimport { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport {\n CRUDForgeSQL,\n ForgeSqlOperation,\n ForgeSqlOrmOptions,\n SchemaSqlForgeSql,\n} from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport type { Knex } from \"knex\";\n\n/**\n * Implementation of ForgeSQLORM that interacts with MikroORM.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly mikroORM: MikroORM;\n private readonly crudOperations: CRUDForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param entities - The list of entities for ORM initialization.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n */\n private constructor(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions,\n ) {\n console.debug(\"Initializing ForgeSQLORM...\");\n\n try {\n this.mikroORM = MikroORM.initSync({\n dbName: \"inmemory\",\n schemaGenerator: {\n disableForeignKeys: false,\n },\n discovery: {\n warnWhenNoEntities: true,\n },\n resultCache: {\n adapter: NullCacheAdapter,\n },\n metadataCache: {\n enabled: false,\n adapter: MemoryCacheAdapter,\n },\n entities: entities,\n preferTs: false,\n debug: false,\n });\n const newOptions: ForgeSqlOrmOptions = options ?? { logRawSqlQuery: false };\n this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);\n this.fetchOperations = new ForgeSQLSelectOperations(newOptions);\n } catch (error) {\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error; // Prevents inconsistent state\n }\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param entities - List of entities (required only on first initialization).\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n ): ForgeSqlOperation {\n if (!ForgeSQLORMImpl.instance) {\n ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);\n }\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the CRUD operations instance.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Creates a new query builder for the given entity.\n * @param entityName - The entity name or an existing query builder.\n * @param alias - The alias for the entity.\n * @param loggerContext - Logging options.\n * @returns The query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.mikroORM.em.createQueryBuilder(entityName, alias, undefined, loggerContext);\n }\n\n /**\n * Provides access to the underlying Knex instance for executing raw queries and building complex query parts.\n * enabling advanced query customization and performance tuning.\n * @returns The Knex instance, which can be used for query building.\n */\n getKnex(): Knex<any, any[]> {\n return this.mikroORM.em.getKnex();\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n */\nclass ForgeSQLORM {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(entities);\n }\n\n /**\n * Proxies the `crud` method from `ForgeSQLORMImpl`.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.ormInstance.crud();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n getKnex(): Knex<any, any[]> {\n return this.ormInstance.getKnex();\n }\n\n /**\n * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.\n * @returns A new query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);\n }\n}\n\nexport default ForgeSQLORM;\n"],"names":["sql","MikroORM","NullCacheAdapter","MemoryCacheAdapter"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ForgeSQLORM.js","sources":["../src/utils/sqlUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/core/ForgeSQLORM.ts"],"sourcesContent":["import { types } from \"@mikro-orm/core/types\";\nimport moment from \"moment\";\nimport { AnyString } from \"@mikro-orm/core/typings\";\n\nexport const transformValue = (value: {\n type: keyof typeof types | AnyString;\n value: unknown;\n}): unknown => {\n switch (value.type) {\n case \"text\":\n case \"string\":\n return `'${value.value}'`;\n case \"datetime\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DDTHH:mm:ss.SSS\")}'`;\n case \"date\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DD\")}'`;\n case \"time\":\n return `'${moment(value.value as Date).format(\"HH:mm:ss.SSS\")}'`;\n default:\n return value.value;\n }\n};\nexport const parseDateTime = (value: string, format: string): Date => {\n return moment(value, format).toDate();\n};\n","import { UpdateQueryResponse, sql } from \"@forge/sql\";\nimport { EntityProperty, EntitySchema, ForgeSqlOrmOptions } from \"..\";\nimport type { types } from \"@mikro-orm/core/types\";\nimport { transformValue } from \"../utils/sqlUtils\";\nimport { CRUDForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLCrudOperations implements CRUDForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(forgeSqlOperations: ForgeSqlOperation, options: ForgeSqlOrmOptions) {\n this.forgeOperations = forgeSqlOperations;\n this.options = options;\n }\n\n /**\n * Generates an SQL insert query with values.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns An object containing the SQL query, fields, and values.\n */\n private async generateInsertScript<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean,\n ): Promise<{\n sql: string;\n fields: string[];\n values: { type: keyof typeof types; value: unknown }[];\n }> {\n const fieldNames: Set<string> = new Set();\n const fieldValueMaps: Record<string, { type: keyof typeof types; value: unknown }>[] = [];\n\n models.forEach((model) => {\n const fieldValueMap: Record<string, { type: keyof typeof types; value: unknown }> = {};\n schema.meta.props.forEach((p) => {\n const modelValue = model[p.name];\n if (p.kind === \"scalar\" && modelValue !== undefined) {\n fieldNames.add(p.fieldNames[0] || p.name);\n fieldValueMap[p.fieldNames[0]] = {\n type: p.type as keyof typeof types,\n value: modelValue,\n };\n }\n });\n fieldValueMaps.push(fieldValueMap);\n });\n\n const fields = Array.from(fieldNames);\n const values = fieldValueMaps.flatMap((fieldValueMap) =>\n fields.map(\n (f) =>\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n );\n\n return {\n sql: `INSERT INTO ${schema.meta.collection} (${fields.join(\",\")}) VALUES ${fieldValueMaps\n .map(\n (fieldValueMap) =>\n `(${fields\n .map((f) =>\n transformValue(\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n )\n .join(\",\")})`,\n )\n .join(\n \", \",\n )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(\",\")}` : \"\"}`,\n fields,\n values,\n };\n }\n\n /**\n * Inserts records into the database.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns The ID of the inserted row.\n */\n async insert<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models || models.length === 0) return 0;\n\n const query = await this.generateInsertScript(schema, models, updateIfExists);\n if (this.options?.logRawSqlQuery) {\n console.debug(\"INSERT SQL: \" + query.sql);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query.sql);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.insertId;\n }\n\n /**\n * Retrieves the primary keys for the given entity schema.\n * @param schema - The entity schema.\n * @returns An array of primary key properties.\n * @throws If no primary keys are found.\n */\n private getPrimaryKeys<T extends object>(schema: EntitySchema<T>): EntityProperty<T, unknown>[] {\n const primaryKeys = schema.meta.props.filter((p) => p.primary);\n if (!primaryKeys.length) {\n throw new Error(`No primary keys found for schema: ${schema.meta.className}`);\n }\n return primaryKeys;\n }\n\n /**\n * Deletes a record by its ID.\n * @param id - The ID of the record to delete.\n * @param schema - The entity schema.\n * @returns The number of rows affected.\n * @throws If the entity has more than one primary key.\n */\n async deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number> {\n const primaryKeys = this.getPrimaryKeys(schema);\n if (primaryKeys.length > 1) {\n throw new Error(\"Only one primary key is supported\");\n }\n\n const primaryKey = primaryKeys[0];\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();\n queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });\n\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"DELETE SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.affectedRows;\n }\n\n /**\n * Updates a record by its ID.\n * @param entity - The entity with updated values.\n * @param schema - The entity schema.\n * @throws If the primary key value is missing in the entity.\n */\n async updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void> {\n const primaryKeys = this.getPrimaryKeys(schema);\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);\n\n primaryKeys.forEach((pk) => {\n const value = entity[pk.name];\n if (value === null || value === undefined) {\n throw new Error(`Primary Key ${pk.name} must exist in the model`);\n }\n queryBuilder.andWhere({ [pk.name]: { $eq: value } });\n });\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"UPDATE SQL: \" + query);\n }\n await this.forgeOperations.fetch().executeRawUpdateSQL(query);\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport { parseDateTime } from \"../utils/sqlUtils\";\nimport { ForgeSqlOrmOptions, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(options: ForgeSqlOrmOptions) {\n this.options = options;\n }\n\n /**\n * Executes a schema-based SQL query and maps the result to the entity schema.\n * @param query - The SQL query to execute.\n * @param schema - The entity schema defining the structure.\n * @returns A list of mapped entity objects.\n */\n async executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]> {\n const datas = await this.executeRawSQL<unknown>(query);\n if (!datas.length) return [];\n\n return datas.map((r) => {\n const rawModel = r as Record<string, unknown>;\n const newModel: Record<string, unknown> = {};\n\n schema.meta.props\n .filter((p) => p.kind === \"scalar\")\n .forEach((p) => {\n const fieldName = p.name;\n const fieldNames = p.fieldNames;\n const rawFieldName = fieldNames && Array.isArray(fieldNames) ? fieldNames[0] : p.name;\n\n switch (p.type) {\n case \"datetime\":\n newModel[fieldName] = parseDateTime(\n rawModel[rawFieldName] as string,\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n );\n break;\n case \"date\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"YYYY-MM-DD\");\n break;\n case \"time\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"HH:mm:ss.SSS\");\n break;\n default:\n newModel[fieldName] = rawModel[rawFieldName];\n }\n });\n return newModel as T;\n });\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * @param query - The raw SQL query to execute.\n * @returns A list of results as objects.\n */\n async executeRawSQL<T extends object | unknown>(query: string): Promise<T[]> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing raw SQL: \" + query);\n }\n const sqlStatement = await sql.prepare<T>(query).execute();\n return sqlStatement.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param query - The raw SQL update query.\n * @returns The update response containing affected rows.\n */\n async executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing update SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import type { EntityName, LoggingOptions } from \"@mikro-orm/core\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport type { AnyEntity, EntityClass, EntityClassGroup } from \"@mikro-orm/core/typings\";\nimport type { QueryBuilder } from \"@mikro-orm/knex/query\";\nimport { MemoryCacheAdapter, MikroORM, NullCacheAdapter } from \"@mikro-orm/mysql\";\nimport { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport {\n CRUDForgeSQL,\n ForgeSqlOperation,\n ForgeSqlOrmOptions,\n SchemaSqlForgeSql,\n} from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport type { Knex } from \"knex\";\n\n/**\n * Implementation of ForgeSQLORM that interacts with MikroORM.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly mikroORM: MikroORM;\n private readonly crudOperations: CRUDForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param entities - The list of entities for ORM initialization.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n */\n private constructor(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions,\n ) {\n console.debug(\"Initializing ForgeSQLORM...\");\n\n try {\n this.mikroORM = MikroORM.initSync({\n dbName: \"inmemory\",\n schemaGenerator: {\n disableForeignKeys: false,\n },\n discovery: {\n warnWhenNoEntities: true,\n },\n resultCache: {\n adapter: NullCacheAdapter,\n },\n metadataCache: {\n enabled: false,\n adapter: MemoryCacheAdapter,\n },\n entities: entities,\n preferTs: false,\n debug: false,\n });\n const newOptions: ForgeSqlOrmOptions = options ?? { logRawSqlQuery: false };\n this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);\n this.fetchOperations = new ForgeSQLSelectOperations(newOptions);\n } catch (error) {\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error; // Prevents inconsistent state\n }\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param entities - List of entities (required only on first initialization).\n * @param options - Options for configuring ForgeSQL ORM behavior.\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions\n ): ForgeSqlOperation {\n if (!ForgeSQLORMImpl.instance) {\n ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities, options);\n }\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the CRUD operations instance.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Creates a new query builder for the given entity.\n * @param entityName - The entity name or an existing query builder.\n * @param alias - The alias for the entity.\n * @param loggerContext - Logging options.\n * @returns The query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.mikroORM.em.createQueryBuilder(entityName, alias, undefined, loggerContext);\n }\n\n /**\n * Provides access to the underlying Knex instance for building complex query parts.\n * enabling advanced query customization and performance tuning.\n * @returns The Knex instance, which can be used for query building.\n */\n getKnex(): Knex<any, any[]> {\n return this.mikroORM.em.getKnex();\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n */\nclass ForgeSQLORM {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(entities, options);\n }\n\n /**\n * Proxies the `crud` method from `ForgeSQLORMImpl`.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.ormInstance.crud();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n getKnex(): Knex<any, any[]> {\n return this.ormInstance.getKnex();\n }\n\n /**\n * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.\n * @returns A new query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);\n }\n}\n\nexport default ForgeSQLORM;\n"],"names":["sql","MikroORM","NullCacheAdapter","MemoryCacheAdapter"],"mappings":"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"}
|
package/dist/ForgeSQLORM.mjs
CHANGED
|
@@ -264,11 +264,12 @@ class ForgeSQLORMImpl {
|
|
|
264
264
|
/**
|
|
265
265
|
* Returns the singleton instance of ForgeSQLORMImpl.
|
|
266
266
|
* @param entities - List of entities (required only on first initialization).
|
|
267
|
+
* @param options - Options for configuring ForgeSQL ORM behavior.
|
|
267
268
|
* @returns The singleton instance of ForgeSQLORMImpl.
|
|
268
269
|
*/
|
|
269
|
-
static getInstance(entities) {
|
|
270
|
+
static getInstance(entities, options) {
|
|
270
271
|
if (!ForgeSQLORMImpl.instance) {
|
|
271
|
-
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);
|
|
272
|
+
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities, options);
|
|
272
273
|
}
|
|
273
274
|
return ForgeSQLORMImpl.instance;
|
|
274
275
|
}
|
|
@@ -297,7 +298,7 @@ class ForgeSQLORMImpl {
|
|
|
297
298
|
return this.mikroORM.em.createQueryBuilder(entityName, alias, void 0, loggerContext);
|
|
298
299
|
}
|
|
299
300
|
/**
|
|
300
|
-
* Provides access to the underlying Knex instance for
|
|
301
|
+
* Provides access to the underlying Knex instance for building complex query parts.
|
|
301
302
|
* enabling advanced query customization and performance tuning.
|
|
302
303
|
* @returns The Knex instance, which can be used for query building.
|
|
303
304
|
*/
|
|
@@ -307,8 +308,8 @@ class ForgeSQLORMImpl {
|
|
|
307
308
|
}
|
|
308
309
|
class ForgeSQLORM {
|
|
309
310
|
ormInstance;
|
|
310
|
-
constructor(entities) {
|
|
311
|
-
this.ormInstance = ForgeSQLORMImpl.getInstance(entities);
|
|
311
|
+
constructor(entities, options) {
|
|
312
|
+
this.ormInstance = ForgeSQLORMImpl.getInstance(entities, options);
|
|
312
313
|
}
|
|
313
314
|
/**
|
|
314
315
|
* Proxies the `crud` method from `ForgeSQLORMImpl`.
|
package/dist/ForgeSQLORM.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForgeSQLORM.mjs","sources":["../src/utils/sqlUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/core/ForgeSQLORM.ts"],"sourcesContent":["import { types } from \"@mikro-orm/core/types\";\nimport moment from \"moment\";\nimport { AnyString } from \"@mikro-orm/core/typings\";\n\nexport const transformValue = (value: {\n type: keyof typeof types | AnyString;\n value: unknown;\n}): unknown => {\n switch (value.type) {\n case \"text\":\n case \"string\":\n return `'${value.value}'`;\n case \"datetime\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DDTHH:mm:ss.SSS\")}'`;\n case \"date\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DD\")}'`;\n case \"time\":\n return `'${moment(value.value as Date).format(\"HH:mm:ss.SSS\")}'`;\n default:\n return value.value;\n }\n};\nexport const parseDateTime = (value: string, format: string): Date => {\n return moment(value, format).toDate();\n};\n","import { UpdateQueryResponse, sql } from \"@forge/sql\";\nimport { EntityProperty, EntitySchema, ForgeSqlOrmOptions } from \"..\";\nimport type { types } from \"@mikro-orm/core/types\";\nimport { transformValue } from \"../utils/sqlUtils\";\nimport { CRUDForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLCrudOperations implements CRUDForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(forgeSqlOperations: ForgeSqlOperation, options: ForgeSqlOrmOptions) {\n this.forgeOperations = forgeSqlOperations;\n this.options = options;\n }\n\n /**\n * Generates an SQL insert query with values.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns An object containing the SQL query, fields, and values.\n */\n private async generateInsertScript<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean,\n ): Promise<{\n sql: string;\n fields: string[];\n values: { type: keyof typeof types; value: unknown }[];\n }> {\n const fieldNames: Set<string> = new Set();\n const fieldValueMaps: Record<string, { type: keyof typeof types; value: unknown }>[] = [];\n\n models.forEach((model) => {\n const fieldValueMap: Record<string, { type: keyof typeof types; value: unknown }> = {};\n schema.meta.props.forEach((p) => {\n const modelValue = model[p.name];\n if (p.kind === \"scalar\" && modelValue !== undefined) {\n fieldNames.add(p.fieldNames[0] || p.name);\n fieldValueMap[p.fieldNames[0]] = {\n type: p.type as keyof typeof types,\n value: modelValue,\n };\n }\n });\n fieldValueMaps.push(fieldValueMap);\n });\n\n const fields = Array.from(fieldNames);\n const values = fieldValueMaps.flatMap((fieldValueMap) =>\n fields.map(\n (f) =>\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n );\n\n return {\n sql: `INSERT INTO ${schema.meta.collection} (${fields.join(\",\")}) VALUES ${fieldValueMaps\n .map(\n (fieldValueMap) =>\n `(${fields\n .map((f) =>\n transformValue(\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n )\n .join(\",\")})`,\n )\n .join(\n \", \",\n )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(\",\")}` : \"\"}`,\n fields,\n values,\n };\n }\n\n /**\n * Inserts records into the database.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns The ID of the inserted row.\n */\n async insert<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models || models.length === 0) return 0;\n\n const query = await this.generateInsertScript(schema, models, updateIfExists);\n if (this.options?.logRawSqlQuery) {\n console.debug(\"INSERT SQL: \" + query.sql);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query.sql);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.insertId;\n }\n\n /**\n * Retrieves the primary keys for the given entity schema.\n * @param schema - The entity schema.\n * @returns An array of primary key properties.\n * @throws If no primary keys are found.\n */\n private getPrimaryKeys<T extends object>(schema: EntitySchema<T>): EntityProperty<T, unknown>[] {\n const primaryKeys = schema.meta.props.filter((p) => p.primary);\n if (!primaryKeys.length) {\n throw new Error(`No primary keys found for schema: ${schema.meta.className}`);\n }\n return primaryKeys;\n }\n\n /**\n * Deletes a record by its ID.\n * @param id - The ID of the record to delete.\n * @param schema - The entity schema.\n * @returns The number of rows affected.\n * @throws If the entity has more than one primary key.\n */\n async deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number> {\n const primaryKeys = this.getPrimaryKeys(schema);\n if (primaryKeys.length > 1) {\n throw new Error(\"Only one primary key is supported\");\n }\n\n const primaryKey = primaryKeys[0];\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();\n queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });\n\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"DELETE SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.affectedRows;\n }\n\n /**\n * Updates a record by its ID.\n * @param entity - The entity with updated values.\n * @param schema - The entity schema.\n * @throws If the primary key value is missing in the entity.\n */\n async updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void> {\n const primaryKeys = this.getPrimaryKeys(schema);\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);\n\n primaryKeys.forEach((pk) => {\n const value = entity[pk.name];\n if (value === null || value === undefined) {\n throw new Error(`Primary Key ${pk.name} must exist in the model`);\n }\n queryBuilder.andWhere({ [pk.name]: { $eq: value } });\n });\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"UPDATE SQL: \" + query);\n }\n await this.forgeOperations.fetch().executeRawUpdateSQL(query);\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport { parseDateTime } from \"../utils/sqlUtils\";\nimport { ForgeSqlOrmOptions, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(options: ForgeSqlOrmOptions) {\n this.options = options;\n }\n\n /**\n * Executes a schema-based SQL query and maps the result to the entity schema.\n * @param query - The SQL query to execute.\n * @param schema - The entity schema defining the structure.\n * @returns A list of mapped entity objects.\n */\n async executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]> {\n const datas = await this.executeRawSQL<unknown>(query);\n if (!datas.length) return [];\n\n return datas.map((r) => {\n const rawModel = r as Record<string, unknown>;\n const newModel: Record<string, unknown> = {};\n\n schema.meta.props\n .filter((p) => p.kind === \"scalar\")\n .forEach((p) => {\n const fieldName = p.name;\n const fieldNames = p.fieldNames;\n const rawFieldName = fieldNames && Array.isArray(fieldNames) ? fieldNames[0] : p.name;\n\n switch (p.type) {\n case \"datetime\":\n newModel[fieldName] = parseDateTime(\n rawModel[rawFieldName] as string,\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n );\n break;\n case \"date\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"YYYY-MM-DD\");\n break;\n case \"time\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"HH:mm:ss.SSS\");\n break;\n default:\n newModel[fieldName] = rawModel[rawFieldName];\n }\n });\n return newModel as T;\n });\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * @param query - The raw SQL query to execute.\n * @returns A list of results as objects.\n */\n async executeRawSQL<T extends object | unknown>(query: string): Promise<T[]> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing raw SQL: \" + query);\n }\n const sqlStatement = await sql.prepare<T>(query).execute();\n return sqlStatement.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param query - The raw SQL update query.\n * @returns The update response containing affected rows.\n */\n async executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing update SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import type { EntityName, LoggingOptions } from \"@mikro-orm/core\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport type { AnyEntity, EntityClass, EntityClassGroup } from \"@mikro-orm/core/typings\";\nimport type { QueryBuilder } from \"@mikro-orm/knex/query\";\nimport { MemoryCacheAdapter, MikroORM, NullCacheAdapter } from \"@mikro-orm/mysql\";\nimport { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport {\n CRUDForgeSQL,\n ForgeSqlOperation,\n ForgeSqlOrmOptions,\n SchemaSqlForgeSql,\n} from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport type { Knex } from \"knex\";\n\n/**\n * Implementation of ForgeSQLORM that interacts with MikroORM.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly mikroORM: MikroORM;\n private readonly crudOperations: CRUDForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param entities - The list of entities for ORM initialization.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n */\n private constructor(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions,\n ) {\n console.debug(\"Initializing ForgeSQLORM...\");\n\n try {\n this.mikroORM = MikroORM.initSync({\n dbName: \"inmemory\",\n schemaGenerator: {\n disableForeignKeys: false,\n },\n discovery: {\n warnWhenNoEntities: true,\n },\n resultCache: {\n adapter: NullCacheAdapter,\n },\n metadataCache: {\n enabled: false,\n adapter: MemoryCacheAdapter,\n },\n entities: entities,\n preferTs: false,\n debug: false,\n });\n const newOptions: ForgeSqlOrmOptions = options ?? { logRawSqlQuery: false };\n this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);\n this.fetchOperations = new ForgeSQLSelectOperations(newOptions);\n } catch (error) {\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error; // Prevents inconsistent state\n }\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param entities - List of entities (required only on first initialization).\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n ): ForgeSqlOperation {\n if (!ForgeSQLORMImpl.instance) {\n ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);\n }\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the CRUD operations instance.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Creates a new query builder for the given entity.\n * @param entityName - The entity name or an existing query builder.\n * @param alias - The alias for the entity.\n * @param loggerContext - Logging options.\n * @returns The query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.mikroORM.em.createQueryBuilder(entityName, alias, undefined, loggerContext);\n }\n\n /**\n * Provides access to the underlying Knex instance for executing raw queries and building complex query parts.\n * enabling advanced query customization and performance tuning.\n * @returns The Knex instance, which can be used for query building.\n */\n getKnex(): Knex<any, any[]> {\n return this.mikroORM.em.getKnex();\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n */\nclass ForgeSQLORM {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(entities);\n }\n\n /**\n * Proxies the `crud` method from `ForgeSQLORMImpl`.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.ormInstance.crud();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n getKnex(): Knex<any, any[]> {\n return this.ormInstance.getKnex();\n }\n\n /**\n * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.\n * @returns A new query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);\n }\n}\n\nexport default ForgeSQLORM;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ForgeSQLORM.mjs","sources":["../src/utils/sqlUtils.ts","../src/core/ForgeSQLCrudOperations.ts","../src/core/ForgeSQLSelectOperations.ts","../src/core/ForgeSQLORM.ts"],"sourcesContent":["import { types } from \"@mikro-orm/core/types\";\nimport moment from \"moment\";\nimport { AnyString } from \"@mikro-orm/core/typings\";\n\nexport const transformValue = (value: {\n type: keyof typeof types | AnyString;\n value: unknown;\n}): unknown => {\n switch (value.type) {\n case \"text\":\n case \"string\":\n return `'${value.value}'`;\n case \"datetime\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DDTHH:mm:ss.SSS\")}'`;\n case \"date\":\n return `'${moment(value.value as Date).format(\"YYYY-MM-DD\")}'`;\n case \"time\":\n return `'${moment(value.value as Date).format(\"HH:mm:ss.SSS\")}'`;\n default:\n return value.value;\n }\n};\nexport const parseDateTime = (value: string, format: string): Date => {\n return moment(value, format).toDate();\n};\n","import { UpdateQueryResponse, sql } from \"@forge/sql\";\nimport { EntityProperty, EntitySchema, ForgeSqlOrmOptions } from \"..\";\nimport type { types } from \"@mikro-orm/core/types\";\nimport { transformValue } from \"../utils/sqlUtils\";\nimport { CRUDForgeSQL, ForgeSqlOperation } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLCrudOperations implements CRUDForgeSQL {\n private readonly forgeOperations: ForgeSqlOperation;\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(forgeSqlOperations: ForgeSqlOperation, options: ForgeSqlOrmOptions) {\n this.forgeOperations = forgeSqlOperations;\n this.options = options;\n }\n\n /**\n * Generates an SQL insert query with values.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns An object containing the SQL query, fields, and values.\n */\n private async generateInsertScript<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean,\n ): Promise<{\n sql: string;\n fields: string[];\n values: { type: keyof typeof types; value: unknown }[];\n }> {\n const fieldNames: Set<string> = new Set();\n const fieldValueMaps: Record<string, { type: keyof typeof types; value: unknown }>[] = [];\n\n models.forEach((model) => {\n const fieldValueMap: Record<string, { type: keyof typeof types; value: unknown }> = {};\n schema.meta.props.forEach((p) => {\n const modelValue = model[p.name];\n if (p.kind === \"scalar\" && modelValue !== undefined) {\n fieldNames.add(p.fieldNames[0] || p.name);\n fieldValueMap[p.fieldNames[0]] = {\n type: p.type as keyof typeof types,\n value: modelValue,\n };\n }\n });\n fieldValueMaps.push(fieldValueMap);\n });\n\n const fields = Array.from(fieldNames);\n const values = fieldValueMaps.flatMap((fieldValueMap) =>\n fields.map(\n (f) =>\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n );\n\n return {\n sql: `INSERT INTO ${schema.meta.collection} (${fields.join(\",\")}) VALUES ${fieldValueMaps\n .map(\n (fieldValueMap) =>\n `(${fields\n .map((f) =>\n transformValue(\n fieldValueMap[f] || {\n type: \"string\",\n value: null,\n },\n ),\n )\n .join(\",\")})`,\n )\n .join(\n \", \",\n )} ${updateIfExists ? `ON DUPLICATE KEY UPDATE ${fields.map((f) => `${f} = VALUES(${f})`).join(\",\")}` : \"\"}`,\n fields,\n values,\n };\n }\n\n /**\n * Inserts records into the database.\n * @param schema - The entity schema.\n * @param models - The list of entities to insert.\n * @param updateIfExists - Whether to update the row if it already exists.\n * @returns The ID of the inserted row.\n */\n async insert<T extends object>(\n schema: EntitySchema<T>,\n models: T[],\n updateIfExists: boolean = false,\n ): Promise<number> {\n if (!models || models.length === 0) return 0;\n\n const query = await this.generateInsertScript(schema, models, updateIfExists);\n if (this.options?.logRawSqlQuery) {\n console.debug(\"INSERT SQL: \" + query.sql);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query.sql);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.insertId;\n }\n\n /**\n * Retrieves the primary keys for the given entity schema.\n * @param schema - The entity schema.\n * @returns An array of primary key properties.\n * @throws If no primary keys are found.\n */\n private getPrimaryKeys<T extends object>(schema: EntitySchema<T>): EntityProperty<T, unknown>[] {\n const primaryKeys = schema.meta.props.filter((p) => p.primary);\n if (!primaryKeys.length) {\n throw new Error(`No primary keys found for schema: ${schema.meta.className}`);\n }\n return primaryKeys;\n }\n\n /**\n * Deletes a record by its ID.\n * @param id - The ID of the record to delete.\n * @param schema - The entity schema.\n * @returns The number of rows affected.\n * @throws If the entity has more than one primary key.\n */\n async deleteById<T extends object>(id: unknown, schema: EntitySchema<T>): Promise<number> {\n const primaryKeys = this.getPrimaryKeys(schema);\n if (primaryKeys.length > 1) {\n throw new Error(\"Only one primary key is supported\");\n }\n\n const primaryKey = primaryKeys[0];\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).delete();\n queryBuilder.andWhere({ [primaryKey.name]: { $eq: id } });\n\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"DELETE SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResult = await sqlStatement.execute();\n return updateQueryResponseResult.rows.affectedRows;\n }\n\n /**\n * Updates a record by its ID.\n * @param entity - The entity with updated values.\n * @param schema - The entity schema.\n * @throws If the primary key value is missing in the entity.\n */\n async updateById<T extends object>(entity: T, schema: EntitySchema<T>): Promise<void> {\n const primaryKeys = this.getPrimaryKeys(schema);\n const queryBuilder = this.forgeOperations.createQueryBuilder(schema.meta.class).update(entity);\n\n primaryKeys.forEach((pk) => {\n const value = entity[pk.name];\n if (value === null || value === undefined) {\n throw new Error(`Primary Key ${pk.name} must exist in the model`);\n }\n queryBuilder.andWhere({ [pk.name]: { $eq: value } });\n });\n const query = queryBuilder.getFormattedQuery();\n if (this.options?.logRawSqlQuery) {\n console.debug(\"UPDATE SQL: \" + query);\n }\n await this.forgeOperations.fetch().executeRawUpdateSQL(query);\n }\n}\n","import { sql, UpdateQueryResponse } from \"@forge/sql\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport { parseDateTime } from \"../utils/sqlUtils\";\nimport { ForgeSqlOrmOptions, SchemaSqlForgeSql } from \"./ForgeSQLQueryBuilder\";\n\nexport class ForgeSQLSelectOperations implements SchemaSqlForgeSql {\n private readonly options: ForgeSqlOrmOptions;\n\n constructor(options: ForgeSqlOrmOptions) {\n this.options = options;\n }\n\n /**\n * Executes a schema-based SQL query and maps the result to the entity schema.\n * @param query - The SQL query to execute.\n * @param schema - The entity schema defining the structure.\n * @returns A list of mapped entity objects.\n */\n async executeSchemaSQL<T extends object>(query: string, schema: EntitySchema<T>): Promise<T[]> {\n const datas = await this.executeRawSQL<unknown>(query);\n if (!datas.length) return [];\n\n return datas.map((r) => {\n const rawModel = r as Record<string, unknown>;\n const newModel: Record<string, unknown> = {};\n\n schema.meta.props\n .filter((p) => p.kind === \"scalar\")\n .forEach((p) => {\n const fieldName = p.name;\n const fieldNames = p.fieldNames;\n const rawFieldName = fieldNames && Array.isArray(fieldNames) ? fieldNames[0] : p.name;\n\n switch (p.type) {\n case \"datetime\":\n newModel[fieldName] = parseDateTime(\n rawModel[rawFieldName] as string,\n \"YYYY-MM-DDTHH:mm:ss.SSS\",\n );\n break;\n case \"date\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"YYYY-MM-DD\");\n break;\n case \"time\":\n newModel[fieldName] = parseDateTime(rawModel[rawFieldName] as string, \"HH:mm:ss.SSS\");\n break;\n default:\n newModel[fieldName] = rawModel[rawFieldName];\n }\n });\n return newModel as T;\n });\n }\n\n /**\n * Executes a raw SQL query and returns the results.\n * @param query - The raw SQL query to execute.\n * @returns A list of results as objects.\n */\n async executeRawSQL<T extends object | unknown>(query: string): Promise<T[]> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing raw SQL: \" + query);\n }\n const sqlStatement = await sql.prepare<T>(query).execute();\n return sqlStatement.rows as T[];\n }\n\n /**\n * Executes a raw SQL update query.\n * @param query - The raw SQL update query.\n * @returns The update response containing affected rows.\n */\n async executeRawUpdateSQL(query: string): Promise<UpdateQueryResponse> {\n if (this.options.logRawSqlQuery) {\n console.debug(\"Executing update SQL: \" + query);\n }\n const sqlStatement = sql.prepare<UpdateQueryResponse>(query);\n const updateQueryResponseResults = await sqlStatement.execute();\n return updateQueryResponseResults.rows;\n }\n}\n","import type { EntityName, LoggingOptions } from \"@mikro-orm/core\";\nimport type { EntitySchema } from \"@mikro-orm/core/metadata/EntitySchema\";\nimport type { AnyEntity, EntityClass, EntityClassGroup } from \"@mikro-orm/core/typings\";\nimport type { QueryBuilder } from \"@mikro-orm/knex/query\";\nimport { MemoryCacheAdapter, MikroORM, NullCacheAdapter } from \"@mikro-orm/mysql\";\nimport { ForgeSQLCrudOperations } from \"./ForgeSQLCrudOperations\";\nimport {\n CRUDForgeSQL,\n ForgeSqlOperation,\n ForgeSqlOrmOptions,\n SchemaSqlForgeSql,\n} from \"./ForgeSQLQueryBuilder\";\nimport { ForgeSQLSelectOperations } from \"./ForgeSQLSelectOperations\";\nimport type { Knex } from \"knex\";\n\n/**\n * Implementation of ForgeSQLORM that interacts with MikroORM.\n */\nclass ForgeSQLORMImpl implements ForgeSqlOperation {\n private static instance: ForgeSQLORMImpl | null = null;\n private readonly mikroORM: MikroORM;\n private readonly crudOperations: CRUDForgeSQL;\n private readonly fetchOperations: SchemaSqlForgeSql;\n\n /**\n * Private constructor to enforce singleton behavior.\n * @param entities - The list of entities for ORM initialization.\n * @param options - Options for configuring ForgeSQL ORM behavior.\n */\n private constructor(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions,\n ) {\n console.debug(\"Initializing ForgeSQLORM...\");\n\n try {\n this.mikroORM = MikroORM.initSync({\n dbName: \"inmemory\",\n schemaGenerator: {\n disableForeignKeys: false,\n },\n discovery: {\n warnWhenNoEntities: true,\n },\n resultCache: {\n adapter: NullCacheAdapter,\n },\n metadataCache: {\n enabled: false,\n adapter: MemoryCacheAdapter,\n },\n entities: entities,\n preferTs: false,\n debug: false,\n });\n const newOptions: ForgeSqlOrmOptions = options ?? { logRawSqlQuery: false };\n this.crudOperations = new ForgeSQLCrudOperations(this, newOptions);\n this.fetchOperations = new ForgeSQLSelectOperations(newOptions);\n } catch (error) {\n console.error(\"ForgeSQLORM initialization failed:\", error);\n throw error; // Prevents inconsistent state\n }\n }\n\n /**\n * Returns the singleton instance of ForgeSQLORMImpl.\n * @param entities - List of entities (required only on first initialization).\n * @param options - Options for configuring ForgeSQL ORM behavior.\n * @returns The singleton instance of ForgeSQLORMImpl.\n */\n static getInstance(\n entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions\n ): ForgeSqlOperation {\n if (!ForgeSQLORMImpl.instance) {\n ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities, options);\n }\n return ForgeSQLORMImpl.instance;\n }\n\n /**\n * Retrieves the CRUD operations instance.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.crudOperations;\n }\n\n /**\n * Retrieves the fetch operations instance.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.fetchOperations;\n }\n\n /**\n * Creates a new query builder for the given entity.\n * @param entityName - The entity name or an existing query builder.\n * @param alias - The alias for the entity.\n * @param loggerContext - Logging options.\n * @returns The query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.mikroORM.em.createQueryBuilder(entityName, alias, undefined, loggerContext);\n }\n\n /**\n * Provides access to the underlying Knex instance for building complex query parts.\n * enabling advanced query customization and performance tuning.\n * @returns The Knex instance, which can be used for query building.\n */\n getKnex(): Knex<any, any[]> {\n return this.mikroORM.em.getKnex();\n }\n}\n\n/**\n * Public class that acts as a wrapper around the private ForgeSQLORMImpl.\n */\nclass ForgeSQLORM {\n private readonly ormInstance: ForgeSqlOperation;\n\n constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],\n options?: ForgeSqlOrmOptions) {\n this.ormInstance = ForgeSQLORMImpl.getInstance(entities, options);\n }\n\n /**\n * Proxies the `crud` method from `ForgeSQLORMImpl`.\n * @returns CRUD operations.\n */\n crud(): CRUDForgeSQL {\n return this.ormInstance.crud();\n }\n\n /**\n * Proxies the `fetch` method from `ForgeSQLORMImpl`.\n * @returns Fetch operations.\n */\n fetch(): SchemaSqlForgeSql {\n return this.ormInstance.fetch();\n }\n\n getKnex(): Knex<any, any[]> {\n return this.ormInstance.getKnex();\n }\n\n /**\n * Proxies the `createQueryBuilder` method from `ForgeSQLORMImpl`.\n * @returns A new query builder instance.\n */\n createQueryBuilder<Entity extends object, RootAlias extends string = never>(\n entityName: EntityName<Entity> | QueryBuilder<Entity>,\n alias?: RootAlias,\n loggerContext?: LoggingOptions,\n ): QueryBuilder<Entity, RootAlias> {\n return this.ormInstance.createQueryBuilder(entityName, alias, loggerContext);\n }\n}\n\nexport default ForgeSQLORM;\n"],"names":[],"mappings":"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"}
|
|
@@ -2,14 +2,14 @@ import type { EntityName, LoggingOptions } from "@mikro-orm/core";
|
|
|
2
2
|
import type { EntitySchema } from "@mikro-orm/core/metadata/EntitySchema";
|
|
3
3
|
import type { AnyEntity, EntityClass, EntityClassGroup } from "@mikro-orm/core/typings";
|
|
4
4
|
import type { QueryBuilder } from "@mikro-orm/knex/query";
|
|
5
|
-
import { CRUDForgeSQL, SchemaSqlForgeSql } from "./ForgeSQLQueryBuilder";
|
|
5
|
+
import { CRUDForgeSQL, ForgeSqlOrmOptions, SchemaSqlForgeSql } from "./ForgeSQLQueryBuilder";
|
|
6
6
|
import type { Knex } from "knex";
|
|
7
7
|
/**
|
|
8
8
|
* Public class that acts as a wrapper around the private ForgeSQLORMImpl.
|
|
9
9
|
*/
|
|
10
10
|
declare class ForgeSQLORM {
|
|
11
11
|
private readonly ormInstance;
|
|
12
|
-
constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]);
|
|
12
|
+
constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[], options?: ForgeSqlOrmOptions);
|
|
13
13
|
/**
|
|
14
14
|
* Proxies the `crud` method from `ForgeSQLORMImpl`.
|
|
15
15
|
* @returns CRUD operations.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ForgeSQLORM.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLORM.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EACL,YAAY,
|
|
1
|
+
{"version":3,"file":"ForgeSQLORM.d.ts","sourceRoot":"","sources":["../../src/core/ForgeSQLORM.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EACL,YAAY,EAEZ,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AA4GjC;;GAEG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;gBAEpC,QAAQ,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,gBAAgB,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,EAAE,EACjF,OAAO,CAAC,EAAE,kBAAkB;IAIxC;;;OAGG;IACH,IAAI,IAAI,YAAY;IAIpB;;;OAGG;IACH,KAAK,IAAI,iBAAiB;IAI1B,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;IAI3B;;;OAGG;IACH,kBAAkB,CAAC,MAAM,SAAS,MAAM,EAAE,SAAS,SAAS,MAAM,GAAG,KAAK,EACxE,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,EACrD,KAAK,CAAC,EAAE,SAAS,EACjB,aAAa,CAAC,EAAE,cAAc,GAC7B,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC;CAGnC;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -88,7 +88,7 @@ export interface QueryBuilderForgeSql {
|
|
|
88
88
|
*/
|
|
89
89
|
createQueryBuilder<Entity extends object, RootAlias extends string = never>(entityName: EntityName<Entity> | QueryBuilder<Entity>, alias?: RootAlias, loggerContext?: LoggingOptions): QueryBuilder<Entity, RootAlias>;
|
|
90
90
|
/**
|
|
91
|
-
* Provides access to the underlying Knex instance for
|
|
91
|
+
* Provides access to the underlying Knex instance for building complex query parts.
|
|
92
92
|
* enabling advanced query customization and performance tuning.
|
|
93
93
|
* @returns The Knex instance, which can be used for query building.
|
|
94
94
|
*/
|
package/package.json
CHANGED
package/src/core/ForgeSQLORM.ts
CHANGED
|
@@ -65,13 +65,15 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
65
65
|
/**
|
|
66
66
|
* Returns the singleton instance of ForgeSQLORMImpl.
|
|
67
67
|
* @param entities - List of entities (required only on first initialization).
|
|
68
|
+
* @param options - Options for configuring ForgeSQL ORM behavior.
|
|
68
69
|
* @returns The singleton instance of ForgeSQLORMImpl.
|
|
69
70
|
*/
|
|
70
71
|
static getInstance(
|
|
71
72
|
entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],
|
|
73
|
+
options?: ForgeSqlOrmOptions
|
|
72
74
|
): ForgeSqlOperation {
|
|
73
75
|
if (!ForgeSQLORMImpl.instance) {
|
|
74
|
-
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities);
|
|
76
|
+
ForgeSQLORMImpl.instance = new ForgeSQLORMImpl(entities, options);
|
|
75
77
|
}
|
|
76
78
|
return ForgeSQLORMImpl.instance;
|
|
77
79
|
}
|
|
@@ -108,7 +110,7 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
/**
|
|
111
|
-
* Provides access to the underlying Knex instance for
|
|
113
|
+
* Provides access to the underlying Knex instance for building complex query parts.
|
|
112
114
|
* enabling advanced query customization and performance tuning.
|
|
113
115
|
* @returns The Knex instance, which can be used for query building.
|
|
114
116
|
*/
|
|
@@ -123,8 +125,9 @@ class ForgeSQLORMImpl implements ForgeSqlOperation {
|
|
|
123
125
|
class ForgeSQLORM {
|
|
124
126
|
private readonly ormInstance: ForgeSqlOperation;
|
|
125
127
|
|
|
126
|
-
constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[]
|
|
127
|
-
|
|
128
|
+
constructor(entities: (EntityClass<AnyEntity> | EntityClassGroup<AnyEntity> | EntitySchema)[],
|
|
129
|
+
options?: ForgeSqlOrmOptions) {
|
|
130
|
+
this.ormInstance = ForgeSQLORMImpl.getInstance(entities, options);
|
|
128
131
|
}
|
|
129
132
|
|
|
130
133
|
/**
|
|
@@ -107,7 +107,7 @@ export interface QueryBuilderForgeSql {
|
|
|
107
107
|
): QueryBuilder<Entity, RootAlias>;
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
|
-
* Provides access to the underlying Knex instance for
|
|
110
|
+
* Provides access to the underlying Knex instance for building complex query parts.
|
|
111
111
|
* enabling advanced query customization and performance tuning.
|
|
112
112
|
* @returns The Knex instance, which can be used for query building.
|
|
113
113
|
*/
|