Passed
Branch master (950424)
by Christopher
11:06
created

ProvidersWrapper::getResourceSets()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 4
nop 0
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace POData\Providers;
4
5
use POData\Common\InvalidOperationException;
6
use POData\Common\Messages;
7
use POData\Common\ODataException;
8
use POData\Configuration\IServiceConfiguration;
9
use POData\Providers\Expression\IExpressionProvider;
10
use POData\Providers\Metadata\EdmSchemaVersion;
11
use POData\Providers\Metadata\IMetadataProvider;
12
use POData\Providers\Metadata\ResourceAssociationSet;
13
use POData\Providers\Metadata\ResourceEntityType;
14
use POData\Providers\Metadata\ResourceProperty;
15
use POData\Providers\Metadata\ResourceSet;
16
use POData\Providers\Metadata\ResourceSetWrapper;
17
use POData\Providers\Metadata\ResourceType;
18
use POData\Providers\Metadata\ResourceTypeKind;
19
use POData\Providers\Query\IQueryProvider;
20
use POData\Providers\Query\QueryResult;
21
use POData\Providers\Query\QueryType;
22
use POData\UriProcessor\QueryProcessor\ExpressionParser\FilterInfo;
23
use POData\UriProcessor\QueryProcessor\OrderByParser\InternalOrderByInfo;
24
use POData\UriProcessor\QueryProcessor\SkipTokenParser\InternalSkipTokenInfo;
25
use POData\UriProcessor\QueryProcessor\SkipTokenParser\SkipTokenInfo;
26
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
27
28
/**
29
 * Class ProvidersWrapper.
30
 *
31
 * A wrapper class over IMetadataProvider and IQueryProvider implementations, All calls to implementation of methods
32
 * of these interfaces should go through this wrapper class so that wrapper methods of this class can perform validation
33
 */
