<?php namespace SmartDataContext\Persistence; use Exception; use MongoDB\Database; use MongoDB\Collection; use SmartDataContext\Domain\SmartDataContext; class SmartDataContextCrud { private Database $connection; private static array $collections = []; function __construct(Database $dbconn) { $this->connection = $dbconn; SmartDataContextCrud::$collections = []; } function create($domain, $t0, $t1, $content, $features, $smartDataSources, $smartDataUnits):array { if (! array_key_exists('identifier', $features)) { $features['identifier'] = $this->build_identifier($content); } $id = UniqueID::generateID(); $this->getCollection($domain)->insertOne([ "id" => $id, "t0" => $t0, "t1" => $t1, "content" => $content, "features" => $features, "smartDataSources" => $smartDataSources, "smartDataUnits" => $smartDataUnits ] ); return array("success" => true, "contents" => array("smartDataContextId" => $id)); } private function getCollection($domain): Collection { if (in_array($domain, SmartDataContextCrud::$collections)) { return $this->connection->{$domain}; } else { $cols = $this->connection->listCollectionNames(["name" => $domain]); $cols->next(); if (! $cols->valid()) { $this->createCollection($domain); } else { SmartDataContextCrud::$collections[] = $domain; } return $this->connection->{$domain}; } } private function createCollection($domain) { $this->connection->createCollection($domain); $this->connection->selectCollection($domain)->createIndex(["id" => 1]); $this->connection->selectCollection($domain)->createIndex(["features" => 1]); $this->connection->selectCollection($domain)->createIndex(["tags" => 1]); $this->connection->selectCollection($domain)->createIndex(["smartDataSources" => 1]); $this->connection->selectCollection($domain)->createIndex(["smartDataUnits" => 1]); $this->connection->selectCollection($domain)->createIndex(["t0" => 1, "t1" => 1, "smartDataUnits" => 1]); $this->connection->selectCollection($domain)->createIndex(["t0" => 1, "t1" => 1, "smartDataSources" => 1]); } private function build_identifier($content) { return sha1(json_encode($content)); } public function get($domain, $id):mixed { $smartdatacontext = $this->getCollection($domain)->findOne(["id" => $id]); if (! isset($smartdatacontext)) { return ["success" => false, "errors" => ["not found"]]; } else { return ["success" => true, "contents" => json_decode(json_encode($smartdatacontext), true)]; } } public function associate(mixed $domain, mixed $id, mixed $smartDataSources, mixed $smartDataUnits) { $errors = array_merge(SmartDataContext::ValidateSmartDataSources($smartDataSources), SmartDataContext::ValidateSmartDataUnits($smartDataUnits)); if ($errors) { return ["success" => false, "errors" => $errors]; } $smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $id])), true); if ($smartdatacontext) { $smartDataUnitsToAdd = []; foreach ($smartDataUnits as $smartDataUnit) { if (! in_array($smartDataUnit, $smartdatacontext['smartDataUnits'])) { $smartDataUnitsToAdd[] = $smartDataUnit; } } $smartDataSourcesToAdd = []; foreach ($smartDataSources as $smartDataSource) { if (! in_array($smartDataSource, $smartdatacontext['smartDataSources'])) { $smartDataSourcesToAdd[] = $smartDataSource; } } $updateData = [ '$push' => [ 'smartDataSources' => [ '$each' => $smartDataSourcesToAdd ], 'smartDataUnits' => [ '$each' => $smartDataUnitsToAdd ] ] ]; $this->getCollection($domain)->updateOne(["id" => $id], $updateData); return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $id])), true)]; } else { return ["success" => false, "errors" => ["smartdatacontext id not found"]]; } } public function unassociate(mixed $domain, mixed $id, mixed $smartDataSources, mixed $smartDataUnits) { $errors = array_merge(SmartDataContext::ValidateSmartDataSources($smartDataSources), SmartDataContext::ValidateSmartDataUnits($smartDataUnits)); if ($errors) { return ["success" => false, "errors" => $errors]; } $smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $id])), true); if ($smartdatacontext) { $smartDataUnitsToRemove = []; foreach ($smartDataUnits as $smartDataUnit) { if (in_array($smartDataUnit, $smartdatacontext['smartDataUnits'])) { $smartDataUnitsToRemove[] = $smartDataUnit; } } $smartDataSourcesToRemove = []; foreach ($smartDataSources as $smartDataSource) { if (in_array($smartDataSource, $smartdatacontext['smartDataSources'])) { $smartDataSourcesToRemove[] = $smartDataSource; } } if ($smartDataSourcesToRemove && $smartDataUnitsToRemove) { $updateData = [ '$pull' => [ 'smartDataSources' => ['$in' => $smartDataSourcesToRemove], 'smartDataUnits' => ['$in' => $smartDataUnitsToRemove] ] ]; } else if ($smartDataSourcesToRemove) { $updateData = [ '$pull' => [ 'smartDataSources' => ['$in' => $smartDataSourcesToRemove] ] ]; } else if ($smartDataUnitsToRemove) { $updateData = [ '$pull' => [ 'smartDataUnits' => ['$in' => $smartDataUnitsToRemove] ] ]; } else { return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $id])), true)]; } $this->getCollection($domain)->updateOne(["id" => $id], $updateData); return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $id])), true)]; } else { return ["success" => false, "errors" => ["smartdatacontext id not found"]]; } } public function query(string $domain, mixed $query) { try { $contentsMongo = $this->getCollection($domain)->find($query); $contents = []; foreach ($contentsMongo as $contentMongo) { $contents[] = json_decode(json_encode($contentMongo), true); } return ["success" => true, "contents" => $contents]; } catch (Exception $exception) { return ["success" => false, "errors" => [$exception->getMessage()]]; } } public function update($domain, $id, array $updateData): array { // Find the document in the MongoDB collection using the id field value $collection = $this->getCollection($domain); $document = $collection->findOne(["id" => $id]); // Check if the document exists if ($document === null) { return ["success" => false, "errors" => ["SmartDataContext with id $id not found"]]; } // Update the document's properties using the associative array received $updateFields = []; foreach ($updateData as $key => $value) { $updateFields[$key] = $value; } // Prepare the update query $updateQuery = ['$set' => $updateFields]; // Update the document in the MongoDB collection try { $collection->updateOne(["id" => $id], $updateQuery); $updatedDocument = $collection->findOne(["id" => $id]); return ["success" => true, "contents" => json_decode(json_encode($updatedDocument), false)]; } catch (Exception $e) { return ["success" => false, "errors" => [$e->getMessage()]]; } } public function addUnstructuredData(mixed $domain, mixed $smartdatacontextid, ?string $objectid, $contentype, $filename) { $smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true); if ($smartdatacontext) { $updateData = [ '$push' => [ 'unstructuredData' => [ "id" => $objectid, "mimetype" => $contentype, "filename" => $filename ] ] ]; $this->getCollection($domain)->updateOne(["id" => $smartdatacontextid], $updateData); return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true)]; } else { return ["success" => false, "errors" => ["smartDataContext id not found"]]; } } public function removeUnstructuredData(mixed $domain, mixed $smartdatacontextid, string $objectid) { $smartdatacontext = json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true); if ($smartdatacontext) { $updateData = [ '$pull' => [ 'unstructuredData' => ['id' => $objectid] ] ]; $this->getCollection($domain)->updateOne(["id" => $smartdatacontextid], $updateData); return ["success" => true, "result" => json_decode(json_encode($this->getCollection($domain)->findOne(["id" => $smartdatacontextid])), true)]; } else { return ["success" => false, "errors" => ["smartDataContext id not found"]]; } } }