Esempio n. 1
0
def create_artist_engine(artist: dict, availability: dict):
    """
    Create an artist in ENGINE mode
    :param artist:          artist to create
    :param availability:    artist availability
    """
    success = False
    artist_name = artist["name"]
    try:
        new_artist = execute(artist_insert_sql(artist))
        if new_artist.rowcount > 0:
            # using raw sql so need to query to get new id
            new_artist = execute(
                id_name_by_unique_properties_sql(
                    *extract_unique_properties_engine(artist)))
            if new_artist.rowcount > 0:
                new_artist = new_artist.fetchone()
                artist_id = new_artist["id"]

                stmts = []
                # add genres
                for stmt in genre_changes_engine([], artist["genres"],
                                                 artist_id, _ARTIST_):
                    stmts.append(stmt)

                if is_available(availability):
                    stmts.append(
                        availability_insert_sql(artist_id, availability))

                execute_transaction(stmts)
                success = True
    except:
        print_exc_info()

    return success, artist_name
Esempio n. 2
0
def create_venue_engine(venue: dict):
    """
    Create an venue in ENGINE mode
    :param venue: venue to create
    """
    success = False
    venue_name = venue["name"]
    try:
        new_venue = execute(venue_insert_sql(venue))
        if new_venue.rowcount > 0:
            # using raw sql so need to query to get new id
            new_venue = execute(
                id_name_by_unique_properties_sql(*extract_unique_properties_engine(venue))
            )
            if new_venue.rowcount > 0:
                new_venue = new_venue.fetchone()
                venue_id = new_venue["id"]

                stmts = []
                # add genres
                for stmt in genre_changes_engine([], venue["genres"], venue_id, _VENUE_):
                    stmts.append(stmt)

                execute_transaction(stmts)
                success = True
    except:
        print_exc_info()

    return success, venue_name
Esempio n. 3
0
def availability_by_artist_engine(
        artist_id: int,
        from_date=datetime,
        as_type=EntityResult.DICT) -> Union[dict, None]:
    """
    Search for an artist's latest availability
    :param artist_id:  id of artist
    :param from_date:  filtering criterion
    :param as_type:    result
    """
    availability = None
    try:
        properties = [
            '"' + AVAILABILITY_TABLE + '".' + p
            for p in get_model_property_list(AVAILABILITY_TABLE)
        ]
        properties = ', '.join(properties)
        result = execute(
            f'SELECT {properties} FROM "{AVAILABILITY_TABLE}" '
            f'INNER JOIN "{ARTIST_TABLE}" '
            f'ON {_AVAILABILITY_.fq_column("artist_id")} = {_ARTIST_.fq_column("id")} '
            f'WHERE {_AVAILABILITY_.fq_column("artist_id")} = {artist_id} '
            f'AND {_AVAILABILITY_.fq_column("from_date")} < TIMESTAMP \'{from_date}\' '
            f'ORDER BY {_AVAILABILITY_.fq_column("from_date")} DESC, '
            f'{_AVAILABILITY_.fq_column("id")} DESC;')
        if result.rowcount == 0:
            availability = None
        else:
            entry = result.mappings().first()
            availability = {k: entry.get(k) for k in entry.keys()}
    except:
        print_exc_info()
        abort(HTTPStatus.INTERNAL_SERVER_ERROR.value)

    return availability
Esempio n. 4
0
def delete_artist_engine(artist_id: int) -> (bool, str):
    """
    Delete an artist in ENGINE mode
    :param artist_id: id of the artist to delete
    """
    success = False
    artist_name = None
    exists = False
    try:
        artist = execute(
            f'SELECT name from "{ARTIST_TABLE}" WHERE id = {artist_id};')
        if artist.rowcount != 0:
            exists = True
            artist_name = artist.mappings().first().get('name')

            # when an artist is deleted, need to delete availability, genres & shows as well to keep the db consistent
            execute_transaction([
                f'DELETE FROM "{AVAILABILITY_TABLE}" WHERE artist_id = {artist_id};',
                f'DELETE FROM "{SHOWS_TABLE}" WHERE artist_id = {artist_id};',
                f'DELETE FROM "{ARTIST_GENRES_TABLE}" WHERE artist_id = {artist_id};',
                f'DELETE FROM "{ARTIST_TABLE}" WHERE id = {artist_id};'
            ])
            success = True
    except:
        print_exc_info()

    if not exists:
        abort(HTTPStatus.NOT_FOUND.value)

    return success, artist_name