34
class ProvidersWrapper
35
{
36
    /**
37
     * Holds reference to IMetadataProvider implementation.
38
     *
39
     * @var IMetadataProvider
40
     */
41
    private $metaProvider;
42
43
    /**
44
     * Holds reference to IServiceConfiguration implementation.
45
     *
46
     * @var IServiceConfiguration
47
     */
48
    private $config;
49
50
    /*
51
     * Holds reference to ProvidersQueryWrapper implementation
52
     *
53
     * @var ProvidersQueryWrapper
54
     */
55
    private $providerWrapper;
56
57
    /**
58
     * Cache for ResourceProperties of a resource type that belongs to a
59
     * resource set. An entry (ResourceProperty collection) in this cache
60
     * contains only the visible properties of ResourceType.
61
     *
62
     * @var array<array>
63
     */
64
    private $propertyCache = [];
65
66
    /**
67
     * Cache for ResourceSetWrappers. If ResourceSet is invisible value will
68
     * be null.
69
     *
70
     * @var ResourceSetWrapper[] indexed by resource set name
71
     */
72
    private $setWrapperCache = [];
73
74
    /**
75
     * Cache for ResourceTypes.
76
     *
77
     * @var ResourceType[] indexed by resource type name
78
     */
79
    private $typeCache = [];
80
81
    /**
82
     * Cache for ResourceAssociationSet. If ResourceAssociationSet is invisible
83
     * value will be null.
84
     *
85
     * @var ResourceAssociationSet[] indexed by name
86
     */
87
    private $associationSetCache = [];
0 ignored issues
show
introduced by
The private property $associationSetCache is not used, and could be removed.
Loading history...
88
89
    /**
90
     * Creates a new instance of ProvidersWrapper.
91
     *
92
     * @param IMetadataProvider     $meta   Reference to IMetadataProvider implementation
93
     * @param IQueryProvider        $query  Reference to IQueryProvider implementation
94
     * @param IServiceConfiguration $config Reference to IServiceConfiguration implementation
95
     */
96
    public function __construct(IMetadataProvider $meta, IQueryProvider $query, IServiceConfiguration $config)
97
    {
98
        $this->metaProvider = $meta;
99
        $this->config = $config;
100
        $this->providerWrapper = new ProvidersQueryWrapper($query);
101
    }
102
103
    /**
104
     * @return ProvidersQueryWrapper
105
     */
106
    public function getProviderWrapper()
107
    {
108
        assert(null != $this->providerWrapper, 'Provider wrapper must be set');
109
        return $this->providerWrapper;
110
    }
111
112
    /**
113
     * @return IMetadataProvider
114
     */
115
    public function getMetaProvider()
116
    {
117
        assert(null != $this->metaProvider, 'Metadata provider must be set');
118
        return $this->metaProvider;
119
    }
120
121
    //Wrappers for IMetadataProvider methods
122
123
    /**
124
     * To get the Container name for the data source,
125
     * Note: Wrapper for IMetadataProvider::getContainerName method
126
     * implementation.
127
     *
128
     * @throws ODataException Exception if implementation returns empty container name
129
     *
130
     * @return string that contains the name of the container
131
     */
132
    public function getContainerName()
133
    {
134
        $containerName = $this->getMetaProvider()->getContainerName();
135
        if (empty($containerName)) {
136
            throw new ODataException(
137
                Messages::providersWrapperContainerNameMustNotBeNullOrEmpty(),
138
                500
139
            );
140
        }
141
142
        return $containerName;
143
    }
144
145
    /**
146
     * To get Namespace name for the data source,
147
     * Note: Wrapper for IMetadataProvider::getContainerNamespace method implementation.
148
     *
149
     * @throws ODataException Exception if implementation returns empty container namespace
150
     *
151
     * @return string that contains the namespace name
152
     */
153
    public function getContainerNamespace()
154
    {
155
        $containerNamespace = $this->getMetaProvider()->getContainerNamespace();
156
        if (empty($containerNamespace)) {
157
            throw new ODataException(
158
                Messages::providersWrapperContainerNamespaceMustNotBeNullOrEmpty(),
159
                500
160
            );
161
        }
162
163
        return $containerNamespace;
164
    }
165
166
    /**
167
     * To get the data service configuration.
168
     *
169
     * @return IServiceConfiguration
170
     */
171
    public function getConfiguration()
172
    {
173
        return $this->config;
174
    }
175
176
    /**
177
     *  To get all entity set information,
178
     *  Note: Wrapper for IMetadataProvider::getResourceSets method implementation,
179
     *  This method returns array of ResourceSetWrapper instances but the corresponding IDSMP method
180
     *  returns array of ResourceSet instances.
181
     *
182
     *  @throws ODataException when two resource sets with the same name are encountered
183
     *
184
     *  @return ResourceSetWrapper[] The ResourceSetWrappers for the visible ResourceSets
185
     */
186
    public function getResourceSets()
187
    {
188
        $resourceSets = $this->getMetaProvider()->getResourceSets();
189
        $resourceSetWrappers = [];
190
        $resourceSetNames = [];
191
        foreach ($resourceSets as $resourceSet) {
192
            $name = $resourceSet->getName();
193
            if (in_array($name, $resourceSetNames)) {
194
                throw new ODataException(Messages::providersWrapperEntitySetNameShouldBeUnique($name), 500);
195
            }
196
197
            $resourceSetNames[] = $name;
198
            $resourceSetWrapper = $this->validateResourceSetAndGetWrapper($resourceSet);
199
            if (null !== $resourceSetWrapper) {
200
                $resourceSetWrappers[] = $resourceSetWrapper;
201
            }
202
        }
203
204
        return $resourceSetWrappers;
205
    }
206
207
    /**
208
     * This function perform the following operations
209
     *  (1) If the cache contain an entry [key, value] for the resourceset then
210
     *      return the entry-value
211
     *  (2) If the cache not contain an entry for the resourceset then validate
212
     *      the resourceset
213
     *            (a) If valid add entry as [resouceset_name, resourceSetWrapper]
214
     *            (b) if not valid add entry as [resouceset_name, null]
215
     *  Note: validating a resourceset means checking the resourceset is visible
216
     *  or not using configuration.
217
     *
218
     * @param ResourceSet $resourceSet The resourceset to validate and get the
219
     *                                 wrapper for
220
     *
221
     * @return ResourceSetWrapper|null Returns an instance if a resource set with the given name is visible
222
     */
223
    private function validateResourceSetAndWrapper(ResourceSet $resourceSet)
224
    {
225
        $cacheKey = $resourceSet->getName();
226
        if (array_key_exists($cacheKey, $this->setWrapperCache)) {
227
            return $this->setWrapperCache[$cacheKey];
228
        }
229
230
        $this->validateResourceType($resourceSet->getResourceType());
231
        $wrapper = new ResourceSetWrapper($resourceSet, $this->config);
232
        $nuVal = $wrapper->isVisible() ? $wrapper : null;
233
        $this->setWrapperCache[$cacheKey] = $nuVal;
234
235
        return $this->setWrapperCache[$cacheKey];
236
    }
237
238
    /**
239
     * Validates the given instance of ResourceType.
240
     *
241
     * @param ResourceType $resourceType The ResourceType to validate
242
     *
243
     * @throws ODataException Exception if $resourceType is invalid
244
     *
245
     * @return ResourceType
246
     */
247
    private function validateResourceType(ResourceType $resourceType)
248
    {
249
        $cacheKey = $resourceType->getName();
250
        if (array_key_exists($cacheKey, $this->typeCache)) {
251
            return $this->typeCache[$cacheKey];
252
        }
253
254
        //TODO: Do validation if any for the ResourceType
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
255
        $this->typeCache[$cacheKey] = $resourceType;
256
257
        return $resourceType;
258
    }
259
260
    /**
261
     * To get all resource types in the data source,
262
     * Note: Wrapper for IMetadataProvider::getTypes method implementation.
263
     *
264
     * @throws ODataException
265
     * @return ResourceType[]
266
     */
267
    public function getTypes()
268
    {
269
        $resourceTypes = $this->getMetaProvider()->getTypes();
270
        $resourceTypeNames = [];
271
        foreach ($resourceTypes as $resourceType) {
272
            if (in_array($resourceType->getName(), $resourceTypeNames)) {
273
                throw new ODataException(
274
                    Messages::providersWrapperEntityTypeNameShouldBeUnique($resourceType->getName()),
275
                    500
276
                );
277
            }
278
279
            $resourceTypeNames[] = $resourceType->getName();
280
            $this->validateResourceType($resourceType);
281
        }
282
283
        return $resourceTypes;
284
    }
285
286
    public function getSingletons()
287
    {
288
        $singletons = $this->getMetaProvider()->getSingletons();
289
        return (null == $singletons) ? [] : $singletons;
290
    }
291
292
    /**
293
     * To get a resource set based on the specified resource set name which is
294
     * visible,
295
     * Note: Wrapper for IMetadataProvider::resolveResourceSet method
296
     * implementation.
297
     *
298
     * @param string $name Name of the resource set
299
     *
300
     * @return ResourceSetWrapper|null Returns resource set with the given name if found,
301
     *                                 NULL if resource set is set to invisible or not found
302
     */
303
    public function resolveResourceSet($name)
304
    {
305
        if (array_key_exists($name, $this->setWrapperCache)) {
306
            return $this->setWrapperCache[$name];
307
        }
308
309
        $resourceSet = $this->getMetaProvider()->resolveResourceSet($name);
310
        if (null === $resourceSet) {
311
            return null;
312
        }
313
314
        return $this->validateResourceSetAndWrapper($resourceSet);
315
    }
316
317
    /**
318
     * To get a resource type based on the resource set name,
319
     * Note: Wrapper for IMetadataProvider::resolveResourceType
320
     * method implementation.
321
     *
322
     * @param string $name Name of the resource set
323
     *
324
     * @throws ODataException If the ResourceType is invalid
325
     *
326
     * @return ResourceType|null resource type with the given resource set name if found else NULL
327
     */
328
    public function resolveResourceType($name)
329
    {
330
        $resourceType = $this->getMetaProvider()->resolveResourceType($name);
331
        if (null === $resourceType) {
332
            return null;
333
        }
334
335
        return $this->validateResourceType($resourceType);
336
    }
337
338
    /**
339
     * Try to resolve named singleton.
340
     *
341
     * @param  string     $name
342
     * @return mixed|null
343
     */
344
    public function resolveSingleton($name)
345
    {
346
        $singletons = $this->getMetaProvider()->getSingletons();
347
        if (array_key_exists($name, $singletons)) {
348
            return $singletons[$name];
349
        }
350
        return null;
351
    }
352
353
    /**
354
     * The method must return a collection of all the types derived from
355
     * $resourceType The collection returned should NOT include the type
356
     * passed in as a parameter
357
     * Note: Wrapper for IMetadataProvider::getDerivedTypes
358
     * method implementation.
359
     *
360
     * @param ResourceEntityType $resourceType Resource to get derived resource types from
361
     *
362
     * @throws InvalidOperationException when the meat provider doesn't return an array
363
     *
364
     * @return ResourceType[]
365
     */
366
    public function getDerivedTypes(ResourceEntityType $resourceType)
367
    {
368
        $derivedTypes = $this->getMetaProvider()->getDerivedTypes($resourceType);
369
        if (!is_array($derivedTypes)) {
370
            throw new InvalidOperationException(
371
                Messages::metadataAssociationTypeSetInvalidGetDerivedTypesReturnType($resourceType->getName())
372
            );
373
        }
374
375
        foreach ($derivedTypes as $derivedType) {
376
            $this->validateResourceType($derivedType);
377
        }
378
379
        return $derivedTypes;
380
    }
381
382
    /**
383
     * Returns true if $resourceType represents an Entity Type which has derived
384
     * Entity Types, else false.
385
     * Note: Wrapper for IMetadataProvider::hasDerivedTypes method implementation.
386
     *
387
     * @param ResourceEntityType $resourceType Resource to check for derived resource types
388
     *
389
     * @throws ODataException If the ResourceType is invalid
390
     *
391
     * @return bool
392
     */
393
    public function hasDerivedTypes(ResourceEntityType $resourceType)
394
    {
395
        $this->validateResourceType($resourceType);
396
397
        return $this->getMetaProvider()->hasDerivedTypes($resourceType);
398
    }
399
400
    /**
401
     * Gets the visible resource properties for the given resource type from the given resource set wrapper.
402
     *
403
     * @param ResourceSetWrapper $setWrapper   Resource set wrapper in question
404
     * @param ResourceType       $resourceType Resource type in question
405
     *
406
     * @return ResourceProperty[] Collection of visible resource properties from the given resource set wrapper
407
     *                            and resource type
408
     */
409
    public function getResourceProperties(ResourceSetWrapper $setWrapper, ResourceType $resourceType)
410
    {
411
        if (!$resourceType instanceof ResourceEntityType) {
412
            //Complex resource type
413
            return $resourceType->getAllProperties();
414
        }
415
        //TODO: move this to doctrine annotations
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
416
        $cacheKey = $setWrapper->getName() . '_' . $resourceType->getFullName();
417
        if (!array_key_exists($cacheKey, $this->propertyCache)) {
418
            //Fill the cache
419
            $this->propertyCache[$cacheKey] = [];
420
            foreach ($resourceType->getAllProperties() as $resourceProperty) {
421
                $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
422
            }
423
        }
424
425
        return $this->propertyCache[$cacheKey];
426
    }
427
428
    /**
429
     * Gets the target resource set wrapper for the given navigation property,
430
     * source resource set wrapper and the source resource type.
431
     *
432
     * @param ResourceSetWrapper $resourceSetWrapper         Source resource set
433
     * @param ResourceEntityType $resourceType               Source resource type
434
     * @param ResourceProperty   $navigationResourceProperty Navigation property
435
     *
436
     * @return ResourceSetWrapper|null Returns instance of ResourceSetWrapper
437
     *                                 (describes the entity set and associated configuration) for the
438
     *                                 given navigation property. returns NULL if resourceset for the
439
     *                                 navigation property is invisible or if metadata provider returns
440
     *                                 null resource association set
441
     */
442
    public function getResourceSetWrapperForNavigationProperty(
443
        ResourceSetWrapper $resourceSetWrapper,
444
        ResourceEntityType $resourceType,
445
        ResourceProperty $navigationResourceProperty
446
    ) {
447
        $associationSet = $this->getResourceAssociationSet(
448
            $resourceSetWrapper,
449
            $resourceType,
450
            $navigationResourceProperty
451
        );
452
453
        if (null !== $associationSet) {
454
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
455
                $resourceSetWrapper->getResourceSet(),
456
                $resourceType,
457
                $navigationResourceProperty
458
            );
459
460
            return $this->validateResourceSetAndWrapper(
461
                $relatedAssociationSetEnd->getResourceSet()
462
            );
463
        }
464
        return null;
465
    }
