Skip to content

Commit

Permalink
Merge pull request #1 from OpenCatalogi/feature/DIMOC-33/psql-compati…
Browse files Browse the repository at this point in the history
…bility

Fix Migrations for PSQL
  • Loading branch information
rjzondervan authored Aug 13, 2024
2 parents b70a363 + 7535d63 commit e4028a5
Show file tree
Hide file tree
Showing 34 changed files with 290 additions and 132 deletions.
1 change: 1 addition & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
['name' => 'metadata#page', 'url' => '/metadata', 'verb' => 'GET'],
['name' => 'publications#page', 'url' => '/publications', 'verb' => 'GET'],
['name' => 'publications#attachments', 'url' => '/api/publications/{id}/attachments', 'verb' => 'GET', 'requirements' => ['id' => '.+']],
['name' => 'catalogi#page', 'url' => '/catalogi', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/search', 'verb' => 'GET'],
['name' => 'search#index', 'url' => '/api/search', 'verb' => 'GET'],
Expand Down
69 changes: 41 additions & 28 deletions lib/Controller/AttachmentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use OCA\OpenCatalogi\Service\FileService;
use OCA\OpenCatalogi\Service\ObjectService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand Down Expand Up @@ -99,7 +100,7 @@ public function index(ObjectService $objectService): JSONResponse
if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
|| $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1'
) {
return new JSONResponse(['results' =>$this->attachmentMapper->findAll()]);
return new JSONResponse(['results' => $this->attachmentMapper->findAll()]);
}
$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey');
Expand Down Expand Up @@ -131,7 +132,11 @@ public function show(string|int $id, ObjectService $objectService): JSONResponse
if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
|| $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1'
) {
return new JSONResponse($this->attachmentMapper->find(id: (int) $id));
try {
return new JSONResponse($this->attachmentMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}
$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey');
Expand All @@ -156,7 +161,7 @@ private function checkUploadedFile(): JSONResponse|array
$uploadedFile = $this->request->getUploadedFile(key: '_file');

if (empty($uploadedFile) === true) {
return new JSONResponse(data: ['error' => 'No file uploaded for key "_file"'], statusCode: 400);
return new JSONResponse(data: ['error' => 'Please upload a file using key "_file" or give a "downloadUrl"'], statusCode: 400);
}

// Check for upload errors
Expand All @@ -168,14 +173,14 @@ private function checkUploadedFile(): JSONResponse|array
}

/**
* Gets all params from the request body and then validates if the URL fields are actual valid urls (or null).
* Validates if the URL fields are actual valid urls (or null).
*
* @param array $data The form-data fields and their values (/request body).
*
* @return JSONResponse|array An error response if there are validation errors or an array containing all request body params.
*/
private function checkRequestBody(): JSONResponse|array
private function checkRequestBody(array $data): JSONResponse|array
{
$data = $this->request->getParams();

$errorMsg = [];
if (empty($data['accessUrl']) === false && filter_var(value: $data['accessUrl'], filter: FILTER_VALIDATE_URL) === false) {
$errorMsg[] = "accessUrl is not a valid url";
Expand Down Expand Up @@ -226,7 +231,7 @@ private function handleFile(array $uploadedFile): JSONResponse|string


/**
* Adds information about the uploaded file to the appropriate Attachment fields. And removes fields we do not want to post.
* Adds information about the uploaded file to the appropriate Attachment fields.
*
* @param array $data The form-data fields and their values (/request body) that we are going to update before posting the Attachment.
* @param array $uploadedFile Information about the uploaded file from the request body.
Expand All @@ -252,14 +257,8 @@ private function AddFileInfoToData(array $data, array $uploadedFile, string $fil
if (empty($data['accessUrl']) === true) {
$data['accessUrl'] = $shareLink;
}
$data['downloadUrl'] = "$shareLink/download";

// Remove fields we should never post
unset($data['id']);
foreach($data as $key => $value) {
if(str_starts_with(haystack: $key, needle: '_')) {
unset($data[$key]);
}
if (empty($data['downloadUrl']) === true) {
$data['downloadUrl'] = "$shareLink/download";
}

return $data;
Expand All @@ -274,26 +273,40 @@ private function AddFileInfoToData(array $data, array $uploadedFile, string $fil
*/
public function create(ObjectService $objectService, ElasticSearchService $elasticSearchService): JSONResponse
{
// Check if a file was uploaded
$uploadedFile = $this->checkUploadedFile();
if ($uploadedFile instanceof JSONResponse) {
return $uploadedFile;
$data = $this->request->getParams();
// Uploaded _file and downloadURL are mutually exclusive
if (empty($data['downloadUrl']) === true) {
// Check if a file was uploaded
$uploadedFile = $this->checkUploadedFile();
if ($uploadedFile instanceof JSONResponse) {
return $uploadedFile;
}
}

// Get form-data field/request body.
$data = $this->checkRequestBody();
// Get form-data field/request body and validate the input.
$data = $this->checkRequestBody($data);
if ($data instanceof JSONResponse) {
return $data;
}

// Handle saving the uploaded file in NextCloud
$filePath = $this->handleFile(uploadedFile: $uploadedFile);
if ($filePath instanceof JSONResponse) {
return $filePath;
if (empty($uploadedFile) === false) {
// Handle saving the uploaded file in NextCloud
$filePath = $this->handleFile(uploadedFile: $uploadedFile);
if ($filePath instanceof JSONResponse) {
return $filePath;
}

// Update Attachment data
$data = $this->AddFileInfoToData(data: $data, uploadedFile: $uploadedFile, filePath: $filePath);
}

// Update Attachment data
$data = $this->AddFileInfoToData(data: $data, uploadedFile: $uploadedFile, filePath: $filePath);
// Remove fields we should never post
unset($data['id']);
foreach($data as $key => $value) {
if(str_starts_with(haystack: $key, needle: '_')) {
unset($data[$key]);
}
}

if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
|| $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1'
Expand Down
7 changes: 6 additions & 1 deletion lib/Controller/CatalogiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\SearchService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand Down Expand Up @@ -81,7 +82,11 @@ public function show(string|int $id, ObjectService $objectService): JSONResponse
if($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->catalogMapper->find(id: (int) $id));
try {
return new JSONResponse($this->catalogMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}

try {
Expand Down
7 changes: 6 additions & 1 deletion lib/Controller/DirectoryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\SearchService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand Down Expand Up @@ -115,7 +116,11 @@ public function show(string|int $id, ObjectService $objectService, DirectoryServ
if($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->listingMapper->find(id: (int) $id));
try {
return new JSONResponse($this->listingMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}
$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey');
Expand Down
7 changes: 6 additions & 1 deletion lib/Controller/MetaDataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\SearchService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand Down Expand Up @@ -84,7 +85,11 @@ public function show(string|int $id, ObjectService $objectService): JSONResponse
if($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->metaDataMapper->find(id: (int) $id));
try {
return new JSONResponse($this->metaDataMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}
$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey');
Expand Down
7 changes: 6 additions & 1 deletion lib/Controller/OrganisationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use OCA\OpenCatalogi\Service\ObjectService;
use OCP\AppFramework\Controller;
use OCA\OpenCatalogi\Service\SearchService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand Down Expand Up @@ -93,7 +94,11 @@ public function show(string $id, ObjectService $objectService): JSONResponse
if($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->organisationMapper->find(id: (int) $id));
try {
return new JSONResponse($this->organisationMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}

try {
Expand Down
71 changes: 56 additions & 15 deletions lib/Controller/PublicationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

namespace OCA\OpenCatalogi\Controller;

use Elastic\Elasticsearch\Client;
use GuzzleHttp\Exception\GuzzleException;
use OCA\OpenCatalogi\Db\AttachmentMapper;
use OCA\opencatalogi\lib\Db\Publication;
use OCA\OpenCatalogi\Db\PublicationMapper;
use OCA\OpenCatalogi\Service\ElasticSearchService;
use OCA\OpenCatalogi\Service\ObjectService;
use OCA\OpenCatalogi\Service\SearchService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IAppConfig;
Expand All @@ -24,6 +25,7 @@ public function __construct
$appName,
IRequest $request,
private readonly PublicationMapper $publicationMapper,
private readonly AttachmentMapper $attachmentMapper,
private readonly IAppConfig $config
)
{
Expand Down Expand Up @@ -83,17 +85,17 @@ public function page(?string $getParameter)
* @NoCSRFRequired
*/
public function catalog(string|int $id): TemplateResponse
{
// The TemplateResponse loads the 'main.php'
// defined in our app's 'templates' folder.
// We pass the $getParameter variable to the template
// so that the value is accessible in the template.
return new TemplateResponse(
$this->appName,
'PublicationsIndex',
[]
);
}
{
// The TemplateResponse loads the 'main.php'
// defined in our app's 'templates' folder.
// We pass the $getParameter variable to the template
// so that the value is accessible in the template.
return new TemplateResponse(
$this->appName,
'PublicationsIndex',
[]
);
}

/**
* @NoAdminRequired
Expand All @@ -112,7 +114,7 @@ public function index(ObjectService $objectService, SearchService $searchService
$sort = $searchService->createSortForMySQL(filters: $filters);
$filters = $searchService->unsetSpecialQueryParams(filters: $filters);

return new JSONResponse(['results' => $this->publicationMapper->findAll(limit: null, offset: null, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams, sort: $sort)]);
return new JSONResponse(['results' => $this->publicationMapper->findAll(filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams, sort: $sort)]);
}

$filters = $searchService->createMongoDBSearchFilter(filters: $filters, fieldsToSearch: $fieldsToSearch);
Expand All @@ -133,16 +135,55 @@ public function index(ObjectService $objectService, SearchService $searchService
return new JSONResponse($results);
}

/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function attachments(string|int $id, ObjectService $objectService): JSONResponse
{
$publication = $this->show($id, $objectService)->getData();
if ($this->config->hasKey(app: $this->appName, key: 'mongoStorage') === false
|| $this->config->getValueString(app: $this->appName, key: 'mongoStorage') !== '1'
) {
$publication = $publication->jsonSerialize();
}

$attachments = $publication['attachments'];

if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse(['results' => $this->attachmentMapper->findMultiple($attachments)]);
}

$filters = [];
$filters['id']['$in'] = $attachments;

$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
$dbConfig['headers']['api-key'] = $this->config->getValueString(app: $this->appName, key: 'mongodbKey');
$dbConfig['mongodbCluster'] = $this->config->getValueString(app: $this->appName, key: 'mongodbCluster');

$filters['_schema'] = 'attachment';

$result = $objectService->findObjects(filters: $filters, config: $dbConfig);

return new JSONResponse(['results' => $result['documents']]);
}

/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function show(string|int $id, ObjectService $objectService): JSONResponse
{
if($this->config->hasKey($this->appName, 'mongoStorage') === false
if ($this->config->hasKey($this->appName, 'mongoStorage') === false
|| $this->config->getValueString($this->appName, 'mongoStorage') !== '1'
) {
return new JSONResponse($this->publicationMapper->find(id: (int) $id));
try {
return new JSONResponse($this->publicationMapper->find(id: (int) $id));
} catch (DoesNotExistException $exception) {
return new JSONResponse(data: ['error' => 'Not Found'], statusCode: 404);
}
}

$dbConfig['base_uri'] = $this->config->getValueString(app: $this->appName, key: 'mongodbLocation');
Expand Down
20 changes: 15 additions & 5 deletions lib/Controller/SearchController.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ public function index(SearchService $searchService): JSONResponse
$searchParams = $searchService->createMySQLSearchParams(filters: $filters);
$searchConditions = $searchService->createMySQLSearchConditions(filters: $filters, fieldsToSearch: $fieldsToSearch);

$limit = null;
$offset = null;
$limit = 30;
$offset = 0;

if(isset($filters['_limit']) === true) {
$limit = $filters['_limit'];
Expand All @@ -114,9 +114,19 @@ public function index(SearchService $searchService): JSONResponse

$filters = $searchService->unsetSpecialQueryParams(filters: $filters);



return new JSONResponse(['results' => $this->publicationMapper->findAll(limit: $limit, offset: $offset, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams)]);
$total = $this->publicationMapper->count($filters);
$results = $this->publicationMapper->findAll(limit: $limit, offset: $offset, filters: $filters, searchConditions: $searchConditions, searchParams: $searchParams);
$pages = (int) ceil($total / $limit);

return new JSONResponse([
'results' => $results,
'facets' => [],
'count' => count($results),
'limit' => $limit,
'page' => isset($filters['_page']) === true ? $filters['_page'] : 1,
'pages' => $pages === 0 ? 1 : $pages,
'total' => $total
]);
}

//@TODO: find a better way to get query params. This fixes it for now.
Expand Down
Loading

0 comments on commit e4028a5

Please sign in to comment.