#!/usr/bin/env python3 """Модуль для работы с авторами""" from db_utils import get_cursor def get_authors_by_prefix(prefix=''): """Возвращает авторов по префиксу фамилии""" conn, cur = get_cursor() if prefix: cur.execute(""" SELECT a.id, a.full_name, a.name_hash, COUNT(DISTINCT ba.book_id) as books_count FROM authors a LEFT JOIN book_authors ba ON ba.author_id = a.id WHERE a.last_name ILIKE %s GROUP BY a.id, a.full_name, a.name_hash ORDER BY a.last_name, a.first_name LIMIT 100 """, (prefix + '%',)) else: cur.execute(""" SELECT DISTINCT lower(substring(last_name, 1, 1)) as letter, COUNT(*) as cnt FROM authors WHERE last_name ~ '^[а-яА-Яa-zA-Z]' GROUP BY lower(substring(last_name, 1, 1)) ORDER BY letter """) result = cur.fetchall() conn.close() return result def get_author_prefixes(prefix=''): """Возвращает группировку по следующим буквам""" conn, cur = get_cursor() next_len = len(prefix) + 1 cur.execute(""" SELECT DISTINCT substring(last_name, %s, 1) as next_letter, COUNT(*) as cnt, MIN(last_name) as first_author, MAX(last_name) as last_author FROM authors WHERE last_name ILIKE %s GROUP BY substring(last_name, %s, 1) ORDER BY next_letter """, (next_len, prefix + '%', next_len)) result = cur.fetchall() conn.close() return result def get_author_by_hash(author_hash): """Возвращает автора по хешу""" conn, cur = get_cursor() cur.execute(""" SELECT id, full_name, last_name, first_name, middle_name, name_hash FROM authors WHERE name_hash = %s """, (author_hash,)) author = cur.fetchone() conn.close() return author def get_author_series(author_id): """Возвращает серии автора""" conn, cur = get_cursor() cur.execute(""" SELECT DISTINCT s.id, s.name, s.name_hash, COUNT(DISTINCT b.id) as books_count FROM series s JOIN books b ON b.series_id = s.id JOIN book_authors ba ON ba.book_id = b.id WHERE ba.author_id = %s GROUP BY s.id, s.name, s.name_hash ORDER BY s.name """, (author_id,)) series = cur.fetchall() conn.close() return series def get_author_books(author_id): """Возвращает книги автора (без серий)""" conn, cur = get_cursor() # Простой запрос без string_agg cur.execute(""" SELECT b.id, b.title, b.language, b.added_date, b.series_number, s.name as series_name, s.name_hash as series_hash FROM books b JOIN book_authors ba ON ba.book_id = b.id LEFT JOIN series s ON s.id = b.series_id WHERE ba.author_id = %s GROUP BY b.id, b.title, b.language, b.added_date, b.series_number, s.name, s.name_hash ORDER BY b.added_date DESC NULLS LAST """, (author_id,)) books = cur.fetchall() # Для каждой книги получаем количество авторов и соавторов for book in books: cur.execute(""" SELECT COUNT(*) as cnt FROM book_authors WHERE book_id = %s """, (book['id'],)) book['authors_count'] = cur.fetchone()['cnt'] cur.execute(""" SELECT string_agg(a.full_name, ', ' ORDER BY ba.position) as coauthors FROM book_authors ba JOIN authors a ON a.id = ba.author_id WHERE ba.book_id = %s """, (book['id'],)) book['coauthors'] = cur.fetchone()['coauthors'] conn.close() return books def get_series_books(series_id): """Возвращает все книги серии""" conn, cur = get_cursor() cur.execute(""" SELECT b.id, b.title, b.language, b.series_number, string_agg(DISTINCT a.full_name, ', ' ORDER BY ba.position) as authors FROM books b JOIN book_authors ba ON ba.book_id = b.id JOIN authors a ON a.id = ba.author_id WHERE b.series_id = %s GROUP BY b.id, b.title, b.language, b.series_number ORDER BY b.series_number """, (series_id,)) books = cur.fetchall() conn.close() return books