Update DbController.php

This commit is contained in:
fanategorius
2026-07-06 16:29:09 +03:00
committed by GitHub
parent b6849053d2
commit c1d9494414
+55 -35
View File
@@ -6,49 +6,68 @@ use OCP\AppFramework\Controller;
use OCP\IRequest; use OCP\IRequest;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\IGroupManager;
use OCP\IUserSession;
class DbController extends Controller class DbController extends Controller
{ {
private $db; private $db;
private $groupManager;
private $userSession;
public function __construct($AppName, IRequest $request, IDBConnection $db) public function __construct(
{ $AppName,
IRequest $request,
IDBConnection $db,
IGroupManager $groupManager,
IUserSession $userSession
) {
parent::__construct($AppName, $request); parent::__construct($AppName, $request);
$this->db = $db; $this->db = $db;
$this->groupManager = $groupManager;
$this->userSession = $userSession;
} }
/** /**
* @NoCSRFRequired * @NoCSRFRequired
* @PublicPage
*/ */
public function query() public function query()
{ {
$sql = $this->request->getParam('sql', ''); // Проверка прав администратора
$user = $this->userSession->getUser();
if (!$user) {
return new JSONResponse(['error' => 'Not authenticated'], 401);
}
if (empty($sql)) { if (!$this->groupManager->isAdmin($user->getUID())) {
return new JSONResponse(['error' => 'Empty query']); return new JSONResponse(['error' => 'Admin privileges required'], 403);
} }
try { $sql = $this->request->getParam('sql', '');
// Разделяем запросы по точке с запятой
$queries = array_filter(array_map('trim', explode(';', $sql)));
$results = [];
foreach ($queries as $query) { if (empty(trim($sql))) {
if (empty($query)) continue; return new JSONResponse(['success' => false, 'error' => 'Empty query']);
}
// Пропускаем SET команды (PostgreSQL specific)
if (stripos($query, 'SET ') === 0) { // Разделяем запросы по точке с запятой. Все запросы выполняются
$results[] = ['query' => $query, 'type' => 'set', 'result' => 'skipped']; // последовательно на одном и том же соединении с БД (в рамках
continue; // одного HTTP-запроса), поэтому SET сохраняет своё значение
} // для current_setting() в последующих запросах пачки.
$queries = array_values(array_filter(array_map('trim', explode(';', $sql)), function ($q) {
return $q !== '';
}));
$results = [];
foreach ($queries as $query) {
$isSelect = stripos($query, 'SELECT') === 0;
$isSet = stripos($query, 'SET ') === 0;
try {
$stmt = $this->db->prepare($query);
$stmt->execute();
// Определяем тип запроса
$isSelect = stripos($query, 'SELECT') === 0;
if ($isSelect) { if ($isSelect) {
$stmt = $this->db->prepare($query);
$stmt->execute();
$rows = $stmt->fetchAll(); $rows = $stmt->fetchAll();
$results[] = [ $results[] = [
'query' => $query, 'query' => $query,
@@ -57,25 +76,26 @@ class DbController extends Controller
'data' => $rows 'data' => $rows
]; ];
} else { } else {
$stmt = $this->db->prepare($query);
$stmt->execute();
$affected = $stmt->rowCount(); $affected = $stmt->rowCount();
$results[] = [ $results[] = [
'query' => $query, 'query' => $query,
'type' => 'write', 'type' => $isSet ? 'set' : 'write',
'affected_rows' => $affected 'affected_rows' => $affected
]; ];
} }
} catch (\Exception $e) {
$results[] = [
'query' => $query,
'type' => 'error',
'error' => $e->getMessage()
];
// Останавливаемся на первой ошибке: не продолжаем выполнять
// оставшиеся запросы пачки (например, серию DELETE),
// если один из предыдущих шагов не выполнился.
break;
} }
return new JSONResponse(['success' => true, 'results' => $results]);
} catch (\Exception $e) {
return new JSONResponse([
'success' => false,
'error' => $e->getMessage(),
'query' => $sql
]);
} }
return new JSONResponse(['success' => true, 'results' => $results]);
} }
} }