466
467
    /**
468
     * Gets the ResourceAssociationSet instance for the given source association end,
469
     * Note: Wrapper for IMetadataProvider::getResourceAssociationSet
470
     * method implementation.
471
     *
472
     * @param ResourceSet        $set      Resource set of the source association end
473
     * @param ResourceEntityType $type     Resource type of the source association end
474
     * @param ResourceProperty   $property Resource property of the source association end
475
     *
476
     * @throws ODataException
477
     * @return ResourceAssociationSet|null Returns ResourceAssociationSet for the source
478
     *                                     association end, NULL if no such
479
     *                                     association end or resource set in the
480
     *                                     other end of the association is invisible
481
     */
482
    public function getResourceAssociationSet(
483
        ResourceSet $set,
484
        ResourceEntityType $type,
485
        ResourceProperty $property
486
    ) {
487
        $type = $this->getResourceTypeWherePropertyIsDeclared($type, $property);
488
        // usage below requires $type to not be null - so kaboom as early as possible
489
        assert(null != $type, 'Resource type obtained from property must not be null.');
490
        assert($type instanceof ResourceEntityType);
0 ignored issues
show
Bug introduced by
The call to assert() has too few arguments starting with description. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

490
        /** @scrutinizer ignore-call */ 
491
        assert($type instanceof ResourceEntityType);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
491
492
        $associationSet = $this->getMetaProvider()->getResourceAssociationSet(
493
            $set,
494
            $type,
495
            $property
496
        );
497
        assert(
498
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
499
            'Retrieved resource association must be either null or an instance of ResourceAssociationSet'
500
        );
501
502
        if (null !== $associationSet) {
503
            $thisAssociationSetEnd = $associationSet->getResourceAssociationSetEnd(
504
                $set,
505
                $type,
506
                $property
507
            );
508
509
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
510
                $set,
511
                $type,
512
                $property
513
            );
514
515
            //If either $thisAssociationSetEnd and/or $relatedAssociationSetEnd
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
516
            //is null means the associationset we got from the IDSMP::getResourceAssociationSet is invalid.
517
518
            //Return null, if either AssociationSet's End1 or End2's resourceset name
519
            //doesn't match the name of resource set wrapper (param1) and resource type is not assignable
520
            //from given resource type (param2)
521
            if (null === $thisAssociationSetEnd || null === $relatedAssociationSetEnd) {
522
                throw new ODataException(
523
                    Messages::providersWrapperIDSMPGetResourceSetReturnsInvalidResourceSet(
524
                        $set->getName(),
525
                        $type->getFullName(),
526
                        $property->getName()
527
                    ),
528
                    500
529
                );
530
            }
531
532
            $relatedResourceSetWrapper = $this->validateResourceSetAndWrapper(
533
                $relatedAssociationSetEnd->getResourceSet()
534
            );
535
            if ($relatedResourceSetWrapper === null) {
536
                $associationSet = null;
537
            } else {
538
                $this->validateResourceType($thisAssociationSetEnd->getResourceType());
539
                $this->validateResourceType($relatedAssociationSetEnd->getResourceType());
540
            }
541
        }
