myorm_pg 9.3.0 → 10.0.1
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/lib/Index.d.ts +0 -1
- package/lib/Index.d.ts.map +1 -1
- package/lib/Index.js +0 -1
- package/lib/Index.js.map +1 -1
- package/lib/core/decorators/SchemasDecorators.d.ts +1 -0
- package/lib/core/decorators/SchemasDecorators.d.ts.map +1 -1
- package/lib/core/decorators/SchemasDecorators.js +12 -0
- package/lib/core/decorators/SchemasDecorators.js.map +1 -1
- package/lib/implementations/PGDBConnection.d.ts +5 -0
- package/lib/implementations/PGDBConnection.d.ts.map +1 -1
- package/lib/implementations/PGDBConnection.js +80 -11
- package/lib/implementations/PGDBConnection.js.map +1 -1
- package/lib/implementations/PGDBContext.d.ts +5 -0
- package/lib/implementations/PGDBContext.d.ts.map +1 -1
- package/lib/implementations/PGDBContext.js +33 -0
- package/lib/implementations/PGDBContext.js.map +1 -1
- package/lib/implementations/PGDBManager.d.ts +10 -4
- package/lib/implementations/PGDBManager.d.ts.map +1 -1
- package/lib/implementations/PGDBManager.js +107 -60
- package/lib/implementations/PGDBManager.js.map +1 -1
- package/lib/implementations/PGDBSet.d.ts +4 -3
- package/lib/implementations/PGDBSet.d.ts.map +1 -1
- package/lib/implementations/PGDBSet.js +24 -2
- package/lib/implementations/PGDBSet.js.map +1 -1
- package/package.json +7 -4
- package/readme.md +229 -22
package/readme.md
CHANGED
|
@@ -18,10 +18,21 @@ npm install myorm_pg
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
---
|
|
21
|
+
## Configuration
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
#### Peer Dependencies
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
This ORM relies on the `reflect-metadata` package to enable runtime type reflection used by decorators.
|
|
26
|
+
|
|
27
|
+
Make sure it is installed and imported **once** in your application entry point:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import 'reflect-metadata';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
#### Typescript
|
|
34
|
+
|
|
35
|
+
Decorators and metadata emission must be enabled in your `tsconfig.json`:
|
|
25
36
|
|
|
26
37
|
```json
|
|
27
38
|
{
|
|
@@ -29,6 +40,9 @@ Decorators must be enabled in your `tsconfig.json`:
|
|
|
29
40
|
"emitDecoratorMetadata": true
|
|
30
41
|
}
|
|
31
42
|
```
|
|
43
|
+
|
|
44
|
+
These options are required for entity mapping, dependency injection, and relationship metadata to work correctly.
|
|
45
|
+
|
|
32
46
|
---
|
|
33
47
|
|
|
34
48
|
|
|
@@ -45,7 +59,10 @@ Defines the database table name associated with the entity.
|
|
|
45
59
|
|
|
46
60
|
### @Column
|
|
47
61
|
Marks a class property as a table column.
|
|
48
|
-
|
|
62
|
+
|
|
63
|
+
You may optionally provide a custom column name as a parameter.
|
|
64
|
+
|
|
65
|
+
If any other column-related decorator is applied to the property, the `@Column` decorator becomes optional — except when you want to explicitly define the column name.
|
|
49
66
|
|
|
50
67
|
### @PrimaryKey
|
|
51
68
|
Indicates that the column is the primary key of the table.
|
|
@@ -154,8 +171,7 @@ import { Message } from './Message';
|
|
|
154
171
|
export class Person
|
|
155
172
|
{
|
|
156
173
|
// Primary key with SERIAL (auto-increment)
|
|
157
|
-
@PrimaryKey()
|
|
158
|
-
@Column()
|
|
174
|
+
@PrimaryKey()
|
|
159
175
|
@DataType(DBTypes.SERIAL)
|
|
160
176
|
public Id!: number;
|
|
161
177
|
|
|
@@ -171,33 +187,27 @@ export class Person
|
|
|
171
187
|
@Column()
|
|
172
188
|
public Age!: number;
|
|
173
189
|
|
|
174
|
-
// Explicit integer column
|
|
175
|
-
@Column()
|
|
190
|
+
// Explicit integer column
|
|
176
191
|
@DataType(DBTypes.INTEGER)
|
|
177
192
|
public CEP!: number;
|
|
178
193
|
|
|
179
|
-
// PostgreSQL TEXT[]
|
|
180
|
-
@Column()
|
|
194
|
+
// PostgreSQL TEXT[]
|
|
181
195
|
@DataType(DBTypes.TEXTARRAY)
|
|
182
196
|
public PhoneNumbers!: string[];
|
|
183
197
|
|
|
184
|
-
// PostgreSQL INTEGER[]
|
|
185
|
-
@Column()
|
|
198
|
+
// PostgreSQL INTEGER[]
|
|
186
199
|
@DataType(DBTypes.INTEGERARRAY)
|
|
187
200
|
public Documents!: number[];
|
|
188
201
|
|
|
189
|
-
// PostgreSQL DATE
|
|
190
|
-
@Column()
|
|
202
|
+
// PostgreSQL DATE
|
|
191
203
|
@DataType(DBTypes.DATE)
|
|
192
204
|
public Birth!: Date;
|
|
193
205
|
|
|
194
|
-
// One person can write many messages
|
|
195
|
-
@Column()
|
|
206
|
+
// One person can write many messages
|
|
196
207
|
@OneToMany(() => Message, "From")
|
|
197
208
|
public MessagesWriten?: Message[];
|
|
198
209
|
|
|
199
210
|
// Many persons can receive many messages
|
|
200
|
-
@Column()
|
|
201
211
|
@ManyToMany(() => Message, "To")
|
|
202
212
|
public MessagesReceived?: Message[];
|
|
203
213
|
|
|
@@ -231,8 +241,7 @@ import { Person } from './Person';
|
|
|
231
241
|
export class Message
|
|
232
242
|
{
|
|
233
243
|
// Primary key with SERIAL (auto-increment)
|
|
234
|
-
@PrimaryKey()
|
|
235
|
-
@Column()
|
|
244
|
+
@PrimaryKey()
|
|
236
245
|
@DataType(DBTypes.SERIAL)
|
|
237
246
|
public Id : number = -1;
|
|
238
247
|
|
|
@@ -240,13 +249,11 @@ export class Message
|
|
|
240
249
|
@Column()
|
|
241
250
|
public Message : string;
|
|
242
251
|
|
|
243
|
-
// One person can write many messages
|
|
244
|
-
@Column()
|
|
252
|
+
// One person can write many messages
|
|
245
253
|
@ManyToOne(()=> Person, "MessagesWriten")
|
|
246
254
|
public From? : Person;
|
|
247
255
|
|
|
248
|
-
// Many persons can receive many messages
|
|
249
|
-
@Column()
|
|
256
|
+
// Many persons can receive many messages
|
|
250
257
|
@ManyToMany(()=> Person, "MessagesReceived")
|
|
251
258
|
public To? : Person[];
|
|
252
259
|
|
|
@@ -684,6 +691,123 @@ await context.Persons.DeleteAsync(person);
|
|
|
684
691
|
|
|
685
692
|
---
|
|
686
693
|
|
|
694
|
+
|
|
695
|
+
# Transactions
|
|
696
|
+
|
|
697
|
+
This ORM provides first-class support for database transactions, including **begin**, **commit**, **rollback**, and **savepoints**.
|
|
698
|
+
This allows you to safely group multiple operations and partially rollback changes when needed.
|
|
699
|
+
|
|
700
|
+
### Basic Usage
|
|
701
|
+
|
|
702
|
+
You can manually control a transaction using the context API:
|
|
703
|
+
|
|
704
|
+
```typescript
|
|
705
|
+
await context.BeginTransactionAsync();
|
|
706
|
+
|
|
707
|
+
// database operations...
|
|
708
|
+
|
|
709
|
+
await context.CommitAsync();
|
|
710
|
+
```
|
|
711
|
+
If something goes wrong, you can rollback the entire transaction:
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
await context.RollBackAsync();
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
### Full Rollback Example
|
|
719
|
+
|
|
720
|
+
In this example, **any error** causes the entire transaction to be rolled back:
|
|
721
|
+
|
|
722
|
+
```typescript
|
|
723
|
+
await context.BeginTransactionAsync();
|
|
724
|
+
|
|
725
|
+
try
|
|
726
|
+
{
|
|
727
|
+
await context.Persons.AddAsync(person1);
|
|
728
|
+
await context.Persons.AddAsync(person2);
|
|
729
|
+
|
|
730
|
+
await context.Messages.AddAsync(message);
|
|
731
|
+
|
|
732
|
+
await context.CommitAsync();
|
|
733
|
+
}
|
|
734
|
+
catch (error)
|
|
735
|
+
{
|
|
736
|
+
// Reverts all operations executed within the transaction
|
|
737
|
+
await context.RollBackAsync();
|
|
738
|
+
throw error;
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
What happens here:
|
|
742
|
+
|
|
743
|
+
- All operations are executed inside a single transaction
|
|
744
|
+
|
|
745
|
+
- If any step fails, no data is persisted
|
|
746
|
+
|
|
747
|
+
- The transaction is only committed if everything succeeds
|
|
748
|
+
|
|
749
|
+
## Savepoint with Partial Rollback Example
|
|
750
|
+
|
|
751
|
+
Savepoints allow you to protect a specific section of a transaction.
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
```typescript
|
|
755
|
+
await context.BeginTransactionAsync();
|
|
756
|
+
|
|
757
|
+
try
|
|
758
|
+
{
|
|
759
|
+
await context.Persons.AddAsync(person1);
|
|
760
|
+
await context.Persons.AddAsync(person2);
|
|
761
|
+
await context.Persons.AddAsync(person3);
|
|
762
|
+
await context.Persons.AddAsync(person4);
|
|
763
|
+
|
|
764
|
+
// Creates a savepoint after all persons are added
|
|
765
|
+
await context.SavePointAsync("persons");
|
|
766
|
+
|
|
767
|
+
await context.Messages.AddAsync(message);
|
|
768
|
+
|
|
769
|
+
// Something went wrong while saving the message
|
|
770
|
+
throw new Error("Message validation failed");
|
|
771
|
+
|
|
772
|
+
await context.CommitAsync();
|
|
773
|
+
}
|
|
774
|
+
catch (error)
|
|
775
|
+
{
|
|
776
|
+
// Rollback only the operations after the savepoint
|
|
777
|
+
await context.RollBackAsync("persons");
|
|
778
|
+
|
|
779
|
+
// Commit everything that happened before the savepoint
|
|
780
|
+
await context.CommitAsync();
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
```
|
|
784
|
+
Result:
|
|
785
|
+
|
|
786
|
+
- All Person entities are saved
|
|
787
|
+
|
|
788
|
+
- The Message entity is discarded
|
|
789
|
+
|
|
790
|
+
- The transaction completes successfully
|
|
791
|
+
|
|
792
|
+
## Recommended Pattern
|
|
793
|
+
```typescript
|
|
794
|
+
await context.BeginTransactionAsync();
|
|
795
|
+
|
|
796
|
+
try
|
|
797
|
+
{
|
|
798
|
+
// operations
|
|
799
|
+
await context.CommitAsync();
|
|
800
|
+
}
|
|
801
|
+
catch
|
|
802
|
+
{
|
|
803
|
+
await context.RollBackAsync();
|
|
804
|
+
throw;
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
Using `try/catch` with transactions is strongly recommended to guarantee data integrity and predictable behavior.
|
|
808
|
+
|
|
809
|
+
---
|
|
810
|
+
|
|
687
811
|
# Fluent query methods
|
|
688
812
|
|
|
689
813
|
## Where
|
|
@@ -743,6 +867,89 @@ let persons = await context.Persons.WhereField("MessagesReceived").IsNull().ToLi
|
|
|
743
867
|
|
|
744
868
|
|
|
745
869
|
|
|
870
|
+
# GetTypeMapping (Type Mapping Helper)
|
|
871
|
+
|
|
872
|
+
The `PGDBSet<T>.GetTypeMapping()` feature exposes metadata about an entity mapping, allowing you to safely build **dynamic SQL statements** based on entity definitions, column mappings, and relationships — without hardcoding table or column names.
|
|
873
|
+
|
|
874
|
+
This is especially useful for:
|
|
875
|
+
- Dynamic queries
|
|
876
|
+
- Custom SQL generation
|
|
877
|
+
- Debugging mappings
|
|
878
|
+
- Advanced filtering scenarios
|
|
879
|
+
|
|
880
|
+
### Basic Usage
|
|
881
|
+
```typescript
|
|
882
|
+
|
|
883
|
+
let helper = context.Persons.GetTypeMapping();
|
|
884
|
+
|
|
885
|
+
```
|
|
886
|
+
The returned helper provides access to:
|
|
887
|
+
|
|
888
|
+
- Table → mapped table name
|
|
889
|
+
|
|
890
|
+
- Columns → mapped column names
|
|
891
|
+
|
|
892
|
+
- EvaluateStatement() → generates SQL expressions from strongly-typed filters
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
#### Update example
|
|
896
|
+
```typescript
|
|
897
|
+
|
|
898
|
+
let helper = context.Persons.GetTypeMapping();
|
|
899
|
+
|
|
900
|
+
let person = await context.Persons.OrderBy("Age").FirstOrDefaultAsync();
|
|
901
|
+
|
|
902
|
+
let update = `update ${helper.Table}
|
|
903
|
+
set ${helper.Columns.Age} = ${helper.Columns.Age} - 1
|
|
904
|
+
where ${helper.Columns.Id} = ${person?.Id}`;
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
let rowCount = (await context.ExecuteQuery(update)).rowCount;
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
#### Select using EvaluateStatement()
|
|
911
|
+
```typescript
|
|
912
|
+
const helper = context.Persons.GetTypeMapping();
|
|
913
|
+
|
|
914
|
+
const whereClause = helper.EvaluateStatement({
|
|
915
|
+
Field: "Age",
|
|
916
|
+
Value: 20
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
const select = `select ${helper.Columns.Name}, ${helper.Columns.Email} from ${helper.Table} where ${whereClause}`;
|
|
920
|
+
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
#### Querying using relation fields
|
|
924
|
+
|
|
925
|
+
```typescript
|
|
926
|
+
|
|
927
|
+
const helper = context.Persons.GetTypeMapping();
|
|
928
|
+
|
|
929
|
+
const whereClause = helper.EvaluateStatement({
|
|
930
|
+
Field: "MessagesReceived",
|
|
931
|
+
Kind: Operation.CONTAINS,
|
|
932
|
+
Value: [messageObject]
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
const select = `select ${helper.Columns.Id} from ${helper.Table} where ${whereClause}`;
|
|
936
|
+
|
|
937
|
+
```
|
|
938
|
+
|
|
939
|
+
`GetTypeMapping()` gives you a low-level but type-aware view of your entity mapping:
|
|
940
|
+
|
|
941
|
+
- No hardcoded table or column names
|
|
942
|
+
|
|
943
|
+
- Safe dynamic SQL generation
|
|
944
|
+
|
|
945
|
+
- Works with scalar fields and relations
|
|
946
|
+
|
|
947
|
+
- Ideal for advanced scenarios where LINQ-like APIs are not enough
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
---
|
|
951
|
+
|
|
952
|
+
|
|
746
953
|
## Contributing
|
|
747
954
|
|
|
748
955
|
Pull requests are welcome. For major changes, please open an issue first
|