Example #1
0
    async def get(self, request, event_id, connection):
        """Returns an event."""

        # Prepare query
        query = (select([models.event.t]).select_from(
            models.event.t).where(models.event.t.c.id == event_id))

        # Compile query, execute and parse
        query, params = asyncpgsa.compile_query(query)
        try:
            try:
                row = await connection.fetchrow(query, *params)
            except PostgresError:
                raise exceptions.NotFetchedError

            if not row:
                raise exceptions.NotFoundError
        except exceptions.NotFoundError:
            return response.json(response_wrapper.error("Event not found"),
                                 status=404)

        event = models.event.json_format(models.event.t.parse(row))

        # Return the event
        return response.json(response_wrapper.ok(event))
Example #2
0
    async def put(self, request, event_id, session_id, tag_id, connection):
        """Adds tag to event session."""

        # Check, is session and tag exists
        for name, model, id in [("Session", models.session, session_id),
                                ("Tag", models.tag, tag_id)]:
            try:
                query = (select([model.t]).select_from(
                    model.t).where(model.t.c.id == id))
                query, params = asyncpgsa.compile_query(query)

                try:
                    row = await connection.fetchrow(query, *params)
                except PostgresError:
                    raise exceptions.NotFetchedError

                if not row:
                    raise exceptions.NotFoundError
            except exceptions.NotFoundError:
                return response.json(
                    response_wrapper.error(f"{name} not found"), status=404)

        # If all is ok, add tag to session
        query = (models.session_tag.t.insert().values(session_id=session_id,
                                                      tag_id=tag_id))

        # Compile query and execute
        query, params = asyncpgsa.compile_query(query)
        try:
            rows = await connection.execute(query, *params)
        except PostgresError:
            raise exceptions.NotCreatedError

        # Return the HTTP 204
        return response.text("", content_type="application/json", status=204)
Example #3
0
    async def post(self, request, event_id, connection):
        """Creates a new event person."""

        # Person form
        person = request.json

        # Check, is event exists
        try:
            query_event = (select([models.event.t]).select_from(
                models.event.t).where(
                    models.event.t.c.id == event_id).apply_labels())
            query_event, params = asyncpgsa.compile_query(query_event)

            try:
                row = await connection.fetchrow(query_event, *params)
            except PostgresError:
                raise exceptions.NotFetchedError

            if not row:
                raise exceptions.NotFoundError

            event = models.event.t.parse(row, prefix="events_")
        except exceptions.NotFoundError:
            return response.json(response_wrapper.error("Event not found"),
                                 status=404)

        # If event exists, create a transaction
        # We need to 1) save person, 2) fetch person from a database
        async with connection.transaction():
            try:
                query = (models.person.t.insert().values(
                    event_id=event["id"],
                    name=person["name"]).returning(models.person.t.c.id))
                query, params = asyncpgsa.compile_query(query)

                id = await connection.fetchval(query, *params)

                query = (select([models.person.t]).select_from(
                    models.person.t).where(
                        models.person.t.c.id == id).apply_labels())
                query, params = asyncpgsa.compile_query(query)

                try:
                    row = await connection.fetchrow(query, *params)
                except PostgresError:
                    raise exceptions.NotFetchedError

                if not row:
                    raise exceptions.NotFoundError

                person = models.person.json_format(
                    models.person.t.parse(row, prefix="persons_"))
            except (PostgresError, exceptions.DatabaseError):
                raise exceptions.NotCreatedError

        return response.json(response_wrapper.ok(person), status=201)
Example #4
0
    async def get(self, request, event_id, connection):
        """Returns a list of event locations."""

        # Check, is event exists
        try:
            query_event = (select([models.event.t])
                .select_from(models.event.t)
                .where(models.event.t.c.id == event_id)
                .apply_labels())
            query_event, params = asyncpgsa.compile_query(query_event)

            try:
                row = await connection.fetchrow(query_event, *params)
            except PostgresError:
                raise exceptions.NotFetchedError

            if not row:
                raise exceptions.NotFoundError

            event = models.event.t.parse(row, prefix="events_")
        except exceptions.NotFoundError:
            return response.json(
                response_wrapper.error("Event not found"),
                status=404)

        # If event exists, query all locations
        query = (select([models.location.t])
            .select_from(models.location.t)
            .where(models.location.t.c.event_id == event["id"])
            .order_by(models.location.t.c.name.asc())
            .order_by(models.location.t.c.id.desc())
            .apply_labels())

        # Compile query, execute and parse
        query, params = asyncpgsa.compile_query(query)
        try:
            rows = await connection.fetch(query, *params)
        except PostgresError:
            raise exceptions.NotFetchedError

        locations = [
            models.location.json_format(models.location.t.parse(row, prefix="locations_"))
            for row in rows
        ]

        # Return the list
        return response.json(response_wrapper.ok(locations))
