Code style (go vet, go lint)
This commit is contained in:
parent
0362051918
commit
2943d217a7
@ -16,93 +16,89 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
TPL_BOOKS = "book.html"
|
||||
TPL_AUTHORS = "author.html"
|
||||
TPL_SERIES = "series.html"
|
||||
TPL_INDEX = "index.html"
|
||||
TPL_SEARCH = "search.html"
|
||||
TPL_ABOUT = "about.html"
|
||||
tplBooks = "book.html"
|
||||
tplAuthors = "author.html"
|
||||
tplSeries = "series.html"
|
||||
tplIndex = "index.html"
|
||||
tplSearch = "search.html"
|
||||
tplAbout = "about.html"
|
||||
|
||||
PARAM_LIST = "list"
|
||||
PARAM_ORDER = "order"
|
||||
PARAM_SORT = "sort"
|
||||
PARAM_PAGE = "page"
|
||||
PARAM_PERPAGE = "perpage"
|
||||
PARAM_TERM = "term"
|
||||
pList = "list"
|
||||
pOrder = "order"
|
||||
pSort = "sort"
|
||||
pPage = "page"
|
||||
pPerPage = "perpage"
|
||||
pTerm = "term"
|
||||
|
||||
LIST_AUTHORS = "authors"
|
||||
LIST_SERIES = "series"
|
||||
LIST_BOOKS = "books"
|
||||
|
||||
URL_INDEX = "/"
|
||||
URL_BOOKS = "/books/"
|
||||
URL_AUTHORS = "/authors/"
|
||||
URL_SERIES = "/series/"
|
||||
URL_SEARCH = "/search/"
|
||||
URL_ABOUT = "/about/"
|
||||
URL_JS = "/js/"
|
||||
URL_CSS = "/css/"
|
||||
URL_FONTS = "/fonts/"
|
||||
URL_CALIBRE = "/calibre/"
|
||||
// URLIndex url of index page
|
||||
URLIndex = "/"
|
||||
// URLBooks url of books page
|
||||
URLBooks = "/books/"
|
||||
// URLAuthors url of authors page
|
||||
URLAuthors = "/authors/"
|
||||
// URLSeries url of series page
|
||||
URLSeries = "/series/"
|
||||
// URLSearch url of search page
|
||||
URLSearch = "/search/"
|
||||
// URLAbout url of about page
|
||||
URLAbout = "/about/"
|
||||
// URLJs url of js assets
|
||||
URLJs = "/js/"
|
||||
// URLCss url of css assets
|
||||
URLCss = "/css/"
|
||||
// URLFonts url of fonts assets
|
||||
URLFonts = "/fonts/"
|
||||
// URLCalibre url of calibre resources (covers, ebooks files)
|
||||
URLCalibre = "/calibre/"
|
||||
)
|
||||
|
||||
// Bouquins contains application common resources: templates, database
|
||||
type Bouquins struct {
|
||||
*template.Template
|
||||
*sql.DB
|
||||
Tpl *template.Template
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
/*
|
||||
* A book series.
|
||||
*/
|
||||
// Series is a book series.
|
||||
type Series struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* A book. Generic data.
|
||||
*/
|
||||
// Book contains basic data on book
|
||||
type Book struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
SeriesIndex float64 `json:"series_idx,omitempty"`
|
||||
Series *Series `json:"series,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* An author.
|
||||
*/
|
||||
// Author contains basic data on author
|
||||
type Author struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
ID int64 `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* Author and number of books.
|
||||
*/
|
||||
// AuthorAdv extends Author with number of books
|
||||
type AuthorAdv struct {
|
||||
Author
|
||||
Count int `json:"count,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* Downloadable book data.
|
||||
*/
|
||||
// BookData contains data for dowloadable book
|
||||
type BookData struct {
|
||||
Size int64 `json:"size,omitempty"`
|
||||
Format string `json:"format,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
/*
|
||||
* A book. Advanced data: authors, tags.
|
||||
*/
|
||||
// BookAdv extends Book with authors and tags
|
||||
type BookAdv struct {
|
||||
Book
|
||||
Authors []*Author `json:"authors,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// AuthorFull extends Author with books, series and co-authors
|
||||
type AuthorFull struct {
|
||||
Author
|
||||
Books []*Book `json:"books,omitempty"`
|
||||
@ -110,6 +106,7 @@ type AuthorFull struct {
|
||||
CoAuthors []*Author `json:"coauthors,omitempty"`
|
||||
}
|
||||
|
||||
// BookFull extends BookAdv with all available data
|
||||
type BookFull struct {
|
||||
BookAdv
|
||||
Data []*BookData `json:"data,omitempty"`
|
||||
@ -118,98 +115,111 @@ type BookFull struct {
|
||||
Isbn string `json:"isbn,omitempty"`
|
||||
Lccn string `json:"lccn,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Uuid string `json:"uuid,omitempty"`
|
||||
Has_cover bool `json:"has_cover,omitempty"`
|
||||
UUID string `json:"uuid,omitempty"`
|
||||
HasCover bool `json:"has_cover,omitempty"`
|
||||
Lang string `json:"lang,omitempty"`
|
||||
Publisher string `json:"publisher,omitempty"`
|
||||
}
|
||||
|
||||
// SeriesAdv extends Series with count of books and authors
|
||||
type SeriesAdv struct {
|
||||
Series
|
||||
Count int64 `json:"count,omitempty"`
|
||||
Authors []*Author `json:"authors,omitempty"`
|
||||
}
|
||||
|
||||
// SeriesFull extends SeriesAdv with related books
|
||||
type SeriesFull struct {
|
||||
SeriesAdv
|
||||
Books []*Book `json:"books,omitempty"`
|
||||
}
|
||||
|
||||
type BouquinsModel struct {
|
||||
// Model is basic page model
|
||||
type Model struct {
|
||||
Title string
|
||||
Page string
|
||||
}
|
||||
|
||||
// Constructor BouquinsModel
|
||||
func NewBouquinsModel(title, page string) *BouquinsModel {
|
||||
return &BouquinsModel{title, page}
|
||||
// NewModel constuctor for Model
|
||||
func NewModel(title, page string) *Model {
|
||||
return &Model{title, page}
|
||||
}
|
||||
|
||||
// IndexModel is the model for index page
|
||||
type IndexModel struct {
|
||||
BouquinsModel
|
||||
Model
|
||||
BooksCount int64 `json:"count"`
|
||||
}
|
||||
|
||||
// Constructor IndexModel
|
||||
// NewIndexModel constructor IndexModel
|
||||
func NewIndexModel(title string, count int64) *IndexModel {
|
||||
return &IndexModel{*NewBouquinsModel(title, "index"), count}
|
||||
return &IndexModel{*NewModel(title, "index"), count}
|
||||
}
|
||||
|
||||
type SearchModel struct {
|
||||
BouquinsModel
|
||||
}
|
||||
|
||||
func NewSearchModel() *SearchModel {
|
||||
return &SearchModel{*NewBouquinsModel("Recherche", "search")}
|
||||
// NewSearchModel constuctor for search page
|
||||
func NewSearchModel() *Model {
|
||||
return NewModel("Recherche", "search")
|
||||
}
|
||||
|
||||
// ResultsModel is a generic model for list pages
|
||||
type ResultsModel struct {
|
||||
Type string `json:"type,omitempty"`
|
||||
More bool `json:"more"`
|
||||
CountResults int `json:"count,omitempty"`
|
||||
}
|
||||
|
||||
// BooksResultsModel is the model for list of books
|
||||
type BooksResultsModel struct {
|
||||
ResultsModel
|
||||
Results []*BookAdv `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
// NewBooksResultsModel constuctor for BooksResultsModel
|
||||
func NewBooksResultsModel(books []*BookAdv, more bool, count int) *BooksResultsModel {
|
||||
return &BooksResultsModel{ResultsModel{"books", more, count}, books}
|
||||
}
|
||||
|
||||
// AuthorsResultsModel is the model for list of authors
|
||||
type AuthorsResultsModel struct {
|
||||
ResultsModel
|
||||
Results []*AuthorAdv `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
// NewAuthorsResultsModel constuctor for AuthorsResultsModel
|
||||
func NewAuthorsResultsModel(authors []*AuthorAdv, more bool, count int) *AuthorsResultsModel {
|
||||
return &AuthorsResultsModel{ResultsModel{"authors", more, count}, authors}
|
||||
}
|
||||
|
||||
// SeriesResultsModel is the model for list of series
|
||||
type SeriesResultsModel struct {
|
||||
ResultsModel
|
||||
Results []*SeriesAdv `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
// NewSeriesResultsModel constuctor for SeriesResultsModel
|
||||
func NewSeriesResultsModel(series []*SeriesAdv, more bool, count int) *SeriesResultsModel {
|
||||
return &SeriesResultsModel{ResultsModel{"series", more, count}, series}
|
||||
}
|
||||
|
||||
// BookModel is the model for single book page
|
||||
type BookModel struct {
|
||||
BouquinsModel
|
||||
Model
|
||||
*BookFull
|
||||
}
|
||||
|
||||
// SeriesModel is the model for single series page
|
||||
type SeriesModel struct {
|
||||
BouquinsModel
|
||||
Model
|
||||
*SeriesFull
|
||||
}
|
||||
|
||||
// AuthorModel is the model for single author page
|
||||
type AuthorModel struct {
|
||||
BouquinsModel
|
||||
Model
|
||||
*AuthorFull
|
||||
}
|
||||
|
||||
// ReqParams contains request parameters for searches and lists
|
||||
type ReqParams struct {
|
||||
Limit int
|
||||
Offset int
|
||||
@ -219,7 +229,7 @@ type ReqParams struct {
|
||||
AllWords bool
|
||||
}
|
||||
|
||||
// add functions to templates
|
||||
// TemplatesFunc adds functions to templates
|
||||
func TemplatesFunc() *template.Template {
|
||||
return template.New("").Funcs(template.FuncMap{
|
||||
"humanSize": func(sz int64) string {
|
||||
@ -237,18 +247,18 @@ func TemplatesFunc() *template.Template {
|
||||
|
||||
// output page with template
|
||||
func (app *Bouquins) render(res http.ResponseWriter, tpl string, model interface{}) error {
|
||||
return app.Template.ExecuteTemplate(res, tpl, model)
|
||||
return app.Tpl.ExecuteTemplate(res, tpl, model)
|
||||
}
|
||||
|
||||
// output as JSON
|
||||
func writeJson(res http.ResponseWriter, model interface{}) error {
|
||||
func writeJSON(res http.ResponseWriter, model interface{}) error {
|
||||
res.Header().Set("Content-Type", "application/json")
|
||||
enc := json.NewEncoder(res)
|
||||
return enc.Encode(model)
|
||||
}
|
||||
|
||||
// test if JSON requested
|
||||
func isJson(req *http.Request) bool {
|
||||
func isJSON(req *http.Request) bool {
|
||||
return req.Header.Get("Accept") == "application/json"
|
||||
}
|
||||
|
||||
@ -268,7 +278,7 @@ func paramInt(name string, req *http.Request) int {
|
||||
|
||||
// get order parameter
|
||||
func paramOrder(req *http.Request) string {
|
||||
val := req.URL.Query().Get(PARAM_ORDER)
|
||||
val := req.URL.Query().Get(pOrder)
|
||||
if val == "desc" || val == "asc" {
|
||||
return val
|
||||
}
|
||||
@ -277,23 +287,23 @@ func paramOrder(req *http.Request) string {
|
||||
|
||||
// get common request parameters
|
||||
func params(req *http.Request) *ReqParams {
|
||||
page, perpage := paramInt(PARAM_PAGE, req), paramInt(PARAM_PERPAGE, req)
|
||||
page, perpage := paramInt(pPage, req), paramInt(pPerPage, req)
|
||||
limit := perpage
|
||||
if perpage == 0 {
|
||||
limit = DEF_LIM
|
||||
limit = defaultLimit
|
||||
}
|
||||
offset := perpage * (page - 1)
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
sort := req.URL.Query().Get(PARAM_SORT)
|
||||
sort := req.URL.Query().Get(pSort)
|
||||
order := paramOrder(req)
|
||||
terms := req.URL.Query()[PARAM_TERM]
|
||||
terms := req.URL.Query()[pTerm]
|
||||
return &ReqParams{limit, offset, sort, order, terms, false}
|
||||
}
|
||||
|
||||
// single element or list elements page
|
||||
func listOrId(res http.ResponseWriter, req *http.Request, url string,
|
||||
func listOrID(res http.ResponseWriter, req *http.Request, url string,
|
||||
listFunc func(res http.ResponseWriter, req *http.Request) error,
|
||||
idFunc func(idParam string, res http.ResponseWriter, req *http.Request) error) error {
|
||||
if !strings.HasPrefix(req.URL.Path, url) {
|
||||
@ -308,40 +318,40 @@ func listOrId(res http.ResponseWriter, req *http.Request, url string,
|
||||
|
||||
// LIST ELEMENTS PAGES //
|
||||
|
||||
func (app *Bouquins) BooksListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJson(req) {
|
||||
func (app *Bouquins) booksListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJSON(req) {
|
||||
books, count, more, err := app.BooksAdv(params(req))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeJson(res, NewBooksResultsModel(books, more, count))
|
||||
return writeJSON(res, NewBooksResultsModel(books, more, count))
|
||||
}
|
||||
return errors.New("Invalid mime")
|
||||
}
|
||||
func (app *Bouquins) AuthorsListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJson(req) {
|
||||
func (app *Bouquins) authorsListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJSON(req) {
|
||||
authors, count, more, err := app.AuthorsAdv(params(req))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeJson(res, NewAuthorsResultsModel(authors, more, count))
|
||||
return writeJSON(res, NewAuthorsResultsModel(authors, more, count))
|
||||
}
|
||||
return errors.New("Invalid mime")
|
||||
}
|
||||
func (app *Bouquins) SeriesListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJson(req) {
|
||||
func (app *Bouquins) seriesListPage(res http.ResponseWriter, req *http.Request) error {
|
||||
if isJSON(req) {
|
||||
series, count, more, err := app.SeriesAdv(params(req))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeJson(res, NewSeriesResultsModel(series, more, count))
|
||||
return writeJSON(res, NewSeriesResultsModel(series, more, count))
|
||||
}
|
||||
return errors.New("Invalid mime")
|
||||
}
|
||||
|
||||
// SINGLE ELEMENT PAGES //
|
||||
|
||||
func (app *Bouquins) BookPage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
func (app *Bouquins) bookPage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
id, err := strconv.Atoi(idParam)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -350,9 +360,9 @@ func (app *Bouquins) BookPage(idParam string, res http.ResponseWriter, req *http
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return app.render(res, TPL_BOOKS, &BookModel{*NewBouquinsModel(book.Title, "book"), book})
|
||||
return app.render(res, tplBooks, &BookModel{*NewModel(book.Title, "book"), book})
|
||||
}
|
||||
func (app *Bouquins) AuthorPage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
func (app *Bouquins) authorPage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
id, err := strconv.Atoi(idParam)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -361,9 +371,9 @@ func (app *Bouquins) AuthorPage(idParam string, res http.ResponseWriter, req *ht
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return app.render(res, TPL_AUTHORS, &AuthorModel{*NewBouquinsModel(author.Name, "author"), author})
|
||||
return app.render(res, tplAuthors, &AuthorModel{*NewModel(author.Name, "author"), author})
|
||||
}
|
||||
func (app *Bouquins) SeriePage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
func (app *Bouquins) seriePage(idParam string, res http.ResponseWriter, req *http.Request) error {
|
||||
id, err := strconv.Atoi(idParam)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -372,34 +382,45 @@ func (app *Bouquins) SeriePage(idParam string, res http.ResponseWriter, req *htt
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return app.render(res, TPL_SERIES, &SeriesModel{*NewBouquinsModel(series.Name, "series"), series})
|
||||
return app.render(res, tplSeries, &SeriesModel{*NewModel(series.Name, "series"), series})
|
||||
}
|
||||
|
||||
// ROUTES //
|
||||
|
||||
// BooksPage displays a single books or a returns a list of books
|
||||
func (app *Bouquins) BooksPage(res http.ResponseWriter, req *http.Request) error {
|
||||
return listOrId(res, req, URL_BOOKS, app.BooksListPage, app.BookPage)
|
||||
return listOrID(res, req, URLBooks, app.booksListPage, app.bookPage)
|
||||
}
|
||||
|
||||
// AuthorsPage displays a single author or returns a list of authors
|
||||
func (app *Bouquins) AuthorsPage(res http.ResponseWriter, req *http.Request) error {
|
||||
return listOrId(res, req, URL_AUTHORS, app.AuthorsListPage, app.AuthorPage)
|
||||
return listOrID(res, req, URLAuthors, app.authorsListPage, app.authorPage)
|
||||
}
|
||||
|
||||
// SeriesPage displays a single series or returns a list of series
|
||||
func (app *Bouquins) SeriesPage(res http.ResponseWriter, req *http.Request) error {
|
||||
return listOrId(res, req, URL_SERIES, app.SeriesListPage, app.SeriePage)
|
||||
return listOrID(res, req, URLSeries, app.seriesListPage, app.seriePage)
|
||||
}
|
||||
|
||||
// SearchPage displays search form and results
|
||||
func (app *Bouquins) SearchPage(res http.ResponseWriter, req *http.Request) error {
|
||||
return app.render(res, TPL_SEARCH, NewSearchModel())
|
||||
return app.render(res, tplSearch, NewSearchModel())
|
||||
}
|
||||
|
||||
// AboutPage displays about page
|
||||
func (app *Bouquins) AboutPage(res http.ResponseWriter, req *http.Request) error {
|
||||
return app.render(res, TPL_ABOUT, NewBouquinsModel("A propos", "about"))
|
||||
return app.render(res, tplAbout, NewModel("A propos", "about"))
|
||||
}
|
||||
|
||||
// IndexPage displays index page: list of books/authors/series
|
||||
func (app *Bouquins) IndexPage(res http.ResponseWriter, req *http.Request) error {
|
||||
count, err := app.BookCount()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
model := NewIndexModel("", count)
|
||||
if isJson(req) {
|
||||
return writeJson(res, model)
|
||||
if isJSON(req) {
|
||||
return writeJSON(res, model)
|
||||
}
|
||||
return app.render(res, TPL_INDEX, model)
|
||||
return app.render(res, tplIndex, model)
|
||||
}
|
||||
|
236
bouquins/db.go
236
bouquins/db.go
@ -2,48 +2,47 @@ package bouquins
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
const (
|
||||
STMT_BOOKS0 = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||
sqlBooks0 = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||
FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book
|
||||
LEFT OUTER JOIN series ON series.id = books_series_link.series `
|
||||
STMT_BOOKS_TAGS0 = `SELECT name, books_tags_link.book as book FROM tags, books_tags_link
|
||||
sqlBooksTags0 = `SELECT name, books_tags_link.book as book FROM tags, books_tags_link
|
||||
WHERE tags.id = books_tags_link.tag AND books_tags_link.book IN ( SELECT id FROM books `
|
||||
STMT_BOOKS_AUTHORS0 = `SELECT authors.id, authors.name, books_authors_link.book as book
|
||||
sqlBooksAuthors0 = `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 ? "
|
||||
sqlBooksTerm = " books.sort like ? "
|
||||
|
||||
STMT_SERIES0 = `SELECT series.id, series.name, count(book) FROM series
|
||||
sqlSeries0 = `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
|
||||
sqlSeriesAuthors0 = `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 ? "
|
||||
sqlSeriesSearch = "SELECT series.id, series.name FROM series WHERE "
|
||||
sqlSeriesTerm = " series.sort like ? "
|
||||
|
||||
STMT_AUTHORS0 = `SELECT authors.id, authors.name, count(book) as count FROM authors, books_authors_link
|
||||
sqlAuthors0 = `SELECT authors.id, authors.name, count(book) as count FROM authors, books_authors_link
|
||||
WHERE authors.id = books_authors_link.author GROUP BY author `
|
||||
STMT_AUTHORS_SEARCH = "SELECT id, name FROM authors WHERE "
|
||||
STMT_SEARCH_TERM_AUTHOR = " sort like ? "
|
||||
sqlAuthorsSearch = "SELECT id, name FROM authors WHERE "
|
||||
sqlAuthorsTerm = " sort like ? "
|
||||
|
||||
STMT_PAGE = " LIMIT ? OFFSET ?"
|
||||
STMT_WHERE = " WHERE "
|
||||
STMT_BOOL_AND = " AND "
|
||||
STMT_BOOL_OR = " OR "
|
||||
sqlPage = " LIMIT ? OFFSET ?"
|
||||
sqlWhere = " WHERE "
|
||||
sqlAnd = " AND "
|
||||
sqlOr = " OR "
|
||||
|
||||
STMT_SEARCH_ORDER_BOOKS = " ORDER BY books.sort"
|
||||
STMT_SEARCH_ORDER_AUTHORS = " ORDER BY authors.sort"
|
||||
STMT_SEARCH_ORDER_SERIES = " ORDER BY series.sort"
|
||||
sqlBooksOrder = " ORDER BY books.sort"
|
||||
sqlAuthorsOrder = " ORDER BY authors.sort"
|
||||
sqlSeriesOrder = " ORDER BY series.sort"
|
||||
|
||||
STMT_BOOKS_COUNT = "SELECT count(id) FROM books"
|
||||
STMT_BOOK = `SELECT books.id AS id,title, series_index, series.name AS series_name, series.id AS series_id,
|
||||
sqlBooksCount = "SELECT count(id) FROM books"
|
||||
sqlBook = `SELECT books.id AS id,title, series_index, series.name AS series_name, series.id AS series_id,
|
||||
strftime('%s', timestamp), strftime('%Y', pubdate), isbn,lccn,path,uuid,has_cover,
|
||||
languages.lang_code, publishers.name AS pubname FROM books
|
||||
LEFT OUTER JOIN books_languages_link ON books_languages_link.book = books.id
|
||||
@ -54,118 +53,121 @@ const (
|
||||
LEFT OUTER JOIN books_publishers_link ON books.id = books_publishers_link.book
|
||||
LEFT OUTER JOIN publishers ON publishers.id = books_publishers_link.publisher
|
||||
WHERE books.id = ?`
|
||||
STMT_BOOK_TAGS = "SELECT name FROM tags, books_tags_link WHERE tags.id = books_tags_link.tag AND books_tags_link.book = ?"
|
||||
STMT_BOOK_AUTHORS = `SELECT authors.id, authors.name, books_authors_link.book as book
|
||||
sqlBookTags = "SELECT name FROM tags, books_tags_link WHERE tags.id = books_tags_link.tag AND books_tags_link.book = ?"
|
||||
sqlBookAuthors = `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 = ?`
|
||||
STMT_BOOK_DATA = "SELECT data.name, data.format, data.uncompressed_size FROM data WHERE data.book = ?"
|
||||
STMT_BOOKS_ID_ASC = STMT_BOOKS0 + " ORDER BY id" + STMT_PAGE
|
||||
STMT_BOOKS_ID_DESC = STMT_BOOKS0 + "ORDER BY id DESC" + STMT_PAGE
|
||||
STMT_BOOKS_TITLE_ASC = STMT_BOOKS0 + "ORDER BY books.sort" + STMT_PAGE
|
||||
STMT_BOOKS_TITLE_DESC = STMT_BOOKS0 + "ORDER BY books.sort DESC" + STMT_PAGE
|
||||
STMT_BOOKS_TAGS_ID_ASC = STMT_BOOKS_TAGS0 + "ORDER BY id" + STMT_PAGE + ")"
|
||||
STMT_BOOKS_TAGS_ID_DESC = STMT_BOOKS_TAGS0 + "ORDER BY id DESC" + STMT_PAGE + ")"
|
||||
STMT_BOOKS_TAGS_TITLE_ASC = STMT_BOOKS_TAGS0 + "ORDER BY books.sort" + STMT_PAGE + ")"
|
||||
STMT_BOOKS_TAGS_TITLE_DESC = STMT_BOOKS_TAGS0 + "ORDER BY books.sort DESC" + STMT_PAGE + ")"
|
||||
STMT_BOOKS_AUTHORS_ID_ASC = STMT_BOOKS_AUTHORS0 + "ORDER BY id" + STMT_PAGE + ")"
|
||||
STMT_BOOKS_AUTHORS_ID_DESC = STMT_BOOKS_AUTHORS0 + "ORDER BY id DESC" + STMT_PAGE + ")"
|
||||
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 + ")"
|
||||
sqlBookData = "SELECT data.name, data.format, data.uncompressed_size FROM data WHERE data.book = ?"
|
||||
sqlBooksIDAsc = sqlBooks0 + " ORDER BY id" + sqlPage
|
||||
sqlBooksIDDesc = sqlBooks0 + "ORDER BY id DESC" + sqlPage
|
||||
sqlBooksTitleAsc = sqlBooks0 + "ORDER BY books.sort" + sqlPage
|
||||
sqlBooksTitleDesc = sqlBooks0 + "ORDER BY books.sort DESC" + sqlPage
|
||||
sqlBooksTagsIDAsc = sqlBooksTags0 + "ORDER BY id" + sqlPage + ")"
|
||||
sqlBooksTagsIDDesc = sqlBooksTags0 + "ORDER BY id DESC" + sqlPage + ")"
|
||||
sqlBooksTagsTitleAsc = sqlBooksTags0 + "ORDER BY books.sort" + sqlPage + ")"
|
||||
sqlBooksTagsTitleDesc = sqlBooksTags0 + "ORDER BY books.sort DESC" + sqlPage + ")"
|
||||
sqlBooksAuthorsIDAsc = sqlBooksAuthors0 + "ORDER BY id" + sqlPage + ")"
|
||||
sqlBooksAuthorsIDDesc = sqlBooksAuthors0 + "ORDER BY id DESC" + sqlPage + ")"
|
||||
sqlBooksAuthorsTitleAsc = sqlBooksAuthors0 + "ORDER BY books.sort" + sqlPage + ")"
|
||||
sqlBooksAuthorsTitleDesc = sqlBooksAuthors0 + "ORDER BY books.sort DESC" + sqlPage + ")"
|
||||
|
||||
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
|
||||
sqlSeriesIDAsc = sqlSeries0 + " ORDER BY series.id" + sqlPage
|
||||
sqlSeriesIDDesc = sqlSeries0 + " ORDER BY series.id DESC" + sqlPage
|
||||
sqlSeriesNameAsc = sqlSeries0 + " ORDER BY series.sort" + sqlPage
|
||||
sqlSeriesNameDesc = sqlSeries0 + " ORDER BY series.sort DESC" + sqlPage
|
||||
sqlSeriesAuthorsIDAsc = sqlSeriesAuthors0 + " ORDER BY series.id" + sqlPage + ")"
|
||||
sqlSeriesAuthorsIDDesc = sqlSeriesAuthors0 + " ORDER BY series.id DESC" + sqlPage + ")"
|
||||
sqlSeriesAuthorsNameAsc = sqlSeriesAuthors0 + " ORDER BY series.sort" + sqlPage + ")"
|
||||
sqlSeriesAuthorsNameDesc = sqlSeriesAuthors0 + " ORDER BY series.sort DESC" + sqlPage + ")"
|
||||
sqlSerie = "SELECT series.id, series.name FROM series WHERE series.id = ?"
|
||||
sqlSerieBooks = `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
|
||||
sqlSerieAuthors = `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 = ?`
|
||||
|
||||
STMT_AUTHORS_ID_ASC = STMT_AUTHORS0 + "ORDER BY authors.id " + STMT_PAGE
|
||||
STMT_AUTHORS_ID_DESC = STMT_AUTHORS0 + "ORDER BY authors.id DESC " + STMT_PAGE
|
||||
STMT_AUTHORS_NAME_ASC = STMT_AUTHORS0 + "ORDER BY authors.sort " + STMT_PAGE
|
||||
STMT_AUTHORS_NAME_DESC = STMT_AUTHORS0 + "ORDER BY authors.sort DESC " + STMT_PAGE
|
||||
STMT_AUTHOR_BOOKS = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||
sqlAuthorsIDAsc = sqlAuthors0 + "ORDER BY authors.id " + sqlPage
|
||||
sqlAuthorsIDDesc = sqlAuthors0 + "ORDER BY authors.id DESC " + sqlPage
|
||||
sqlAuthorsNameAsc = sqlAuthors0 + "ORDER BY authors.sort " + sqlPage
|
||||
sqlAuthorsNameDesc = sqlAuthors0 + "ORDER BY authors.sort DESC " + sqlPage
|
||||
sqlAuthorBooks = `SELECT books.id AS id,title,series_index,name as series_name,series.id AS series_id
|
||||
FROM books LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book
|
||||
LEFT OUTER JOIN series ON series.id = books_series_link.series
|
||||
LEFT OUTER JOIN books_authors_link ON books.id = books_authors_link.book
|
||||
WHERE books_authors_link.author = ? ORDER BY id`
|
||||
STMT_AUTHOR_AUTHORS = `SELECT DISTINCT authors.id, authors.name
|
||||
sqlAuthorAuthors = `SELECT DISTINCT authors.id, authors.name
|
||||
FROM authors, books_authors_link WHERE books_authors_link.author = authors.id
|
||||
AND books_authors_link.book IN ( SELECT books.id FROM books LEFT OUTER JOIN books_authors_link
|
||||
ON books.id = books_authors_link.book WHERE books_authors_link.author = ? ORDER BY books.id)
|
||||
AND authors.id != ? ORDER BY authors.id`
|
||||
STMT_AUTHOR = "SELECT name FROM authors WHERE id = ?"
|
||||
sqlAuthor = "SELECT name FROM authors WHERE id = ?"
|
||||
|
||||
DEF_LIM = 10
|
||||
defaultLimit = 10
|
||||
|
||||
BOOKS QueryType = iota
|
||||
BOOKS_TAGS
|
||||
BOOKS_AUTHORS
|
||||
BOOK
|
||||
BOOK_TAGS
|
||||
BOOK_DATA
|
||||
BOOK_AUTHORS
|
||||
BOOKS_COUNT
|
||||
SERIE
|
||||
SERIES
|
||||
SERIES_AUTHORS
|
||||
SERIE_AUTHORS
|
||||
SERIE_BOOKS
|
||||
AUTHORS
|
||||
AUTHOR
|
||||
AUTHOR_BOOKS
|
||||
AUTHOR_COAUTHORS
|
||||
qtBook QueryType = iota
|
||||
qtBookTags
|
||||
qtBookData
|
||||
qtBookAuthors
|
||||
qtBookCount
|
||||
qtBooks
|
||||
qtBooksTags
|
||||
qtBooksAuthors
|
||||
qtSerie
|
||||
qtSerieAuthors
|
||||
qtSerieBooks
|
||||
qtSeries
|
||||
qtSeriesAuthors
|
||||
qtAuthor
|
||||
qtAuthorBooks
|
||||
qtAuthorCoauthors
|
||||
qtAuthors
|
||||
)
|
||||
|
||||
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{SERIE, false, false}: STMT_SERIE,
|
||||
Query{SERIES, true, true}: STMT_SERIES_NAME_DESC,
|
||||
Query{SERIES, true, false}: STMT_SERIES_NAME_ASC,
|
||||
Query{SERIES, false, true}: STMT_SERIES_ID_DESC,
|
||||
Query{SERIES, false, false}: STMT_SERIES_ID_ASC,
|
||||
Query{SERIES_AUTHORS, true, true}: STMT_SERIES_AUTHORS_NAME_DESC,
|
||||
Query{SERIES_AUTHORS, true, false}: STMT_SERIES_AUTHORS_NAME_ASC,
|
||||
Query{SERIES_AUTHORS, false, true}: STMT_SERIES_AUTHORS_ID_DESC,
|
||||
Query{SERIES_AUTHORS, false, false}: STMT_SERIES_AUTHORS_ID_ASC,
|
||||
Query{SERIE_AUTHORS, false, false}: STMT_SERIE_AUTHORS,
|
||||
Query{SERIE_BOOKS, false, false}: STMT_SERIE_BOOKS,
|
||||
Query{AUTHORS, true, true}: STMT_AUTHORS_NAME_DESC,
|
||||
Query{AUTHORS, true, false}: STMT_AUTHORS_NAME_ASC,
|
||||
Query{AUTHORS, false, true}: STMT_AUTHORS_ID_DESC,
|
||||
Query{AUTHORS, false, false}: STMT_AUTHORS_ID_ASC,
|
||||
Query{AUTHOR, false, false}: STMT_AUTHOR,
|
||||
Query{AUTHOR_BOOKS, false, false}: STMT_AUTHOR_BOOKS,
|
||||
Query{AUTHOR_COAUTHORS, false, false}: STMT_AUTHOR_AUTHORS,
|
||||
var queries = map[Query]string{
|
||||
Query{qtBooks, true, true}: sqlBooksTitleDesc,
|
||||
Query{qtBooks, true, false}: sqlBooksTitleAsc,
|
||||
Query{qtBooks, false, true}: sqlBooksIDDesc,
|
||||
Query{qtBooks, false, false}: sqlBooksIDAsc,
|
||||
Query{qtBooksTags, true, true}: sqlBooksTagsTitleDesc,
|
||||
Query{qtBooksTags, true, false}: sqlBooksTagsTitleAsc,
|
||||
Query{qtBooksTags, false, true}: sqlBooksTagsIDDesc,
|
||||
Query{qtBooksTags, false, false}: sqlBooksTagsIDAsc,
|
||||
Query{qtBooksAuthors, true, true}: sqlBooksAuthorsTitleDesc,
|
||||
Query{qtBooksAuthors, true, false}: sqlBooksAuthorsTitleAsc,
|
||||
Query{qtBooksAuthors, false, true}: sqlBooksAuthorsIDDesc,
|
||||
Query{qtBooksAuthors, false, false}: sqlBooksAuthorsIDAsc,
|
||||
Query{qtBook, false, false}: sqlBook,
|
||||
Query{qtBookTags, false, false}: sqlBookTags,
|
||||
Query{qtBookData, false, false}: sqlBookData,
|
||||
Query{qtBookAuthors, false, false}: sqlBookAuthors,
|
||||
Query{qtBookCount, false, false}: sqlBooksCount,
|
||||
Query{qtSerie, false, false}: sqlSerie,
|
||||
Query{qtSeries, true, true}: sqlSeriesNameDesc,
|
||||
Query{qtSeries, true, false}: sqlSeriesNameAsc,
|
||||
Query{qtSeries, false, true}: sqlSeriesIDDesc,
|
||||
Query{qtSeries, false, false}: sqlSeriesIDAsc,
|
||||
Query{qtSeriesAuthors, true, true}: sqlSeriesAuthorsNameDesc,
|
||||
Query{qtSeriesAuthors, true, false}: sqlSeriesAuthorsNameAsc,
|
||||
Query{qtSeriesAuthors, false, true}: sqlSeriesAuthorsIDDesc,
|
||||
Query{qtSeriesAuthors, false, false}: sqlSeriesAuthorsIDAsc,
|
||||
Query{qtSerieAuthors, false, false}: sqlSerieAuthors,
|
||||
Query{qtSerieBooks, false, false}: sqlSerieBooks,
|
||||
Query{qtAuthors, true, true}: sqlAuthorsNameDesc,
|
||||
Query{qtAuthors, true, false}: sqlAuthorsNameAsc,
|
||||
Query{qtAuthors, false, true}: sqlAuthorsIDDesc,
|
||||
Query{qtAuthors, false, false}: sqlAuthorsIDAsc,
|
||||
Query{qtAuthor, false, false}: sqlAuthor,
|
||||
Query{qtAuthorBooks, false, false}: sqlAuthorBooks,
|
||||
Query{qtAuthorCoauthors, false, false}: sqlAuthorAuthors,
|
||||
}
|
||||
var STMTS = make(map[Query]*sql.Stmt)
|
||||
var stmts = make(map[Query]*sql.Stmt)
|
||||
|
||||
// QueryType is a type of query, with variants for sort and order
|
||||
type QueryType uint
|
||||
|
||||
// Query is a key for SQL queries catalog
|
||||
type Query struct {
|
||||
Type QueryType
|
||||
SortField bool // sort by name or title
|
||||
@ -179,10 +181,10 @@ func (app *Bouquins) searchHelper(all bool, terms []string, stub, termExpr, orde
|
||||
queryTerms = append(queryTerms, "%"+term+"%")
|
||||
query += termExpr
|
||||
if i < len(terms)-1 && all {
|
||||
query += STMT_BOOL_AND
|
||||
query += sqlAnd
|
||||
}
|
||||
if i < len(terms)-1 && !all {
|
||||
query += STMT_BOOL_OR
|
||||
query += sqlOr
|
||||
}
|
||||
}
|
||||
query += orderExpr
|
||||
@ -200,18 +202,20 @@ func (app *Bouquins) searchHelper(all bool, terms []string, stub, termExpr, orde
|
||||
}
|
||||
|
||||
// PREPARED STATEMENTS //
|
||||
|
||||
// PrepareAll prepares statement for (almost) all queries
|
||||
func (app *Bouquins) PrepareAll() error {
|
||||
errcount := 0
|
||||
for q, v := range QUERIES {
|
||||
for q, v := range queries {
|
||||
stmt, err := app.DB.Prepare(v)
|
||||
if err != nil {
|
||||
log.Println(err, v)
|
||||
errcount++
|
||||
}
|
||||
STMTS[q] = stmt
|
||||
stmts[q] = stmt
|
||||
}
|
||||
if errcount > 0 {
|
||||
return errors.New(fmt.Sprintf("%d errors on queries, see logs", errcount))
|
||||
return fmt.Errorf("%d errors on queries, see logs", errcount)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -228,9 +232,9 @@ func (app *Bouquins) psSortSeries(qt QueryType, sort, order string) (*sql.Stmt,
|
||||
}
|
||||
func (app *Bouquins) psSort(sortNameField string, qt QueryType, sort, order string) (*sql.Stmt, error) {
|
||||
q := Query{qt, sort == sortNameField, order == "desc"}
|
||||
query := QUERIES[q]
|
||||
query := queries[q]
|
||||
log.Println(query)
|
||||
stmt := STMTS[q]
|
||||
stmt := stmts[q]
|
||||
if stmt == nil {
|
||||
log.Println("Missing statement for ", q)
|
||||
var err error
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
// SUB QUERIES //
|
||||
|
||||
func (app *Bouquins) searchAuthors(limit int, terms []string, all bool) ([]*AuthorAdv, int, error) {
|
||||
rows, err := app.searchHelper(all, terms, STMT_AUTHORS_SEARCH, STMT_SEARCH_TERM_AUTHOR, STMT_SEARCH_ORDER_AUTHORS)
|
||||
rows, err := app.searchHelper(all, terms, sqlAuthorsSearch, sqlAuthorsTerm, sqlAuthorsOrder)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@ -17,7 +17,7 @@ func (app *Bouquins) searchAuthors(limit int, terms []string, all bool) ([]*Auth
|
||||
for rows.Next() {
|
||||
if len(authors) <= limit {
|
||||
author := new(AuthorAdv)
|
||||
if err := rows.Scan(&author.Id, &author.Name); err != nil {
|
||||
if err := rows.Scan(&author.ID, &author.Name); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
authors = append(authors, author)
|
||||
@ -32,7 +32,7 @@ func (app *Bouquins) searchAuthors(limit int, terms []string, all bool) ([]*Auth
|
||||
|
||||
func (app *Bouquins) queryAuthors(limit, offset int, sort, order string) ([]*AuthorAdv, bool, error) {
|
||||
authors := make([]*AuthorAdv, 0, limit)
|
||||
stmt, err := app.psSortAuthors(AUTHORS, sort, order)
|
||||
stmt, err := app.psSortAuthors(qtAuthors, sort, order)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
@ -47,7 +47,7 @@ func (app *Bouquins) queryAuthors(limit, offset int, sort, order string) ([]*Aut
|
||||
more = true
|
||||
} else {
|
||||
author := new(AuthorAdv)
|
||||
if err := rows.Scan(&author.Id, &author.Name, &author.Count); err != nil {
|
||||
if err := rows.Scan(&author.ID, &author.Name, &author.Count); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
authors = append(authors, author)
|
||||
@ -60,11 +60,11 @@ func (app *Bouquins) queryAuthors(limit, offset int, sort, order string) ([]*Aut
|
||||
}
|
||||
|
||||
func (app *Bouquins) queryAuthorBooks(author *AuthorFull) error {
|
||||
stmt, err := app.ps(AUTHOR_BOOKS)
|
||||
stmt, err := app.ps(qtAuthorBooks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(author.Id)
|
||||
rows, err := stmt.Query(author.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -72,14 +72,14 @@ func (app *Bouquins) queryAuthorBooks(author *AuthorFull) error {
|
||||
series := make(map[int64]*Series, 0)
|
||||
for rows.Next() {
|
||||
book := new(Book)
|
||||
var seriesId sql.NullInt64
|
||||
var seriesID sql.NullInt64
|
||||
var seriesName sql.NullString
|
||||
if err = rows.Scan(&book.Id, &book.Title, &book.SeriesIndex, &seriesName, &seriesId); err != nil {
|
||||
if err = rows.Scan(&book.ID, &book.Title, &book.SeriesIndex, &seriesName, &seriesID); err != nil {
|
||||
return err
|
||||
}
|
||||
if seriesId.Valid && seriesName.Valid {
|
||||
series[seriesId.Int64] = &Series{
|
||||
seriesId.Int64,
|
||||
if seriesID.Valid && seriesName.Valid {
|
||||
series[seriesID.Int64] = &Series{
|
||||
seriesID.Int64,
|
||||
seriesName.String,
|
||||
}
|
||||
}
|
||||
@ -96,18 +96,18 @@ func (app *Bouquins) queryAuthorBooks(author *AuthorFull) error {
|
||||
}
|
||||
|
||||
func (app *Bouquins) queryAuthorAuthors(author *AuthorFull) error {
|
||||
stmt, err := app.ps(AUTHOR_COAUTHORS)
|
||||
stmt, err := app.ps(qtAuthorCoauthors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(author.Id, author.Id)
|
||||
rows, err := stmt.Query(author.ID, author.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
coauthor := new(Author)
|
||||
if err = rows.Scan(&coauthor.Id, &coauthor.Name); err != nil {
|
||||
if err = rows.Scan(&coauthor.ID, &coauthor.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
author.CoAuthors = append(author.CoAuthors, coauthor)
|
||||
@ -119,12 +119,12 @@ func (app *Bouquins) queryAuthorAuthors(author *AuthorFull) error {
|
||||
}
|
||||
|
||||
func (app *Bouquins) queryAuthor(id int64) (*AuthorFull, error) {
|
||||
stmt, err := app.ps(AUTHOR)
|
||||
stmt, err := app.ps(qtAuthor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
author := new(AuthorFull)
|
||||
author.Id = id
|
||||
author.ID = id
|
||||
err = stmt.QueryRow(id).Scan(&author.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -134,6 +134,7 @@ func (app *Bouquins) queryAuthor(id int64) (*AuthorFull, error) {
|
||||
|
||||
// DB LOADS //
|
||||
|
||||
// AuthorsAdv loads a list of authors
|
||||
func (app *Bouquins) AuthorsAdv(params *ReqParams) ([]*AuthorAdv, int, bool, error) {
|
||||
limit, offset, sort, order := params.Limit, params.Offset, params.Sort, params.Order
|
||||
if len(params.Terms) > 0 {
|
||||
@ -147,6 +148,7 @@ func (app *Bouquins) AuthorsAdv(params *ReqParams) ([]*AuthorAdv, int, bool, err
|
||||
return authors, 0, more, nil
|
||||
}
|
||||
|
||||
// AuthorFull loads an author
|
||||
func (app *Bouquins) AuthorFull(id int64) (*AuthorFull, error) {
|
||||
author, err := app.queryAuthor(id)
|
||||
if err != nil {
|
||||
|
@ -7,15 +7,15 @@ import (
|
||||
// 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]
|
||||
b.Authors = authors[b.ID]
|
||||
b.Tags = tags[b.ID]
|
||||
}
|
||||
}
|
||||
|
||||
// SUB QUERIES //
|
||||
|
||||
func (app *Bouquins) searchBooks(limit int, terms []string, all bool) ([]*BookAdv, int, error) {
|
||||
rows, err := app.searchHelper(all, terms, STMT_BOOKS0+STMT_WHERE, STMT_SEARCH_TERM_BOOKS, STMT_SEARCH_ORDER_BOOKS)
|
||||
rows, err := app.searchHelper(all, terms, sqlBooks0+sqlWhere, sqlBooksTerm, sqlBooksOrder)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@ -25,15 +25,15 @@ func (app *Bouquins) searchBooks(limit int, terms []string, all bool) ([]*BookAd
|
||||
for rows.Next() {
|
||||
if len(books) <= limit {
|
||||
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 {
|
||||
var seriesName sql.NullString
|
||||
var seriesID sql.NullInt64
|
||||
if err := rows.Scan(&book.ID, &book.Title, &book.SeriesIndex, &seriesName, &seriesID); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if series_name.Valid && series_id.Valid {
|
||||
if seriesName.Valid && seriesID.Valid {
|
||||
book.Series = &Series{
|
||||
series_id.Int64,
|
||||
series_name.String,
|
||||
seriesID.Int64,
|
||||
seriesName.String,
|
||||
}
|
||||
}
|
||||
books = append(books, book)
|
||||
@ -48,7 +48,7 @@ func (app *Bouquins) searchBooks(limit int, terms []string, all bool) ([]*BookAd
|
||||
|
||||
func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookAdv, bool, error) {
|
||||
books := make([]*BookAdv, 0, limit)
|
||||
stmt, err := app.psSortBooks(BOOKS, sort, order)
|
||||
stmt, err := app.psSortBooks(qtBooks, sort, order)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
@ -63,15 +63,15 @@ func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookA
|
||||
more = true
|
||||
} else {
|
||||
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 {
|
||||
var seriesName sql.NullString
|
||||
var seriesID sql.NullInt64
|
||||
if err := rows.Scan(&book.ID, &book.Title, &book.SeriesIndex, &seriesName, &seriesID); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if series_name.Valid && series_id.Valid {
|
||||
if seriesName.Valid && seriesID.Valid {
|
||||
book.Series = &Series{
|
||||
series_id.Int64,
|
||||
series_name.String,
|
||||
seriesID.Int64,
|
||||
seriesName.String,
|
||||
}
|
||||
}
|
||||
books = append(books, book)
|
||||
@ -85,7 +85,7 @@ func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookA
|
||||
|
||||
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)
|
||||
stmt, err := app.psSortBooks(qtBooksAuthors, sort, order)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -97,7 +97,7 @@ func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (m
|
||||
for rows.Next() {
|
||||
author := new(Author)
|
||||
var book int64
|
||||
if err := rows.Scan(&author.Id, &author.Name, &book); err != nil {
|
||||
if err := rows.Scan(&author.ID, &author.Name, &book); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if authors[book] == nil {
|
||||
@ -113,7 +113,7 @@ func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (m
|
||||
}
|
||||
|
||||
func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[int64][]string, error) {
|
||||
stmt, err := app.psSortBooks(BOOKS_TAGS, sort, order)
|
||||
stmt, err := app.psSortBooks(qtBooksTags, sort, order)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -143,23 +143,23 @@ func (app *Bouquins) queryBooksTags(limit, offset int, sort, order string) (map[
|
||||
}
|
||||
|
||||
func (app *Bouquins) queryBook(id int64) (*BookFull, error) {
|
||||
stmt, err := app.ps(BOOK)
|
||||
stmt, err := app.ps(qtBook)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
book := new(BookFull)
|
||||
var seriesIdx sql.NullFloat64
|
||||
var seriesId, timestamp, pubdate sql.NullInt64
|
||||
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,
|
||||
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 {
|
||||
if seriesID.Valid && seriesName.Valid && seriesIdx.Valid {
|
||||
book.SeriesIndex = seriesIdx.Float64
|
||||
book.Series = &Series{seriesId.Int64, seriesName.String}
|
||||
book.Series = &Series{seriesID.Int64, seriesName.String}
|
||||
}
|
||||
if timestamp.Valid {
|
||||
book.Timestamp = timestamp.Int64
|
||||
@ -174,7 +174,7 @@ func (app *Bouquins) queryBook(id int64) (*BookFull, error) {
|
||||
book.Lccn = lccn.String
|
||||
}
|
||||
if uuid.Valid {
|
||||
book.Uuid = uuid.String
|
||||
book.UUID = uuid.String
|
||||
}
|
||||
if lang.Valid {
|
||||
book.Lang = lang.String
|
||||
@ -183,16 +183,16 @@ func (app *Bouquins) queryBook(id int64) (*BookFull, error) {
|
||||
book.Publisher = publisher.String
|
||||
}
|
||||
if cover.Valid {
|
||||
book.Has_cover = cover.Bool
|
||||
book.HasCover = cover.Bool
|
||||
}
|
||||
return book, nil
|
||||
}
|
||||
func (app *Bouquins) queryBookTags(book *BookFull) error {
|
||||
stmt, err := app.ps(BOOK_TAGS)
|
||||
stmt, err := app.ps(qtBookTags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(book.Id)
|
||||
rows, err := stmt.Query(book.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -210,11 +210,11 @@ func (app *Bouquins) queryBookTags(book *BookFull) error {
|
||||
return nil
|
||||
}
|
||||
func (app *Bouquins) queryBookData(book *BookFull) error {
|
||||
stmt, err := app.ps(BOOK_DATA)
|
||||
stmt, err := app.ps(qtBookData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(book.Id)
|
||||
rows, err := stmt.Query(book.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -232,19 +232,19 @@ func (app *Bouquins) queryBookData(book *BookFull) error {
|
||||
return nil
|
||||
}
|
||||
func (app *Bouquins) queryBookAuthors(book *BookFull) error {
|
||||
stmt, err := app.ps(BOOK_AUTHORS)
|
||||
stmt, err := app.ps(qtBookAuthors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(book.Id)
|
||||
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 {
|
||||
var bookID int64
|
||||
if err = rows.Scan(&author.ID, &author.Name, &bookID); err != nil {
|
||||
return err
|
||||
}
|
||||
book.Authors = append(book.Authors, author)
|
||||
@ -257,9 +257,10 @@ func (app *Bouquins) queryBookAuthors(book *BookFull) error {
|
||||
|
||||
// DB LOADS //
|
||||
|
||||
// BookCount counts books in database
|
||||
func (app *Bouquins) BookCount() (int64, error) {
|
||||
var count int64
|
||||
stmt, err := app.ps(BOOKS_COUNT)
|
||||
stmt, err := app.ps(qtBookCount)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -268,6 +269,7 @@ func (app *Bouquins) BookCount() (int64, error) {
|
||||
return count, err
|
||||
}
|
||||
|
||||
// BookFull loads a book
|
||||
func (app *Bouquins) BookFull(id int64) (*BookFull, error) {
|
||||
book, err := app.queryBook(id)
|
||||
if err != nil {
|
||||
@ -288,6 +290,7 @@ func (app *Bouquins) BookFull(id int64) (*BookFull, error) {
|
||||
return book, nil
|
||||
}
|
||||
|
||||
// BooksAdv loads a list of books
|
||||
func (app *Bouquins) BooksAdv(params *ReqParams) ([]*BookAdv, int, bool, error) {
|
||||
limit, offset, sort, order := params.Limit, params.Offset, params.Sort, params.Order
|
||||
if len(params.Terms) > 0 {
|
||||
|
@ -4,14 +4,14 @@ package bouquins
|
||||
|
||||
func assignAuthorsSeries(series []*SeriesAdv, authors map[int64][]*Author) {
|
||||
for _, s := range series {
|
||||
s.Authors = authors[s.Id]
|
||||
s.Authors = authors[s.ID]
|
||||
}
|
||||
}
|
||||
|
||||
// SUB QUERIES //
|
||||
|
||||
func (app *Bouquins) searchSeries(limit int, terms []string, all bool) ([]*SeriesAdv, int, error) {
|
||||
rows, err := app.searchHelper(all, terms, STMT_SERIES_SEARCH, STMT_SEARCH_TERM_SERIES, STMT_SEARCH_ORDER_SERIES)
|
||||
rows, err := app.searchHelper(all, terms, sqlSeriesSearch, sqlSeriesTerm, sqlSeriesOrder)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@ -21,7 +21,7 @@ func (app *Bouquins) searchSeries(limit int, terms []string, all bool) ([]*Serie
|
||||
for rows.Next() {
|
||||
if len(series) <= limit {
|
||||
serie := new(SeriesAdv)
|
||||
if err := rows.Scan(&serie.Id, &serie.Name); err != nil {
|
||||
if err := rows.Scan(&serie.ID, &serie.Name); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
series = append(series, serie)
|
||||
@ -36,7 +36,7 @@ func (app *Bouquins) searchSeries(limit int, terms []string, all bool) ([]*Serie
|
||||
|
||||
func (app *Bouquins) querySeriesList(limit, offset int, sort, order string) ([]*SeriesAdv, bool, error) {
|
||||
series := make([]*SeriesAdv, 0, limit)
|
||||
stmt, err := app.psSortSeries(SERIES, sort, order)
|
||||
stmt, err := app.psSortSeries(qtSeries, sort, order)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
@ -51,7 +51,7 @@ func (app *Bouquins) querySeriesList(limit, offset int, sort, order string) ([]*
|
||||
more = true
|
||||
} else {
|
||||
serie := new(SeriesAdv)
|
||||
if err := rows.Scan(&serie.Id, &serie.Name, &serie.Count); err != nil {
|
||||
if err := rows.Scan(&serie.ID, &serie.Name, &serie.Count); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
series = append(series, serie)
|
||||
@ -64,7 +64,7 @@ func (app *Bouquins) querySeriesList(limit, offset int, sort, order string) ([]*
|
||||
}
|
||||
func (app *Bouquins) querySeriesListAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) {
|
||||
authors := make(map[int64][]*Author)
|
||||
stmt, err := app.psSortBooks(SERIES_AUTHORS, sort, order)
|
||||
stmt, err := app.psSortBooks(qtSeriesAuthors, sort, order)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -75,14 +75,14 @@ func (app *Bouquins) querySeriesListAuthors(limit, offset int, sort, order strin
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
author := new(Author)
|
||||
var serId int64
|
||||
if err := rows.Scan(&author.Id, &author.Name, &serId); err != nil {
|
||||
var seriesID int64
|
||||
if err := rows.Scan(&author.ID, &author.Name, &seriesID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if authors[serId] == nil {
|
||||
authors[serId] = append(make([]*Author, 0), author)
|
||||
if authors[seriesID] == nil {
|
||||
authors[seriesID] = append(make([]*Author, 0), author)
|
||||
} else {
|
||||
authors[serId] = append(authors[serId], author)
|
||||
authors[seriesID] = append(authors[seriesID], author)
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
@ -92,27 +92,27 @@ func (app *Bouquins) querySeriesListAuthors(limit, offset int, sort, order strin
|
||||
}
|
||||
|
||||
func (app *Bouquins) querySeries(id int64) (*SeriesFull, error) {
|
||||
stmt, err := app.ps(SERIE)
|
||||
stmt, err := app.ps(qtSerie)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
series := new(SeriesFull)
|
||||
err = stmt.QueryRow(id).Scan(&series.Id, &series.Name)
|
||||
err = stmt.QueryRow(id).Scan(&series.ID, &series.Name)
|
||||
return series, nil
|
||||
}
|
||||
func (app *Bouquins) querySeriesAuthors(series *SeriesFull) error {
|
||||
stmt, err := app.ps(SERIE_AUTHORS)
|
||||
stmt, err := app.ps(qtSerieAuthors)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(series.Id)
|
||||
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 {
|
||||
if err = rows.Scan(&author.ID, &author.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
series.Authors = append(series.Authors, author)
|
||||
@ -123,18 +123,18 @@ func (app *Bouquins) querySeriesAuthors(series *SeriesFull) error {
|
||||
return nil
|
||||
}
|
||||
func (app *Bouquins) querySeriesBooks(series *SeriesFull) error {
|
||||
stmt, err := app.ps(SERIE_BOOKS)
|
||||
stmt, err := app.ps(qtSerieBooks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := stmt.Query(series.Id)
|
||||
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 {
|
||||
if err = rows.Scan(&book.ID, &book.Title, &book.SeriesIndex); err != nil {
|
||||
return err
|
||||
}
|
||||
series.Books = append(series.Books, book)
|
||||
@ -147,6 +147,7 @@ func (app *Bouquins) querySeriesBooks(series *SeriesFull) error {
|
||||
|
||||
// DB LOADS //
|
||||
|
||||
// SeriesFull loads a series
|
||||
func (app *Bouquins) SeriesFull(id int64) (*SeriesFull, error) {
|
||||
series, err := app.querySeries(id)
|
||||
if err != nil {
|
||||
@ -163,6 +164,7 @@ func (app *Bouquins) SeriesFull(id int64) (*SeriesFull, error) {
|
||||
return series, nil
|
||||
}
|
||||
|
||||
// SeriesAdv loads a list of series
|
||||
func (app *Bouquins) SeriesAdv(params *ReqParams) ([]*SeriesAdv, int, bool, error) {
|
||||
limit, offset, sort, order := params.Limit, params.Offset, params.Sort, params.Order
|
||||
if len(params.Terms) > 0 {
|
||||
|
33
main.go
33
main.go
@ -9,9 +9,10 @@ import (
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
||||
. "meutel.net/meutel/go-bouquins/bouquins"
|
||||
"meutel.net/meutel/go-bouquins/bouquins"
|
||||
)
|
||||
|
||||
// BouquinsConf App configuration
|
||||
type BouquinsConf struct {
|
||||
BindAddress string `json:"bind-address"`
|
||||
DbPath string `json:"db-path"`
|
||||
@ -20,7 +21,7 @@ type BouquinsConf struct {
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
// load config
|
||||
// ReadConfig loads configuration file and initialize default value
|
||||
func ReadConfig() (*BouquinsConf, error) {
|
||||
conf := new(BouquinsConf)
|
||||
confPath := "bouquins.json"
|
||||
@ -55,7 +56,7 @@ func initApp() *BouquinsConf {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
tpl, err := TemplatesFunc().ParseGlob("templates/*.html")
|
||||
tpl, err := bouquins.TemplatesFunc().ParseGlob("templates/*.html")
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
@ -63,7 +64,7 @@ func initApp() *BouquinsConf {
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
app := &Bouquins{tpl, db}
|
||||
app := &bouquins.Bouquins{Tpl: tpl, DB: db}
|
||||
err = app.PrepareAll()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
@ -74,10 +75,10 @@ func initApp() *BouquinsConf {
|
||||
}
|
||||
|
||||
func assets(calibre string) {
|
||||
http.Handle(URL_JS, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(URL_CSS, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(URL_FONTS, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(URL_CALIBRE, http.StripPrefix(URL_CALIBRE, http.FileServer(http.Dir(calibre))))
|
||||
http.Handle(bouquins.URLJs, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(bouquins.URLCss, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(bouquins.URLFonts, http.FileServer(http.Dir("assets")))
|
||||
http.Handle(bouquins.URLCalibre, http.StripPrefix(bouquins.URLCalibre, http.FileServer(http.Dir(calibre))))
|
||||
}
|
||||
|
||||
func handle(f func(res http.ResponseWriter, req *http.Request) error) func(res http.ResponseWriter, req *http.Request) {
|
||||
@ -90,17 +91,17 @@ func handle(f func(res http.ResponseWriter, req *http.Request) error) func(res h
|
||||
}
|
||||
}
|
||||
|
||||
func handleUrl(url string, f func(res http.ResponseWriter, req *http.Request) error) {
|
||||
func handleURL(url string, f func(res http.ResponseWriter, req *http.Request) error) {
|
||||
http.HandleFunc(url, handle(f))
|
||||
}
|
||||
|
||||
func router(app *Bouquins) {
|
||||
handleUrl(URL_INDEX, app.IndexPage)
|
||||
handleUrl(URL_BOOKS, app.BooksPage)
|
||||
handleUrl(URL_AUTHORS, app.AuthorsPage)
|
||||
handleUrl(URL_SERIES, app.SeriesPage)
|
||||
handleUrl(URL_SEARCH, app.SearchPage)
|
||||
handleUrl(URL_ABOUT, app.AboutPage)
|
||||
func router(app *bouquins.Bouquins) {
|
||||
handleURL(bouquins.URLIndex, app.IndexPage)
|
||||
handleURL(bouquins.URLBooks, app.BooksPage)
|
||||
handleURL(bouquins.URLAuthors, app.AuthorsPage)
|
||||
handleURL(bouquins.URLSeries, app.SeriesPage)
|
||||
handleURL(bouquins.URLSearch, app.SearchPage)
|
||||
handleURL(bouquins.URLAbout, app.AboutPage)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{ template "header.html" . }}
|
||||
<div class="container" id="author">
|
||||
{{ if .Id }}
|
||||
{{ if .ID }}
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<span class="glyphicon glyphicon-user"></span>
|
||||
@ -21,7 +21,7 @@
|
||||
{{ range .Books }}
|
||||
<ul class="list-unstyled">
|
||||
<li><span class="glyphicon glyphicon-book"></span>
|
||||
<a href="/books/{{ .Id }}">{{ .Title }}</a>
|
||||
<a href="/books/{{ .ID }}">{{ .Title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{{ end }}
|
||||
@ -33,7 +33,7 @@
|
||||
{{ range .Series }}
|
||||
<ul class="list-unstyled">
|
||||
<li><span class="glyphicon glyphicon-list"></span>
|
||||
<a href="/series/{{ .Id }}">{{ .Name }}</a>
|
||||
<a href="/series/{{ .ID }}">{{ .Name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{{ end }}
|
||||
@ -46,7 +46,7 @@
|
||||
{{ range .CoAuthors }}
|
||||
<ul class="list-unstyled">
|
||||
<li> <span class="glyphicon glyphicon-user"></span>
|
||||
<a href="/authors/{{ .Id }}">{{ .Name }}</a>
|
||||
<a href="/authors/{{ .ID }}">{{ .Name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{{ template "header.html" . }}
|
||||
<div class="container" id="app">
|
||||
{{ if .Id }}
|
||||
{{ if .ID }}
|
||||
<div class="page-header">
|
||||
{{ if .Has_cover }}
|
||||
{{ if .HasCover }}
|
||||
<div class="row">
|
||||
<img src="{{ bookCover .BookFull }}" alt="Pas de couverture" title="Couverture" class="img-responsive img-rounded" width="400px"/>
|
||||
</div>
|
||||
@ -34,7 +34,7 @@
|
||||
<ul>
|
||||
{{ range .Authors }}
|
||||
<li>
|
||||
<a href="/authors/{{.Id}}">{{ .Name }}</a>
|
||||
<a href="/authors/{{.ID}}">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
@ -44,7 +44,7 @@
|
||||
<span class="glyphicon glyphicon-list"></span> Serie
|
||||
</h2>
|
||||
<div>
|
||||
<a href="/series/{{ .Series.Id }}">{{ .Series.Name }}</a>
|
||||
<a href="/series/{{ .Series.ID }}">{{ .Series.Name }}</a>
|
||||
<span class="badge">{{ .SeriesIndex }}</span>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{{ template "header.html" . }}
|
||||
<div class="container" id="app">
|
||||
{{ if .Id }}
|
||||
{{ if .ID }}
|
||||
<div class="page-header">
|
||||
<h1>
|
||||
<span class="glyphicon glyphicon-list"></span>
|
||||
@ -13,7 +13,7 @@
|
||||
<ul>
|
||||
{{ range .Books }}
|
||||
<li class="list-unstyled">{{ .SeriesIndex }}.
|
||||
<a href="/books/{{ .Id }}">{{ .Title }}</a>
|
||||
<a href="/books/{{ .ID }}">{{ .Title }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
@ -24,7 +24,7 @@
|
||||
{{ range .Authors }}
|
||||
<li class="list-unstyled">
|
||||
<span class="glyphicon glyphicon-user"></span>
|
||||
<a href="/authors/{{ .Id }}">{{ .Name }}</a>
|
||||
<a href="/authors/{{ .ID }}">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
Loading…
Reference in New Issue
Block a user