542
        assert(
543
            null == $associationSet || $associationSet instanceof ResourceAssociationSet,
544
            'Retrieved resource assocation must be either null or an instance of ResourceAssociationSet'
545
        );
546
547
        return $associationSet;
548
    }
549
550
    /**
551
     * Gets the resource type on which the resource property is declared on,
552
     * If property is not declared in the given resource type, then this
553
     * function drill down to the inheritance hierarchy of the given resource
554
     * type to find out the base class in which the property is declared.
555
     *
556
     * @param ResourceType     $type     The resource type to start looking
557
     * @param ResourceProperty $property The resource property in question
558
     *
559
     * @return ResourceType|null Returns reference to the ResourceType on which
560
     *                           the $property is declared, NULL if
561
     *                           $property is not declared anywhere
562
     *                           in the inheritance hierarchy
563
     */
564
    private function getResourceTypeWherePropertyIsDeclared(ResourceType $type, ResourceProperty $property)
565
    {
566
        while (null !== $type) {
567
            if (null !== $type->resolvePropertyDeclaredOnThisType($property->getName())) {
568
                break;
569
            }
570
571
            $type = $type->getBaseType();
572
        }
573
574
        return $type;
575
    }
576
577
    /**
578
     * Wrapper function over _validateResourceSetAndGetWrapper function.
579
     *
580
     * @param ResourceSet $resourceSet see the comments of _validateResourceSetAndGetWrapper
581
     *
582
     * @return ResourceSetWrapper|null see the comments of _validateResourceSetAndGetWrapper
583
     */
