]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
baculum: Add group_offset and unique_objects parameters to objects endpoint
authorMarcin Haba <marcin.haba@bacula.pl>
Mon, 5 Jun 2023 08:49:34 +0000 (10:49 +0200)
committerMarcin Haba <marcin.haba@bacula.pl>
Mon, 3 Jul 2023 08:46:57 +0000 (10:46 +0200)
gui/baculum/protected/API/Modules/Database.php
gui/baculum/protected/API/Modules/ObjectManager.php
gui/baculum/protected/API/Pages/API/Objects.php
gui/baculum/protected/API/openapi_baculum.json

index 71b5d91e402d4ac55b5927b9beadc65b540f72d8..8e135bb86e4bcaba948544916d0cc4be2bedca4f 100644 (file)
@@ -232,15 +232,17 @@ class Database extends APIModule {
         * @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;
@@ -248,10 +250,19 @@ class Database extends APIModule {
                                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}] = [
index a6437e94ac576a45ecce6c615e7e695ba00a8fc9..12e27bac3eb6780f7fddcf5f094f4526b4057783 100644 (file)
@@ -60,6 +60,7 @@ class ObjectManager extends APIModule
         */
        const OBJECT_RESULT_MODE_NORMAL = 'normal';
        const OBJECT_RESULT_MODE_OVERVIEW = 'overview';
+       const OBJECT_RESULT_MODE_OVERVIEW_UNIQUE = 'overview_unique';
 
        /**
         * Object result record view.
@@ -83,7 +84,7 @@ class ObjectManager extends APIModule
         * @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);
@@ -121,8 +122,16 @@ LEFT JOIN Client USING (ClientId) '
 . $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,
index be18c949a3db298570e8d84404a3567cf9d44589..c236ab75e51cdf5afe226aec2bcd690ec3d80d1b 100644 (file)
@@ -52,6 +52,7 @@ class Objects extends BaculumAPIServer {
                        $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
@@ -82,6 +83,10 @@ class Objects extends BaculumAPIServer {
                $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();
@@ -378,6 +383,7 @@ class Objects extends BaculumAPIServer {
                        $order_direction,
                        $group_by,
                        $group_limit,
+                       $group_offset,
                        ObjectManager::OBJ_RESULT_VIEW_FULL,
                        $mode
                );
index e1bf1f41a69a6e87e732b1e097526e301ad1e43c..01ca997387e481642ec2f7253389be3d84ddbc13 100644 (file)
                                                "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"
                                                }
                                        },
                                        {