diff --git a/README.md b/README.md
index 32861387..4b7b2d30 100644
--- a/README.md
+++ b/README.md
@@ -531,7 +531,7 @@ The following operators are supported:
- max
- avg
-You can also elevate associated data to the root level for easier access. In the example below, balance of the customer is elevated to the root level.
+You can also elevate associated data to a parent level for easier access. In the example below, balance of the customer is elevated to the root level.
```javascript
import map from './map';
@@ -1766,7 +1766,7 @@ Supported functions include:
__On each row__
For each row we are counting the number of lines.
-You can also elevate associated data to the root level for easier access. In the example below, balance of the customer is elevated to the root level.
+You can also elevate associated data to the a parent level for easier access. In the example below, balance of the customer is elevated to the root level.
```javascript
import map from './map';
diff --git a/docs/changelog.md b/docs/changelog.md
index 6ca39dff..b4eb5e9c 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,7 @@
## Changelog
+__3.9.0__
+Possible to elevate associated column on a related table to a parent table when fetching. See https://github.com/alfateam/rdb/#user-content-aggregate-results
__3.8.0__
Aggregate operators: count, max, min, avg and sum.
__3.7.0__
diff --git a/package.json b/package.json
index 204e770a..f618768d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rdb",
- "version": "3.8.0",
+ "version": "3.9.0",
"main": "./src/index.js",
"browser": "./src/client/index.mjs",
"bin": {
diff --git a/src/client/index.mjs b/src/client/index.mjs
index 636b736e..fb12ff7d 100644
--- a/src/client/index.mjs
+++ b/src/client/index.mjs
@@ -5591,6 +5591,9 @@ function rdbClient(options = {}) {
for (let name in _strategy) {
if (name === 'where' && typeof strategy[name] === 'function')
strategy.where = column(path + 'where')(strategy.where); // Assuming `column` is defined elsewhere.
+ else if (typeof strategy[name] === 'function') {
+ strategy[name] = aggregate(path, strategy[name]);
+ }
else
strategy[name] = where(_strategy[name], path + name + '.');
}
@@ -6099,6 +6102,55 @@ function tableProxy() {
return new Proxy({}, handler);
}
+function aggregate(path, arg) {
+
+ const c = {
+ sum,
+ count,
+ avg,
+ max,
+ min
+ };
+
+ let handler = {
+ get(_target, property,) {
+ if (property in c)
+ return Reflect.get(...arguments);
+ else {
+ subColumn = column(path + 'aggregate');
+ return column(property);
+ }
+ }
+
+ };
+ let subColumn;
+ const proxy = new Proxy(c, handler);
+
+ const result = arg(proxy);
+
+ if (subColumn)
+ return subColumn(result.self());
+ else
+ return result;
+
+
+ function sum(fn) {
+ return column(path + 'aggregate')(fn(column('')).sum());
+ }
+ function avg(fn) {
+ return column(path + 'aggregate')(fn(column('')).avg());
+ }
+ function max(fn) {
+ return column(path + 'aggregate')(fn(column('')).max());
+ }
+ function min(fn) {
+ return column(path + 'aggregate')(fn(column('')).min());
+ }
+ function count(fn) {
+ return column(path + 'aggregate')(fn(column('')).count());
+ }
+}
+
function column(path, ...previous) {
function c() {
let args = [];
@@ -6131,8 +6183,10 @@ function column(path, ...previous) {
return Reflect.get(...arguments);
else if (property === 'then')
return;
- else
- return column(path + '.' + property);
+ else {
+ const nextPath = path ? path + '.' : '';
+ return column(nextPath + property);
+ }
}
};