584
    public function validateResourceSetAndGetWrapper(ResourceSet $resourceSet)
585
    {
586
        return $this->validateResourceSetAndWrapper($resourceSet);
587
    }
588
589
    /**
590
     * Gets the Edm Schema version compliance to the metadata.
591
     *
592
     * @return EdmSchemaVersion
593
     */
594
    public function getEdmSchemaVersion()
595
    {
596
        //The minimal schema version for custom provider is 1.1
597
        return EdmSchemaVersion::VERSION_1_DOT_1;
0 ignored issues
show
Bug Best Practice introduced by
The expression return POData\Providers\...ersion::VERSION_1_DOT_1 returns the type double which is incompatible with the documented return type POData\Providers\Metadata\EdmSchemaVersion.
Loading history...
598
    }
599
600
    /**
601
     * Gets the underlying custom expression provider, the end developer is
602
     * responsible for implementing IExpressionProvider if he choose for.
603
     *
604
     * @return IExpressionProvider Instance of IExpressionProvider implementation
605
     */
606
    public function getExpressionProvider()
607
    {
608
        return $this->getProviderWrapper()->getExpressionProvider();
609
    }
610
611
    /**
612
     * Indicates if the QueryProvider can handle ordered paging, this means respecting order, skip, and top parameters
613
     * If the query provider can not handle ordered paging, it must return the entire result set and POData will
614
     * perform the ordering and paging.
615
     *
616
     * @return bool True if the query provider can handle ordered paging, false if POData should perform the paging
617
     */
