2014-06-29 19:41:29 -05:00
|
|
|
package database
|
|
|
|
|
|
|
|
import (
|
2014-08-18 19:27:53 -05:00
|
|
|
"gopkg.in/mgo.v2"
|
|
|
|
"gopkg.in/mgo.v2/bson"
|
2014-07-02 20:58:00 -05:00
|
|
|
"gopkgs.com/unidecode.v1"
|
|
|
|
"strings"
|
|
|
|
"unicode"
|
2014-06-29 19:41:29 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
books_coll = "books"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Book struct {
|
2014-08-21 19:24:23 -05:00
|
|
|
Id string
|
2014-06-29 19:41:29 -05:00
|
|
|
Title string
|
|
|
|
Author []string
|
|
|
|
Contributor string
|
|
|
|
Publisher string
|
|
|
|
Description string
|
|
|
|
Subject []string
|
|
|
|
Date string
|
|
|
|
Lang []string
|
|
|
|
Isbn string
|
|
|
|
Type string
|
|
|
|
Format string
|
|
|
|
Source string
|
|
|
|
Relation string
|
|
|
|
Coverage string
|
|
|
|
Rights string
|
|
|
|
Meta string
|
|
|
|
FileSize int
|
2014-08-21 19:24:23 -05:00
|
|
|
Cover bool
|
2014-06-29 19:41:29 -05:00
|
|
|
Active bool
|
|
|
|
Keywords []string
|
|
|
|
}
|
|
|
|
|
2014-07-02 20:58:00 -05:00
|
|
|
func addBook(coll *mgo.Collection, book map[string]interface{}) error {
|
|
|
|
book["keywords"] = keywords(book)
|
2014-06-29 19:41:29 -05:00
|
|
|
return coll.Insert(book)
|
|
|
|
}
|
|
|
|
|
2014-07-02 20:58:00 -05:00
|
|
|
func getBooks(coll *mgo.Collection, query string, length int, start int) (books []Book, num int, err error) {
|
|
|
|
return _getBooks(coll, buildQuery(query), length, start)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getNewBooks(coll *mgo.Collection, length int, start int) (books []Book, num int, err error) {
|
|
|
|
return _getBooks(coll, bson.M{"$nor": []bson.M{{"active": true}}}, length, start)
|
|
|
|
}
|
|
|
|
|
|
|
|
func _getBooks(coll *mgo.Collection, query bson.M, length int, start int) (books []Book, num int, err error) {
|
2014-06-29 19:41:29 -05:00
|
|
|
q := coll.Find(query).Sort("-_id")
|
|
|
|
num, err = q.Count()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if start != 0 {
|
|
|
|
q = q.Skip(start)
|
|
|
|
}
|
|
|
|
if length != 0 {
|
|
|
|
q = q.Limit(length)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = q.All(&books)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-07-02 20:40:24 -05:00
|
|
|
func getBookId(coll *mgo.Collection, id string) (Book, error) {
|
|
|
|
var book Book
|
2014-08-21 19:24:23 -05:00
|
|
|
err := coll.Find(bson.M{"id": id}).One(&book)
|
2014-07-02 20:40:24 -05:00
|
|
|
return book, err
|
|
|
|
}
|
|
|
|
|
2014-07-02 21:09:41 -05:00
|
|
|
func deleteBook(coll *mgo.Collection, id string) error {
|
2014-08-21 19:24:23 -05:00
|
|
|
return coll.Remove(bson.M{"id": id})
|
2014-06-29 19:41:29 -05:00
|
|
|
}
|
|
|
|
|
2014-07-02 21:09:41 -05:00
|
|
|
func updateBook(coll *mgo.Collection, id string, data map[string]interface{}) error {
|
2014-08-21 19:24:23 -05:00
|
|
|
var book map[string]interface{}
|
|
|
|
err := coll.Find(bson.M{"id": id}).One(&book)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for k, v := range data {
|
|
|
|
book[k] = v
|
|
|
|
}
|
|
|
|
|
|
|
|
data["keywords"] = keywords(book)
|
|
|
|
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
2014-06-29 19:41:29 -05:00
|
|
|
}
|
|
|
|
|
2014-08-21 19:24:23 -05:00
|
|
|
func activeBook(coll *mgo.Collection, id string) error {
|
|
|
|
data := map[string]interface{}{"active": true}
|
|
|
|
return coll.Update(bson.M{"id": id}, bson.M{"$set": data})
|
|
|
|
}
|
|
|
|
|
|
|
|
func isBookActive(coll *mgo.Collection, id string) bool {
|
2014-06-29 19:41:29 -05:00
|
|
|
var book Book
|
2014-08-21 19:24:23 -05:00
|
|
|
err := coll.Find(bson.M{"id": id}).One(&book)
|
2014-06-29 19:41:29 -05:00
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return book.Active
|
|
|
|
}
|
2014-07-02 20:58:00 -05:00
|
|
|
|
|
|
|
func buildQuery(q string) bson.M {
|
|
|
|
var keywords []string
|
|
|
|
query := bson.M{"active": true}
|
|
|
|
words := strings.Split(q, " ")
|
|
|
|
for _, w := range words {
|
|
|
|
tag := strings.SplitN(w, ":", 2)
|
|
|
|
if len(tag) > 1 {
|
|
|
|
query[tag[0]] = bson.RegEx{tag[1], "i"}
|
|
|
|
} else {
|
|
|
|
toks := tokens(w)
|
|
|
|
keywords = append(keywords, toks...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(keywords) > 0 {
|
|
|
|
query["keywords"] = bson.M{"$all": keywords}
|
|
|
|
}
|
|
|
|
return query
|
|
|
|
}
|
|
|
|
|
|
|
|
func keywords(b map[string]interface{}) (k []string) {
|
|
|
|
title, _ := b["title"].(string)
|
|
|
|
k = tokens(title)
|
2014-08-21 19:24:23 -05:00
|
|
|
|
|
|
|
k = append(k, listKeywords(b["author"])...)
|
|
|
|
|
2014-07-02 20:58:00 -05:00
|
|
|
publisher, _ := b["publisher"].(string)
|
|
|
|
k = append(k, tokens(publisher)...)
|
2014-08-21 19:24:23 -05:00
|
|
|
|
|
|
|
k = append(k, listKeywords(b["subject"])...)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func listKeywords(v interface{}) (k []string) {
|
|
|
|
list, ok := v.([]string)
|
|
|
|
if !ok {
|
|
|
|
list, _ := v.([]interface{})
|
|
|
|
for _, e := range list {
|
|
|
|
str := e.(string)
|
|
|
|
k = append(k, tokens(str)...)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, e := range list {
|
|
|
|
k = append(k, tokens(e)...)
|
2014-07-02 20:58:00 -05:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func tokens(str string) []string {
|
|
|
|
str = unidecode.Unidecode(str)
|
|
|
|
str = strings.ToLower(str)
|
|
|
|
f := func(r rune) bool {
|
|
|
|
return unicode.IsControl(r) || unicode.IsPunct(r) || unicode.IsSpace(r)
|
|
|
|
}
|
|
|
|
return strings.FieldsFunc(str, f)
|
|
|
|
}
|