Skip to content

Commit

Permalink
Merge branch 'master' of github.com:alfateam/rdb
Browse files Browse the repository at this point in the history
  • Loading branch information
lroal committed May 4, 2024
2 parents a6663a0 + 398ccdf commit 25efb90
Show file tree
Hide file tree
Showing 36 changed files with 506 additions and 81 deletions.
38 changes: 36 additions & 2 deletions src/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,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 + '.');
}
Expand Down Expand Up @@ -803,6 +806,35 @@ function tableProxy() {
return new Proxy({}, handler);
}

function aggregate(path, arg) {
const c = {
sum,
count,
avg,
max,
min
};

return arg(c);


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 = [];
Expand Down Expand Up @@ -835,8 +867,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);
}
}

};
Expand Down
19 changes: 15 additions & 4 deletions src/getManyDto.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ async function getManyDto(table, filter, strategy) {
let arg = typeof strategy.where === 'function' ? strategy.where(table) : strategy.where;
filter = filter.and(arg);
}

let span = strategyToSpan(table, strategy);
let alias = table._dbName;

Expand All @@ -26,8 +27,8 @@ function newCreateRow(span) {
const manyNames = [];

const c = {};
c.visitJoin = () => {};
c.visitOne = () => {};
c.visitJoin = () => { };
c.visitOne = () => { };
c.visitMany = function(leg) {
manyNames.push(leg.name);
};
Expand All @@ -53,6 +54,9 @@ function createProto(columns, span) {
for (let i = 0; i < columns.length; i++) {
obj[columns[i].alias] = null;
}
for (let key in span.aggregates) {
obj[key] = null;
}
const c = {};

c.visitJoin = function(leg) {
Expand All @@ -75,7 +79,7 @@ function createProto(columns, span) {
function hasManyRelations(span) {
let result;
const c = {};
c.visitJoin = () => {};
c.visitJoin = () => { };
c.visitOne = c.visitJoin;
c.visitMany = function() {
result = true;
Expand All @@ -100,6 +104,7 @@ async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys
const rowsMap = new Map();
const fkIds = new Array(rows.length);
const getIds = createGetIds();
const aggregateKeys = Object.keys(span.aggregates);

const outRows = new Array(rowsLength);
const createRow = newCreateRow(span);
Expand All @@ -122,13 +127,19 @@ async function decode(strategy, span, rows, keys = rows.length > 0 ? Object.keys
if (shouldCreateMap)
fkIds[i] = getIds(outRow);
}

for (let j = 0; j < aggregateKeys.length; j++) {
outRow[aggregateKeys[j]] = Number.parseFloat(row[keys[j+columnsLength]]);
}

outRows[i] = outRow;
if (shouldCreateMap)
addToMap(rowsMap, primaryColumns, outRow);
}
span._rowsMap = rowsMap;
span._ids = fkIds;
for (let i = 0; i < columnsLength; i++) {

for (let i = 0; i < columnsLength + aggregateKeys.length; i++) {
keys.shift();
}
await decodeRelations(strategy, span, rows, outRows, keys);
Expand Down
2 changes: 1 addition & 1 deletion src/getManyDto/query/singleQuery/newJoinedColumnSql.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var util = require('util');

//todo delete
function _new(table,alias,span) {
let columnsMap = span.columns;
var columnFormat = '%s as "%s"';
Expand Down
2 changes: 1 addition & 1 deletion src/getManyDto/query/singleQuery/newShallowColumnSql.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var util = require('util');

//todo delete
function _new(table,alias,span) {
let columnsMap = span.columns;
var columnFormat = '%s as "%s"';
Expand Down
24 changes: 15 additions & 9 deletions src/hostExpress/executePath.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ let _allowedOps = {
any: true,
none: true,
where: true,
sum: true,
avg: true,
max: true,
min: true,
count: true,
aggregate: true
};

async function executePath({ table, JSONFilter, baseFilter, customFilters = {}, request, response, readonly, disableBulkDeletes, isHttp, client }) {
Expand Down Expand Up @@ -99,7 +105,8 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
table = table[path[i]];
}

let ops = new Set(['all', 'any', 'none', 'where']);
let ops = new Set(['all', 'any', 'none', 'where', 'aggregate']);
// let ops = new Set(['all', 'any', 'none', 'where']);
let last = path.slice(-1)[0];
if (ops.has(last) || (table && (table._primaryColumns || (table.any && table.all))))
return table;
Expand Down Expand Up @@ -255,21 +262,20 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
if (_baseFilter)
filter = filter.and(_baseFilter);
let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
await negotiateWhere(strategy);
await negotiateWhereAndAggregate(strategy);
return table.getManyDto.apply(null, args);
}

async function negotiateWhere(strategy) {
async function negotiateWhereAndAggregate(strategy) {
if (typeof strategy !== 'object')
return;

for(let name in strategy) {
if(name === 'where') {
// validateArgs(strategy);
strategy.where = await parseFilter(strategy[name], table);
}
const target = strategy[name];
if (isFilter(target))
strategy[name] = await parseFilter(strategy[name], table);
else
await negotiateWhere(strategy[name]);
await negotiateWhereAndAggregate(strategy[name]);
}

}
Expand All @@ -281,7 +287,7 @@ async function executePath({ table, JSONFilter, baseFilter, customFilters = {},
if (_baseFilter)
filter = filter.and(_baseFilter);
let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
await negotiateWhere(strategy);
await negotiateWhereAndAggregate(strategy);
return table.getMany.apply(null, args);
}

Expand Down
71 changes: 62 additions & 9 deletions src/map.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ type MappedDbInstance<T> = {
transaction(
fn: (db: MappedDbInstance<T>) => Promise<unknown>
): Promise<void>;
saveChanges(arraysOrRow: {saveChanges(): Promise<void>}): Promise<void>;
saveChanges(arraysOrRow: { saveChanges(): Promise<void> }): Promise<void>;
express(): import('express').RequestHandler;
express(config: ExpressConfig<T>): import('express').RequestHandler;
readonly metaData: DbConcurrency<T>;
Expand Down Expand Up @@ -183,7 +183,7 @@ type ExpandedMappedTable<T, FL = ExpandedFetchingStrategy<T>> = {
rows: StrategyToInsertRowData<T>[],
originalRows: StrategyToInsertRowData<T>[]
): Promise<StrategyToRowArray<FetchedProperties<T, FL>, T>>;

update<FS extends FetchingStrategy<T>>(
row: StrategyToInsertRowData<T>,
strategy: FS
Expand Down Expand Up @@ -244,7 +244,7 @@ type ExpandedMappedTable<T, FL = ExpandedFetchingStrategy<T>> = {
count(filter?: Filter | PrimaryRowFilter<T>[]): Promise<number>;
delete(filter?: Filter | PrimaryRowFilter<T>[]): Promise<void>;
deleteCascade(filter?: Filter | PrimaryRowFilter<T>[]): Promise<void>;

proxify(
row: StrategyToInsertRowData<T>
): StrategyToRow<FetchedProperties<T, FL>, T>;
Expand Down Expand Up @@ -308,7 +308,7 @@ type MappedTable<T> = {
modifiedRows: StrategyToInsertRowData<T>[],
originalRows: StrategyToInsertRowData<T>[]
): Promise<StrategyToRowArray<FetchedProperties<T, {}>, T>>;

update<FS extends FetchingStrategy<T>>(
row: StrategyToInsertRowData<T>,
strategy: FS
Expand Down Expand Up @@ -559,22 +559,68 @@ type AllowedColumnsAndTablesConcurrency<T> = {
[P in keyof T]: T[P] extends ColumnAndTableTypes ? T[P] : never;
};

type FetchingStrategy<T> = {

type FetchingStrategy<T> = FetchingStrategyBase<T> | AggType<T>
type AggType<T> = {
[name: string]: AggregationFunction<T>;
} & {
where?: (agg: MappedColumnsAndRelations<T>) => RawFilter;
};

type AggregationFunction<T> = (agg: Aggregate<T>) => NumericColumnSymbol;

type FetchingStrategyBase<T> = {
[K in keyof T &
keyof RemoveNever<
AllowedColumnsAndTablesStrategy<T>
>]?: T[K] extends ColumnSymbols
? boolean
: boolean | FetchingStrategy<T[K]>;
: boolean | FetchingStrategyBase<T[K]> | AggType<T[K]>;
} & {
orderBy?:
| OrderBy<Extract<keyof AllowedColumns<T>, string>>[]
| OrderBy<Extract<keyof AllowedColumns<T>, string>>;
limit?: number;
offset?: number;
where?: (table: MappedColumnsAndRelations<T>) => RawFilter;

};

type Aggregate<T> = {
sum(fn: (x: AggregateColumns<T>) => NumericColumnTypeDef<any>): ColumnTypeOf<any>;
avg(fn: (x: AggregateColumns<T>) => NumericColumnTypeDef<any>): ColumnTypeOf<any>;
min(fn: (x: AggregateColumns<T>) => NumericColumnTypeDef<any>): ColumnTypeOf<any>;
max(fn: (x: AggregateColumns<T>) => NumericColumnTypeDef<any>): ColumnTypeOf<any>;
count(fn: (x: AggregateColumns<T>) => NumericColumnTypeDef<any>): ColumnTypeOf<any>;
}

type AggregateColumns<T> = RemoveNeverFlat<{
[K in keyof T]:
T[K] extends ManyRelation
? AggregateColumns2<T[K]>
: T[K] extends RelatedTable
? AggregateColumns2<T[K]>
: never;
}>;

type AggregateColumns2<T> = RemoveNeverFlat<{
[K in keyof T]:
T[K] extends NumericColumnTypeDef<infer M> ? ColumnTypeOf<any>
:T[K] extends ManyRelation
? AggregateColumns2<T[K]>
: T[K] extends RelatedTable
? AggregateColumns2<T[K]>
: never;
}>;

type TablesDeep<T> = RemoveNeverFlat<{
[K in keyof T]:
T[K] extends ManyRelation
? TablesDeep<T[K]>
: T[K] extends RelatedTable
? TablesDeep<T[K]>
: never;
}>;

type ColumnConcurrency = {
readonly?: boolean;
concurrency?: ConcurrencyValues;
Expand Down Expand Up @@ -970,8 +1016,15 @@ type ExtractColumnBools<T, TStrategy> = RemoveNever<{

type NegotiateNotNull<T> = T extends NotNull ? NotNull : {};

type FetchedProperties<T, TStrategy> = FetchedColumnProperties<T, TStrategy> &
FetchedRelationProperties<T, TStrategy>;
type FetchedProperties<T, TStrategy> = FetchedColumnProperties<T, TStrategy> & FetchedRelationProperties<T, TStrategy> & ExtractAggregates< TStrategy>

type ExtractAggregates<Agg> = {
[K in keyof Agg as
Required<Agg>[K] extends (agg: Aggregate<any>) => NumericColumnSymbol | BooleanColumnSymbol
? K extends 'where'? never : K
: never
]: Agg[K] extends (agg: Aggregate<any>) => infer R ? R & NotNull : never;
}

type FetchedRelationProperties<T, TStrategy> = RemoveNeverFlat<{
[K in keyof T]: K extends keyof TStrategy
Expand Down
1 change: 1 addition & 0 deletions src/mssql/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitSqlite();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/mySql/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitMySql();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/oracle/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitSqlite();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/pg/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitPg();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/sap/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitSap();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
1 change: 1 addition & 0 deletions src/sqlite/newTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function newResolveTransaction(domain, pool) {
rdb.accept = function(caller) {
caller.visitSqlite();
};
rdb.aggregateCount = 0;
domain.rdb = rdb;
onSuccess();
} catch (e) {
Expand Down
2 changes: 2 additions & 0 deletions src/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var newEmitEvent = require('./emitEvent');
var hostLocal = require('./hostLocal');
var getTSDefinition = require('./getTSDefinition');
var where = require('./table/where');
var aggregate = require('./table/aggregate');

function _new(tableName) {
var table = newContext();
Expand Down Expand Up @@ -159,6 +160,7 @@ function _new(tableName) {
};

table.where = where(table);
table.aggregate = aggregate(table);

return table;
}
Expand Down
Loading

0 comments on commit 25efb90

Please sign in to comment.