diff --git a/bouquins/bouquins.go b/bouquins/bouquins.go index 81a874c..fe89082 100644 --- a/bouquins/bouquins.go +++ b/bouquins/bouquins.go @@ -157,6 +157,11 @@ type BookModel struct { *BookFull } +type SeriesModel struct { + BouquinsModel + *SeriesFull +} + func (app *Bouquins) render(res http.ResponseWriter, tpl string, model interface{}) { err := app.Template.ExecuteTemplate(res, tpl, model) if err != nil { @@ -238,8 +243,32 @@ func (app *Bouquins) BooksPage(res http.ResponseWriter, req *http.Request) { app.render(res, TPL_BOOKS, model) } func (app *Bouquins) AuthorsPage(res http.ResponseWriter, req *http.Request) { + /* + if !strings.HasPrefix(req.URL.Path, URL_AUTHORS) { + // FIXME 404 + log.Fatalln("Invalid URL") + } + id, err := strconv.Atoi(req.URL.Path[len(URL_AUTHORS):]) + if err != nil { + // FIXME 404 + log.Fatalln(err) + } + */ app.render(res, TPL_AUTHORS, nil) } func (app *Bouquins) SeriesPage(res http.ResponseWriter, req *http.Request) { - app.render(res, TPL_SERIES, nil) + if !strings.HasPrefix(req.URL.Path, URL_SERIES) { + // FIXME 404 + log.Fatalln("Invalid URL") + } + id, err := strconv.Atoi(req.URL.Path[len(URL_SERIES):]) + if err != nil { + // FIXME 404 + log.Fatalln(err) + } + series, err := app.SeriesFull(int64(id)) + app.render(res, TPL_SERIES, &SeriesModel{ + *NewBouquinsModel(series.Name), + series, + }) } diff --git a/bouquins/db.go b/bouquins/db.go index 5900838..df925d5 100644 --- a/bouquins/db.go +++ b/bouquins/db.go @@ -17,8 +17,19 @@ const ( STMT_BOOKS_AUTHORS0 = `SELECT authors.id, authors.name, books_authors_link.book as book FROM authors, books_authors_link WHERE books_authors_link.author = authors.id AND books_authors_link.book IN ( SELECT id FROM books ` + STMT_SEARCH_TERM_BOOKS = " books.sort like ? " + + STMT_SERIES0 = `SELECT series.id, series.name, count(book) FROM series + LEFT OUTER JOIN books_series_link ON books_series_link.series = series.id + GROUP BY series.id ` + STMT_SERIES_AUTHORS0 = `SELECT DISTINCT authors.id, authors.name, books_series_link.series + FROM authors, books_authors_link, books_series_link + WHERE books_authors_link.book = books_series_link.book AND books_authors_link.author = authors.id + AND books_series_link.series IN ( SELECT id FROM series ` + STMT_SERIES_SEARCH = "SELECT series.id, series.name FROM series WHERE " + STMT_SEARCH_TERM_SERIES = " series.sort like ? " + STMT_WHERE = " WHERE " - STMT_SEARCH_TERM = " books.sort like ? " STMT_BOOL_AND = " AND " STMT_BOOL_OR = " OR " STMT_SEARCH_ORDER = " ORDER BY books.sort" @@ -53,36 +64,59 @@ const ( STMT_BOOKS_AUTHORS_TITLE_ASC = STMT_BOOKS_AUTHORS0 + "ORDER BY books.sort" + STMT_PAGE + ")" STMT_BOOKS_AUTHORS_TITLE_DESC = STMT_BOOKS_AUTHORS0 + "ORDER BY books.sort DESC" + STMT_PAGE + ")" + STMT_SERIES_ID_ASC = STMT_SERIES0 + " ORDER BY series.id" + STMT_PAGE + STMT_SERIES_ID_DESC = STMT_SERIES0 + " ORDER BY series.id DESC" + STMT_PAGE + STMT_SERIES_NAME_ASC = STMT_SERIES0 + " ORDER BY series.sort" + STMT_PAGE + STMT_SERIES_NAME_DESC = STMT_SERIES0 + " ORDER BY series.sort DESC" + STMT_PAGE + STMT_SERIES_AUTHORS_ID_ASC = STMT_SERIES_AUTHORS0 + " ORDER BY series.id" + STMT_PAGE + ")" + STMT_SERIES_AUTHORS_ID_DESC = STMT_SERIES_AUTHORS0 + " ORDER BY series.id DESC" + STMT_PAGE + ")" + STMT_SERIES_AUTHORS_NAME_ASC = STMT_SERIES_AUTHORS0 + " ORDER BY series.sort" + STMT_PAGE + ")" + STMT_SERIES_AUTHORS_NAME_DESC = STMT_SERIES_AUTHORS0 + " ORDER BY series.sort DESC" + STMT_PAGE + ")" + STMT_SERIE = "SELECT series.id, series.name FROM series WHERE series.id = ?" + STMT_SERIE_BOOKS = `SELECT books.id, title, series_index FROM books + LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book + WHERE books_series_link.series = ? ORDER BY series_index ASC` + STMT_SERIE_AUTHORS = `SELECT DISTINCT authors.id, authors.name + FROM authors, books_authors_link, books_series_link + WHERE books_authors_link.book = books_series_link.book AND books_authors_link.author = authors.id + AND books_series_link.series = ?` + DEF_LIM = 10 - BOOKS QueryType = iota - BOOKS_TAGS QueryType = iota - BOOKS_AUTHORS QueryType = iota - BOOK QueryType = iota - BOOK_TAGS QueryType = iota - BOOK_DATA QueryType = iota - BOOK_AUTHORS QueryType = iota - BOOKS_COUNT QueryType = iota + BOOKS QueryType = iota + BOOKS_TAGS QueryType = iota + BOOKS_AUTHORS QueryType = iota + BOOK QueryType = iota + BOOK_TAGS QueryType = iota + BOOK_DATA QueryType = iota + BOOK_AUTHORS QueryType = iota + BOOKS_COUNT QueryType = iota + SERIES QueryType = iota + SERIES_AUTHORS QueryType = iota + SERIES_BOOKS QueryType = iota ) var QUERIES = map[Query]string{ - Query{BOOKS, true, true}: STMT_BOOKS_TITLE_DESC, - Query{BOOKS, true, false}: STMT_BOOKS_TITLE_ASC, - Query{BOOKS, false, true}: STMT_BOOKS_ID_DESC, - Query{BOOKS, false, false}: STMT_BOOKS_ID_ASC, - Query{BOOKS_TAGS, true, true}: STMT_BOOKS_TAGS_TITLE_DESC, - Query{BOOKS_TAGS, true, false}: STMT_BOOKS_TAGS_TITLE_ASC, - Query{BOOKS_TAGS, false, true}: STMT_BOOKS_TAGS_ID_DESC, - Query{BOOKS_TAGS, false, false}: STMT_BOOKS_TAGS_ID_ASC, - Query{BOOKS_AUTHORS, true, true}: STMT_BOOKS_AUTHORS_TITLE_DESC, - Query{BOOKS_AUTHORS, true, false}: STMT_BOOKS_AUTHORS_TITLE_ASC, - Query{BOOKS_AUTHORS, false, true}: STMT_BOOKS_AUTHORS_ID_DESC, - Query{BOOKS_AUTHORS, false, false}: STMT_BOOKS_AUTHORS_ID_ASC, - Query{BOOK, false, false}: STMT_BOOK, - Query{BOOK_TAGS, false, false}: STMT_BOOK_TAGS, - Query{BOOK_DATA, false, false}: STMT_BOOK_DATA, - Query{BOOK_AUTHORS, false, false}: STMT_BOOK_AUTHORS, - Query{BOOKS_COUNT, false, false}: STMT_BOOKS_COUNT, + Query{BOOKS, true, true}: STMT_BOOKS_TITLE_DESC, + Query{BOOKS, true, false}: STMT_BOOKS_TITLE_ASC, + Query{BOOKS, false, true}: STMT_BOOKS_ID_DESC, + Query{BOOKS, false, false}: STMT_BOOKS_ID_ASC, + Query{BOOKS_TAGS, true, true}: STMT_BOOKS_TAGS_TITLE_DESC, + Query{BOOKS_TAGS, true, false}: STMT_BOOKS_TAGS_TITLE_ASC, + Query{BOOKS_TAGS, false, true}: STMT_BOOKS_TAGS_ID_DESC, + Query{BOOKS_TAGS, false, false}: STMT_BOOKS_TAGS_ID_ASC, + Query{BOOKS_AUTHORS, true, true}: STMT_BOOKS_AUTHORS_TITLE_DESC, + Query{BOOKS_AUTHORS, true, false}: STMT_BOOKS_AUTHORS_TITLE_ASC, + Query{BOOKS_AUTHORS, false, true}: STMT_BOOKS_AUTHORS_ID_DESC, + Query{BOOKS_AUTHORS, false, false}: STMT_BOOKS_AUTHORS_ID_ASC, + Query{BOOK, false, false}: STMT_BOOK, + Query{BOOK_TAGS, false, false}: STMT_BOOK_TAGS, + Query{BOOK_DATA, false, false}: STMT_BOOK_DATA, + Query{BOOK_AUTHORS, false, false}: STMT_BOOK_AUTHORS, + Query{BOOKS_COUNT, false, false}: STMT_BOOKS_COUNT, + Query{SERIES, false, false}: STMT_SERIE, + Query{SERIES_AUTHORS, false, false}: STMT_SERIE_AUTHORS, + Query{SERIES_BOOKS, false, false}: STMT_SERIE_BOOKS, } var STMTS = make(map[Query]*sql.Stmt) @@ -131,275 +165,3 @@ func (app *Bouquins) psSortBooks(qt QueryType, sort, order string) (*sql.Stmt, e func (app *Bouquins) ps(qt QueryType) (*sql.Stmt, error) { return app.psSortBooks(qt, "", "") } - -// MERGE SUB QUERIES // -func assignAuthorsTagsBooks(books []*BookAdv, authors map[int64][]*Author, tags map[int64][]string) { - for _, b := range books { - b.Authors = authors[b.Id] - b.Tags = tags[b.Id] - } -} - -// SUB QUERIES // - -func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookAdv, error) { - books := make([]*BookAdv, 0, limit) - stmt, err := app.psSortBooks(BOOKS, sort, order) - if err != nil { - return nil, err - } - rows, err := stmt.Query(limit, offset) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - book := new(BookAdv) - var series_name sql.NullString - var series_id sql.NullInt64 - if err := rows.Scan(&book.Id, &book.Title, &book.SeriesIndex, &series_name, &series_id); err != nil { - return nil, err - } - if series_name.Valid && series_id.Valid { - book.Series = &Series{ - series_id.Int64, - series_name.String, - } - } - books = append(books, book) - } - if err := rows.Err(); err != nil { - return nil, err - } - return books, nil -} - -func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) { - authors := make(map[int64][]*Author) - stmt, err := app.psSortBooks(BOOKS_AUTHORS, sort, order) - if err != nil { - return nil, err - } - rows, err := stmt.Query(limit, offset) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - author := new(Author) - var book int64 - if err := rows.Scan(&author.Id, &author.Name, &book); err != nil { - return nil, err - } - if authors[book] == nil { - authors[book] = append(make([]*Author, 0), author) - } else { - authors[book] = append(authors[book], author) - } - } - if err := rows.Err(); err != nil { - return nil, err - } - return authors, nil -} - -func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[int64][]string, error) { - stmt, err := app.psSortBooks(BOOKS_TAGS, sort, order) - if err != nil { - return nil, err - } - rows, err := stmt.Query(limit, offset) - if err != nil { - return nil, err - } - defer rows.Close() - tags := make(map[int64][]string) - for rows.Next() { - var tag string - var book int64 - if err := rows.Scan(&tag, &book); err != nil { - return nil, err - } - bookTags := tags[book] - if bookTags == nil { - bookTags = make([]string, 0) - tags[book] = bookTags - } - tags[book] = append(bookTags, tag) - } - if err := rows.Err(); err != nil { - return nil, err - } - return tags, nil -} -func (app *Bouquins) queryBook(id int64) (*BookFull, error) { - stmt, err := app.ps(BOOK) - if err != nil { - return nil, err - } - book := new(BookFull) - var seriesIdx sql.NullFloat64 - var seriesId, timestamp, pubdate sql.NullInt64 - var seriesName, isbn, lccn, uuid, lang, publisher sql.NullString - var cover sql.NullBool - err = stmt.QueryRow(id).Scan(&book.Id, &book.Title, &seriesIdx, &seriesName, &seriesId, - ×tamp, &pubdate, &isbn, &lccn, &book.Path, &uuid, &cover, &lang, &publisher) - if err != nil { - return nil, err - } - if seriesId.Valid && seriesName.Valid && seriesIdx.Valid { - book.SeriesIndex = seriesIdx.Float64 - book.Series = &Series{seriesId.Int64, seriesName.String} - } - if timestamp.Valid { - book.Timestamp = timestamp.Int64 - } - if pubdate.Valid { - book.Pubdate = pubdate.Int64 - } - if isbn.Valid { - book.Isbn = isbn.String - } - if lccn.Valid { - book.Lccn = lccn.String - } - if uuid.Valid { - book.Uuid = uuid.String - } - if lang.Valid { - book.Lang = lang.String - } - if publisher.Valid { - book.Publisher = publisher.String - } - if cover.Valid { - book.Has_cover = cover.Bool - } - return book, nil -} -func (app *Bouquins) queryBookTags(book *BookFull) error { - stmt, err := app.ps(BOOK_TAGS) - if err != nil { - return err - } - rows, err := stmt.Query(book.Id) - if err != nil { - return err - } - defer rows.Close() - for rows.Next() { - var tag string - if err = rows.Scan(&tag); err != nil { - return err - } - book.Tags = append(book.Tags, tag) - } - if err := rows.Err(); err != nil { - return err - } - return nil -} -func (app *Bouquins) queryBookData(book *BookFull) error { - stmt, err := app.ps(BOOK_DATA) - if err != nil { - return err - } - rows, err := stmt.Query(book.Id) - if err != nil { - return err - } - defer rows.Close() - for rows.Next() { - data := new(BookData) - if err = rows.Scan(&data.Name, &data.Format, &data.Size); err != nil { - return err - } - book.Data = append(book.Data, data) - } - if err := rows.Err(); err != nil { - return err - } - return nil -} -func (app *Bouquins) queryBookAuthors(book *BookFull) error { - stmt, err := app.ps(BOOK_AUTHORS) - if err != nil { - return err - } - rows, err := stmt.Query(book.Id) - if err != nil { - return err - } - defer rows.Close() - for rows.Next() { - author := new(Author) - var bookId int64 - if err = rows.Scan(&author.Id, &author.Name, &bookId); err != nil { - return err - } - book.Authors = append(book.Authors, author) - } - if err := rows.Err(); err != nil { - return err - } - return nil -} - -// DB LOADS // - -func (app *Bouquins) BookCount() (int64, error) { - var count int64 - stmt, err := app.ps(BOOKS_COUNT) - if err != nil { - return 0, err - } - row := stmt.QueryRow() - err = row.Scan(&count) - return count, err -} -func (app *Bouquins) SeriesAdv(limit, offset int, sort, order string) ([]*SeriesAdv, error) { - panic("not implemented") -} -func (app *Bouquins) AuthorsAdv(limit, offset int, sort, order string) ([]*AuthorAdv, error) { - panic("not implemented") -} - -func (app *Bouquins) BookFull(id int64) (*BookFull, error) { - book, err := app.queryBook(id) - if err != nil { - return nil, err - } - err = app.queryBookTags(book) - if err != nil { - return nil, err - } - err = app.queryBookAuthors(book) - if err != nil { - return nil, err - } - err = app.queryBookData(book) - if err != nil { - return nil, err - } - return book, nil -} - -func (app *Bouquins) BooksAdv(limit, offset int, sort, order string) ([]*BookAdv, error) { - if limit == 0 { - limit = DEF_LIM - } - books, err := app.queryBooks(limit, offset, sort, order) - if err != nil { - return nil, err - } - authors, err := app.queryBooksAuthors(limit, offset, sort, order) - if err != nil { - return nil, err - } - tags, err := app.queryBooksTags(limit, offset, sort, order) - if err != nil { - return nil, err - } - assignAuthorsTagsBooks(books, authors, tags) - return books, nil -} diff --git a/bouquins/dbbooks.go b/bouquins/dbbooks.go new file mode 100644 index 0000000..98ee34d --- /dev/null +++ b/bouquins/dbbooks.go @@ -0,0 +1,276 @@ +package bouquins + +import "database/sql" + +// MERGE SUB QUERIES // +func assignAuthorsTagsBooks(books []*BookAdv, authors map[int64][]*Author, tags map[int64][]string) { + for _, b := range books { + b.Authors = authors[b.Id] + b.Tags = tags[b.Id] + } +} + +// SUB QUERIES // + +func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookAdv, error) { + books := make([]*BookAdv, 0, limit) + stmt, err := app.psSortBooks(BOOKS, sort, order) + if err != nil { + return nil, err + } + rows, err := stmt.Query(limit, offset) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + book := new(BookAdv) + var series_name sql.NullString + var series_id sql.NullInt64 + if err := rows.Scan(&book.Id, &book.Title, &book.SeriesIndex, &series_name, &series_id); err != nil { + return nil, err + } + if series_name.Valid && series_id.Valid { + book.Series = &Series{ + series_id.Int64, + series_name.String, + } + } + books = append(books, book) + } + if err := rows.Err(); err != nil { + return nil, err + } + return books, nil +} + +func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) { + authors := make(map[int64][]*Author) + stmt, err := app.psSortBooks(BOOKS_AUTHORS, sort, order) + if err != nil { + return nil, err + } + rows, err := stmt.Query(limit, offset) + if err != nil { + return nil, err + } + defer rows.Close() + for rows.Next() { + author := new(Author) + var book int64 + if err := rows.Scan(&author.Id, &author.Name, &book); err != nil { + return nil, err + } + if authors[book] == nil { + authors[book] = append(make([]*Author, 0), author) + } else { + authors[book] = append(authors[book], author) + } + } + if err := rows.Err(); err != nil { + return nil, err + } + return authors, nil +} + +func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[int64][]string, error) { + stmt, err := app.psSortBooks(BOOKS_TAGS, sort, order) + if err != nil { + return nil, err + } + rows, err := stmt.Query(limit, offset) + if err != nil { + return nil, err + } + defer rows.Close() + tags := make(map[int64][]string) + for rows.Next() { + var tag string + var book int64 + if err := rows.Scan(&tag, &book); err != nil { + return nil, err + } + bookTags := tags[book] + if bookTags == nil { + bookTags = make([]string, 0) + tags[book] = bookTags + } + tags[book] = append(bookTags, tag) + } + if err := rows.Err(); err != nil { + return nil, err + } + return tags, nil +} + +func (app *Bouquins) queryBook(id int64) (*BookFull, error) { + stmt, err := app.ps(BOOK) + if err != nil { + return nil, err + } + book := new(BookFull) + var seriesIdx sql.NullFloat64 + var seriesId, timestamp, pubdate sql.NullInt64 + var seriesName, isbn, lccn, uuid, lang, publisher sql.NullString + var cover sql.NullBool + err = stmt.QueryRow(id).Scan(&book.Id, &book.Title, &seriesIdx, &seriesName, &seriesId, + ×tamp, &pubdate, &isbn, &lccn, &book.Path, &uuid, &cover, &lang, &publisher) + if err != nil { + return nil, err + } + if seriesId.Valid && seriesName.Valid && seriesIdx.Valid { + book.SeriesIndex = seriesIdx.Float64 + book.Series = &Series{seriesId.Int64, seriesName.String} + } + if timestamp.Valid { + book.Timestamp = timestamp.Int64 + } + if pubdate.Valid { + book.Pubdate = pubdate.Int64 + } + if isbn.Valid { + book.Isbn = isbn.String + } + if lccn.Valid { + book.Lccn = lccn.String + } + if uuid.Valid { + book.Uuid = uuid.String + } + if lang.Valid { + book.Lang = lang.String + } + if publisher.Valid { + book.Publisher = publisher.String + } + if cover.Valid { + book.Has_cover = cover.Bool + } + return book, nil +} +func (app *Bouquins) queryBookTags(book *BookFull) error { + stmt, err := app.ps(BOOK_TAGS) + if err != nil { + return err + } + rows, err := stmt.Query(book.Id) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + var tag string + if err = rows.Scan(&tag); err != nil { + return err + } + book.Tags = append(book.Tags, tag) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} +func (app *Bouquins) queryBookData(book *BookFull) error { + stmt, err := app.ps(BOOK_DATA) + if err != nil { + return err + } + rows, err := stmt.Query(book.Id) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + data := new(BookData) + if err = rows.Scan(&data.Name, &data.Format, &data.Size); err != nil { + return err + } + book.Data = append(book.Data, data) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} +func (app *Bouquins) queryBookAuthors(book *BookFull) error { + stmt, err := app.ps(BOOK_AUTHORS) + if err != nil { + return err + } + rows, err := stmt.Query(book.Id) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + author := new(Author) + var bookId int64 + if err = rows.Scan(&author.Id, &author.Name, &bookId); err != nil { + return err + } + book.Authors = append(book.Authors, author) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} + +// DB LOADS // + +func (app *Bouquins) BookCount() (int64, error) { + var count int64 + stmt, err := app.ps(BOOKS_COUNT) + if err != nil { + return 0, err + } + row := stmt.QueryRow() + err = row.Scan(&count) + return count, err +} +func (app *Bouquins) SeriesAdv(limit, offset int, sort, order string) ([]*SeriesAdv, error) { + panic("not implemented") +} +func (app *Bouquins) AuthorsAdv(limit, offset int, sort, order string) ([]*AuthorAdv, error) { + panic("not implemented") +} + +func (app *Bouquins) BookFull(id int64) (*BookFull, error) { + book, err := app.queryBook(id) + if err != nil { + return nil, err + } + err = app.queryBookTags(book) + if err != nil { + return nil, err + } + err = app.queryBookAuthors(book) + if err != nil { + return nil, err + } + err = app.queryBookData(book) + if err != nil { + return nil, err + } + return book, nil +} + +func (app *Bouquins) BooksAdv(limit, offset int, sort, order string) ([]*BookAdv, error) { + if limit == 0 { + limit = DEF_LIM + } + books, err := app.queryBooks(limit, offset, sort, order) + if err != nil { + return nil, err + } + authors, err := app.queryBooksAuthors(limit, offset, sort, order) + if err != nil { + return nil, err + } + tags, err := app.queryBooksTags(limit, offset, sort, order) + if err != nil { + return nil, err + } + assignAuthorsTagsBooks(books, authors, tags) + return books, nil +} diff --git a/bouquins/dbseries.go b/bouquins/dbseries.go new file mode 100644 index 0000000..33c6d2d --- /dev/null +++ b/bouquins/dbseries.go @@ -0,0 +1,75 @@ +package bouquins + +// SUB QUERIES // + +func (app *Bouquins) querySeries(id int64) (*SeriesFull, error) { + stmt, err := app.ps(SERIES) + if err != nil { + return nil, err + } + series := new(SeriesFull) + err = stmt.QueryRow(id).Scan(&series.Id, &series.Name) + return series, nil +} +func (app *Bouquins) querySeriesAuthors(series *SeriesFull) error { + stmt, err := app.ps(SERIES_AUTHORS) + if err != nil { + return err + } + rows, err := stmt.Query(series.Id) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + author := new(Author) + if err = rows.Scan(&author.Id, &author.Name); err != nil { + return err + } + series.Authors = append(series.Authors, author) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} +func (app *Bouquins) querySeriesBooks(series *SeriesFull) error { + stmt, err := app.ps(SERIES_BOOKS) + if err != nil { + return err + } + rows, err := stmt.Query(series.Id) + if err != nil { + return err + } + defer rows.Close() + for rows.Next() { + book := new(Book) + if err = rows.Scan(&book.Id, &book.Title, &book.SeriesIndex); err != nil { + return err + } + series.Books = append(series.Books, book) + } + if err := rows.Err(); err != nil { + return err + } + return nil +} + +// DB LOADS // + +func (app *Bouquins) SeriesFull(id int64) (*SeriesFull, error) { + series, err := app.querySeries(id) + if err != nil { + return nil, err + } + err = app.querySeriesBooks(series) + if err != nil { + return nil, err + } + err = app.querySeriesAuthors(series) + if err != nil { + return nil, err + } + return series, nil +} diff --git a/templates/header.html b/templates/header.html index 5164504..84e90e0 100644 --- a/templates/header.html +++ b/templates/header.html @@ -1,7 +1,7 @@ - Bouquins{{ if .Title }} - {{ .Title }}{{ end }} + {{ if .Title }}{{ .Title }} | {{ end }}Bouquins @@ -10,7 +10,7 @@