43
43
PropertyNotFound ,
44
44
NotInstanceProperty ,
45
45
NotAbstractProperty ,
46
- InstanceNotFound )
46
+ InstanceNotFound ,
47
+ PageNotFound )
47
48
# from sqlalchemy.orm.session import Session
48
49
from sqlalchemy .orm .scoping import scoped_session
49
50
from typing import Dict , Optional , Any , List
@@ -514,19 +515,30 @@ def update(id_: str,
514
515
def get_collection (API_NAME : str ,
515
516
type_ : str ,
516
517
session : scoped_session ,
517
- path : str = None ) -> Dict [str ,
518
- Any ]:
518
+ paginate : bool ,
519
+ page_size : int ,
520
+ page : int = 1 ,
521
+ path : str = None ) -> Dict [str , Any ]:
519
522
"""Retrieve a type of collection from the database.
520
523
:param API_NAME: api name specified while starting server
521
524
:param type_: type of object to be updated
522
525
:param session: sqlalchemy scoped session
526
+ :param paginate: Enable/disable pagination
527
+ :param page_size: Number maximum elements showed in a page
528
+ :param page: page number
523
529
:param path: endpoint
524
- :return: response containing all the objects of that particular type_
530
+ :return: response containing a page of the objects of that particular type_
525
531
526
532
Raises:
527
- ClassNotFound: If `type_` does not represt a valid/defined RDFClass.
533
+ ClassNotFound: If `type_` does not represent a valid/defined RDFClass.
528
534
529
535
"""
536
+ # Check for valid page value
537
+ try :
538
+ page = int (page )
539
+ except ValueError :
540
+ raise PageNotFound (page )
541
+
530
542
if path is not None :
531
543
collection_template = {
532
544
"@id" : "/{}/{}/" .format (API_NAME , path ),
@@ -548,8 +560,13 @@ def get_collection(API_NAME: str,
548
560
raise ClassNotFound (type_ = type_ )
549
561
550
562
try :
551
- instances = session .query (Instance ).filter (
552
- Instance .type_ == rdf_class .id ).all ()
563
+ if paginate is True :
564
+ offset = (page - 1 ) * page_size
565
+ instances = session .query (Instance ).filter (
566
+ Instance .type_ == rdf_class .id ).limit (page_size ).offset (offset )
567
+ else :
568
+ instances = session .query (Instance ).filter (
569
+ Instance .type_ == rdf_class .id ).all ()
553
570
except NoResultFound :
554
571
instances = list ()
555
572
@@ -563,6 +580,37 @@ def get_collection(API_NAME: str,
563
580
object_template = {
564
581
"@id" : "/{}/{}Collection/{}" .format (API_NAME , type_ , instance_ .id ), "@type" : type_ }
565
582
collection_template ["members" ].append (object_template )
583
+
584
+ # If pagination is disabled then stop and return the collection template
585
+ if paginate is False :
586
+ return collection_template
587
+
588
+ number_of_instances = len (collection_template ["members" ])
589
+ # If we are on the first page and there are fewer elements than the
590
+ # page size then there is no need to make an extra DB call to get count
591
+ if page == 1 and number_of_instances < page_size :
592
+ total_items = number_of_instances
593
+ else :
594
+ total_items = session .query (Instance ).filter (
595
+ Instance .type_ == rdf_class .id ).count ()
596
+ collection_template ["totalItems" ] = total_items
597
+ # Calculate last page number
598
+ if total_items != 0 and total_items % page_size == 0 :
599
+ last = total_items // page_size
600
+ else :
601
+ last = total_items // page_size + 1
602
+ if page < 1 or page > last :
603
+ raise PageNotFound (str (page ))
604
+ collection_template ["view" ] = {
605
+ "@id" : "/{}/{}?page={}" .format (API_NAME , path , page ),
606
+ "@type" : "PartialCollectionView" ,
607
+ "first" : "/{}/{}?page=1" .format (API_NAME , path ),
608
+ "last" : "/{}/{}?page={}" .format (API_NAME , path , last )
609
+ }
610
+ if page != 1 :
611
+ collection_template ["view" ]["previous" ] = "/{}/{}?page={}" .format (API_NAME , path , page - 1 )
612
+ if page != last :
613
+ collection_template ["view" ]["next" ] = "/{}/{}?page={}" .format (API_NAME , path , page + 1 )
566
614
return collection_template
567
615
568
616
0 commit comments