This commit is contained in:
Meutel 2017-08-05 19:40:58 +02:00
parent c8fc680331
commit e724ac4e5a
6 changed files with 143 additions and 103 deletions

View File

@ -68,33 +68,63 @@ Vue.component('result-cell', {
});
Vue.component('paginate', {
template: '#paginate-template',
props: ['page'],
props: ['page','more'],
methods: {
prevPage: function() {
if (this.page > 1) this.$emit('prev');
},
nextPage: function() {
if (this.more) this.$emit('next');
}
}
});
var index = new Vue({
el: '#index',
data: {
url: '',
page: 0,
perpage: 20,
more: false,
sort_by: null,
order_desc: false,
cols: [],
results: []
},
methods: {
updatePage: function(p) {
this.page += p;
this.updateResults();
},
order: function(query) {
if (this.order_desc)
return query + '&order=desc';
return query;
},
sort: function(query) {
if (this.sort_by)
return query + '&sort=' + this.sort_by;
return query;
},
paginate: function(query) {
return query + '?page=' + this.page + '&perpage=' + this.perpage;
},
params: function(url) {
return this.order(this.sort(this.paginate(url)));
},
updateResults: function() {
this.sendQuery(this.params(this.url), this.stdError, this.loadResults);
},
showSeries: function() {
this.sendQuery('/series/', this.stdError, this.loadResults);
this.url = '/series/';
this.updateResults();
},
showAuthors: function() {
this.sendQuery('/authors/', this.stdError, this.loadResults);
this.url = '/authors/';
this.updateResults();
},
showBooks: function() {
this.sendQuery('/books/', this.stdError, this.loadResults);
this.url = '/books/';
this.updateResults();
},
loadCols: function(type) {
switch (type) {
@ -122,10 +152,14 @@ var index = new Vue({
},
loadResults(resp) {
this.results = [];
this.page = 1;
this.more = resp.more;
this.loadCols(resp.type);
if (resp.results)
if (resp.results) {
this.results = resp.results;
if (this.page == 0) this.page = 1;
} else {
this.page = 0;
}
},
sendQuery: function(url, error, success) {
var xmh = new XMLHttpRequest();

View File

@ -24,8 +24,8 @@ const (
PARAM_LIST = "list"
PARAM_ORDER = "order"
PARAM_SORT = "sort"
PARAM_LIMIT = "limit"
PARAM_OFFSET = "offset"
PARAM_PAGE = "page"
PARAM_PERPAGE = "perpage"
LIST_AUTHORS = "authors"
LIST_SERIES = "series"
@ -161,14 +161,15 @@ func NewIndexModel(title, js string, count int64) *IndexModel {
type ResultsModel struct {
Type string `json:"type,omitempty"`
More bool `json:"more"`
}
type BooksResultsModel struct {
ResultsModel
Results []*BookAdv `json:"results,omitempty"`
}
func NewBooksResultsModel(books []*BookAdv) *BooksResultsModel {
return &BooksResultsModel{ResultsModel{"books"}, books}
func NewBooksResultsModel(books []*BookAdv, more bool) *BooksResultsModel {
return &BooksResultsModel{ResultsModel{"books", more}, books}
}
type AuthorsResultsModel struct {
@ -176,8 +177,8 @@ type AuthorsResultsModel struct {
Results []*AuthorAdv `json:"results,omitempty"`
}
func NewAuthorsResultsModel(authors []*AuthorAdv) *AuthorsResultsModel {
return &AuthorsResultsModel{ResultsModel{"authors"}, authors}
func NewAuthorsResultsModel(authors []*AuthorAdv, more bool) *AuthorsResultsModel {
return &AuthorsResultsModel{ResultsModel{"authors", more}, authors}
}
type SeriesResultsModel struct {
@ -185,8 +186,8 @@ type SeriesResultsModel struct {
Results []*SeriesAdv `json:"results,omitempty"`
}
func NewSeriesResultsModel(series []*SeriesAdv) *SeriesResultsModel {
return &SeriesResultsModel{ResultsModel{"series"}, series}
func NewSeriesResultsModel(series []*SeriesAdv, more bool) *SeriesResultsModel {
return &SeriesResultsModel{ResultsModel{"series", more}, series}
}
type BookModel struct {
@ -249,6 +250,22 @@ func paramOrder(req *http.Request) string {
return ""
}
// return limit, offset, sort, order
func paramPaginate(req *http.Request) (int, int, string, string) {
page, perpage := paramInt(PARAM_PAGE, req), paramInt(PARAM_PERPAGE, req)
limit := perpage
if perpage == 0 {
limit = DEF_LIM
}
offset := perpage * (page - 1)
if offset < 0 {
offset = 0
}
sort := req.URL.Query().Get(PARAM_SORT)
order := paramOrder(req)
return limit, offset, sort, order
}
// ROUTES //
func (app *Bouquins) IndexPage(res http.ResponseWriter, req *http.Request) {
@ -257,23 +274,6 @@ func (app *Bouquins) IndexPage(res http.ResponseWriter, req *http.Request) {
log.Print(err)
}
model := NewIndexModel("", "index.js", count)
/*
order, sort := paramOrder(req), req.URL.Query().Get(PARAM_SORT)
limit, offset := paramInt(PARAM_LIMIT, req), paramInt(PARAM_OFFSET, req)
switch req.URL.Query().Get(PARAM_LIST) {
case LIST_AUTHORS:
model.Authors, err = app.AuthorsAdv(limit, offset, sort, order)
case LIST_SERIES:
model.Series, err = app.SeriesAdv(limit, offset, sort, order)
case LIST_BOOKS:
fallthrough
default:
model.Books, err = app.BooksAdv(limit, offset, sort, order)
}
if err != nil {
log.Print(err)
}
*/
if isJson(req) {
err := writeJson(res, model)
if err != nil {
@ -286,11 +286,11 @@ func (app *Bouquins) IndexPage(res http.ResponseWriter, req *http.Request) {
}
func (app *Bouquins) BooksListPage(res http.ResponseWriter, req *http.Request) error {
if isJson(req) {
books, err := app.BooksAdv(10, 0, "", "")
books, more, err := app.BooksAdv(paramPaginate(req))
if err != nil {
return err
}
return writeJson(res, NewBooksResultsModel(books))
return writeJson(res, NewBooksResultsModel(books, more))
}
return errors.New("Invalid mime")
}
@ -325,11 +325,11 @@ func (app *Bouquins) BooksPage(res http.ResponseWriter, req *http.Request) {
}
func (app *Bouquins) AuthorsListPage(res http.ResponseWriter, req *http.Request) error {
if isJson(req) {
authors, err := app.AuthorsAdv(10, 0, "", "")
authors, more, err := app.AuthorsAdv(paramPaginate(req))
if err != nil {
return err
}
return writeJson(res, NewAuthorsResultsModel(authors))
return writeJson(res, NewAuthorsResultsModel(authors, more))
}
return errors.New("Invalid mime")
}
@ -364,11 +364,11 @@ func (app *Bouquins) AuthorsPage(res http.ResponseWriter, req *http.Request) {
}
func (app *Bouquins) SeriesListPage(res http.ResponseWriter, req *http.Request) error {
if isJson(req) {
series, err := app.SeriesAdv(10, 0, "", "")
series, more, err := app.SeriesAdv(paramPaginate(req))
if err != nil {
return err
}
return writeJson(res, NewSeriesResultsModel(series))
return writeJson(res, NewSeriesResultsModel(series, more))
}
return errors.New("Invalid mime")
}

View File

@ -6,28 +6,33 @@ import (
// SUB QUERIES //
func (app *Bouquins) queryAuthors(limit, offset int, sort, order string) ([]*AuthorAdv, error) {
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)
if err != nil {
return nil, err
return nil, false, err
}
rows, err := stmt.Query(limit, offset)
rows, err := stmt.Query(limit+1, offset)
if err != nil {
return nil, err
return nil, false, err
}
defer rows.Close()
more := false
for rows.Next() {
if len(authors) == limit {
more = true
} else {
author := new(AuthorAdv)
if err := rows.Scan(&author.Id, &author.Name, &author.Count); err != nil {
return nil, err
return nil, false, err
}
authors = append(authors, author)
}
if err := rows.Err(); err != nil {
return nil, err
}
return authors, nil
if err := rows.Err(); err != nil {
return nil, false, err
}
return authors, more, nil
}
func (app *Bouquins) queryAuthorBooks(author *AuthorFull) error {
@ -105,15 +110,12 @@ func (app *Bouquins) queryAuthor(id int64) (*AuthorFull, error) {
// DB LOADS //
func (app *Bouquins) AuthorsAdv(limit, offset int, sort, order string) ([]*AuthorAdv, error) {
if limit == 0 {
limit = DEF_LIM
}
authors, err := app.queryAuthors(limit, offset, sort, order)
func (app *Bouquins) AuthorsAdv(limit, offset int, sort, order string) ([]*AuthorAdv, bool, error) {
authors, more, err := app.queryAuthors(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
return authors, nil
return authors, more, nil
}
func (app *Bouquins) AuthorFull(id int64) (*AuthorFull, error) {

View File

@ -12,23 +12,27 @@ func assignAuthorsTagsBooks(books []*BookAdv, authors map[int64][]*Author, tags
// SUB QUERIES //
func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookAdv, error) {
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)
if err != nil {
return nil, err
return nil, false, err
}
rows, err := stmt.Query(limit, offset)
rows, err := stmt.Query(limit+1, offset)
if err != nil {
return nil, err
return nil, false, err
}
defer rows.Close()
more := false
for rows.Next() {
if len(books) == limit {
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 {
return nil, err
return nil, false, err
}
if series_name.Valid && series_id.Valid {
book.Series = &Series{
@ -38,10 +42,11 @@ func (app *Bouquins) queryBooks(limit, offset int, sort, order string) ([]*BookA
}
books = append(books, book)
}
if err := rows.Err(); err != nil {
return nil, err
}
return books, nil
if err := rows.Err(); err != nil {
return nil, false, err
}
return books, more, nil
}
func (app *Bouquins) queryBooksAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) {
@ -249,22 +254,19 @@ func (app *Bouquins) BookFull(id int64) (*BookFull, error) {
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)
func (app *Bouquins) BooksAdv(limit, offset int, sort, order string) ([]*BookAdv, bool, error) {
books, more, err := app.queryBooks(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
authors, err := app.queryBooksAuthors(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
tags, err := app.queryBooksTags(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
assignAuthorsTagsBooks(books, authors, tags)
return books, nil
return books, more, nil
}

View File

@ -10,28 +10,33 @@ func assignAuthorsSeries(series []*SeriesAdv, authors map[int64][]*Author) {
// SUB QUERIES //
func (app *Bouquins) querySeriesList(limit, offset int, sort, order string) ([]*SeriesAdv, error) {
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)
if err != nil {
return nil, err
return nil, false, err
}
rows, err := stmt.Query(limit, offset)
rows, err := stmt.Query(limit+1, offset)
if err != nil {
return nil, err
return nil, false, err
}
defer rows.Close()
more := false
for rows.Next() {
if len(series) == limit {
more = true
} else {
serie := new(SeriesAdv)
if err := rows.Scan(&serie.Id, &serie.Name, &serie.Count); err != nil {
return nil, err
return nil, false, err
}
series = append(series, serie)
}
if err := rows.Err(); err != nil {
return nil, err
}
return series, nil
if err := rows.Err(); err != nil {
return nil, false, err
}
return series, more, nil
}
func (app *Bouquins) querySeriesListAuthors(limit, offset int, sort, order string) (map[int64][]*Author, error) {
authors := make(map[int64][]*Author)
@ -134,18 +139,15 @@ func (app *Bouquins) SeriesFull(id int64) (*SeriesFull, error) {
return series, nil
}
func (app *Bouquins) SeriesAdv(limit, offset int, sort, order string) ([]*SeriesAdv, error) {
if limit == 0 {
limit = DEF_LIM
}
series, err := app.querySeriesList(limit, offset, sort, order)
func (app *Bouquins) SeriesAdv(limit, offset int, sort, order string) ([]*SeriesAdv, bool, error) {
series, more, err := app.querySeriesList(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
authors, err := app.querySeriesListAuthors(limit, offset, sort, order)
if err != nil {
return nil, err
return nil, false, err
}
assignAuthorsSeries(series, authors)
return series, nil
return series, more, nil
}

View File

@ -8,7 +8,7 @@
<button class="btn btn-primary" type="button" @click="showSeries">Series</button>
</div>
<div class="table-responsive">
<paginate :page="page"></paginate>
<paginate v-on:next="updatePage(1)" v-on:prev="updatePage(-1)" :page="page" :more="more"></paginate>
<results :results="results" :cols="cols" :sort_by="sort_by" :order_desc="order_desc"></results>
<paginate :page="page"></paginate>
</div>
@ -35,7 +35,7 @@
<nav aria-label="Pages" v-if="page > 0">
<ul class="pager">
<li class="previous" v-bind:class="{ disabled: page <= 1 }"><a href="#" @click="prevPage"><span aria-hidden="true">&larr;</span> Précédents</a></li>
<li class="next"><a href="#" @click="nextPage">Suivants <span aria-hidden="true">&rarr;</span></a></li>
<li class="next" v-bind:class="{ disabled: !more }"><a href="#" @click="nextPage">Suivants <span aria-hidden="true">&rarr;</span></a></li>
</ul>
</nav>
</script>