}
return array('where' => $where, 'params' => $parameters);
}
+
+ /**
+ * Group database records by specific column.
+ *
+ * @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)
+ */
+ public static function groupBy($group_by, &$result, $group_limit = 0) {
+ if (is_string($group_by) && is_array($result)) {
+ // Group results
+ $new_result = [];
+ for ($i = 0; $i < count($result); $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 ($group_limit > 0 && count($new_result[$result[$i]->{$group_by}]) >= $group_limit) {
+ // limit per group reached
+ continue;
+ }
+ $new_result[$result[$i]->{$group_by}][] = $result[$i];
+ }
+ $result = $new_result;
+ }
+ }
}
?>
* @category Module
* @package Baculum API
*/
-class ObjectManager extends APIModule {
+class ObjectManager extends APIModule
+{
- public function getObjects($criteria = array(), $limit_val = null, $groupby = null) {
- $sort_col = 'ObjectId';
+ /**
+ * Get objects.
+ *
+ * @param array $criteria criteria in nested array format (@see Databaes::getWhere)
+ * @param integer $limit_val maximum number of elements to return
+ * @param string $sort_col column to sort
+ * @param string $sort_order sort order (asc - ascending, desc - descending)
+ * @param string $group_by column to group
+ * @param integer $group_limit maximum number of elements in one group
+ * @return array object list
+ */
+ public function getObjects($criteria = array(), $limit_val = null, $sort_col = 'ObjectId', $sort_order = 'DESC', $group_by = null, $group_limit = 0) {
$db_params = $this->getModule('api_config')->getConfig('db');
if ($db_params['type'] === Database::PGSQL_TYPE) {
$sort_col = strtolower($sort_col);
}
- $order = ' ORDER BY ' . $sort_col . ' DESC';
+ $order = sprintf(
+ ' ORDER BY %s %s',
+ $sort_col,
+ $sort_order
+ );
$limit = '';
if(is_int($limit_val) && $limit_val > 0) {
- $limit = ' LIMIT ' . $limit_val;
+ $limit = sprintf(
+ ' LIMIT %s',
+ $limit_val
+ );
}
$where = Database::getWhere($criteria);
. $where['where'] . $order . $limit;
$result = ObjectRecord::finder()->findAllBySql($sql, $where['params']);
- if (is_string($groupby) && is_array($result)) {
- // Group results
- $new_result = [];
- for ($i = 0; $i < count($result); $i++) {
- if (!property_exists($result[$i], $groupby)) {
- continue;
- }
- if (!key_exists($result[$i]->{$groupby}, $new_result)) {
- $new_result[$result[$i]->{$groupby}] = [];
- }
- $new_result[$result[$i]->{$groupby}][] = $result[$i];
- }
- $result = $new_result;
- }
+ Database::groupBy($group_by, $result, $group_limit);
return $result;
}
}
if ($error === false) {
- $jobs = $this->getModule('job')->getJobs($params, $limit, $order_by, $order_direction);
- $this->output = $jobs;
+ $result = $this->getModule('job')->getJobs(
+ $params,
+ $limit,
+ $order_by,
+ $order_direction
+ );
+ $this->output = $result;
$this->error = JobError::ERROR_NO_ERRORS;
}
} else {
$objectstatus = $this->Request->contains('objectstatus') && $misc->isValidState($this->Request['objectstatus']) ? $this->Request['objectstatus'] : null;
$jobname = $this->Request->contains('jobname') && $misc->isValidName($this->Request['jobname']) ? $this->Request['jobname'] : null;
$jobids = $this->Request->contains('jobids') && $misc->isValidIdsList($this->Request['jobids']) ? explode(',', $this->Request['jobids']) : [];
- $groupby = $this->Request->contains('groupby') && $misc->isValidColumn($this->Request['groupby']) ? strtolower($this->Request['groupby']) : null;
+ $group_by = $this->Request->contains('groupby') && $misc->isValidColumn($this->Request['groupby']) ? strtolower($this->Request['groupby']) : null;
+ $group_limit = $this->Request->contains('group_limit') ? intval($this->Request['group_limit']) : 0;
$schedtime_from = $this->Request->contains('schedtime_from') && $misc->isValidInteger($this->Request['schedtime_from']) ? (int)$this->Request['schedtime_from'] : null;
$schedtime_to = $this->Request->contains('schedtime_to') && $misc->isValidInteger($this->Request['schedtime_to']) ? (int)$this->Request['schedtime_to'] : null;
$starttime_from = $this->Request->contains('starttime_from') && $misc->isValidInteger($this->Request['starttime_from']) ? (int)$this->Request['starttime_from'] : null;
$endtime_to = $this->Request->contains('endtime_to') && $misc->isValidInteger($this->Request['endtime_to']) ? (int)$this->Request['endtime_to'] : null;
$realendtime_from = $this->Request->contains('realendtime_from') && $misc->isValidInteger($this->Request['realendtime_from']) ? (int)$this->Request['realendtime_from'] : null;
$realendtime_to = $this->Request->contains('realendtime_to') && $misc->isValidInteger($this->Request['realendtime_to']) ? (int)$this->Request['realendtime_to'] : null;
+ $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';
- if (is_string($groupby)) {
- $or = new \ReflectionClass('Baculum\API\Modules\ObjectRecord');
- $group_cols = $or->getProperties();
-
- $cols_excl = ['jobname'];
+ $or = new \ReflectionClass('Baculum\API\Modules\ObjectRecord');
+ $prop_cols = $or->getProperties();
+ $cols_excl = ['jobname'];
+ $columns = [];
+ if (is_string($group_by)) {
$columns = [];
- foreach ($group_cols as $cols) {
+ foreach ($prop_cols as $cols) {
$name = $cols->getName();
// skip columns not existing in the catalog
if (in_array($name, $cols_excl)) {
$columns[] = $name;
}
- if (!in_array($groupby, $columns)) {
+ if (!in_array($group_by, $columns)) {
$this->output = ObjectError::MSG_ERROR_INVALID_PROPERTY;
$this->error = ObjectError::ERROR_INVALID_PROPERTY;
return;
}
}
+ $order_by_lc = strtolower($order_by);
+ $columns = [];
+ foreach ($prop_cols as $cols) {
+ $name = $cols->getName();
+ // skip columns not existing in the catalog
+ if (in_array($name, $cols_excl)) {
+ continue;
+ }
+ $columns[] = $name;
+ }
+ if (!in_array($order_by_lc, $columns)) {
+ $this->output = ObjectError::MSG_ERROR_INVALID_PROPERTY;
+ $this->error = ObjectError::ERROR_INVALID_PROPERTY;
+ return;
+ }
+
+
$params = [];
if (!empty($objecttype)) {
$params['Object.ObjectType'] = [];
}
}
- $objects = $this->getModule('object')->getObjects($params, $limit, $groupby);
+ $objects = $this->getModule('object')->getObjects(
+ $params,
+ $limit,
+ $order_by_lc,
+ $order_direction,
+ $group_by,
+ $group_limit
+ );
$this->output = $objects;
$this->error = ObjectError::ERROR_NO_ERRORS;
}
"type": "string"
}
},
+ {
+ "name": "group_limit",
+ "in": "query",
+ "required": false,
+ "description": "Maximum number elements per group.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "order_by",
+ "in": "query",
+ "required": false,
+ "description": "Sort by selected object property (default objectid). There can be any object property (objectid, objectname, objectsource ...etc.) except jobname.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "order_direction",
+ "in": "query",
+ "required": false,
+ "description": "Order direction. It can be 'asc' (ascending order) or 'desc' (descending order - default)",
+ "schema": {
+ "type": "string",
+ "enum": ["asc", "desc"]
+ }
+ },
{
"name": "schedtime_from",
"in": "query",