Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
27pchrisl committed May 9, 2021
1 parent 4475215 commit 384c5ac
Show file tree
Hide file tree
Showing 28 changed files with 2,175 additions and 123 deletions.
16 changes: 16 additions & 0 deletions src/Annotation/Core/V1/Immutable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Flat3\Lodata\Annotation\Core\V1;

use Flat3\Lodata\Annotation;
use Flat3\Lodata\Type\Boolean;

class Immutable extends Annotation
{
protected $name = 'Org.OData.Core.V1.Immutable';

public function __construct(bool $isImmutable = true)
{
$this->value = new Boolean($isImmutable);
}
}
39 changes: 38 additions & 1 deletion src/ComplexType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@

namespace Flat3\Lodata;

use Flat3\Lodata\Annotation\Core\V1\Computed;
use Flat3\Lodata\Annotation\Core\V1\Immutable;
use Flat3\Lodata\Controller\Transaction;
use Flat3\Lodata\Helper\Constants;
use Flat3\Lodata\Helper\Identifier;
use Flat3\Lodata\Helper\ObjectArray;
use Flat3\Lodata\Interfaces\AnnotationInterface;
use Flat3\Lodata\Interfaces\ContextInterface;
use Flat3\Lodata\Interfaces\IdentifierInterface;
use Flat3\Lodata\Interfaces\ResourceInterface;
use Flat3\Lodata\Traits\HasAnnotations;
use Flat3\Lodata\Traits\HasIdentifier;

/**
* Complex Type
* @link https://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/odata-csdl-xml-v4.01.html#_Toc38530372
* @package Flat3\Lodata
*/
class ComplexType extends Type implements ResourceInterface, ContextInterface, IdentifierInterface
class ComplexType extends Type implements ResourceInterface, ContextInterface, IdentifierInterface, AnnotationInterface
{
const identifier = 'Edm.ComplexType';

use HasAnnotations;
use HasIdentifier;

/**
Expand Down Expand Up @@ -211,4 +216,36 @@ public function toOpenAPISchema(): array
})
];
}

/**
* Render this type as an OpenAPI schema for creation paths
* @return array
*/
public function toOpenAPICreateSchema(): array
{
return [
'type' => Constants::OAPI_OBJECT,
'properties' => $this->getDeclaredProperties()->filter(function (DeclaredProperty $property) {
return !$property->getAnnotations()->sliceByClass(Computed::class)->hasEntries();
})->map(function (DeclaredProperty $property) {
return $property->getType()->toOpenAPISchema();
})
];
}

/**
* Render this type as an OpenAPI schema for update paths
* @return array
*/
public function toOpenAPIUpdateSchema(): array
{
return [
'type' => Constants::OAPI_OBJECT,
'properties' => $this->getDeclaredProperties()->filter(function (DeclaredProperty $property) {
return !$property->getAnnotations()->sliceByClass([Computed::class, Immutable::class])->hasEntries();
})->map(function (DeclaredProperty $property) {
return $property->getType()->toOpenAPISchema();
})
];
}
}
3 changes: 2 additions & 1 deletion src/Drivers/CSVEntityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Flat3\Lodata\Drivers;

use Flat3\Lodata\Annotation\Core\V1\Computed;
use Flat3\Lodata\DeclaredProperty;
use Flat3\Lodata\EntityType;
use Flat3\Lodata\Type;
Expand All @@ -15,6 +16,6 @@ class CSVEntityType extends EntityType
public function __construct($identifier)
{
parent::__construct($identifier);
$this->setKey(new DeclaredProperty('offset', Type::int64()));
$this->setKey((new DeclaredProperty('offset', Type::int64()))->addAnnotation(new Computed()));
}
}
8 changes: 7 additions & 1 deletion src/Drivers/SQL/SQLSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Types;
use Flat3\Lodata\Annotation\Core\V1\Computed;
use Flat3\Lodata\DeclaredProperty;
use Flat3\Lodata\EntityType;
use Flat3\Lodata\Exception\Protocol\InternalServerErrorException;
Expand Down Expand Up @@ -39,8 +40,13 @@ public function discoverProperties()
}

$column = $columns[$index->getColumns()[0]];
$property = $this->columnToDeclaredProperty($column);