618
    public function handlesOrderedPaging()
619
    {
620
        return $this->getProviderWrapper()->handlesOrderedPaging();
621
    }
622
623
    /**
624
     * Gets collection of entities belongs to an entity set
625
     * IE: http://host/EntitySet
626
     *  http://host/EntitySet?$skip=10&$top=5&filter=Prop gt Value.
627
     *
628
     * @param QueryType                $queryType   Is this is a query for a count, entities, or entities-with-count
629
     * @param ResourceSet              $resourceSet The entity set containing the entities to fetch
630
     * @param FilterInfo|null          $filterInfo  The $filter parameter of the OData query.  NULL if none specified
631
     * @param null|InternalOrderByInfo $orderBy     sorted order if we want to get the data in some specific order
632
     * @param int|null                 $top         number of records which need to be retrieved
633
     * @param int|null                 $skip        number of records which need to be skipped
634
     * @param SkipTokenInfo|null       $skipToken   value indicating what records to skip
635
     * @param string[]|null            $eagerLoad   array of relations to eager load
636
     *
637
     * @return QueryResult
638
     */
639 View Code Duplication
    public function getResourceSet(
640
        QueryType $queryType,
641
        ResourceSet $resourceSet,
642
        FilterInfo $filterInfo = null,
643
        InternalOrderByInfo $orderBy = null,
644
        $top = null,
645
        $skip = null,
646
        SkipTokenInfo $skipToken = null,
647
        array $eagerLoad = null
648
    ) {
649
        return $this->getProviderWrapper()->getResourceSet(
650
            $queryType,
651
            $resourceSet,
652
            $filterInfo,
653
            $orderBy,
654
            $top,
655
            $skip,
656
            $skipToken,
657
            $eagerLoad
658
        );
659
    }
660
661
    /**
662
     * Gets an entity instance from an entity set identified by a key.
663
     *
664
     * @param ResourceSet   $resourceSet   The entity set containing the entity to fetch
665
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to fetch
666
     * @param string[]|null $eagerLoad     array of relations to eager load
667
     *
668
     * @return object|null Returns entity instance if found, else null
669
     */
670
    public function getResourceFromResourceSet(
671
        ResourceSet $resourceSet,
672
        KeyDescriptor $keyDescriptor,
673
        array $eagerLoad = null
674
    ) {
675
        return $this->getProviderWrapper()->getResourceFromResourceSet($resourceSet, $keyDescriptor, $eagerLoad);
676
    }
677
678
    /**
679
     * Puts an entity instance to entity set identified by a key.
680
     *
681
     * @param ResourceSet   $resourceSet   The entity set containing the entity to update
682
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to update
683
     * @param mixed         $data
684
     *
685
     * @return bool|null Returns result of executing query
686
     */
687
    public function putResource(
688
        ResourceSet $resourceSet,
689
        KeyDescriptor $keyDescriptor,
690
        $data
691
    ) {
692
        return $this->getProviderWrapper()->putResource(
693
            $resourceSet,
694
            $keyDescriptor,
695
            $data
696
        );
697
    }
698
699
    /**
700
     * Get related resource set for a resource.
701
     *
702
     * @param QueryType          $queryType         Indicates if this is a query for a count, entities, or entities
703
     *                                              with a count
704
     * @param ResourceSet        $sourceResourceSet The entity set containing the source entity
705
     * @param object             $sourceEntity      The source entity instance
706
     * @param ResourceSet        $targetResourceSet The resource set containing the target of the navigation property
707
     * @param ResourceProperty   $targetProperty    The navigation property to retrieve
708
     * @param FilterInfo|null    $filterInfo        Represents the $filter parameter of the OData query.
709
     *                                              NULL if no $filter specified
710
     * @param mixed|null         $orderBy           sorted order if we want to get the data in some specific order
711
     * @param int|null           $top               number of records which need to be retrieved
712
     * @param int|null           $skip              number of records which need to be skipped
713
     * @param SkipTokenInfo|null $skipToken         value indicating what records to skip
714
     *
715
     * @throws ODataException
716
     *
717
     * @return QueryResult
718
     */
719 View Code Duplication
    public function getRelatedResourceSet(
720
        QueryType $queryType,
721
        ResourceSet $sourceResourceSet,
722
        $sourceEntity,
723
        ResourceSet $targetResourceSet,
724
        ResourceProperty $targetProperty,
725
        FilterInfo $filterInfo = null,
726
        $orderBy = null,
727
        $top = null,
728
        $skip = null,
729
        SkipTokenInfo $skipToken = null
730
    ) {
731
        return $this->getProviderWrapper()->getRelatedResourceSet(
732
            $queryType,
733
            $sourceResourceSet,
734
            $sourceEntity,
735
            $targetResourceSet,
736
            $targetProperty,
737
            $filterInfo,
738
            $orderBy,
739
            $top,
740
            $skip,
741
            $skipToken
742
        );
743
    }
