orange-orm 3.10.2 → 4.0.0

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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  The ultimate Object Relational Mapper for Node.js and Typescript, offering seamless integration with a variety of popular databases. Whether you're building applications in TypeScript or JavaScript (including both CommonJS and ECMAScript), Orange ORM has got you covered.
6
6
 
7
- [![npm version](https://img.shields.io/npm/v/rdb.svg?style=flat-square)](https://www.npmjs.org/package/orange-orm)
7
+ [![npm version](https://img.shields.io/npm/v/orange-orm.svg?style=flat-square)](https://www.npmjs.org/package/orange-orm)
8
8
  [![Build status](https://github.com/alfateam/orange-orm/workflows/Node.js%20CI/badge.svg)](https://github.com/alfateam/orange-orm/actions)
9
9
  [![Coverage Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/lroal/1a69422f03da7f8155cf94fe66022452/raw/rdb__heads_master.json)](https://github.com/alfateam/orange-orm/actions)
10
10
  [![Github](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/lroal/1ccb2b79abbe0258d636e9b5e4630a1a/raw/rdb__heads_master.json)](https://github.com/alfateam/orange-orm)
@@ -46,7 +46,7 @@ $ npm install orange-orm
46
46
  ## Example
47
47
  Watch the [tutorial video on YouTube](https://youtu.be/1IwwjPr2lMs)
48
48
 
49
- ![Relations diagram](./docs/relations.png)
49
+ ![Relations diagram](./docs/diagram.svg)
50
50
 
51
51
  Here we choose SQLite.
52
52
  ```bash
@@ -77,6 +77,12 @@ const map = orange.map(x => ({
77
77
  amount: column('amount').numeric(),
78
78
  })),
79
79
 
80
+ package: x.table('package').map(({ column }) => ({
81
+ id: column('packageId').numeric().primary().notNullExceptInsert(),
82
+ lineId: column('lineId').numeric().notNullExceptInsert(),
83
+ sscc: column('sscc').string() //the barcode
84
+ })),
85
+
80
86
  deliveryAddress: x.table('deliveryAddress').map(({ column }) => ({
81
87
  id: column('id').numeric().primary(),
82
88
  orderId: column('orderId').numeric(),
@@ -87,6 +93,10 @@ const map = orange.map(x => ({
87
93
  countryCode: column('countryCode').string(),
88
94
  }))
89
95
 
96
+ })).map(x => ({
97
+ orderLine: x.orderLine.map(({ hasMany }) => ({
98
+ packages: hasMany(x.package).by('lineId')
99
+ }))
90
100
  })).map(x => ({
91
101
  order: x.order.map(v => ({
92
102
  customer: v.references(x.customer).by('customerId'),
@@ -130,8 +140,10 @@ async function getRows() {
130
140
  const orders = await db.order.getAll({
131
141
  where: x => x.lines.any(line => line.product.contains('broomstick'))
132
142
  .and(db.order.customer.name.startsWith('Harry')),
133
- lines: true,
134
- deliveryAddress: true,
143
+ lines: {
144
+ packages: true
145
+ },
146
+ deliveryAddress: true,
135
147
  customer: true
136
148
  });
137
149
  }
@@ -145,7 +157,7 @@ async function getRows() {
145
157
 
146
158
  Each column within your database table is designated by using the <strong><i>column()</i></strong> method, in which you specify its name. This action generates a reference to a column object that enables you to articulate further column properties like its data type or if it serves as a primary key.
147
159
 
148
- Relationships between tables can also be outlined. By using methods like <strong><i>hasOne</i></strong>, <strong><i>hasMany</i></strong>, and <strong><i>references</i></strong>, you can establish connections that reflect the relationships in your data schema. In the example below, an 'order' is linked to a 'customer' reference, a 'deliveryAddress', and multiple 'lines'. The hasMany and hasOne relations represents ownership - the tables 'deliveryAddress' and 'orderLine' are owned by the 'order' table, and therefore, they contain the 'orderId' column referring to their parent table, which is 'order'. Conversely, the customer table is independent and can exist without any knowledge of the 'order' table. Therefore we say that the order table <i>references</i> the customer table - necessitating the existence of a 'customerId' column in the 'order' table.</p>
160
+ Relationships between tables can also be outlined. By using methods like <strong><i>hasOne</i></strong>, <strong><i>hasMany</i></strong>, and <strong><i>references</i></strong>, you can establish connections that reflect the relationships in your data schema. In the example below, an 'order' is linked to a 'customer' reference, a 'deliveryAddress', and multiple 'lines'. The hasMany and hasOne relations represents ownership - the tables 'deliveryAddress' and 'orderLine' are owned by the 'order' table, and therefore, they contain the 'orderId' column referring to their parent table, which is 'order'. The similar relationship exists between orderLine and package - hence the packages are owned by the orderLine. Conversely, the customer table is independent and can exist without any knowledge of the 'order' table. Therefore we say that the order table <i>references</i> the customer table - necessitating the existence of a 'customerId' column in the 'order' table.</p>
149
161
 
150
162
  <sub>📄 map.ts</sub>
151
163
  ```javascript
@@ -171,6 +183,12 @@ const map = orange.map(x => ({
171
183
  product: column('product').string(),
172
184
  })),
173
185
 
186
+ package: x.table('package').map(({ column }) => ({
187
+ id: column('packageId').numeric().primary().notNullExceptInsert(),
188
+ lineId: column('lineId').numeric().notNullExceptInsert(),
189
+ sscc: column('sscc').string() //the barcode
190
+ })),
191
+
174
192
  deliveryAddress: x.table('deliveryAddress').map(({ column }) => ({
175
193
  id: column('id').numeric().primary(),
176
194
  orderId: column('orderId').numeric(),
@@ -181,6 +199,10 @@ const map = orange.map(x => ({
181
199
  countryCode: column('countryCode').string(),
182
200
  }))
183
201
 
202
+ })).map(x => ({
203
+ orderLine: x.orderLine.map(({ hasMany }) => ({
204
+ packages: hasMany(x.package).by('lineId')
205
+ }))
184
206
  })).map(x => ({
185
207
  order: x.order.map(({ hasOne, hasMany, references }) => ({
186
208
  customer: references(x.customer).by('customerId'),
@@ -225,6 +247,12 @@ CREATE TABLE orderLine (
225
247
  amount NUMERIC(10,2)
226
248
  );
227
249
 
250
+ CREATE TABLE package (
251
+ packageId INTEGER PRIMARY KEY,
252
+ lineId INTEGER REFERENCES orderLine,
253
+ sscc TEXT
254
+ );
255
+
228
256
  CREATE TABLE deliveryAddress (
229
257
  id INTEGER PRIMARY KEY,
230
258
  orderId INTEGER REFERENCES _order,
@@ -329,7 +357,7 @@ $ npm install pg
329
357
  ```
330
358
  ```javascript
331
359
  import map from './map';
332
- const db = map.pg('postgres://postgres:postgres@postgres/postgres');
360
+ const db = map.postgres('postgres://postgres:postgres@postgres/postgres');
333
361
  ```
334
362
  __Oracle__
335
363
  ```bash
@@ -497,12 +525,14 @@ async function getRows() {
497
525
  const orders = await db.order.getAll({
498
526
  customer: true,
499
527
  deliveryAddress: true,
500
- lines: true
528
+ lines: {
529
+ packages: true
530
+ }
501
531
  });
502
532
  }
503
533
  ```
504
534
  __Limit, offset and order by__
505
- This script demonstrates how to fetch orders with customer, lines and deliveryAddress, limiting the results to 10, skipping the first row, and sorting the data based on the orderDate in descending order followed by id. The lines are sorted by product.
535
+ This script demonstrates how to fetch orders with customer, lines, packages and deliveryAddress, limiting the results to 10, skipping the first row, and sorting the data based on the orderDate in descending order followed by id. The lines are sorted by product.
506
536
 
507
537
  ```javascript
508
538
  import map from './map';
@@ -518,6 +548,7 @@ async function getRows() {
518
548
  customer: true,
519
549
  deliveryAddress: true,
520
550
  lines: {
551
+ packages: true,
521
552
  orderBy: 'product'
522
553
  },
523
554
  });
@@ -593,7 +624,7 @@ getRows();
593
624
 
594
625
  async function getRows() {
595
626
  const order = await db.order.getOne(undefined /* optional filter */, {
596
- where: x => x.order.customer(customer => customer.isActive.eq(true)
627
+ where: x => x.customer(customer => customer.isActive.eq(true)
597
628
  .and(customer.startsWith('Harr'))),
598
629
  customer: true,
599
630
  deliveryAddress: true,
@@ -616,7 +647,6 @@ async function getRows() {
616
647
  });
617
648
  }
618
649
  ```
619
- ```
620
650
 
621
651
  __Single row by primary key__
622
652
 
@@ -710,8 +740,8 @@ async function update() {
710
740
  await orders.saveChanges();
711
741
  }
712
742
  ```
713
- __Updating from JSON__
714
- The update method is suitable when a complete overwrite is required from a JSON object - typically in a REST API. However, it's important to consider that this method replaces the entire row and it's children, which might not always be desirable in a multi-user environment.
743
+ __Selective updates__
744
+ The update method is ideal for updating specific columns and relationships across one or multiple rows. You must provide a where filter to specify which rows to target. If you include a fetching strategy, the affected rows and their related data will be returned; otherwise, no data is returned.
715
745
 
716
746
  ```javascript
717
747
  import map from './map';
@@ -721,7 +751,33 @@ update();
721
751
 
722
752
  async function update() {
723
753
 
754
+ const propsToBeModified = {
755
+ orderDate: new Date(),
756
+ customerId: 2,
757
+ lines: [
758
+ { id: 1, product: 'Bicycle', amount: 250 }, //already existing line
759
+ { id: 2, product: 'Small guitar', amount: 150 }, //already existing line
760
+ { product: 'Piano', amount: 800 } //the new line to be inserted
761
+ ]
762
+ };
763
+
764
+ const strategy = {customer: true, deliveryAddress: true, lines: true};
765
+ const orders = await db.order.update(propsToBeModified, { where: x => x.id.eq(1) }, strategy);
766
+ }
767
+ ```
768
+ __Replacing a row from JSON__
769
+ The replace method is suitable when a complete overwrite is required from a JSON object - typically in a REST API. However, it's important to consider that this method replaces the entire row and it's children, which might not always be desirable in a multi-user environment.
770
+
771
+ ```javascript
772
+ import map from './map';
773
+ const db = map.sqlite('demo.db');
774
+
775
+ replace();
776
+
777
+ async function replace() {
778
+
724
779
  const modified = {
780
+ id: 1,
725
781
  orderDate: '2023-07-14T12:00:00',
726
782
  customer: {
727
783
  id: 2
@@ -740,7 +796,7 @@ async function update() {
740
796
  ]
741
797
  };
742
798
 
743
- const order = await db.order.update(modified, {customer: true, deliveryAddress: true, lines: true});
799
+ const order = await db.order.replace(modified, {customer: true, deliveryAddress: true, lines: true});
744
800
  }
745
801
  ```
746
802
  __Partially updating from JSON__
@@ -1795,7 +1851,7 @@ async function getRows() {
1795
1851
  ```
1796
1852
  </details>
1797
1853
 
1798
- <details><summary><strong>Aggregate functions</strong></summary>
1854
+ <details id="aggregates"><summary><strong>Aggregate functions</strong></summary>
1799
1855
 
1800
1856
  You can count records and aggregate numerical columns. This can either be done across rows or separately for each row.
1801
1857
  Supported functions include:
package/docs/changelog.md CHANGED
@@ -1,11 +1,15 @@
1
1
  ## Changelog
2
- __3.10.2_
2
+ __4.0.0__
3
+ Changed the behaviour of `update` to accept a `where` filter and only update passed in columns and relations. The previous behaviour of `update` has moved to `replace` method.
4
+ __3.10.3__
5
+ Fix duplicate method signatures for those still using code generation
6
+ __3.10.2__
3
7
  Orange ORM was renamed from rdb. New installation url: [npmjs.org/package/orange-orm](https://npmjs.org/package/orange-orm) . Old url was npmjs.org/package/rdb
4
- __3.10.1_
8
+ __3.10.1__
5
9
  Bugfix: Adding hasOne row to existing parent throws. See [#86](https://github.com/alfateam/orange-orm/issues/86)
6
- __3.10.0_
10
+ __3.10.0__
7
11
  Aggregate functions
8
- __3.9.1_
12
+ __3.9.1__
9
13
  Bugfix: Crashing on many relations if foreign key column is omitted in strategy. See [#83](https://github.com/alfateam/orange-orm/issues/83)
10
14
  __3.9.0__
11
15
  Possible to elevate associated column on a related table to a parent table when fetching. See https://github.com/alfateam/orange-orm/#user-content-aggregate-results