From e798f045f5272c881c7c0c77bb973fb7e3df6f6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Victor=20L=C3=B6fgren?= <viclo211@student.liu.se>
Date: Tue, 8 Jun 2021 17:30:07 +0200
Subject: [PATCH] Order competitions by year, users and regions by name

---
 server/app/apis/misc.py                  | 22 +++++++++++-----------
 server/app/database/__init__.py          | 10 +++++-----
 server/app/database/controller/get.py    | 23 ++++++++++++++---------
 server/app/database/controller/search.py | 15 +++++++--------
 4 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/server/app/apis/misc.py b/server/app/apis/misc.py
index 713a707d..31c295f6 100644
--- a/server/app/apis/misc.py
+++ b/server/app/apis/misc.py
@@ -36,7 +36,7 @@ class TypesResponseSchema(BaseSchema):
 class Types(MethodView):
     @blp.response(http_codes.OK, TypesResponseSchema)
     def get(self):
-        """ Gets a list of all types """
+        """Gets a list of all types"""
         return dict(
             media_types=dbc.get.all(MediaType),
             component_types=dbc.get.all(ComponentType),
@@ -50,7 +50,7 @@ class RoleList(MethodView):
     @blp.authorization(allowed_roles=ALL)
     @blp.response(http_codes.OK, RoleSchema(many=True))
     def get(self):
-        """ Gets a list of all roles. """
+        """Gets a list of all roles."""
         return dbc.get.all(Role)
 
 
@@ -66,16 +66,16 @@ class CitiesList(MethodView):
     @blp.authorization(allowed_roles=ALL)
     @blp.response(http_codes.OK, CitySchema(many=True))
     def get(self):
-        """ Gets a list of all cities. """
-        return dbc.get.all(City)
+        """Gets a list of all cities."""
+        return dbc.get.all(City, order_columns=(City.name,))
 
     @blp.authorization(allowed_roles=["Admin"])
     @blp.arguments(CitySchema)
     @blp.response(http_codes.OK, CitySchema(many=True))
     def post(self, args):
-        """ Posts the specified city. """
+        """Posts the specified city."""
         dbc.add.city(**args)
-        return dbc.get.all(City)
+        return dbc.get.all(City, order_columns=(City.name,))
 
 
 @blp.route("/cities/<city_id>")
@@ -88,9 +88,9 @@ class Cities(MethodView):
         http_codes.CONFLICT, ErrorSchema, description="The city can't be updated with the provided values"
     )
     def put(self, args, city_id):
-        """ Edits the specified city with the provided arguments. """
+        """Edits the specified city with the provided arguments."""
         dbc.edit.default(dbc.get.one(City, city_id), **args)
-        return dbc.get.all(City)
+        return dbc.get.all(City, order_columns=(City.name,))
 
     @blp.authorization(allowed_roles=["Admin"])
     @blp.response(http_codes.OK, CitySchema(many=True))
@@ -99,9 +99,9 @@ class Cities(MethodView):
         http_codes.CONFLICT, ErrorSchema, description="The city can't be updated with the provided values"
     )
     def delete(self, city_id):
-        """ Deletes the specified city. """
+        """Deletes the specified city."""
         dbc.delete.default(dbc.get.one(City, city_id))
-        return dbc.get.all(City)
+        return dbc.get.all(City, order_columns=(City.name,))
 
 
 class StatisticsResponseSchema(BaseSchema):
@@ -115,5 +115,5 @@ class Statistics(MethodView):
     @blp.authorization(allowed_roles=ALL)
     @blp.response(http_codes.OK, StatisticsResponseSchema)
     def get(self):
-        """ Gets statistics. """
+        """Gets statistics."""
         return {"users": User.query.count(), "competitions": Competition.query.count(), "regions": City.query.count()}
diff --git a/server/app/database/__init__.py b/server/app/database/__init__.py
index 4e6c7df6..4654647b 100644
--- a/server/app/database/__init__.py
+++ b/server/app/database/__init__.py
@@ -49,7 +49,7 @@ class ExtendedQuery(BaseQuery):
 
         return item
 