Esempio n. 5
0
def bookings_by_venue_engine(venue_id: int, query_date: datetime):
    """
    Search for a venue's bookings
    :param venue_id:   id of venue
    :param query_date: date filtering criterion
    """
    bookings = []
    try:
        sql = f'SELECT "{SHOWS_TABLE}".start_time, "{SHOWS_TABLE}".duration, "{ARTIST_TABLE}".name ' \
              f'FROM (("{SHOWS_TABLE}" ' \
              f'INNER JOIN "{VENUE_TABLE}" ON "{SHOWS_TABLE}".venue_id = "{VENUE_TABLE}".id) ' \
              f'INNER JOIN "{ARTIST_TABLE}" ON "{SHOWS_TABLE}".artist_id = "{ARTIST_TABLE}".id) ' \
              f'WHERE "{SHOWS_TABLE}".venue_id = {venue_id}'
        if query_date is not None:
            sql = f'{sql} AND DATE("{SHOWS_TABLE}".start_time) = \'{date_to_str(query_date)}\''
        else:
            sql = f'{sql} ORDER BY "{SHOWS_TABLE}".start_time'
        sql = sql + ';'

        bookings = execute(sql).fetchall()

    except:
        print_exc_info()
        abort(HTTPStatus.INTERNAL_SERVER_ERROR.value)

    # [{'start_time': ?, 'duration' ?, ...}, {}, ...] }
    return [{k: show[BOOKING_BY_VENUE_DICT[k]] for k, v in BOOKING_BY_VENUE_DICT.items()} for show in bookings]
Esempio n. 6
0
def delete_venue_engine(venue_id: int) -> (bool, str):
    """
    Delete a venue in ENGINE mode
    :param venue_id: id of the venue to delete
    """
    success = False
    venue_name = None
    exists = False
    try:
        venue = execute(f'SELECT name from "{VENUE_TABLE}" WHERE id = {venue_id};')
        if venue.rowcount != 0:
            exists = True
            venue_name = venue.mappings().first().get('name')

            # when an venue is deleted, need to delete genres & shows as well to keep the db consistent
            execute_transaction([
                f'DELETE FROM "{SHOWS_TABLE}" WHERE venue_id = {venue_id};',
                f'DELETE FROM "{VENUE_GENRES_TABLE}" WHERE venue_id = {venue_id};',
                f'DELETE FROM "{VENUE_TABLE}" WHERE id = {venue_id};'
            ])
            success = True
    except:
        print_exc_info()

    if not exists:
        abort(HTTPStatus.NOT_FOUND.value)

    return success, venue_name
Esempio n. 7
0
def artists_and_venues_engine():
    """
    Get artists and venues for show listing
    """
    artists = []
    venues = []
    try:
        artists = execute(f'SELECT id, name FROM "{ARTIST_TABLE}" ORDER BY name;') \
            .fetchall()
        artists = [(a["id"], a["name"]) for a in artists]
        venues = execute(f'SELECT id, name FROM "{VENUE_TABLE}" ORDER BY name;') \
            .fetchall()
        venues = [(a["id"], a["name"]) for a in venues]
    except:
        print_exc_info()

    return artists, venues
Esempio n. 8
0
def create_show_engine(show: dict):
    """
    Create an show in ENGINE mode
    :param show:   show to create
    """
    success = False
    try:
        new_show = execute(show_insert_sql(show))
        success = new_show.rowcount > 0
    except:
        print_exc_info()

    return success
Esempio n. 9
0
def venues_engine():
    """
    List all venues
    """
    venues = []
    try:
        cities_states = execute(f'SELECT DISTINCT state, city from "{VENUE_TABLE}";')
        for city_state in cities_states:
            city = city_state["city"]
            state = city_state["state"]
            venue_list = execute(
                f'SELECT DISTINCT id, name from "{VENUE_TABLE}" WHERE state = \'{state}\' AND city = \'{city}\';')
            venues.append({
                "state": state,
                "city": city,
                "venues": entity_shows_count(venue_list, _VENUE_)
            })
    except:
        print_exc_info()
        abort(HTTPStatus.INTERNAL_SERVER_ERROR.value)

    return venues
