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); + } } };