$type->setKey($this->columnToDeclaredProperty($column));
if ($column->getAutoincrement()) {
$property->addAnnotation(new Computed());
}

$type->setKey($property);
}

if (!$type->getKey()) {
Expand Down
21 changes: 21 additions & 0 deletions src/EntityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace Flat3\Lodata;

use Flat3\Lodata\Annotation\Core\V1\Computed;
use Flat3\Lodata\Annotation\Core\V1\Immutable;
use Flat3\Lodata\Controller\Transaction;
use Flat3\Lodata\Exception\Internal\PathNotHandledException;
use Flat3\Lodata\Exception\Protocol\NotFoundException;
use Flat3\Lodata\Facades\Lodata;
use Flat3\Lodata\Helper\Constants;
use Flat3\Lodata\Helper\Identifier;
use Flat3\Lodata\Interfaces\PipeInterface;

Expand Down Expand Up @@ -87,4 +90,22 @@ public static function pipe(

return $argument;
}

/**
* Render this type as an OpenAPI schema for update paths
* @return array
*/
public function toOpenAPIUpdateSchema(): array
{
return [
'type' => Constants::OAPI_OBJECT,
'properties' => $this->getDeclaredProperties()->filter(function (DeclaredProperty $property) {
return !($property->getAnnotations()->sliceByClass([
Computed::class, Immutable::class
])->hasEntries() || $property === $this->getKey());
})->map(function (DeclaredProperty $property) {
return $property->getType()->toOpenAPISchema();
})
];
}
}
19 changes: 13 additions & 6 deletions src/PathSegment/OpenAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ public function emitJson(Transaction $transaction): void

foreach (Lodata::getEntityTypes() as $entityType) {
$schemas->{$entityType->getIdentifier()} = $entityType->toOpenAPISchema();
$schemas->{$entityType->getIdentifier().'~create'} = $entityType->toOpenAPICreateSchema();
$schemas->{$entityType->getIdentifier().'~update'} = $entityType->toOpenAPIUpdateSchema();
}

$schemas->{ComplexType::identifier} = ['type' => Constants::OAPI_OBJECT];
Expand Down Expand Up @@ -527,8 +529,13 @@ public function emitJson(Transaction $transaction): void