744
745
    /**
746
     * Gets a related entity instance from an entity set identified by a key.
747
     *
748
     * @param ResourceSet      $sourceResourceSet The entity set related to the entity to be fetched
749
     * @param object           $sourceEntity      The related entity instance
750
     * @param ResourceSet      $targetResourceSet The entity set from which entity needs to be fetched
751
     * @param ResourceProperty $targetProperty    The metadata of the target property
752
     * @param KeyDescriptor    $keyDescriptor     The key to identify the entity to be fetched
753
     *
754
     * @return object|null Returns entity instance if found, else null
755
     */
756
    public function getResourceFromRelatedResourceSet(
757
        ResourceSet $sourceResourceSet,
758
        $sourceEntity,
759
        ResourceSet $targetResourceSet,
760
        ResourceProperty $targetProperty,
761
        KeyDescriptor $keyDescriptor
762
    ) {
763
        return $this->getProviderWrapper()->getResourceFromRelatedResourceSet(
764
            $sourceResourceSet,
765
            $sourceEntity,
766
            $targetResourceSet,
767
            $targetProperty,
768
            $keyDescriptor
769
        );
770
    }
771
772
    /**
773
     * Get related resource for a resource.
774
     *
775
     * @param ResourceSet      $sourceResourceSet The source resource set
776
     * @param object           $sourceEntity      The source resource
777
     * @param ResourceSet      $targetResourceSet The resource set of the navigation
778
     *                                            property
779
     * @param ResourceProperty $targetProperty    The navigation property to be
780
     *                                            retrieved
781
     *
782
     * @return object|null The related resource if exists, else null
783
     */
784
    public function getRelatedResourceReference(
785
        ResourceSet $sourceResourceSet,
786
        $sourceEntity,
787
        ResourceSet $targetResourceSet,
788
        ResourceProperty $targetProperty
789
    ) {
790
        return $this->getProviderWrapper()->getRelatedResourceReference(
791
            $sourceResourceSet,
792
            $sourceEntity,
793
            $targetResourceSet,
794
            $targetProperty
795
        );
796
    }
797
798
    /**
799
     * Updates a resource.
800
     *
801
     * @param ResourceSet   $sourceResourceSet    The entity set containing the source entity
802
     * @param object        $sourceEntityInstance The source entity instance
803
     * @param KeyDescriptor $keyDescriptor        The key identifying the entity to fetch
804
     * @param object        $data                 the New data for the entity instance
805
     * @param bool          $shouldUpdate         Should undefined values be updated or reset to default
806
     *
807
     * @return object|null the new resource value if it is assignable, or throw exception for null
808
     */
809
    public function updateResource(
810
        ResourceSet $sourceResourceSet,
811
        $sourceEntityInstance,
812
        KeyDescriptor $keyDescriptor,
813
        $data,
814
        $shouldUpdate = false
815
    ) {
816
        return $this->getProviderWrapper()->updateResource(
817
            $sourceResourceSet,
818
            $sourceEntityInstance,
819
            $keyDescriptor,
820
            $data,
821
            $shouldUpdate
822
        );
823
    }
824
825
    /**
826
     * Delete resource from a resource set.
827
     *
828
     * @param ResourceSet $sourceResourceSet
829
     * @param object      $sourceEntityInstance
830
     *
831
     * @return bool true if resources successfully deleted, otherwise false
832
     */
833
    public function deleteResource(
834
        ResourceSet $sourceResourceSet,
835
        $sourceEntityInstance
836
    ) {
837
        return $this->getProviderWrapper()->deleteResource(
838
            $sourceResourceSet,
839
            $sourceEntityInstance
840
        );
841
    }
842
843
    /**
844
     * @param ResourceSet $resourceSet          The entity set containing the entity to fetch
845
     * @param object|null $sourceEntityInstance The source entity instance
846
     * @param object      $data                 the New data for the entity instance
847
     *
848
     * @return object|null returns the newly created model if successful, or null if model creation failed
849
     */
850
    public function createResourceforResourceSet(
851
        ResourceSet $resourceSet,
852
        $sourceEntityInstance,
853
        $data
854
    ) {
855
        return $this->getProviderWrapper()->createResourceforResourceSet(
856
            $resourceSet,
857
            $sourceEntityInstance,
858
            $data
859
        );
860
    }