Esempio n. 10
0
def existing_artist_engine(name: str, city: str, state: str):
    """
    Check for existing artist
    :param name:    artist name
    :param city:    artist city
    :param state:   artist state
    :return: existing artist id and name, or None
    """
    artist_id = None
    artist_name = None
    try:
        existing = execute(id_name_by_unique_properties_sql(name, city, state))
        if existing.rowcount > 0:
            hit = existing.mappings().first()
            artist_id = hit.get('id')
            artist_name = hit.get('name')

    except:
        print_exc_info()

    return artist_id, artist_name
Esempio n. 11
0
def existing_venue_engine(name: str, address: str, city: str, state: str):
    """
    Check for existing venue
    :param name:    venue name
    :param address: venue address
    :param city:    venue city
    :param state:   venue state
    :return: existing venue id and name, or None
    """
    venue_id = None
    venue_name = None
    try:
        existing = execute(
            id_name_by_unique_properties_sql(name, address, city, state)
        )
        if existing.rowcount > 0:
            hit = existing.mappings().first()
            venue_id = hit.get('id')
            venue_name = hit.get('name')

    except:
        print_exc_info()

    return venue_id, venue_name
Esempio n. 12
0
def shows_engine(page: int, filterby: str, mode: str, form: FlaskForm,
                 search_term: str) -> dict:
    """
    List all shows
    :param page:         requested page of search results
    :param filterby:     results filter; one of 'all', 'previous' or 'upcoming'
    :param mode:         one of 'basic', 'advanced' or 'all'
    :param form:         form data for advanced search
    :param search_term:  search_term for basic search
    """
    shows_list = []
    pagination = Pagination(None, page, SHOWS_PER_PAGE, 0, shows_list)
    # advanced search on Venue & Artist, joining class clauses with 'and' and the result of those with 'or'
    # e.g. if have 'name' do same search on Venue & Artist and 'or' their results
    search = \
        SearchParams([_VENUE_, _ARTIST_], conjunction=[OR_CONJUNC, AND_CONJUNC],
                     genre_aliases=[None, _ALIAS_GENRE_TABLE_]).load_form(form)
    search.simple_search_term = search_term
    try:
        if filterby == FILTER_PREVIOUS:
            time_filter = f'"{SHOWS_TABLE}".start_time < \'{datetime_to_str(datetime.today())}\''
        elif filterby == FILTER_UPCOMING:
            time_filter = f'"{SHOWS_TABLE}".start_time > \'{datetime_to_str(datetime.today())}\''
        else:
            time_filter = None

        # get search terms and clauses for both Venue & Artist
        ncsg_search_clauses(mode, search)

        from_term = _GENRE_FROM_JOIN_ if search.searching_on[
            SP_GENRES] else _BASIC_FROM_JOIN_

        if len(search.clauses) > 0:
            search_filter = entity_search_clauses('', search,
                                                  entity_search_expression)
        else:
            search_filter = None

        filters = _combine_filters(search_filter, time_filter)

        # get total count
        sql = f'SELECT COUNT("{SHOWS_TABLE}".venue_id) FROM {from_term}{filters};'
        total = execute(sql).scalar()

        if total > 0:
            offset = SHOWS_PER_PAGE * (page - 1)
            if offset >= total:
                abort(HTTPStatus.BAD_REQUEST.value)
        else:
            offset = 0

        # get items for this request
        sql = f'SELECT {_FIELDS_LIST_} FROM {from_term}{filters} ' \
              f'ORDER BY "{SHOWS_TABLE}".start_time LIMIT {SHOWS_PER_PAGE} OFFSET {offset};'

        shows_list = execute(sql).fetchall()
        total = len(shows_list)

        pagination = Pagination(None, page, SHOWS_PER_PAGE, total, shows_list)
        shows_list = pagination.items

    except:
        print_exc_info()
        abort(HTTPStatus.INTERNAL_SERVER_ERROR.value)

    # [{'venue_id': ?, 'artist_id' ?, ...}, {}, ...] }
    data = [{
        k: show[v] if k != 'start_time' else show[v].isoformat()
        for k, v in SHOWS_DICT.items()
    } for show in shows_list]

    return {
        "count": pagination.total,
        "data": data,
        "search_term": ', '.join(search.search_terms),
        "mode": mode,
        "pagination": pagination
    }