diff --git a/examples/grantQuery.php b/examples/grantQuery.php index 0a0c694..fa7225a 100644 --- a/examples/grantQuery.php +++ b/examples/grantQuery.php @@ -4,13 +4,14 @@ global $db; require_once __DIR__ . '/../vendor/autoload.php'; require_once __DIR__ . '/../examples/connection.php'; +use Darksparrow\DeegraphInteractions\Enumerators\DeegraphEqualityOperator; use Darksparrow\DeegraphInteractions\Enumerators\DeegraphPermissionType; use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilder; -$grantQuery = QueryBuilder::Grant() +QueryBuilder::Grant() ->GrantAll() - // ->Permissions(permissionTypes: [DeegraphPermissionType::READ]) - ->To(uuid: $db->GetActor()); + ->On(target: "*") + ->Bu($db); $result = $db->RunQuery($grantQuery); var_dump($result); diff --git a/src/Attributes/QueryBuilderQuery.php b/src/Attributes/QueryBuilderQuery.php index 5bb9bd6..3bcf3cf 100644 --- a/src/Attributes/QueryBuilderQuery.php +++ b/src/Attributes/QueryBuilderQuery.php @@ -2,9 +2,9 @@ namespace Darksparrow\DeegraphInteractions\Attributes; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\InsertQuery; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\PutQuery; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\SelectQuery; +use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\InsertQueryBuilder; +use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\PutQueryBuilder; +use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\SelectQueryBuilder; use PhpParser\Node\Attribute; use PhpParser\Node\Name; use ReflectionClass; @@ -17,7 +17,7 @@ use ReflectionClass; } public function ValidateValues( - InsertQuery|PutQuery|SelectQuery $target + InsertQueryBuilder|PutQueryBuilder|SelectQueryBuilder $target ): void { $nameBase = "Darksparrow\\DeegraphPHP\\Attributes"; diff --git a/src/Core/DeegraphServer.php b/src/Core/DeegraphServer.php index f244656..9a8084e 100644 --- a/src/Core/DeegraphServer.php +++ b/src/Core/DeegraphServer.php @@ -2,12 +2,7 @@ namespace Darksparrow\DeegraphInteractions\Core; -use Darksparrow\DeegraphInteractions\DataStructures\QueryResponseWrapper; use Darksparrow\DeegraphInteractions\DataStructures\ServerInfo; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\GrantQuery; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\InsertQuery; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\PutQuery; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders\SelectQuery; final class DeegraphServer { @@ -48,7 +43,7 @@ final class DeegraphServer return ServerInfo::FromAPIResponse(response: $response); } - private function RunRawRequest(string $endpoint, string $method = "GET", string $body = null): string + public function RunRawRequest(string $endpoint, string $method = "GET", string $body = null): string { $ch = curl_init("https://{$this->ServerDomain}:{$this->Port}{$endpoint}"); curl_setopt($ch, CURLOPT_HTTPHEADER, [ @@ -85,20 +80,4 @@ final class DeegraphServer return $result; } - - /** - * @param InsertQuery|PutQuery|SelectQuery $query Takes in a Query Builder object. - * @return QueryResponseWrapper - */ - public function RunQuery( - GrantQuery|InsertQuery|PutQuery|SelectQuery $query - ): QueryResponseWrapper - { - $response = $this->RunRawRequest( - endpoint: "/api/v1/@query", - method: "POST", - body: $query - ); - return QueryResponseWrapper::FromAPIResponse($response); - } } diff --git a/src/DataStructures/QueryResponseWrapper.php b/src/DataStructures/QueryResponseWrapper.php index b868b3a..c398f10 100644 --- a/src/DataStructures/QueryResponseWrapper.php +++ b/src/DataStructures/QueryResponseWrapper.php @@ -9,6 +9,8 @@ class QueryResponseWrapper public array $Rows; public string $RowFormat; + public string $RuleID; + public static function FromAPIResponse(string $response): QueryResponseWrapper { $response = json_decode($response, true); @@ -31,7 +33,11 @@ class QueryResponseWrapper { $builder->Nodes = []; foreach($response["@nodes"] as $row) - $builder->Nodes = $response["@nodes"]; + $builder->Nodes = $row; + } + if(array_key_exists(key: "@rule_id", array: $response)) + { + $builder->RuleID = $response["@rule_id"]; } return $builder; diff --git a/src/Interfaces/QueryBuilderInterface.php b/src/Interfaces/QueryBuilderInterface.php new file mode 100644 index 0000000..8df0bf9 --- /dev/null +++ b/src/Interfaces/QueryBuilderInterface.php @@ -0,0 +1,14 @@ +PermissionTypes)) $builder .= implode(separator: ",", array: $this->PermissionTypes); - if($this->GrantTo != "") $builder .= " TO $this->GrantTo"; if($this->GrantOn != "") $builder .= " ON $this->GrantOn"; if($this->GrantWhere != "") $builder .= " WHERE $this->GrantWhere"; - return $builder; + return new GrantQuery(queryString: $builder); } - public function Permissions(array $permissionTypes): GrantQuery + public function Permissions(array $permissionTypes): GrantQueryBuilder { $this->PermissionTypes = []; foreach($permissionTypes as $permissionType) $this->PermissionTypes[] = $permissionType->value; return $this; } - public function GrantAll(): GrantQuery + public function GrantAll(): GrantQueryBuilder { $this->PermissionTypes = [ DeegraphPermissionType::WRITE->value, @@ -52,9 +52,15 @@ class GrantQuery return $this; } - public function To(string $uuid): GrantQuery + public function On(string $target): GrantQueryBuilder + { + $this->GrantOn = $target; + return $this; + } + + public function Where(string $target, DeegraphEqualityOperator $operator, string $value): GrantQueryBuilder { - $this->GrantTo = "{" . $uuid . "}"; + $this->GrantWhere = "$target $operator->value $value"; return $this; } } diff --git a/src/QueryBuilder/QueryBuilders/InsertQuery.php b/src/QueryBuilder/QueryBuilders/InsertQueryBuilder.php similarity index 68% rename from src/QueryBuilder/QueryBuilders/InsertQuery.php rename to src/QueryBuilder/QueryBuilders/InsertQueryBuilder.php index 96bda5c..a266e02 100755 --- a/src/QueryBuilder/QueryBuilders/InsertQuery.php +++ b/src/QueryBuilder/QueryBuilders/InsertQueryBuilder.php @@ -4,10 +4,12 @@ namespace Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders; use Darksparrow\DeegraphInteractions\Attributes\QueryBuilderQuery; use Darksparrow\DeegraphInteractions\Attributes\QueryBuilderRequiredField; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilderTrait; +use Darksparrow\DeegraphInteractions\Interfaces\QueryBuilderInterface; +use Darksparrow\DeegraphInteractions\Traits\QueryBuilderTrait; +use Darksparrow\DeegraphInteractions\QueryInstance\InsertQuery; #[QueryBuilderQuery] -final class InsertQuery +final class InsertQueryBuilder implements QueryBuilderInterface { use QueryBuilderTrait; @@ -25,11 +27,8 @@ final class InsertQuery protected bool $Replace = false; - public function __construct() - { - } - public function __toString(): string + public function Build(): InsertQuery { $instance = new QueryBuilderQuery(); $instance->ValidateValues($this); @@ -42,41 +41,41 @@ final class InsertQuery if($this->Duplicate) $builder .= "DUPLICATE"; if($this->Replace) $builder .= "REPLACE"; - return $builder; + return new InsertQuery($builder); } - public function RelativePath(string $relativePath): InsertQuery + public function RelativePath(string $relativePath): InsertQueryBuilder { self::ValidateDeegraphPath(target: $relativePath); $this->RelativePath = $relativePath; return $this; } - public function Keys(string $keys): InsertQuery + public function Keys(string $keys): InsertQueryBuilder { $this->Keys = $keys; return $this; } - public function Schemas(string $schemas): InsertQuery + public function Schemas(string $schemas): InsertQueryBuilder { $this->Schemas = $schemas; return $this; } - public function Values(string $values): InsertQuery + public function Values(string $values): InsertQueryBuilder { $this->Values .= $values; return $this; } - public function Duplicate(): InsertQuery + public function Duplicate(): InsertQueryBuilder { $this->Duplicate = true; return $this; } - public function Replace(): InsertQuery + public function Replace(): InsertQueryBuilder { $this->Replace = true; return $this; diff --git a/src/QueryBuilder/QueryBuilders/PutQuery.php b/src/QueryBuilder/QueryBuilders/PutQueryBuilder.php similarity index 51% rename from src/QueryBuilder/QueryBuilders/PutQuery.php rename to src/QueryBuilder/QueryBuilders/PutQueryBuilder.php index eaf7dc7..4c6efee 100755 --- a/src/QueryBuilder/QueryBuilders/PutQuery.php +++ b/src/QueryBuilder/QueryBuilders/PutQueryBuilder.php @@ -5,47 +5,47 @@ namespace Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilders; use Darksparrow\DeegraphInteractions\Exceptions\QueryBuilderConflictingFieldAlreadyExistsException; use Darksparrow\DeegraphInteractions\Exceptions\QueryBuilderInvalidInputException; use Darksparrow\DeegraphInteractions\Exceptions\QueryBuilderRequiredFieldIsNotSetException; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilderTrait; +use Darksparrow\DeegraphInteractions\Interfaces\QueryBuilderInterface; +use Darksparrow\DeegraphInteractions\QueryInstance\PutQuery; +use Darksparrow\DeegraphInteractions\Traits\QueryBuilderTrait; -final class PutQuery +final class PutQueryBuilder implements QueryBuilderInterface { use QueryBuilderTrait; protected string $PutWhat = ""; + protected string $PutData = ""; protected string $PutAt = ""; protected string $PutInto = ""; protected bool $Safe = false; - - public function __construct() - { - } - /** * @throws QueryBuilderRequiredFieldIsNotSetException */ - public function __toString(): string + public function Build(): PutQuery { - $builder = "PUT"; - if($this->PutWhat != "") $builder .= " $this->PutWhat"; + $builder = "PUT $this->PutWhat"; + if($this->PutData != "") $builder .= " \"$this->PutData\" "; - if($this->PutAt != "") $builder .= " $this->PutAt"; - elseif ($this->PutInto != "") $builder .= " $this->PutInto"; + if($this->PutAt != "") $builder .= "AT $this->PutAt"; + elseif ($this->PutInto != "") $builder .= "INTO $this->PutInto"; else throw new QueryBuilderRequiredFieldIsNotSetException(); if($this->Safe) $builder .= " SAFE"; - return $builder; + + return new PutQuery($builder); } /** * @throws QueryBuilderInvalidInputException */ - public function Schema(string $uri): PutQuery + public function Schema(string $schema): PutQueryBuilder { - $this->PutWhat = self::RegexValidate( - target: "SCHEMA \"$uri\"", - pattern: "/SCHEMA \".+\"/" + $this->PutWhat = "SCHEMA"; + $this->PutData = self::RegexValidate( + target: $schema, + pattern: "/.+/" ); return $this; } @@ -53,11 +53,12 @@ final class PutQuery /** * @throws QueryBuilderInvalidInputException */ - public function URI(string $uri): PutQuery + public function URI(string $uri): PutQueryBuilder { - $this->PutWhat = self::RegexValidate( - target: "URI \"$uri\"", - pattern: "/URI \".+\"/" + $this->PutWhat = "URI"; + $this->PutData = self::RegexValidate( + target: $uri, + pattern: "/.+/" ); return $this; } @@ -65,11 +66,12 @@ final class PutQuery /** * @throws QueryBuilderInvalidInputException */ - public function DataURI(string $mimeType, string $data): PutQuery + public function DataURI(string $mimeType, string $data): PutQueryBuilder { - $this->PutWhat = self::RegexValidate( - target: "URI \"data:$mimeType;$data\"", - pattern: "/URI \"data:[a-zA-Z0-9]/[a-zA-Z0-9];.+\"/" + $this->PutWhat = "URI"; + $this->PutData = self::RegexValidate( + target: "data:$mimeType;$data", + pattern: "data:[a-zA-Z0-9]/[a-zA-Z0-9];.+/" ); return $this; } @@ -79,12 +81,11 @@ final class PutQuery * @throws QueryBuilderInvalidInputException * @throws QueryBuilderConflictingFieldAlreadyExistsException */ - public function At(string $node, string $uwu): PutQuery + public function At(string $relativePath): PutQueryBuilder { self::EnsureNotSet($this->PutInto); - $this->PutAt = self::RegexValidate( - target: 'AT {' . $node . '}/' . $uwu, - pattern: "/AT {[a-zA-Z0-9\-]+}\/[a-zA-Z0-9]+/" + $this->PutAt = self::ValidateDeegraphPath( + target: $relativePath ); return $this; } @@ -94,18 +95,18 @@ final class PutQuery * @throws QueryBuilderInvalidInputException * @throws QueryBuilderConflictingFieldAlreadyExistsException */ - public function Into(string $relativePath, string $propertyName): PutQuery + public function Into(string $relativePath, string $propertyName): PutQueryBuilder { self::EnsureNotSet($this->PutAt); $this->PutInto = self::RegexValidate( - target: "INTO \"$relativePath\" AS \"$propertyName\"", - pattern: "/INTO \"[a-zA-Z0-9\-]+\" AS \"[a-zA-Z0-9]+\"/" + target: "\"$relativePath\" AS \"$propertyName\"", + pattern: "/\"[a-zA-Z0-9\-]+\" AS \"[a-zA-Z0-9]+\"/" ); return $this; } - public function Safe(): PutQuery + public function Safe(): PutQueryBuilder { $this->Safe = true; return $this; diff --git a/src/QueryBuilder/QueryBuilders/SelectQuery.php b/src/QueryBuilder/QueryBuilders/SelectQueryBuilder.php similarity index 72% rename from src/QueryBuilder/QueryBuilders/SelectQuery.php rename to src/QueryBuilder/QueryBuilders/SelectQueryBuilder.php index e076544..91d5ed9 100755 --- a/src/QueryBuilder/QueryBuilders/SelectQuery.php +++ b/src/QueryBuilder/QueryBuilders/SelectQueryBuilder.php @@ -6,10 +6,12 @@ use Darksparrow\DeegraphInteractions\Attributes\QueryBuilderQuery; use Darksparrow\DeegraphInteractions\Attributes\QueryBuilderRequiredField; use Darksparrow\DeegraphInteractions\Enumerators\DeegraphEqualityOperator; use Darksparrow\DeegraphInteractions\Exceptions\QueryBuilderRequiredFieldIsNotSetException; -use Darksparrow\DeegraphInteractions\QueryBuilder\QueryBuilderTrait; +use Darksparrow\DeegraphInteractions\Interfaces\QueryBuilderInterface; +use Darksparrow\DeegraphInteractions\QueryInstance\SelectQuery; +use Darksparrow\DeegraphInteractions\Traits\QueryBuilderTrait; #[QueryBuilderQuery] -final class SelectQuery +final class SelectQueryBuilder implements QueryBuilderInterface { use QueryBuilderTrait; @@ -20,14 +22,16 @@ final class SelectQuery protected string $InstanceOf = ""; - public function __construct() - { - } - /** * @throws QueryBuilderRequiredFieldIsNotSetException */ public function __toString(): string + { + return $this->Build(); + } + + + public function Build(): SelectQuery { $builder = "SELECT "; if(sizeof($this->RelativePaths)) $builder .= " " . implode(separator: ", ", array: $this->RelativePaths); @@ -35,30 +39,30 @@ final class SelectQuery if($this->Where != "") $builder .= " WHERE $this->Where"; if($this->InstanceOf != "") $builder .= " INSTANCEOF $this->InstanceOf"; - return $builder; + return new SelectQuery(queryString: $builder); } - public function RelativePath(string $relativePath): SelectQuery + public function RelativePath(string $relativePath): SelectQueryBuilder { $this->RelativePaths = [$relativePath]; return $this; } - public function RelativePaths(array $relativePaths): SelectQuery + public function RelativePaths(array $relativePaths): SelectQueryBuilder { $this->RelativePaths = $relativePaths; return $this; } - public function From(string $target): SelectQuery + public function From(string $target): SelectQueryBuilder { $this->From = "" . $target; return $this; } - public function Where(string $target, DeegraphEqualityOperator $operator, string $value): SelectQuery + public function Where(string $target, DeegraphEqualityOperator $operator, string $value): SelectQueryBuilder { $this->Where = "" . $target . " " . $operator->value . " " . $value; return $this; } - public function InstanceOf(string $schema): SelectQuery + public function InstanceOf(string $schema): SelectQueryBuilder { $this->InstanceOf = "" . $schema; return $this; diff --git a/src/QueryInstance/GrantQuery.php b/src/QueryInstance/GrantQuery.php new file mode 100644 index 0000000..5f965e1 --- /dev/null +++ b/src/QueryInstance/GrantQuery.php @@ -0,0 +1,21 @@ +RunRawRequest( + endpoint: "/api/v1/@query", + method: "POST", + body: $this->QueryString + ); + return GrantQueryResponse::FromAPIResponse(response: $response); + } +} diff --git a/src/QueryInstance/InsertQuery.php b/src/QueryInstance/InsertQuery.php new file mode 100644 index 0000000..65f2443 --- /dev/null +++ b/src/QueryInstance/InsertQuery.php @@ -0,0 +1,20 @@ +RunRawRequest( + endpoint: "/api/v1/@query", + method: "POST", + body: $this->QueryString + ); + return InsertQueryResponse::FromAPIResponse(response: $response); + } +} diff --git a/src/QueryInstance/PutQuery.php b/src/QueryInstance/PutQuery.php new file mode 100644 index 0000000..eb621b7 --- /dev/null +++ b/src/QueryInstance/PutQuery.php @@ -0,0 +1,21 @@ +RunRawRequest( + endpoint: "/api/v1/@query", + method: "POST", + body: $this->QueryString + ); + return PutQueryResponse::FromAPIResponse(response: $response); + } +} diff --git a/src/QueryInstance/SelectQuery.php b/src/QueryInstance/SelectQuery.php new file mode 100644 index 0000000..e225a95 --- /dev/null +++ b/src/QueryInstance/SelectQuery.php @@ -0,0 +1,21 @@ +RunRawRequest( + endpoint: "/api/v1/@query", + method: "POST", + body: $this->QueryString + ); + return new SelectQueryResponse(response: $response); + } +} diff --git a/src/QueryResponse/GrantQueryResponse.php b/src/QueryResponse/GrantQueryResponse.php new file mode 100644 index 0000000..58831f6 --- /dev/null +++ b/src/QueryResponse/GrantQueryResponse.php @@ -0,0 +1,17 @@ +RuleID = $response["@rule_id"]; + } +} diff --git a/src/QueryResponse/InsertQueryResponse.php b/src/QueryResponse/InsertQueryResponse.php new file mode 100644 index 0000000..7c62e93 --- /dev/null +++ b/src/QueryResponse/InsertQueryResponse.php @@ -0,0 +1,13 @@ +Rows = []; + foreach($response["@rows"] as $row) + $this->Rows[] = QueryResponseRow::FromArray(array: $row); + $this->RowFormat = $response["@row_format"]; + } + } + + public function FlattenRows(): array + { + $builder = []; + + foreach($this->Rows as $row) + { + foreach($row->Results as $result) + { + $builder[] = $result; + } + } + + return $builder; + } +} \ No newline at end of file diff --git a/src/Superclasses/QueryInstanceSuperclass.php b/src/Superclasses/QueryInstanceSuperclass.php new file mode 100644 index 0000000..2bea448 --- /dev/null +++ b/src/Superclasses/QueryInstanceSuperclass.php @@ -0,0 +1,28 @@ +QueryString = $queryString; + } + + /** + * Returns back the Query Instance as a string object. + * + * @return string + */ + public function __toString(): string + { + return $this->QueryString; + } +} diff --git a/src/QueryBuilder/QueryBuilderTrait.php b/src/Traits/QueryBuilderTrait.php similarity index 92% rename from src/QueryBuilder/QueryBuilderTrait.php rename to src/Traits/QueryBuilderTrait.php index c6e5425..afa0f84 100755 --- a/src/QueryBuilder/QueryBuilderTrait.php +++ b/src/Traits/QueryBuilderTrait.php @@ -1,6 +1,6 @@