861
862
    /**
863
     * Create multiple new resources in a resource set.
864
     * @param ResourceSet $sourceResourceSet The entity set containing the entity to fetch
865
     * @param object[]    $data              The new data for the entity instance
866
     *
867
     * @return object[]|null returns the newly created model if successful, or null if model creation failed
868
     */
869
    public function createBulkResourceforResourceSet(
870
        ResourceSet $sourceResourceSet,
871
        array $data
872
    ) {
873
        return $this->getProviderWrapper()->createBulkResourceforResourceSet(
874
            $sourceResourceSet,
875
            $data
876
        );
877
    }
878
879
    /**
880
     * Updates a group of resources in a resource set.
881
     *
882
     * @param ResourceSet     $sourceResourceSet    The entity set containing the source entity
883
     * @param object          $sourceEntityInstance The source entity instance
884
     * @param KeyDescriptor[] $keyDescriptor        The key identifying the entity to fetch
885
     * @param object[]        $data                 The new data for the entity instances
886
     * @param bool            $shouldUpdate         Should undefined values be updated or reset to default
887
     *
888
     * @return object[]|null the new resource value if it is assignable, or throw exception for null
889
     */
890
    public function updateBulkResource(
891
        ResourceSet $sourceResourceSet,
892
        $sourceEntityInstance,
893
        array $keyDescriptor,
894
        array $data,
895
        $shouldUpdate = false
896
    ) {
897
        return $this->getProviderWrapper()->updateBulkResource(
898
            $sourceResourceSet,
899
            $sourceEntityInstance,
900
            $keyDescriptor,
901
            $data,
902
            $shouldUpdate
903
        );
904
    }
905
906
    /**
907
     * Attaches child model to parent model.
908
     *
909
     * @param ResourceSet $sourceResourceSet
910
     * @param object      $sourceEntityInstance
911
     * @param ResourceSet $targetResourceSet
912
     * @param object      $targetEntityInstance
913
     * @param $navPropName
914
     *
915
     * @return bool
916
     */
917
    public function hookSingleModel(
918
        ResourceSet $sourceResourceSet,
919
        $sourceEntityInstance,
920
        ResourceSet $targetResourceSet,
921
        $targetEntityInstance,
922
        $navPropName
923
    ) {
924
        return $this->getProviderWrapper()->hookSingleModel(
925
            $sourceResourceSet,
926
            $sourceEntityInstance,
927
            $targetResourceSet,
928
            $targetEntityInstance,
929
            $navPropName
930
        );
931
    }
932
933
    /**
934
     * Removes child model from parent model.
935
     *
936
     * @param ResourceSet $sourceResourceSet
937
     * @param object      $sourceEntityInstance
938
     * @param ResourceSet $targetResourceSet
939
     * @param object      $targetEntityInstance
940
     * @param $navPropName
941
     *
942
     * @return bool
943
     */
944
    public function unhookSingleModel(
945
        ResourceSet $sourceResourceSet,
946
        $sourceEntityInstance,
947
        ResourceSet $targetResourceSet,
948
        $targetEntityInstance,
949
        $navPropName
950
    ) {
951
        return $this->getProviderWrapper()->unhookSingleModel(
952
            $sourceResourceSet,
953
            $sourceEntityInstance,
954
            $targetResourceSet,
955
            $targetEntityInstance,
956
            $navPropName
957
        );
958
    }
959
960
    /**
961
     * @return mixed
962
     */
963
    public function getMetadataXML()
964
    {
965
        return $this->getMetaProvider()->getXML();
0 ignored issues
show
Bug introduced by
The method getXML() does not exist on POData\Providers\Metadata\IMetadataProvider. Since it exists in all sub-types, consider adding an abstract or default implementation to POData\Providers\Metadata\IMetadataProvider. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

965
        return $this->getMetaProvider()->/** @scrutinizer ignore-call */ getXML();
Loading history...
966
    }
967
968
    /**
969
     * Start database transaction.
970
     *
971
     * @return void
972
     */
973
    public function startTransaction()
974
    {
975
        $this->getProviderWrapper()->startTransaction();
976
    }
977
978
    /**
979
     * Commit database transaction.
980
     *
981
     * @return void
982
     */
983
    public function commitTransaction()
984
    {
985
        $this->getProviderWrapper()->commitTransaction();
986
    }
987
988
    /**
989
     * Abort database transaction.
990
     *
991
     * @return void
992
     */
993
    public function rollBackTransaction()
994
    {
995
        $this->getProviderWrapper()->rollBackTransaction();
996
    }
997
}
998