Example #5
0
    async def get(self, request, connection):
        """Returns a list of platforms."""
        # Validate listing
        try:
            pivot, limit, direction = \
                self.default_listing.validate_from_request(request)
        except ValueError:
            return response.json(
                response_wrapper.error("Listing arguments error"), status=400)

        # Prepare query
        query = select([models.platform.t]).select_from(models.platform.t)

        # Adjust query according to listing options
        if pivot is not None:
            try:
                query_pivot = query.where(models.platform.t.c.id == pivot)
                query_pivot, params = asyncpgsa.compile_query(query_pivot)

                try:
                    row = await connection.fetchrow(query_pivot, *params)
                except PostgresError:
                    raise exceptions.NotFetchedError

                if not row:
                    raise exceptions.NotFoundError

                pivot = models.platform.t.parse(row)
            except exceptions.NotFoundError:
                return response.json(
                    response_wrapper.error("Pivot platform not found"),
                    status=400)

            if direction == listing.Direction.BEFORE:
                query = (
                    query.where((models.platform.t.c.slug < pivot["slug"])
                                | ((models.platform.t.c.slug == pivot["slug"])
                                   & (models.platform.t.c.id > pivot["id"]))))
            elif direction == listing.Direction.AFTER:
                query = (
                    query.where((models.platform.t.c.slug > pivot["slug"])
                                | ((models.platform.t.c.slug == pivot["slug"])
                                   & (models.platform.t.c.id < pivot["id"]))))

        # Apply sorting and limit
        if direction == listing.Direction.BEFORE:
            query = (query.order_by(models.platform.t.c.slug.desc()).order_by(
                models.platform.t.c.id.asc()).limit(limit))
        elif direction == listing.Direction.AFTER:
            query = (query.order_by(models.platform.t.c.slug.asc()).order_by(
                models.platform.t.c.id.desc()).limit(limit))

        # Compile query, execute and parse
        query, params = asyncpgsa.compile_query(query)
        try:
            rows = await connection.fetch(query, *params)
        except PostgresError:
            raise exceptions.NotFetchedError

        platforms = [
            models.platform.json_format(models.platform.t.parse(row))
            for row in rows
        ]

        if direction == listing.Direction.BEFORE:
            platforms.reverse()

        # Return the list
        return response.json(response_wrapper.ok(platforms))
Example #6
0
    async def get(self, request, event_id, connection):
        """Returns a list of event sessions aka schedule.

        This endpoint returns complete list, w/o support of listing.
        """

        # Check, is event exists
        try:
            query_event = (select([models.event.t]).select_from(
                models.event.t).where(
                    models.event.t.c.id == event_id).apply_labels())
            query_event, params = asyncpgsa.compile_query(query_event)

            try:
                row = await connection.fetchrow(query_event, *params)
            except PostgresError:
                raise exceptions.NotFetchedError

            if not row:
                raise exceptions.NotFoundError

            event = models.event.t.parse(row, prefix="events_")
        except exceptions.NotFoundError:
            return response.json(response_wrapper.error("Event not found"),
                                 status=404)

        # If event exists, query all sessions
        query = (select([models.session.t]).select_from(
            models.session.t).where(
                models.session.t.c.event_id == event["id"]).order_by(
                    models.session.t.c.start_time.asc()).order_by(
                        models.session.t.c.end_time.asc()).order_by(
                            models.session.t.c.created_at.asc()).order_by(
                                models.session.t.c.id.desc()).apply_labels())

        # Compile query, execute and parse
        query, params = asyncpgsa.compile_query(query)
        try:
            rows = await connection.fetch(query, *params)
        except PostgresError:
            raise exceptions.NotFetchedError

        sessions = [
            models.session.json_format(
                models.session.t.parse(row, prefix="sessions_"))
            for row in rows
        ]

        # Construct sessions map for fetching persons, locations and tags
        smap = {session["id"]: session for session in sessions}
        sids = list(smap.keys())

        # Query all persons, locations and tags ids for sessions
        # TODO: Optimizations
        for name, field, model in [
            ("persons", "person_id", models.session_person),
            ("locations", "location_id", models.session_location),
            ("tags", "tag_id", models.session_tag)
        ]:
            for session in sessions:
                session[name] = []

            query = (select([model.t]).select_from(model.t).where(
                model.t.c.session_id.in_(sids)))  # Probably, hot spot

            query, params = asyncpgsa.compile_query(query)
            try:
                rows = await connection.fetch(query, *params)
            except PostgresError:
                raise exceptions.NotFetchedError

            rows = [model.t.parse(row) for row in rows]
            for row in rows:
                smap[str(row["session_id"])][name].append(str(row[field]))

        # Return the list
        return response.json(response_wrapper.ok(sessions))