package database import ( log "github.com/cihub/seelog" "errors" "os" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) const ( visited_coll = "visited" downloaded_coll = "downloaded" tags_coll = "tags" ) type DB struct { session *mgo.Session name string } func Init(host string, name string) *DB { var err error db := new(DB) db.session, err = mgo.Dial(host) if err != nil { log.Critical(err) os.Exit(1) } db.name = name db.initIndexes() return db } func (db *DB) initIndexes() { dbCopy := db.session.Copy() booksColl := dbCopy.DB(db.name).C(books_coll) go indexBooks(booksColl) statsColl := dbCopy.DB(db.name).C(stats_coll) go indexStats(statsColl) newsColl := dbCopy.DB(db.name).C(news_coll) go indexNews(newsColl) } func (db *DB) Close() { db.session.Close() } func (db *DB) Copy() *DB { dbCopy := new(DB) dbCopy.session = db.session.Copy() dbCopy.name = db.name return dbCopy } func (db *DB) AddBook(book map[string]interface{}) error { booksColl := db.session.DB(db.name).C(books_coll) return addBook(booksColl, book) } func (db *DB) GetBooks(query string, length int, start int) (books []Book, num int, err error) { booksColl := db.session.DB(db.name).C(books_coll) return getBooks(booksColl, query, length, start) } func (db *DB) GetNewBooks(length int, start int) (books []Book, num int, err error) { booksColl := db.session.DB(db.name).C(books_coll) return getNewBooks(booksColl, length, start) } func (db *DB) GetBookId(id string) (Book, error) { booksColl := db.session.DB(db.name).C(books_coll) return getBookId(booksColl, id) } func (db *DB) DeleteBook(id string) error { booksColl := db.session.DB(db.name).C(books_coll) return deleteBook(booksColl, id) } func (db *DB) UpdateBook(id string, data map[string]interface{}) error { booksColl := db.session.DB(db.name).C(books_coll) return updateBook(booksColl, id, data) } func (db *DB) FlagBadQuality(id string, user string) error { booksColl := db.session.DB(db.name).C(books_coll) return flagBadQuality(booksColl, id, user) } func (db *DB) ActiveBook(id string) error { booksColl := db.session.DB(db.name).C(books_coll) return activeBook(booksColl, id) } func (db *DB) IsBookActive(id string) bool { booksColl := db.session.DB(db.name).C(books_coll) return isBookActive(booksColl, id) } func (db *DB) User(name string) *User { userColl := db.session.DB(db.name).C(user_coll) return getUser(userColl, name) } func (db *DB) AddUser(name string, pass string) error { userColl := db.session.DB(db.name).C(user_coll) return addUser(userColl, name, pass) } func (db *DB) AddNews(text string) error { newsColl := db.session.DB(db.name).C(news_coll) return addNews(newsColl, text) } func (db *DB) GetNews(num int, days int) (news []News, err error) { newsColl := db.session.DB(db.name).C(news_coll) return getNews(newsColl, num, days) } // TODO: split code in files func (db *DB) AddStats(stats interface{}) error { statsColl := db.session.DB(db.name).C(stats_coll) return statsColl.Insert(stats) } /* Get the most visited books */ func (db *DB) GetVisitedBooks() (books []Book, err error) { visitedColl := db.session.DB(db.name).C(visited_coll) bookId, err := GetBooksVisited(visitedColl) if err != nil { return nil, err } books = make([]Book, len(bookId)) for i, id := range bookId { booksColl := db.session.DB(db.name).C(books_coll) booksColl.Find(bson.M{"_id": id}).One(&books[i]) books[i].Id = bson.ObjectId(books[i].Id).Hex() } return } func (db *DB) UpdateMostVisited() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(visited_coll) return u.UpdateMostBooks("book") } /* Get the most downloaded books */ func (db *DB) GetDownloadedBooks() (books []Book, err error) { downloadedColl := db.session.DB(db.name).C(downloaded_coll) bookId, err := GetBooksVisited(downloadedColl) if err != nil { return nil, err } books = make([]Book, len(bookId)) for i, id := range bookId { booksColl := db.session.DB(db.name).C(books_coll) booksColl.Find(bson.M{"_id": id}).One(&books[i]) books[i].Id = bson.ObjectId(books[i].Id).Hex() } return } func (db *DB) UpdateDownloadedBooks() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(downloaded_coll) return u.UpdateMostBooks("download") } func (db *DB) GetTags() ([]string, error) { tagsColl := db.session.DB(db.name).C(tags_coll) return GetTags(tagsColl) } func (db *DB) UpdateTags() error { var u dbUpdate u.src = db.session.DB(db.name).C(books_coll) u.dst = db.session.DB(db.name).C(tags_coll) return u.UpdateTags() } func (db *DB) GetVisits(visitType VisitType) ([]Visits, error) { var coll *mgo.Collection switch visitType { case Hourly_visits: coll = db.session.DB(db.name).C(hourly_visits_coll) case Daily_visits: coll = db.session.DB(db.name).C(daily_visits_coll) case Monthly_visits: coll = db.session.DB(db.name).C(monthly_visits_coll) case Hourly_downloads: coll = db.session.DB(db.name).C(hourly_downloads_coll) case Daily_downloads: coll = db.session.DB(db.name).C(daily_downloads_coll) case Monthly_downloads: coll = db.session.DB(db.name).C(monthly_downloads_coll) default: return nil, errors.New("Not valid VisitType") } return GetVisits(coll) } func (db *DB) UpdateHourVisits() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(hourly_visits_coll) return u.UpdateHourVisits(false) } func (db *DB) UpdateDayVisits() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(daily_visits_coll) return u.UpdateDayVisits(false) } func (db *DB) UpdateMonthVisits() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(monthly_visits_coll) return u.UpdateMonthVisits(false) } func (db *DB) UpdateHourDownloads() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(hourly_downloads_coll) return u.UpdateHourVisits(true) } func (db *DB) UpdateDayDownloads() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(daily_downloads_coll) return u.UpdateDayVisits(true) } func (db *DB) UpdateMonthDownloads() error { var u dbUpdate u.src = db.session.DB(db.name).C(stats_coll) u.dst = db.session.DB(db.name).C(monthly_downloads_coll) return u.UpdateMonthVisits(true) } // function defined for the tests func (db *DB) del() { defer db.Close() db.session.DB(db.name).DropDatabase() }