$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
}
+
+ /**
+ * Get object job statistics by category.
+ * There are taken into account last three jobs.
+ *
+ * @param string $objecttype object type (usually short name such as 'm365' or 'MySQL')
+ * @param string $objectsource object source
+ * @param string $objectcategory object category like: 'mailbox' or 'team'
+ * @return array object statistics
+ */
+ public function getObjectCategoryStatus($objecttype = null, $objectsource = null, $objectcategory = null) {
+ $where = [];
+ if (!is_null($objecttype)) {
+ $where[] = ' Object.ObjectType=:objecttype ';
+ }
+ if (!is_null($objectsource)) {
+ $where[] = ' Object.ObjectSource=:objectsource ';
+ }
+ if (!is_null($objectcategory)) {
+ $where[] = ' Object.ObjectCategory=:objectcategory ';
+ }
+ $where_val = implode(' AND ', $where);
+
+ $sql = 'SELECT
+ DISTINCT b.JobId, b.JobStatus, b.StartTime, b.ObjectCategory
+ FROM (
+ SELECT
+ Job.JobId AS jobid,
+ Job.JobStatus AS jobstatus,
+ Job.StartTime AS starttime,
+ Object.ObjectCategory AS objectcategory,
+ ROW_NUMBER() OVER (PARTITION BY Object.ObjectCategory ORDER BY Job.JobId DESC) AS r
+ FROM Job
+ JOIN Object USING(JobId)
+ ' . ($where_val ? ' WHERE ' . $where_val : '') . '
+ ) AS b
+ WHERE
+ b.r <= 3';
+ $connection = ObjectRecord::finder()->getDbConnection();
+ $connection->setActive(true);
+ $pdo = $connection->getPdoInstance();
+ $sth = $pdo->prepare($sql);
+ if (!is_null($objecttype)) {
+ $sth->bindParam(':objecttype', $objecttype, \PDO::PARAM_STR, 100);
+ }
+ if (!is_null($objectsource)) {
+ $sth->bindParam(':objectsource', $objectsource, \PDO::PARAM_STR, 400);
+ }
+ if (!is_null($objectcategory)) {
+ $sth->bindParam(':objectcategory', $objectcategory, \PDO::PARAM_STR, 400);
+ }
+ $sth->execute();
+ return $sth->fetchAll(\PDO::FETCH_ASSOC);
+ }
}
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2022 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+use Baculum\Common\Modules\Errors\ObjectError;
+
+/**
+ * Object size stats endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class ObjectStatsCategoryStatus extends BaculumAPIServer {
+
+ public function get() {
+ $misc = $this->getModule('misc');
+ $objecttype = null;
+ if ($this->Request->contains('objecttype') && $misc->isValidName($this->Request['objecttype'])) {
+ $objecttype = $this->Request['objecttype'];
+ }
+ $objectsource = null;
+ if ($this->Request->contains('objectsource') && $misc->isValidName($this->Request['objectsource'])) {
+ $objectsource = $this->Request['objectsource'];
+ }
+ $objectcategory = null;
+ if ($this->Request->contains('objectcategory') && $misc->isValidName($this->Request['objectcategory'])) {
+ $objectcategory = $this->Request['objectcategory'];
+ }
+
+ $objects = $this->getModule('object')->getObjectCategoryStatus(
+ $objecttype,
+ $objectsource,
+ $objectcategory
+ );
+ $this->output = $objects;
+ $this->error = ObjectError::ERROR_NO_ERRORS;
+ }
+}
<url ServiceParameter="ObjectClass" pattern="api/v2/objects/{id}/" parameters.id="\d+" />
<url ServiceParameter="ObjectVersions" pattern="api/v2/objects/versions/{uuid}" parameters.uuid="[a-zA-Z0-9:.\-_ ]+" />
<url ServiceParameter="ObjectStatsCategorySum" pattern="api/v2/objects/stats/category-sum/" />
+ <url ServiceParameter="ObjectStatsCategoryStatus" pattern="api/v2/objects/stats/category-status/" />
<url ServiceParameter="ObjectStatsSizeSum" pattern="api/v2/objects/stats/size-sum/" />
<!-- @TODO: Separate this endpoint outside 'joblog' -->
<url ServiceParameter="Messages" pattern="api/v2/joblog/messages" />
]
}
},
+ "/api/v2/objects/stats/category-status": {
+ "get": {
+ "tags": ["objects"],
+ "summary": "Get object category status stats",
+ "description": "Get object category status statistics",
+ "responses": {
+ "200": {
+ "description": "Object category statistics",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "output": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "jobid": {
+ "type": "integer",
+ "description": "Job identifier"
+ },
+ "jobstatus": {
+ "type": "string",
+ "description": "Job status letter"
+ },
+ "starttime": {
+ "type": "string",
+ "description": "Job start time"
+ },
+ "objectcategory": {
+ "type": "string",
+ "description": "Object category"
+ }
+ }
+ }
+ },
+ "error": {
+ "type": "integer",
+ "description": "Error code",
+ "enum": [0, 1, 2, 3, 6, 7, 1000]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "name": "objecttype",
+ "in": "query",
+ "required": false,
+ "description": "Object type, ex. 'm365' or 'PostgreSQL'",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "objectsource",
+ "in": "query",
+ "required": false,
+ "description": "Object data source",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "objectcategory",
+ "in": "query",
+ "required": false,
+ "description": "Object category like 'mailbox' or 'team'",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
"/api/v2/objects/stats/size-sum": {
"get": {
"tags": ["objects"],