150 lines
4.5 KiB
Python
150 lines
4.5 KiB
Python
#!/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 |