* @param string $group_by column to use as group
* @param array $result database results/records (please note - reference)
* @param integer $group_limit group limit (zero means no limit)
+ * @param integer $group_offset group offset
* @param string|null $overview_by prepare overview (counts) by given object output property
* @param array overview array or empty array if no overview requested
*/
- public static function groupBy($group_by, &$result, $group_limit = 0, $overview_by = null) {
+ public static function groupBy($group_by, &$result, $group_limit = 0, $group_offset = 0, $overview_by = null) {
$overview = [];
if (is_string($group_by) && is_array($result)) {
// Group results
$new_result = [];
$len = count($result);
+ $group_cnts = [];
for ($i = 0; $i < $len; $i++) {
if (!property_exists($result[$i], $group_by)) {
continue;
if (!key_exists($result[$i]->{$group_by}, $new_result)) {
$new_result[$result[$i]->{$group_by}] = [];
}
+ if (!key_exists($result[$i]->{$group_by}, $group_cnts)) {
+ $group_cnts[$result[$i]->{$group_by}] = 0;
+ }
+ if ($group_cnts[$result[$i]->{$group_by}] < $group_offset) {
+ $group_cnts[$result[$i]->{$group_by}]++;
+ // don't display elements lower than offset
+ continue;
+ }
if ($group_limit > 0 && count($new_result[$result[$i]->{$group_by}]) >= $group_limit) {
// limit per group reached
continue;
}
+ $group_cnts[$result[$i]->{$group_by}]++;
$new_result[$result[$i]->{$group_by}][] = $result[$i];
if (!key_exists($result[$i]->{$overview_by}, $overview)) {
$overview[$result[$i]->{$overview_by}] = [
*/
const OBJECT_RESULT_MODE_NORMAL = 'normal';
const OBJECT_RESULT_MODE_OVERVIEW = 'overview';
+ const OBJECT_RESULT_MODE_OVERVIEW_UNIQUE = 'overview_unique';
/**
* Object result record view.
* @param string $view job records view (basic, full)
* @return array object list
*/
- public function getObjects($criteria = array(), $limit_val = null, $offset_val = 0, $sort_col = 'ObjectId', $sort_order = 'DESC', $group_by = null, $group_limit = 0, $view = self::OBJ_RESULT_VIEW_FULL, $mode = self::OBJECT_RESULT_MODE_NORMAL) {
+ public function getObjects($criteria = array(), $limit_val = null, $offset_val = 0, $sort_col = 'ObjectId', $sort_order = 'DESC', $group_by = null, $group_limit = 0, $group_offset = 0, $view = self::OBJ_RESULT_VIEW_FULL, $mode = self::OBJECT_RESULT_MODE_NORMAL) {
$db_params = $this->getModule('api_config')->getConfig('db');
if ($db_params['type'] === Database::PGSQL_TYPE) {
$sort_col = strtolower($sort_col);
. $where['where'] . $order . $limit . $offset;
$statement = Database::runQuery($sql, $where['params']);
$result = $statement->fetchAll(\PDO::FETCH_OBJ);
- $overview = Database::groupBy($group_by, $result, $group_limit, 'objecttype');
- if ($mode == self::OBJECT_RESULT_MODE_OVERVIEW) {
+ if ($mode == self::OBJECT_RESULT_MODE_OVERVIEW_UNIQUE) {
+ Database::groupBy('objectname', $result, 1, 0, 'objecttype');
+ $func = function ($item) {
+ return ((object)$item[0]);
+ };
+ $result = array_values($result);
+ $result = array_map($func, $result);
+ }
+ $overview = Database::groupBy($group_by, $result, $group_limit, $group_offset, 'objecttype');
+ if ($mode == self::OBJECT_RESULT_MODE_OVERVIEW || $mode == self::OBJECT_RESULT_MODE_OVERVIEW_UNIQUE) {
// Overview mode.
$result = [
'objects' => $result,
$joberrors = $misc->isValidBooleanTrue($this->Request['joberrors']) ? true : false;
}
$group_by = $this->Request->contains('groupby') && $misc->isValidColumn($this->Request['groupby']) ? strtolower($this->Request['groupby']) : null;
+ $group_offset = $this->Request->contains('group_offset') ? intval($this->Request['group_offset']) : 0;
$group_limit = $this->Request->contains('group_limit') ? intval($this->Request['group_limit']) : 0;
// UNIX timestamp values
$order_by = $this->Request->contains('order_by') && $misc->isValidColumn($this->Request['order_by']) ? $this->Request['order_by']: 'ObjectId';
$order_direction = $this->Request->contains('order_direction') && $misc->isValidOrderDirection($this->Request['order_direction']) ? $this->Request['order_direction']: 'DESC';
$mode = ($this->Request->contains('overview') && $misc->isValidBooleanTrue($this->Request['overview'])) ? ObjectManager::OBJECT_RESULT_MODE_OVERVIEW : ObjectManager::OBJECT_RESULT_MODE_NORMAL;
+ $unique_objects = ($this->Request->contains('unique_objects') && $misc->isValidBooleanTrue($this->Request['unique_objects'])) ? true : false;
+ if ($mode === ObjectManager::OBJECT_RESULT_MODE_OVERVIEW && $unique_objects) {
+ $mode = ObjectManager::OBJECT_RESULT_MODE_OVERVIEW_UNIQUE;
+ }
$or = new \ReflectionClass('Baculum\API\Modules\ObjectRecord');
$prop_cols = $or->getProperties();
$order_direction,
$group_by,
$group_limit,
+ $group_offset,
ObjectManager::OBJ_RESULT_VIEW_FULL,
$mode
);
"required": false,
"description": "Maximum number elements per group.",
"schema": {
- "type": "string"
+ "type": "integer"
+ }
+ },
+ {
+ "name": "group_offset",
+ "in": "query",
+ "required": false,
+ "description": "Element offset per group.",
+ "schema": {
+ "type": "integer"
+ }
+ },
+ {
+ "name": "unique_objects",
+ "in": "query",
+ "required": false,
+ "description": "Display only unique objects (equivalent for: groupby=objectname&group_limit=1).",
+ "schema": {
+ "type": "boolean"
}
},
{