forge-sql-orm 1.0.24 → 1.0.25
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 +222 -94
- package/dist/ForgeSQLORM.js +380 -61
- package/dist/ForgeSQLORM.js.map +1 -1
- package/dist/ForgeSQLORM.mjs +380 -61
- package/dist/ForgeSQLORM.mjs.map +1 -1
- package/dist/core/ForgeSQLCrudOperations.d.ts +119 -8
- package/dist/core/ForgeSQLCrudOperations.d.ts.map +1 -1
- package/dist/core/ForgeSQLORM.d.ts.map +1 -1
- package/dist/core/ForgeSQLQueryBuilder.d.ts +48 -3
- package/dist/core/ForgeSQLQueryBuilder.d.ts.map +1 -1
- package/dist/core/ForgeSQLSelectOperations.d.ts +4 -1
- package/dist/core/ForgeSQLSelectOperations.d.ts.map +1 -1
- package/dist/utils/sqlUtils.d.ts +3 -3
- package/dist/utils/sqlUtils.d.ts.map +1 -1
- package/dist-cli/cli.js +84 -13
- package/dist-cli/cli.js.map +1 -1
- package/dist-cli/cli.mjs +84 -13
- package/dist-cli/cli.mjs.map +1 -1
- package/package.json +11 -8
- package/src/core/ForgeSQLCrudOperations.ts +462 -68
- package/src/core/ForgeSQLORM.ts +6 -4
- package/src/core/ForgeSQLQueryBuilder.ts +61 -3
- package/src/core/ForgeSQLSelectOperations.ts +21 -8
- package/src/utils/sqlUtils.ts +17 -8
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Forge SQL ORM
|
|
2
2
|
|
|
3
|
+
[](https://github.com/vzakharchenko/forge-sql-orm/actions/workflows/node.js.yml)
|
|
4
|
+
|
|
3
5
|
**Forge-SQL-ORM** is an ORM designed for working with [@forge/sql](https://developer.atlassian.com/platform/forge/storage-reference/sql-tutorial/) in **Atlassian Forge**. It is built on top of [MikroORM](https://mikro-orm.io/docs/query-builder) and provides advanced capabilities for working with relational databases inside Forge.
|
|
4
6
|
|
|
5
7
|
## Key Features
|
|
@@ -10,6 +12,13 @@
|
|
|
10
12
|
- ✅ **Schema migration support**, allowing automatic schema evolution.
|
|
11
13
|
- ✅ **Automatic entity generation** from MySQL/tidb databases.
|
|
12
14
|
- ✅ **Automatic migration generation** from MySQL/tidb databases.
|
|
15
|
+
- ✅ **Optimistic Locking** Ensures data consistency by preventing conflicts when multiple users update the same record.
|
|
16
|
+
|
|
17
|
+
🚀 **Development in Progress** 🚀
|
|
18
|
+
I am currently working on implementing the following features:
|
|
19
|
+
- 🗑️ **Soft Deletion Support** – Allows marking records as deleted without actually removing them from the database, enabling easy recovery.
|
|
20
|
+
- 🏗️ **Complex Query Handling** _(JOIN, GROUP BY, etc.) without requiring an EntitySchema_ – Simplifies the execution of advanced SQL queries without the need to define additional schemas.
|
|
21
|
+
---
|
|
13
22
|
|
|
14
23
|
## Installation
|
|
15
24
|
|
|
@@ -125,8 +134,6 @@ import ENTITIES from "./entities";
|
|
|
125
134
|
const forgeSQL = new ForgeSQL(ENTITIES);
|
|
126
135
|
```
|
|
127
136
|
|
|
128
|
-
|
|
129
|
-
|
|
130
137
|
- Fetch Data:
|
|
131
138
|
|
|
132
139
|
```js
|
|
@@ -175,50 +182,86 @@ const results = await forgeSQL.fetch().executeSchemaSQL(query, innerJoinSchema);
|
|
|
175
182
|
console.log(results);
|
|
176
183
|
```
|
|
177
184
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
- Insert Data
|
|
181
|
-
|
|
182
|
-
```js
|
|
183
|
-
// INSERT INTO users (id, name) VALUES (1,'Smith')
|
|
184
|
-
const userId = await forgeSQL.crud().insert(UsersSchema, [{ id: 1, name: "Smith" }]);
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
- Insert Bulk Data
|
|
188
|
-
|
|
189
|
-
```js
|
|
190
|
-
// INSERT INTO users (id,name) VALUES (2,'Smith'), (3,'Vasyl')
|
|
191
|
-
await forgeSQL.crud().insert(UsersSchema, [
|
|
192
|
-
{ id: 2, name: "Smith" },
|
|
193
|
-
{ id: 3, name: "Vasyl" },
|
|
194
|
-
]);
|
|
195
|
-
```
|
|
185
|
+
Below is an example of how you can extend your README's CRUD Operations section with information and examples for both `updateFieldById` and `updateFields` methods:
|
|
196
186
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
```js
|
|
200
|
-
// INSERT INTO users (id,name) VALUES (4,'Smith'), (4, 'Vasyl') ON DUPLICATE KEY UPDATE name = VALUES(name)
|
|
201
|
-
await forgeSQL.crud().insert(
|
|
202
|
-
UsersSchema,
|
|
203
|
-
[
|
|
204
|
-
{ id: 4, name: "Smith" },
|
|
205
|
-
{ id: 4, name: "Vasyl" },
|
|
206
|
-
],
|
|
207
|
-
true,
|
|
208
|
-
);
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
- Update Data
|
|
212
|
-
|
|
213
|
-
```js
|
|
214
|
-
await forgeSQL.crud().updateById({ id: 1, name: "Smith Updated" }, UsersSchema);
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
- Delete Data
|
|
187
|
+
---
|
|
218
188
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
189
|
+
🛠 **CRUD Operations**
|
|
190
|
+
|
|
191
|
+
- **Insert Data**
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
// INSERT INTO users (id, name) VALUES (1, 'Smith')
|
|
195
|
+
const userId = await forgeSQL.crud().insert(UsersSchema, [{ id: 1, name: "Smith" }]);
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
- **Insert Bulk Data**
|
|
199
|
+
|
|
200
|
+
```js
|
|
201
|
+
// INSERT INTO users (id, name) VALUES (2, 'Smith'), (3, 'Vasyl')
|
|
202
|
+
await forgeSQL.crud().insert(UsersSchema, [
|
|
203
|
+
{ id: 2, name: "Smith" },
|
|
204
|
+
{ id: 3, name: "Vasyl" },
|
|
205
|
+
]);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
- **Insert Data with Duplicates**
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
// INSERT INTO users (id, name) VALUES (4, 'Smith'), (4, 'Vasyl')
|
|
212
|
+
// ON DUPLICATE KEY UPDATE name = VALUES(name)
|
|
213
|
+
await forgeSQL.crud().insert(
|
|
214
|
+
UsersSchema,
|
|
215
|
+
[
|
|
216
|
+
{ id: 4, name: "Smith" },
|
|
217
|
+
{ id: 4, name: "Vasyl" },
|
|
218
|
+
],
|
|
219
|
+
true,
|
|
220
|
+
);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- **Update Data by Primary Key**
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
// This uses the updateById method which wraps updateFieldById (with optimistic locking if configured)
|
|
227
|
+
await forgeSQL.crud().updateById({ id: 1, name: "Smith Updated" }, UsersSchema);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
- **Update Specific Fields by Primary Key**
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
// Updates specific fields of a record identified by its primary key.
|
|
234
|
+
// Note: The primary key field (e.g. id) must be included in the fields array.
|
|
235
|
+
await forgeSQL.crud().updateFieldById({ id: 1, name: "Updated Name" }, ["id", "name"], UsersSchema);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
- **Update Fields Without Primary Key and Versioning**
|
|
239
|
+
|
|
240
|
+
```js
|
|
241
|
+
// Updates specified fields for records matching the given conditions.
|
|
242
|
+
// In this example, the "name" and "age" fields are updated for users where the email is 'smith@example.com'.
|
|
243
|
+
const affectedRows = await forgeSQL.crud().updateFields(
|
|
244
|
+
{ name: "New Name", age: 35, email: "smith@example.com" },
|
|
245
|
+
["name", "age"],
|
|
246
|
+
UsersSchema
|
|
247
|
+
);
|
|
248
|
+
console.log(`Rows affected: ${affectedRows}`);
|
|
249
|
+
|
|
250
|
+
// Alternatively, you can provide an explicit WHERE condition:
|
|
251
|
+
const affectedRowsWithWhere = await forgeSQL.crud().updateFields(
|
|
252
|
+
{ name: "New Name", age: 35 },
|
|
253
|
+
["name", "age"],
|
|
254
|
+
UsersSchema,
|
|
255
|
+
{ email: "smith@example.com" }
|
|
256
|
+
);
|
|
257
|
+
console.log(`Rows affected: ${affectedRowsWithWhere}`);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
- **Delete Data**
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
await forgeSQL.crud().deleteById(1, UsersSchema);
|
|
264
|
+
```
|
|
222
265
|
|
|
223
266
|
## Quick Start
|
|
224
267
|
|
|
@@ -501,9 +544,12 @@ console.log(results);
|
|
|
501
544
|
|
|
502
545
|
The `ForgeSqlOrmOptions` object allows customization of ORM behavior. Currently, it supports the following options:
|
|
503
546
|
|
|
504
|
-
| Option
|
|
505
|
-
|
|
506
|
-
| `logRawSqlQuery`
|
|
547
|
+
| Option | Type | Description |
|
|
548
|
+
| -------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
549
|
+
| `logRawSqlQuery` | `boolean` | Enables logging of raw SQL queries in the Atlassian Forge Developer Console. Useful for debugging and monitoring. Defaults to `false`. |
|
|
550
|
+
| `disableOptimisticLocking` | `boolean` | Disables optimistic locking. When set to `true`, no additional condition (e.g., a version check) is added during record updates, which can improve performance. However, this may lead to conflicts when multiple transactions attempt to update the same record concurrently. |
|
|
551
|
+
|
|
552
|
+
---
|
|
507
553
|
|
|
508
554
|
### Example: Initializing `ForgeSQL` with Options
|
|
509
555
|
|
|
@@ -520,9 +566,7 @@ const options = {
|
|
|
520
566
|
const forgeSQL = new ForgeSQL(ENTITIES, options);
|
|
521
567
|
```
|
|
522
568
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
## Using `getKnex()` for Advanced SQL Queries
|
|
569
|
+
## Using `getKnex()` for Advanced SQL Queries
|
|
526
570
|
|
|
527
571
|
The `getKnex()` method allows direct interaction with Knex.js, enabling execution of raw SQL queries and complex query building.
|
|
528
572
|
|
|
@@ -545,10 +589,7 @@ let selectQueryBuilder = forgeSQL
|
|
|
545
589
|
.having("COUNT(*) > 1");
|
|
546
590
|
|
|
547
591
|
// Generate the final SQL query with ordering by count
|
|
548
|
-
const query = selectQueryBuilder
|
|
549
|
-
.getKnexQuery()
|
|
550
|
-
.orderByRaw("count ASC")
|
|
551
|
-
.toSQL().sql;
|
|
592
|
+
const query = selectQueryBuilder.getKnexQuery().orderByRaw("count ASC").toSQL().sql;
|
|
552
593
|
|
|
553
594
|
/*
|
|
554
595
|
SQL Query:
|
|
@@ -566,6 +607,7 @@ const duplicateResult = await forgeSQL
|
|
|
566
607
|
```
|
|
567
608
|
|
|
568
609
|
🔹 **What does this example do?**
|
|
610
|
+
|
|
569
611
|
1. Selects `name` and `email`, along with the count of duplicate occurrences (`COUNT(*) as count`).
|
|
570
612
|
2. Groups the data by `name` and `email` to identify duplicates.
|
|
571
613
|
3. Filters the results to include only groups with more than one record (`HAVING COUNT(*) > 1`).
|
|
@@ -574,6 +616,54 @@ const duplicateResult = await forgeSQL
|
|
|
574
616
|
|
|
575
617
|
---
|
|
576
618
|
|
|
619
|
+
Below is the plain text version of the additional section for Optimistic Locking. You can copy and paste it directly into your README:
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
## Optimistic Locking
|
|
624
|
+
|
|
625
|
+
Optimistic locking is a concurrency control mechanism that prevents data conflicts when multiple transactions attempt to update the same record concurrently. Instead of using locks, this technique relies on a version field in your entity models. Each time an update occurs, the current version is checked, and if it doesn't match the stored version, the update is rejected. This ensures data consistency and helps avoid accidental overwrites.
|
|
626
|
+
|
|
627
|
+
### How It Works
|
|
628
|
+
|
|
629
|
+
- **Version Field:**
|
|
630
|
+
A specific field in your entity schema is designated to track the version of the record. This field is marked with the flag `version: true`.
|
|
631
|
+
|
|
632
|
+
- **Supported Types:**
|
|
633
|
+
The version field must be of type `datetime`, `timestamp`, `integer`, or `decimal` and must be non-nullable. If the field's type does not meet these requirements, a warning message will be logged to the console during model generation.
|
|
634
|
+
|
|
635
|
+
- **Automatic Configuration:**
|
|
636
|
+
When generating models, you can specify a field (e.g., `updatedAt`) that automatically becomes the version field by using the `--versionField` flag. For example:
|
|
637
|
+
```sh
|
|
638
|
+
npx forge-sql-orm generate:model --versionField updatedAt
|
|
639
|
+
```
|
|
640
|
+
In this case, any model that includes a field named `updatedAt` meeting the required conditions will have it configured for optimistic locking.
|
|
641
|
+
|
|
642
|
+
### Example
|
|
643
|
+
|
|
644
|
+
Here’s how you can define an entity with optimistic locking using MikroORM:
|
|
645
|
+
|
|
646
|
+
```js
|
|
647
|
+
export class TestEntityVersion {
|
|
648
|
+
id!: number;
|
|
649
|
+
name?: string;
|
|
650
|
+
version!: number;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
export const TestEntityVersionSchema = new EntitySchema({
|
|
654
|
+
class: TestEntityVersion,
|
|
655
|
+
properties: {
|
|
656
|
+
id: { primary: true, type: "integer", unsigned: false, autoincrement: false },
|
|
657
|
+
name: { type: "string", nullable: true },
|
|
658
|
+
version: { type: "integer", nullable: false, version: true },
|
|
659
|
+
},
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
In this example, the `version` field is used to track changes. Every update will check the current version to ensure that no conflicting modifications occur.
|
|
664
|
+
|
|
665
|
+
---
|
|
666
|
+
|
|
577
667
|
## Usage with MikroORM Generator
|
|
578
668
|
|
|
579
669
|
If you prefer to use MikroORM's default entity generator, then manually import your entities:
|
|
@@ -584,9 +674,13 @@ import { UserEntity, TaskEntity } from "./entities";
|
|
|
584
674
|
|
|
585
675
|
---
|
|
586
676
|
|
|
587
|
-
##
|
|
677
|
+
## Forge SQL ORM CLI Documentation
|
|
678
|
+
|
|
679
|
+
The CLI provides commands to generate models and manage migrations for MikroORM in Forge.
|
|
680
|
+
|
|
681
|
+
---
|
|
588
682
|
|
|
589
|
-
|
|
683
|
+
### 📌 Available Commands
|
|
590
684
|
|
|
591
685
|
```sh
|
|
592
686
|
$ npx forge-sql-orm --help
|
|
@@ -594,58 +688,79 @@ $ npx forge-sql-orm --help
|
|
|
594
688
|
Usage: forge-sql-orm [options] [command]
|
|
595
689
|
|
|
596
690
|
Options:
|
|
597
|
-
-V, --version
|
|
598
|
-
-h, --help
|
|
691
|
+
-V, --version Output the version number
|
|
692
|
+
-h, --help Display help for command
|
|
599
693
|
|
|
600
694
|
Commands:
|
|
601
695
|
generate:model [options] Generate MikroORM models from the database.
|
|
602
696
|
migrations:create [options] Generate an initial migration for the entire database.
|
|
603
697
|
migrations:update [options] Generate a migration to update the database schema.
|
|
604
|
-
patch:mikroorm Patch MikroORM and Knex dependencies to work properly with Forge
|
|
605
|
-
help [command]
|
|
698
|
+
patch:mikroorm Patch MikroORM and Knex dependencies to work properly with Forge.
|
|
699
|
+
help [command] Display help for a specific command.
|
|
606
700
|
```
|
|
607
701
|
|
|
608
|
-
|
|
702
|
+
---
|
|
703
|
+
|
|
704
|
+
### 📌 Entity Generation
|
|
609
705
|
|
|
610
706
|
```sh
|
|
611
|
-
npx forge-sql-orm generate:model --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/entities
|
|
707
|
+
npx forge-sql-orm generate:model --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/entities --versionField updatedAt --saveEnv
|
|
612
708
|
```
|
|
613
709
|
|
|
614
710
|
This command will:
|
|
615
711
|
|
|
616
|
-
- Connect to mydb on localhost:3306
|
|
617
|
-
- Generate MikroORM entity classes
|
|
618
|
-
- Save them in
|
|
619
|
-
- Create an index.ts file with all entities
|
|
712
|
+
- Connect to `mydb` on `localhost:3306`.
|
|
713
|
+
- Generate MikroORM entity classes.
|
|
714
|
+
- Save them in `./src/database/entities`.
|
|
715
|
+
- Create an `index.ts` file with all entities.
|
|
716
|
+
- **`--versionField updatedAt`**: Specifies the field used for entity versioning.
|
|
717
|
+
- **`--saveEnv`**: Saves configuration settings to `.env` for future use.
|
|
718
|
+
|
|
719
|
+
#### 🔹 VersionField Explanation
|
|
720
|
+
|
|
721
|
+
The `--versionField` option is crucial for handling entity versioning. It should be a field of type `datetime`, `integer`, or `decimal`. This field is used to track changes to entities, ensuring that updates follow proper versioning strategies.
|
|
722
|
+
|
|
723
|
+
**Example:**
|
|
724
|
+
|
|
725
|
+
- `updatedAt` (datetime) - Commonly used for timestamp-based versioning.
|
|
726
|
+
- `versionNumber` (integer) - Can be used for numeric version increments.
|
|
620
727
|
|
|
621
|
-
|
|
728
|
+
If the specified field does not meet the required criteria, warnings will be logged.
|
|
729
|
+
|
|
730
|
+
---
|
|
731
|
+
|
|
732
|
+
### 📌 Database Migrations
|
|
622
733
|
|
|
623
734
|
```sh
|
|
624
|
-
npx forge-sql-orm migrations:create --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/migration --entitiesPath ./src/database/entities
|
|
735
|
+
npx forge-sql-orm migrations:create --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/migration --entitiesPath ./src/database/entities --saveEnv
|
|
625
736
|
```
|
|
626
737
|
|
|
627
738
|
This command will:
|
|
628
739
|
|
|
629
|
-
- Create initial migration
|
|
630
|
-
- Save migration files in
|
|
631
|
-
- Create
|
|
632
|
-
-
|
|
740
|
+
- Create the initial migration based on all detected entities.
|
|
741
|
+
- Save migration files in `./src/database/migration`.
|
|
742
|
+
- Create `index.ts` for automatic migration execution.
|
|
743
|
+
- **`--saveEnv`**: Saves configuration settings to `.env` for future use.
|
|
633
744
|
|
|
634
|
-
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
### 📌 Update Schema Migration
|
|
635
748
|
|
|
636
749
|
```sh
|
|
637
|
-
npx forge-sql-orm migrations:update --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/migration --entitiesPath ./src/database/entities
|
|
750
|
+
npx forge-sql-orm migrations:update --host localhost --port 3306 --user root --password secret --dbName mydb --output ./src/database/migration --entitiesPath ./src/database/entities --saveEnv
|
|
638
751
|
```
|
|
639
752
|
|
|
640
753
|
This command will:
|
|
641
754
|
|
|
642
|
-
Detect schema changes (new tables, columns, indexes)
|
|
755
|
+
- Detect schema changes (new tables, columns, indexes).
|
|
756
|
+
- Generate only the required migrations.
|
|
757
|
+
- Update `index.ts` to include new migrations.
|
|
758
|
+
- **`--saveEnv`**: Saves configuration settings to `.env` for future use.
|
|
759
|
+
|
|
760
|
+
---
|
|
643
761
|
|
|
644
|
-
|
|
645
|
-
- Increment migrationCount.ts
|
|
646
|
-
- Update index.ts to include new migrations
|
|
762
|
+
### 📌 Using the patch:mikroorm Command
|
|
647
763
|
|
|
648
|
-
📌 Using the patch:mikroorm Command
|
|
649
764
|
If needed, you can manually apply the patch at any time using:
|
|
650
765
|
|
|
651
766
|
```sh
|
|
@@ -658,23 +773,19 @@ This command:
|
|
|
658
773
|
- Fixes dynamic imports to work in Forge.
|
|
659
774
|
- Ensures Knex and MikroORM work properly inside Forge.
|
|
660
775
|
|
|
661
|
-
|
|
662
|
-
To manually execute migrations in your application:
|
|
663
|
-
|
|
664
|
-
```js
|
|
665
|
-
import migrationRunner from "./src/database/migration";
|
|
666
|
-
import { MigrationRunner } from "@forge/sql/out/migration";
|
|
776
|
+
---
|
|
667
777
|
|
|
668
|
-
|
|
669
|
-
await migrationRunner(runner);
|
|
670
|
-
await runner.run(); // ✅ Apply migrations
|
|
671
|
-
```
|
|
778
|
+
### 📌 Configuration Methods
|
|
672
779
|
|
|
673
|
-
🔧 Configuration
|
|
674
780
|
You can define database credentials using:
|
|
675
781
|
|
|
676
|
-
1
|
|
677
|
-
|
|
782
|
+
1️⃣ **Command-line arguments**:
|
|
783
|
+
|
|
784
|
+
```sh
|
|
785
|
+
--host, --port, --user, --password, --dbName, --output, --versionField, --saveEnv
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
2️⃣ **Environment variables**:
|
|
678
789
|
|
|
679
790
|
```bash
|
|
680
791
|
export FORGE_SQL_ORM_HOST=localhost
|
|
@@ -684,7 +795,7 @@ export FORGE_SQL_ORM_PASSWORD=secret
|
|
|
684
795
|
export FORGE_SQL_ORM_DBNAME=mydb
|
|
685
796
|
```
|
|
686
797
|
|
|
687
|
-
3
|
|
798
|
+
3️⃣ **Using a `.env` file**:
|
|
688
799
|
|
|
689
800
|
```sh
|
|
690
801
|
FORGE_SQL_ORM_HOST=localhost
|
|
@@ -694,7 +805,24 @@ FORGE_SQL_ORM_PASSWORD=secret
|
|
|
694
805
|
FORGE_SQL_ORM_DBNAME=mydb
|
|
695
806
|
```
|
|
696
807
|
|
|
697
|
-
4
|
|
808
|
+
4️⃣ **Interactive prompts** (if missing parameters, the CLI will ask for input).
|
|
809
|
+
|
|
810
|
+
---
|
|
811
|
+
|
|
812
|
+
### 📌 Manual Migration Execution
|
|
813
|
+
|
|
814
|
+
To manually execute migrations in your application:
|
|
815
|
+
|
|
816
|
+
```js
|
|
817
|
+
import migrationRunner from "./src/database/migration";
|
|
818
|
+
import { MigrationRunner } from "@forge/sql/out/migration";
|
|
819
|
+
|
|
820
|
+
const runner = new MigrationRunner();
|
|
821
|
+
await migrationRunner(runner);
|
|
822
|
+
await runner.run(); // ✅ Apply migrations
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
This approach allows you to apply migrations programmatically in a Forge application.
|
|
698
826
|
|
|
699
827
|
---
|
|
700
828
|
|