2014-05-22 19:08:41 +00:00
var express = require ( 'express' ) ;
var router = express . Router ( ) ;
2014-06-29 10:50:28 +00:00
var _ = require ( 'underscore' ) ;
2014-05-25 12:15:29 +00:00
var paginate = require ( '../util/paginate' ) ;
2014-06-19 20:51:00 +00:00
var HashMap = require ( 'hashmap' ) . HashMap ;
2014-05-22 19:08:41 +00:00
2014-06-29 10:50:28 +00:00
function find ( db , pager , appendwhere , callback ) {
2014-06-28 06:44:52 +00:00
var books = new HashMap ( ) ;
2014-06-27 16:40:59 +00:00
var qparams = new Array ( ) ;
var query = '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' ;
2014-06-29 10:50:28 +00:00
if ( appendwhere ) {
query = appendwhere ( query , qparams ) ;
}
2014-06-28 07:36:47 +00:00
query += ' LIMIT ? OFFSET ?' ;
2014-06-29 10:50:28 +00:00
qparams . push ( pager . perpage + 1 ) ;
qparams . push ( pager . offset ) ;
// console.log(query);
// console.log(qparams);
db . each ( query , qparams ,
2014-06-27 16:40:59 +00:00
function ( err , book ) {
2014-06-29 10:50:28 +00:00
if ( books . count ( ) < pager . perpage ) {
2014-06-27 16:40:59 +00:00
books . set ( '' + book . id , book ) ;
} else
2014-06-29 10:50:28 +00:00
pager . hasNext = true ; /* more than perpage */
2014-06-27 16:40:59 +00:00
} ,
function ( err ) {
if ( err ) console . log ( err ) ;
/* query books authors */
var qAuthors = 'SELECT books_authors_link.book as book,authors.id as id,name FROM authors, books_authors_link WHERE books_authors_link.author = authors.id AND books_authors_link.book IN (' ;
for ( var i = 0 ; i < books . count ( ) - 1 ; i ++ ) qAuthors += '?,' ;
qAuthors += '?)' ;
2014-06-29 10:50:28 +00:00
db . each ( qAuthors , books . keys ( ) ,
2014-06-27 16:40:59 +00:00
function ( err , author ) {
var book = books . get ( '' + author . book ) ;
if ( ! book . authors ) book . authors = new Array ( ) ;
book . authors . push ( author ) ;
} ,
function ( err ) {
if ( err ) console . log ( err ) ;
2014-06-29 10:50:28 +00:00
callback ( books . values ( ) ) ;
2014-06-27 16:40:59 +00:00
}
) ;
}
) ;
2014-06-29 10:50:28 +00:00
}
/* All books */
router . get ( '/' , function ( req , res ) {
var pager = new paginate ( req ) ;
find ( req . db , pager ,
function ( query , qparams ) {
/* books with given initial */
query = pager . appendInitialQuery ( query , 'books.sort' , qparams , true ) ;
/* recent */
if ( req . query . sort == 'recent' )
query += ' ORDER BY books.last_modified DESC' ;
else
query += ' ORDER BY books.sort' ;
return query ;
} ,
function ( books ) {
res . links ( pager . links ( ) ) ;
res . json ( books ) ;
}
) ;
} ) ;
/* Search */
router . post ( '/' , function ( req , res ) {
/ * p a r a m q = s e a r c h t e r m
* Search in
* book . sort weight 1000
* author . sort weight 1
* serie . sort weight 5
* comment weight 100
* /
var found = new Array ( ) ;
var term = '%' + req . body . q . toUpperCase ( ) + '%' ;
console . log ( term ) ;
var nbqueries = 4 ;
var output = function ( err ) {
if ( err ) console . log ( err ) ;
nbqueries -- ;
if ( nbqueries == 0 ) {
var merged = new HashMap ( ) ;
_ . each ( found , function ( elt ) {
var weight = merged . get ( '' + elt . id ) || 0 ;
merged . set ( '' + elt . id , weight + elt . weight ) ;
} ) ;
/* sort ids by weight */
var ids = _ . sortBy ( merged . keys ( ) , function ( id ) { return - 1 * merged . get ( '' + id ) ; } ) ;
/* truncate */
var pager = new paginate ( req ) ;
ids . length = Math . min ( ids . length , pager . perpage ) ;
find ( req . db , pager ,
function ( query , qparams ) {
_ . each ( ids , function ( id , index ) {
if ( index == 0 )
query += ' WHERE books.id IN (' ;
else
query += ',' ;
query += '?' ;
qparams . push ( id ) ;
} ) ;
query += ')' ;
2014-06-29 15:14:00 +00:00
query = pager . appendInitialQuery ( query , 'books.sort' , qparams , false ) ;
2014-06-29 10:50:28 +00:00
return query ;
} ,
function ( books ) {
// TODO no pager res.links(pager.links());
/* sort by weight */
res . json ( _ . sortBy ( books , function ( book ) { return - 1 * merged . get ( '' + book . id ) ; } ) ) ;
}
) ;
}
} ;
req . db . each ( 'SELECT id FROM books WHERE UPPER(sort) LIKE ?' , term ,
function ( err , row ) { found . push ( { id : row . id , weight : 1000 } ) ; } ,
function ( err ) { output ( err ) ; }
) ;
req . db . each ( 'SELECT books_authors_link.book AS id FROM authors' +
' LEFT OUTER JOIN books_authors_link ON books_authors_link.author = authors.id' +
' WHERE UPPER(authors.sort) LIKE ?' , term ,
function ( err , row ) { found . push ( { id : row . id , weight : 5 } ) ; } ,
function ( err ) { output ( err ) ; }
) ;
req . db . each ( 'SELECT books_series_link.book AS id FROM series' +
' LEFT OUTER JOIN books_series_link ON books_series_link.series = series.id' +
' WHERE UPPER(series.sort) LIKE ?' , term ,
function ( err , row ) { found . push ( { id : row . id , weight : 100 } ) ; } ,
function ( err ) { output ( err ) ; }
) ;
req . db . each ( 'SELECT book FROM comments WHERE UPPER(text) LIKE ?' , term ,
function ( err , row ) { found . push ( { id : row . book , weight : 10 } ) ; } ,
function ( err ) { output ( err ) ; }
) ;
2014-06-20 18:58:12 +00:00
} ) ;
/* Single book */
router . get ( '/:id' , function ( req , res ) {
2014-09-02 18:07:44 +00:00
var book , authors , tags , details ;
2014-09-03 17:40:12 +00:00
var queries = 3 ;
if ( req . locals . book _details _custom ) queries += req . locals . book _details _custom . length ;
2014-06-20 18:58:12 +00:00
var callback = function ( ) {
if ( queries == 0 ) {
book . authors = authors ;
book . tags = tags ;
2014-09-02 18:07:44 +00:00
book . custom = custom ;
2014-06-20 18:58:12 +00:00
res . format ( {
html : function ( ) {
res . render ( 'book' , book ) ;
} ,
json : function ( ) {
res . json ( book ) ;
}
} ) ;
}
} ;
// book
req . db . get ( 'SELECT books.id AS id,title,timestamp,pubdate,series_index,isbn,lccn,path,uuid,has_cover,' +
2014-06-21 22:35:59 +00:00
'languages.lang_code,format,uncompressed_size,data.name AS data_name,series.name AS series_name,' +
2014-09-03 17:40:12 +00:00
'series.id AS series_id, publishers.name AS pubname FROM books ' +
2014-06-20 18:58:12 +00:00
' LEFT OUTER JOIN books_languages_link ON books_languages_link.book = books.id ' +
' LEFT OUTER JOIN languages ON languages.id = books_languages_link.lang_code ' +
' LEFT OUTER JOIN data ON data.book = books.id ' +
' LEFT OUTER JOIN books_series_link ON books.id = books_series_link.book ' +
' LEFT OUTER JOIN series ON series.id = books_series_link.series ' +
2014-09-03 17:40:12 +00:00
' LEFT OUTER JOIN books_publishers_link ON books.id = books_publishers_link.book ' +
' LEFT OUTER JOIN publishers ON publishers.id = books_publishers_link.publisher ' +
2014-06-20 18:58:12 +00:00
' WHERE books.id = ?' , req . params . id ,
function ( err , row ) {
2014-06-21 22:35:59 +00:00
if ( err ) console . log ( 'ERR book: ' + err ) ;
2014-06-20 18:58:12 +00:00
book = row ;
queries -- ;
callback ( ) ;
}
) ;
// authors
authors = new Array ( ) ;
req . db . each ( 'SELECT authors.id as id,name FROM authors, books_authors_link WHERE books_authors_link.author = authors.id AND books_authors_link.book = ?' , req . params . id ,
function ( err , author ) {
authors . push ( author ) ;
} ,
function ( err ) {
2014-06-21 22:35:59 +00:00
if ( err ) console . log ( 'ERR authors: ' + err ) ;
2014-06-20 18:58:12 +00:00
queries -- ;
callback ( ) ;
}
) ;
// tags
tags = new Array ( ) ;
req . db . each ( 'SELECT tags.id as id,name FROM tags, books_tags_link WHERE books_tags_link.tag = tags.id AND books_tags_link.book = ?' , req . params . id ,
function ( err , tag ) {
tags . push ( tag ) ;
} ,
function ( err ) {
2014-06-21 22:35:59 +00:00
if ( err ) console . log ( 'ERR tags: ' + err ) ;
2014-06-20 18:58:12 +00:00
queries -- ;
callback ( ) ;
}
) ;
2014-09-02 18:07:44 +00:00
// details
custom = new Array ( ) ;
2014-09-03 17:40:12 +00:00
if ( req . locals . book _details _custom ) {
_ . each ( req . locals . book _details _custom , function ( detail ) {
req . db . each ( detail . query , req . params . id ,
function ( err , row ) {
row . name = detail . name ;
row . type = detail . type ;
custom . push ( row ) ;
} ,
function ( err ) {
if ( err ) console . log ( 'ERR tags: ' + err ) ;
queries -- ;
callback ( ) ;
}
) ;
} ) ;
}
2014-05-22 19:08:41 +00:00
} ) ;
2014-06-20 18:58:12 +00:00
2014-05-22 19:08:41 +00:00
module . exports = router ;