From 40148931677a4044da7e3bcfa24cc57b6fefb168 Mon Sep 17 00:00:00 2001 From: Slavi Boyanov Date: Sun, 29 Mar 2020 07:13:04 +0300 Subject: [PATCH 1/2] Joins are taken in account for reduce queries --- .../src/db/postgresql/postgresql_query_reduce.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart b/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart index e250235dd..776c3d9ab 100644 --- a/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart +++ b/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart @@ -2,15 +2,17 @@ import 'dart:async'; import '../managed/object.dart'; import '../query/query.dart'; +import 'builders/column.dart'; import 'postgresql_persistent_store.dart'; import 'postgresql_query.dart'; import 'query_builder.dart'; class PostgresQueryReduce extends QueryReduceOperation { - PostgresQueryReduce(this.query); + PostgresQueryReduce(this.query) : builder = PostgresQueryBuilder(query); final PostgresQuery query; + final PostgresQueryBuilder builder; @override Future average(num selector(T object)) { @@ -38,15 +40,20 @@ class PostgresQueryReduce } String _columnName(dynamic selector(T object)) { - return query.entity.identifyAttribute(selector).name; + final property = query.entity.identifyAttribute(selector); + final columnBuilder = ColumnBuilder(builder, property); + return columnBuilder.sqlColumnName(withTableNamespace: true); } Future _execute(String function) async { - final builder = PostgresQueryBuilder(query); final buffer = StringBuffer(); buffer.write("SELECT $function "); buffer.write("FROM ${builder.sqlTableName} "); + if (builder.containsJoins) { + buffer.write("${builder.sqlJoin} "); + } + if (builder.sqlWhereClause != null) { buffer.write("WHERE ${builder.sqlWhereClause} "); } From f1c03df7ce63c216e10ef098e2aaa8e3adc31f54 Mon Sep 17 00:00:00 2001 From: Slavi Boyanov Date: Thu, 11 Jun 2020 11:05:05 +0300 Subject: [PATCH 2/2] Refactoring query reduce for postgres --- .../postgresql/postgresql_query_reduce.dart | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart b/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart index 776c3d9ab..222bb8ca8 100644 --- a/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart +++ b/aqueduct/lib/src/db/postgresql/postgresql_query_reduce.dart @@ -1,12 +1,22 @@ import 'dart:async'; import '../managed/object.dart'; +import '../managed/property_description.dart'; import '../query/query.dart'; import 'builders/column.dart'; import 'postgresql_persistent_store.dart'; import 'postgresql_query.dart'; import 'query_builder.dart'; +// ignore_for_file: constant_identifier_names +enum _Reducer { + AVG, + COUNT, + MAX, + MIN, + SUM, +} + class PostgresQueryReduce extends QueryReduceOperation { PostgresQueryReduce(this.query) : builder = PostgresQueryBuilder(query); @@ -16,38 +26,49 @@ class PostgresQueryReduce @override Future average(num selector(T object)) { - return _execute("avg(${_columnName(selector)})::float"); + return _execute( + _Reducer.AVG, query.entity.identifyAttribute(selector)); } @override Future count() { - return _execute("count(*)"); + return _execute(_Reducer.COUNT); } @override Future maximum(U selector(T object)) { - return _execute("max(${_columnName(selector)})"); + return _execute(_Reducer.MAX, query.entity.identifyAttribute(selector)); } @override Future minimum(U selector(T object)) { - return _execute("min(${_columnName(selector)})"); + return _execute(_Reducer.MIN, query.entity.identifyAttribute(selector)); } @override Future sum(U selector(T object)) { - return _execute("sum(${_columnName(selector)})"); + return _execute(_Reducer.SUM, query.entity.identifyAttribute(selector)); } - String _columnName(dynamic selector(T object)) { - final property = query.entity.identifyAttribute(selector); + String _columnName(ManagedAttributeDescription property) { + if (property == null) { + // This should happen only in count + return "*"; + } final columnBuilder = ColumnBuilder(builder, property); return columnBuilder.sqlColumnName(withTableNamespace: true); } - Future _execute(String function) async { + String _function(_Reducer reducer, ManagedAttributeDescription property) { + return "${reducer.toString().split('.').last}" // The aggregation function + "(${_columnName(property)})" // The Column for the aggregation + "${reducer == _Reducer.AVG ? '::float' : ''}"; // Optional cast to float for AVG + } + + Future _execute(_Reducer reducer, + [ManagedAttributeDescription property]) async { final buffer = StringBuffer(); - buffer.write("SELECT $function "); + buffer.write("SELECT ${_function(reducer, property)} "); buffer.write("FROM ${builder.sqlTableName} "); if (builder.containsJoins) {