From 45faa77bfc8f9ad6f87cb4ea805a6cbe07b06b3d Mon Sep 17 00:00:00 2001 From: Marcin Haba Date: Tue, 28 Feb 2023 15:22:55 +0100 Subject: [PATCH] baculum: Add support for plugin filter in client list endpoint --- .../protected/API/Modules/ClientManager.php | 67 +++++++++++++++++-- .../protected/API/Modules/Database.php | 4 ++ .../protected/API/Pages/API/Clients.php | 15 ++++- .../protected/API/openapi_baculum.json | 8 +++ 4 files changed, 87 insertions(+), 7 deletions(-) diff --git a/gui/baculum/protected/API/Modules/ClientManager.php b/gui/baculum/protected/API/Modules/ClientManager.php index f2608a24a..2ee07aa27 100644 --- a/gui/baculum/protected/API/Modules/ClientManager.php +++ b/gui/baculum/protected/API/Modules/ClientManager.php @@ -33,15 +33,70 @@ use Prado\Data\ActiveRecord\TActiveRecordCriteria; */ class ClientManager extends APIModule { - public function getClients($limit_val = 0, $offset_val = 0) { - $criteria = new TActiveRecordCriteria; - if(is_numeric($limit_val) && $limit_val > 0) { - $criteria->Limit = $limit_val; + /** + * SQL query builder. + * + * @var TDbCommandBuilder command builder + */ + private static $query_builder; + + /** + * Get the SQL query builder instance. + * Note: Singleton + * + * @return TDbCommandBuilder command builder + */ + private function getQueryBuilder() { + if (is_null(self::$query_builder)) { + $record = ClientRecord::finder(); + $connection = $record->getDbConnection(); + $tableInfo = $record->getRecordGateway()->getRecordTableInfo($record); + self::$query_builder = $tableInfo->createCommandBuilder($connection); + } + return self::$query_builder; + } + + /** + * Get client list. + * + * @param mixed $limit_val result limit value + * @param int $offset_val result offset value + * @param array $criteria SQL criteria to get job list + * @return array clients or empty list if no client found + */ + public function getClients($limit_val = 0, $offset_val = 0, $criteria = []) { + $limit = ''; + if(is_int($limit_val) && $limit_val > 0) { + $limit = ' LIMIT ' . $limit_val; } + $offset = ''; if (is_int($offset_val) && $offset_val > 0) { - $criteria->Offset = $offset_val; + $offset = ' OFFSET ' . $offset_val; + } + $where = Database::getWhere($criteria); + + $sql = 'SELECT * +FROM Client +' . $where['where'] . $offset . $limit; + + $builder = $this->getQueryBuilder(); + if (count($where['params']) == 0) { + /** + * Please note that in case no params the TDbCommandBuilder::applyCriterias() + * returns empty the PDO statement handler. From this reason here + * the query is called directly by PDO. + */ + $connection = JobRecord::finder()->getDbConnection(); + $connection->setActive(true); + $pdo = $connection->getPdoInstance(); + $statement = $pdo->query($sql); + + } else { + $command = $builder->applyCriterias($sql, $where['params']); + $statement = $command->getPdoStatement(); + $command->query(); } - return ClientRecord::finder()->findAll($criteria); + return $statement->fetchAll(\PDO::FETCH_OBJ); } public function getClientByName($name) { diff --git a/gui/baculum/protected/API/Modules/Database.php b/gui/baculum/protected/API/Modules/Database.php index 8134c284c..226f039e7 100644 --- a/gui/baculum/protected/API/Modules/Database.php +++ b/gui/baculum/protected/API/Modules/Database.php @@ -194,6 +194,10 @@ class Database extends APIModule { } elseif (in_array($value[$i]['operator'], ['IS', 'IS NOT'])) { $cond[] = "{$key} {$value[$i]['operator']} {$value[$i]['vals']}"; $value[$i]['operator'] = ''; + } elseif ($value[$i]['operator'] == 'LIKE') { + $cond[] = "{$key} {$value[$i]['operator']} :{$kval}{$i}"; + $vals[":{$kval}{$i}"] = $value[$i]['vals']; + $value[$i]['operator'] = ''; } else { $cond[] = "$key = :{$kval}{$i}"; $vals[":{$kval}{$i}"] = $value[$i]['vals']; diff --git a/gui/baculum/protected/API/Pages/API/Clients.php b/gui/baculum/protected/API/Pages/API/Clients.php index a11d25c51..69bc1f5f3 100644 --- a/gui/baculum/protected/API/Pages/API/Clients.php +++ b/gui/baculum/protected/API/Pages/API/Clients.php @@ -36,9 +36,22 @@ class Clients extends BaculumAPIServer { $misc = $this->getModule('misc'); $limit = $this->Request->contains('limit') ? intval($this->Request['limit']) : 0; $offset = $this->Request->contains('offset') && $misc->isValidInteger($this->Request['offset']) ? (int)$this->Request['offset'] : 0; + $plugin = $this->Request->contains('plugin') && $misc->isValidAlphaNumeric($this->Request['plugin']) ? $this->Request['plugin'] : ''; $result = $this->getModule('bconsole')->bconsoleCommand($this->director, array('.client')); if ($result->exitcode === 0) { - $clients = $this->getModule('client')->getClients($limit, $offset); + $params = []; + if (!empty($plugin)) { + $params['Plugins'] = []; + $params['Plugins'][] = [ + 'operator' => 'LIKE', + 'vals' => "%{$plugin}%" + ]; + } + $clients = $this->getModule('client')->getClients( + $limit, + $offset, + $params + ); array_shift($result->output); $clients_output = array(); foreach($clients as $client) { diff --git a/gui/baculum/protected/API/openapi_baculum.json b/gui/baculum/protected/API/openapi_baculum.json index 7c25719fb..38e5b4621 100644 --- a/gui/baculum/protected/API/openapi_baculum.json +++ b/gui/baculum/protected/API/openapi_baculum.json @@ -458,6 +458,14 @@ }, { "$ref": "#/components/parameters/Offset" + }, + { + "name": "plugin", + "in": "query", + "description": "List clients that contain given plugin. Note, it searches by *keyword* so for PostgreSQL plugin both 'postgre' and 'postgresql' will work.", + "schema": { + "type": "string" + } } ] } -- 2.47.3