Skip to content

Commit

Permalink
add events to QueryBuilder class
Browse files Browse the repository at this point in the history
Signed-off-by: summersab <[email protected]>

clean up php lint
  • Loading branch information
summersab committed Feb 7, 2023
1 parent 24ebc19 commit 0bab7ae
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 1 deletion.
65 changes: 65 additions & 0 deletions lib/private/DB/QueryBuilder/Events/AfterQueryExecuted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2023 Andrew Summers
*
* @author Andrew Summers
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OC\DB\QueryBuilder\Events;

use OCP\EventDispatcher\Event;
use OCP\DB\QueryBuilder\IQueryBuilder;

/**
* This event is used by apps to intercept, inspect, and potentially modify
* the results of database queries after execution. This can be used for deep
* integrations, restricting user access to certain data, redacting information,
* etc.
*
* @see https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html
* @since 26.0.0
*/
class AfterQueryExecuted extends Event {
private IQueryBuilder $queryBuilder;
private $result;

public function __construct(IQueryBuilder $queryBuilder, $result) {
$this->queryBuilder = $queryBuilder;
$this->result = $result;
}

public function getQueryBuilder() {
return $this->queryBuilder;
}

public function setQueryBuilder() {
return $this->queryBuilder;
}

public function getResult() {
return $this->result;
}

public function setResult() {
return $this->result;
}
}
69 changes: 69 additions & 0 deletions lib/private/DB/QueryBuilder/Events/BeforeQueryExecuted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

/**
* @copyright Copyright (c) 2023 Andrew Summers
*
* @author Andrew Summers
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OC\DB\QueryBuilder\Events;

use OCP\EventDispatcher\Event;
use OCP\DB\QueryBuilder\IQueryBuilder;

/**
* This event is used by apps to intercept, inspect, and potentially modify
* database queries prior to execution. This can be used for deep integrations,
* restricting user access to certain data, redacting information, etc.
*
* The result field can optionally be set by the event listener by executing the
* query in the event handler logic. This allows apps to inspect the results,
* use try/catch blocks around the query execution, and/or modify/re-execute the
* query if necessary. If the result field is not set, the QueryBuilder class
* will execute the query as expected by default.
*
* @see https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html
* @since 26.0.0
*/
class BeforeQueryExecuted extends Event {
private IQueryBuilder $queryBuilder;
private $result = null;

public function __construct(IQueryBuilder $queryBuilder) {
$this->queryBuilder = $queryBuilder;
}

public function getQueryBuilder() {
return $this->queryBuilder;
}

public function setQueryBuilder() {
return $this->queryBuilder;
}

public function getResult() {
return $this->result;
}

public function setResult() {
return $this->result;
}
}
20 changes: 19 additions & 1 deletion lib/private/DB/QueryBuilder/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Query\QueryException;
use OC\DB\ConnectionAdapter;
use OC\DB\QueryBuilder\Events\BeforeQueryExecuted;
use OC\DB\QueryBuilder\Events\AfterQueryExecuted;
use OC\DB\QueryBuilder\ExpressionBuilder\ExpressionBuilder;
use OC\DB\QueryBuilder\ExpressionBuilder\MySqlExpressionBuilder;
use OC\DB\QueryBuilder\ExpressionBuilder\OCIExpressionBuilder;
Expand All @@ -53,6 +55,7 @@
use OCP\DB\QueryBuilder\IParameter;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\QueryBuilder\IQueryFunction;
use OCP\EventDispatcher\IEventDispatcher;
use Psr\Log\LoggerInterface;

class QueryBuilder implements IQueryBuilder {
Expand All @@ -76,6 +79,9 @@ class QueryBuilder implements IQueryBuilder {
/** @var string */
protected $lastInsertedTable;

/** @var IEventDispatcher */
private $dispatcher;

/**
* Initializes a new QueryBuilder.
*
Expand All @@ -88,6 +94,7 @@ public function __construct(ConnectionAdapter $connection, SystemConfig $systemC
$this->logger = $logger;
$this->queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder($this->connection->getInner());
$this->helper = new QuoteHelper();
$this->dispatcher = \OC::$server->get(IEventDispatcher::class);
}

/**
Expand Down Expand Up @@ -277,7 +284,18 @@ public function execute() {
]);
}

$result = $this->queryBuilder->execute();
$event = new BeforeQueryExecuted($this);
$this->dispatcher->dispatchTyped($event);
$result = $event->getResult();

if ($result === null) {
$result = $this->queryBuilder->execute();
}

$event = new AfterQueryExecuted($this, $result);
$this->dispatcher->dispatchTyped($event);
$result = $event->getResult();

if (is_int($result)) {
return $result;
}
Expand Down

0 comments on commit 0bab7ae

Please sign in to comment.