-    def paginate_api(self, pagination_parameters, order_column=None, order=1):
+    def paginate_api(self, pagination_parameters, order_columns=None):
         """
         When looking for lists of items this is used to only return a few of
         them to allow for pagination.
@@ -57,8 +57,8 @@ class ExtendedQuery(BaseQuery):
         :type page: int
         :param page_size: Amount of rows that will be retrieved from the query
         :type page_size: int
-        :param order_column: Field of a DbModel in which the query shall order by
-        :type order_column: sqlalchemy.sql.schema.Column
+        :param order_columns: Field of a DbModel in which the query shall order by
+        :type tuple: Tuple containting sqlalchemy.sql.schema.Column
         :param order: If equals 1 then order by ascending otherwise order by descending
         :type order: int
         :return: A page/list of items with offset page*page_size and the total count of all rows ignoring page and page_size
@@ -67,8 +67,8 @@ class ExtendedQuery(BaseQuery):
 
         pagination_parameters = pagination_parameters or PaginationParameters(page=1, page_size=10)
 
-        if order_column:
-            self = self.order_by(order_column if order == 1 else order_column.desc())
+        if order_columns:
+            self = self.order_by(*order_columns)
 
         pagination = self.paginate(page=pagination_parameters.page, per_page=pagination_parameters.page_size)
         pagination_parameters.item_count = pagination.total
diff --git a/server/app/database/controller/get.py b/server/app/database/controller/get.py
index bcaece40..17569ff8 100644
--- a/server/app/database/controller/get.py
+++ b/server/app/database/controller/get.py
@@ -24,21 +24,26 @@ from sqlalchemy.orm import joinedload, subqueryload
 from sqlalchemy.orm.util import with_polymorphic
 
 
-def all(db_type):
-    """ Gets a list of all lazy db-items in the provided table. """
+def all(db_type, order_columns=None):
+    """Gets a list of all lazy db-items in the provided table."""
 
-    return db_type.query.all()
+    query = db_type.query
+
+    if order_columns:
+        query = query.order_by(*order_columns)
+
+    return query.all()
 
 
 def one(db_type, id, required=True):
-    """ Get lazy db-item in the table that has the same id. """
+    """Get lazy db-item in the table that has the same id."""
 
     return db_type.query.filter(db_type.id == id).first_api(required=required)
 
 
 ### Codes ###
 def code_by_code(code):
-    """ Gets the code object associated with the provided code. """
+    """Gets the code object associated with the provided code."""
 
     return Code.query.filter(Code.code == code.upper()).first_api(True, "A presentation with that code does not exist")
 
@@ -56,13 +61,13 @@ def code_list(competition_id):
 
 ### Users ###
 def user_exists(email):
-    """ Checks if an user has that email. """
+    """Checks if an user has that email."""
 
     return dbc.utils.count(User, {"email": email}) > 0
 
 
 def user_by_email(email):
-    """ Gets the user object associated with the provided email. """
+    """Gets the user object associated with the provided email."""
     return User.query.filter(User.email == email).first_api()
 
 
@@ -91,7 +96,7 @@ def slide_list(competition_id):
 
 ### Teams ###
 def team(competition_id, team_id):
-    """ Gets the team object associated with the competition and team. """
+    """Gets the team object associated with the competition and team."""
 
     join_competition = Competition.id == Team.competition_id
     filters = (Competition.id == competition_id) & (Team.id == team_id)
@@ -297,7 +302,7 @@ def component_list(competition_id, slide_id):
 
 ### Competitions ###
 def competition(competition_id, required=True):
-    """ Get Competition and all it's sub-entities. """
+    """Get Competition and all it's sub-entities."""
 
     join_component = joinedload(Competition.slides).subqueryload(Slide.components)
     join_alternatives = joinedload(Competition.slides).joinedload(Slide.questions).joinedload(Question.alternatives)
diff --git a/server/app/database/controller/search.py b/server/app/database/controller/search.py
index 1be280e4..1a175e11 100644
--- a/server/app/database/controller/search.py
+++ b/server/app/database/controller/search.py
@@ -6,7 +6,7 @@ from app.database.models import Competition, Media, Question, Slide, User
 
 
 def image(pagination_parameters=None, filename=None, order=1, order_by=None):
-    """ Finds and returns an image from the file name. """
+    """Finds and returns an image from the file name."""
 
     query = Media.query.filter(Media.type_id == 1)
     if filename:
@@ -22,7 +22,7 @@ def user(
     city_id=None,
     role_id=None,
 ):
-    """ Finds and returns any number of users from the provided parameters. """
+    """Finds and returns any number of users from the provided parameters."""
 
     query = User.query
     if name:
@@ -34,7 +34,7 @@ def user(
     if role_id:
         query = query.filter(User.role_id == role_id)
 
-    return query.paginate_api(pagination_parameters)
+    return query.paginate_api(pagination_parameters, order_columns=(User.name,))
 
 
 def competition(
@@ -43,7 +43,7 @@ def competition(
     year=None,
     city_id=None,
 ):
-    """ Finds and returns a competition from the provided parameters. """
+    """Finds and returns a competition from the provided parameters."""
 
     query = Competition.query
     if name:
@@ -53,7 +53,7 @@ def competition(
     if city_id:
         query = query.filter(Competition.city_id == city_id)
 
-    return query.paginate_api(pagination_parameters)
+    return query.paginate_api(pagination_parameters, order_columns=(Competition.year.desc(), Competition.name))
 
 
 def slide(
@@ -62,9 +62,8 @@ def slide(
     title=None,
     body=None,
     competition_id=None,
-    order_by=None,
 ):
-    """ Finds and returns a slide from the provided parameters. """
+    """Finds and returns a slide from the provided parameters."""
 
     query = Slide.query
     if slide_order:
@@ -90,7 +89,7 @@ def questions(
     order=1,
     order_by=None,
 ):
-    """ Finds and returns a question from the provided parameters. """
+    """Finds and returns a question from the provided parameters."""
 
     query = Question.query
     if name:
-- 
GitLab