$schemas->{'count'} = [
'anyOf' => [
['type' => Constants::OAPI_NUMBER],
['type' => Constants::OAPI_STRING],
[
'type' => Constants::OAPI_INTEGER,
'minimum' => 0,
],
[
'type' => Constants::OAPI_STRING
],
],
'description' => __(
'The number of entities in the collection. Available when using the :ref query option',
Expand Down Expand Up @@ -851,7 +858,7 @@ protected function generateCreateRoutes(
'content' => [
MediaType::json => [
'schema' => [
'$ref' => '#/components/schemas/'.$entitySet->getType()->getIdentifier(),
'$ref' => "#/components/schemas/{$entitySet->getType()->getIdentifier()}~create",
]
]
]
Expand All @@ -864,7 +871,7 @@ protected function generateCreateRoutes(
'content' => [
MediaType::json => [
'schema' => [
'$ref' => '#/components/schemas/'.$entitySet->getType()->getIdentifier(),
'$ref' => "#/components/schemas/{$entitySet->getType()->getIdentifier()}",
]
]
]
Expand Down Expand Up @@ -904,7 +911,7 @@ protected function generateReadRoutes(object $pathItemObject, ResourceInterface
'content' => [
MediaType::json => [
'schema' => [
'$ref' => '#/components/schemas/'.$entityType->getIdentifier(),
'$ref' => "#/components/schemas/{$entityType->getIdentifier()}",
],
],
],
Expand All @@ -930,7 +937,7 @@ protected function generateUpdateRoutes(object $pathItemObject, ResourceInterfac
'content' => [
MediaType::json => [
'schema' => [
'$ref' => '#/components/schemas/'.$entityType->getIdentifier(),
'$ref' => "#/components/schemas/{$entityType->getIdentifier()}~update",
],
],
],
Expand Down
18 changes: 18 additions & 0 deletions src/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,22 @@ abstract public function instance($value = null);
* @return array
*/
abstract public function toOpenAPISchema(): array;

/**
* Render this type as an OpenAPI schema for creation paths
* @return array
*/
public function toOpenAPICreateSchema(): array
{
return $this->toOpenAPISchema();
}

/**
* Render this type as an OpenAPI schema for update paths
* @return array
*/
public function toOpenAPIUpdateSchema(): array
{
return $this->toOpenAPISchema();
}
}
4 changes: 3 additions & 1 deletion tests/Unit/CSV/__snapshots__/CSVTest__test_metadata__1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@
<Key>
<PropertyRef Name="offset"/>
</Key>
<Property Name="offset" Type="Edm.Int64" Nullable="false"/>
<Property Name="offset" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
<Property Name="name" Type="Edm.String" Nullable="true"/>
<Property Name="datetime" Type="Edm.DateTimeOffset" Nullable="true"/>
<Property Name="duration" Type="Edm.Duration" Nullable="true"/>
Expand Down
3 changes: 2 additions & 1 deletion tests/Unit/CSV/__snapshots__/CSVTest__test_metadata__3.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@
],
"offset": {
"$Type": "Edm.Int64",
"$Nullable": false
"$Nullable": false,
"@Org.OData.Core.V1.Computed": true
},
"name": {
"$Type": "Edm.String",
Expand Down
45 changes: 44 additions & 1 deletion tests/Unit/CSV/__snapshots__/CSVTest__test_metadata__4.json
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,48 @@
}
}
},
"com.example.odata.entry~create": {
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true
},
"datetime": {
"type": "string",
"format": "date-time",
"pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$",
"nullable": true
},
"duration": {
"type": "string",
"format": "duration",
"pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$",
"nullable": true
}
}
},
"com.example.odata.entry~update": {
"type": "object",
"properties": {
"name": {
"type": "string",
"nullable": true
},
"datetime": {
"type": "string",
"format": "date-time",
"pattern": "^[0-9]{4,}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]([.][0-9]{1,12})?(Z|[+-][0-9][0-9]:[0-9][0-9])$",
"nullable": true
},
"duration": {
"type": "string",
"format": "duration",
"pattern": "^-?P([0-9]+D)?(T([0-9]+H)?([0-9]+M)?([0-9]+([.][0-9]+)?S)?)?$",
"nullable": true
}
}
},
"Edm.ComplexType": {
"type": "object"
},
Expand Down Expand Up @@ -420,7 +462,8 @@
"count": {
"anyOf": [
{
"type": "number"
"type": "integer",
"minimum": 0
},
{
"type": "string"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int64" Nullable="false"/>
<Property Name="id" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
<Property Name="name" Type="Edm.String" Nullable="false"/>
<Property Name="code" Type="Edm.String" Nullable="false"/>
<Property Name="construction_date" Type="Edm.Date" Nullable="true"/>
Expand All @@ -265,7 +267,9 @@
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int64" Nullable="false"/>
<Property Name="id" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
<Property Name="origin" Type="Edm.String" Nullable="true"/>
<Property Name="destination" Type="Edm.String" Nullable="true"/>
<Property Name="gate" Type="Edm.Int32" Nullable="true"/>
Expand All @@ -284,7 +288,9 @@
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int64" Nullable="false"/>
<Property Name="id" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
<Property Name="name" Type="Edm.String" Nullable="false"/>
<NavigationProperty Name="airports" Type="Collection(com.example.odata.Airport)" Nullable="true">
<ReferentialConstraint Property="id" ReferencedProperty="country_id"/>
Expand All @@ -294,7 +300,9 @@
<Key>
<PropertyRef Name="id"/>
</Key>
<Property Name="id" Type="Edm.Int64" Nullable="false"/>
<Property Name="id" Type="Edm.Int64" Nullable="false">
<Annotation Term="Org.OData.Core.V1.Computed" Bool="true"/>
</Property>
<Property Name="flight_id" Type="Edm.Int32" Nullable="false"/>
<Property Name="name" Type="Edm.String" Nullable="false"/>
<NavigationProperty Name="flight" Type="com.example.odata.Flight" Nullable="true"/>
Expand Down
Loading

0 comments on commit 384c5ac

Please sign in to comment.