Add: singleThreadLock for sqlite performance, and change Db.Tag method
This commit is contained in:
@@ -54,7 +54,13 @@ func (api *API) HandleInsertTag(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tag, err := api.Db.InsertTag(req)
|
||||
tagID, err := api.Db.InsertTag(req)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
tag, err := api.Db.GetTag(tagID)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
@@ -114,16 +120,14 @@ func (api *API) HandleUpdateTag(w http.ResponseWriter, r *http.Request) {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
tag, err := api.Db.UpdateTag(req)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
err = json.NewEncoder(w).Encode(tag)
|
||||
|
||||
err = api.Db.UpdateTag(req)
|
||||
if err != nil {
|
||||
api.HandleError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.HandleOK(w, r)
|
||||
}
|
||||
|
||||
type DeleteTagRequest struct {
|
||||
|
||||
@@ -2,6 +2,7 @@ package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"sync"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
type Database struct {
|
||||
sqlConn *sql.DB
|
||||
stmt *Stmt
|
||||
singleThreadLock *sync.Mutex
|
||||
}
|
||||
|
||||
func NewDatabase(dbName string) (*Database, error) {
|
||||
@@ -30,6 +32,7 @@ func NewDatabase(dbName string) (*Database, error) {
|
||||
database := &Database{
|
||||
sqlConn: sqlConn,
|
||||
stmt: stmt,
|
||||
singleThreadLock: &sync.Mutex{},
|
||||
}
|
||||
|
||||
return database, nil
|
||||
|
||||
@@ -8,6 +8,9 @@ import (
|
||||
)
|
||||
|
||||
func (database *Database) GetRandomFiles(limit int64) ([]File, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getRandomFiles.Query(limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -28,6 +31,9 @@ func (database *Database) GetRandomFiles(limit int64) ([]File, error) {
|
||||
}
|
||||
|
||||
func (database *Database) GetRandomFilesWithTag(tagID, limit int64) ([]File, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getRandomFilesWithTag.Query(tagID, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -48,6 +54,9 @@ func (database *Database) GetRandomFilesWithTag(tagID, limit int64) ([]File, err
|
||||
}
|
||||
|
||||
func (database *Database) GetFilesInFolder(folder_id int64, limit int64, offset int64) ([]File, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getFilesInFolder.Query(folder_id, limit, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -69,6 +78,9 @@ func (database *Database) GetFilesInFolder(folder_id int64, limit int64, offset
|
||||
}
|
||||
|
||||
func (database *Database) SearchFolders(foldername string, limit int64, offset int64) ([]Folder, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.searchFolders.Query("%"+foldername+"%", limit, offset)
|
||||
if err != nil {
|
||||
return nil, errors.New("Error searching folders at query " + err.Error())
|
||||
@@ -92,6 +104,10 @@ func (database *Database) GetFile(id int64) (*File, error) {
|
||||
file := &File{
|
||||
Db: database,
|
||||
}
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
err := database.stmt.getFile.QueryRow(id).Scan(&file.ID, &file.Folder_id, &file.Filename, &file.Foldername, &file.Filesize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -178,6 +194,10 @@ func (database *Database) GetFolder(folderId int64) (*Folder, error) {
|
||||
folder := &Folder{
|
||||
Db: database,
|
||||
}
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
err := database.stmt.getFolder.QueryRow(folderId).Scan(&folder.Folder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -186,6 +206,9 @@ func (database *Database) GetFolder(folderId int64) (*Folder, error) {
|
||||
}
|
||||
|
||||
func (database *Database) SearchFiles(filename string, limit int64, offset int64) ([]File, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.searchFiles.Query("%"+filename+"%", limit, offset)
|
||||
if err != nil {
|
||||
return nil, errors.New("Error searching files at query " + err.Error())
|
||||
@@ -210,6 +233,10 @@ func (database *Database) SearchFiles(filename string, limit int64, offset int64
|
||||
|
||||
func (database *Database) FindFolder(folder string) (int64, error) {
|
||||
var id int64
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
err := database.stmt.findFolder.QueryRow(folder).Scan(&id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -219,6 +246,10 @@ func (database *Database) FindFolder(folder string) (int64, error) {
|
||||
|
||||
func (database *Database) FindFile(folderId int64, filename string) (int64, error) {
|
||||
var id int64
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
err := database.stmt.findFile.QueryRow(folderId, filename).Scan(&id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -227,6 +258,10 @@ func (database *Database) FindFile(folderId int64, filename string) (int64, erro
|
||||
}
|
||||
|
||||
func (database *Database) InsertFolder(folder string) (int64, error) {
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.insertFolder.Exec(folder, filepath.Base(folder))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -239,6 +274,9 @@ func (database *Database) InsertFolder(folder string) (int64, error) {
|
||||
}
|
||||
|
||||
func (database *Database) InsertFile(folderId int64, filename string, filesize int64) (int64, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.insertFile.Exec(folderId, filename, filesize)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -274,6 +312,9 @@ func (database *Database) Insert(path string, filesize int64) (int64, error) {
|
||||
}
|
||||
|
||||
func (database *Database) UpdateFoldername(folderId int64, foldername string) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.updateFoldername.Exec(foldername, folderId)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package database
|
||||
|
||||
func (database *Database) InsertFeedback(time int64, content string, userID int64, header string) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.insertFeedback.Exec(time, content, userID, header)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -9,6 +12,9 @@ func (database *Database) InsertFeedback(time int64, content string, userID int6
|
||||
}
|
||||
|
||||
func (database *Database) GetFeedbacks() ([]*Feedback, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getFeedbacks.Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -32,6 +38,9 @@ func (database *Database) GetFeedbacks() ([]*Feedback, error) {
|
||||
}
|
||||
|
||||
func (database *Database) DeleteFeedback(id int64) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.deleteFeedback.Exec(id)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package database
|
||||
|
||||
func (database *Database) InsertReview(review *Review) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.insertReview.Exec(
|
||||
review.UserId,
|
||||
review.FileId,
|
||||
@@ -10,6 +13,9 @@ func (database *Database) InsertReview(review *Review) error {
|
||||
}
|
||||
|
||||
func (database *Database) GetReviewsOnFile(fileId int64) ([]*Review, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getReviewsOnFile.Query(fileId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -42,6 +48,9 @@ func (database *Database) GetReviewsOnFile(fileId int64) ([]*Review, error) {
|
||||
}
|
||||
|
||||
func (database *Database) GetReview(reviewId int64) (*Review, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
row := database.stmt.getReview.QueryRow(reviewId)
|
||||
|
||||
review := &Review{}
|
||||
@@ -60,6 +69,9 @@ func (database *Database) GetReview(reviewId int64) (*Review, error) {
|
||||
}
|
||||
|
||||
func (database *Database) UpdateReview(review *Review) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.updateReview.Exec(
|
||||
review.Content,
|
||||
review.UpdatedAt,
|
||||
@@ -68,11 +80,17 @@ func (database *Database) UpdateReview(review *Review) error {
|
||||
}
|
||||
|
||||
func (database *Database) DeleteReview(reviewId int64) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.deleteReview.Exec(reviewId)
|
||||
return err
|
||||
}
|
||||
|
||||
func (database *Database) GetReviewsByUser(userId int64) ([]*Review, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getReviewsByUser.Query(userId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,19 +2,26 @@ package database
|
||||
|
||||
import "errors"
|
||||
|
||||
func (database *Database) InsertTag(tag *Tag) (*Tag, error) {
|
||||
func (database *Database) InsertTag(tag *Tag) (int64, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.insertTag.Exec(tag.Name, tag.Description, tag.CreatedByUserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return 0, err
|
||||
}
|
||||
id, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return 0, err
|
||||
}
|
||||
return database.GetTag(id)
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (database *Database) GetTag(id int64) (*Tag, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
tag := &Tag{CreatedByUser: &User{}}
|
||||
err := database.stmt.getTag.QueryRow(id).Scan(
|
||||
&tag.ID, &tag.Name, &tag.Description,
|
||||
@@ -27,6 +34,10 @@ func (database *Database) GetTag(id int64) (*Tag, error) {
|
||||
|
||||
func (database *Database) GetTags() ([]*Tag, error) {
|
||||
tags := []*Tag{}
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getTags.Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -46,23 +57,30 @@ func (database *Database) GetTags() ([]*Tag, error) {
|
||||
return tags, nil
|
||||
}
|
||||
|
||||
func (database *Database) UpdateTag(tag *Tag) (*Tag, error) {
|
||||
func (database *Database) UpdateTag(tag *Tag) (error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.updateTag.Exec(tag.Name, tag.Description, tag.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
rowsAffected, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
if rowsAffected == 0 {
|
||||
return nil, errors.New("No rows affected")
|
||||
return errors.New("No rows affected")
|
||||
}
|
||||
return database.GetTag(tag.ID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// delete tag and all its references in file_has_tag
|
||||
func (database *Database) DeleteTag(id int64) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
// begin transaction
|
||||
tx, err := database.sqlConn.Begin()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package database
|
||||
|
||||
func (database *Database) PutTagOnFile(tagID, fileID, userID int64) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.putTagOnFile.Exec(tagID, fileID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -12,6 +15,9 @@ func (database *Database) PutTagOnFile(tagID, fileID, userID int64) error {
|
||||
}
|
||||
|
||||
func (database *Database) GetTagsOnFile(fileID int64) ([]*Tag, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getTagsOnFile.Query(fileID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -31,6 +37,9 @@ func (database *Database) GetTagsOnFile(fileID int64) ([]*Tag, error) {
|
||||
}
|
||||
|
||||
func (database *Database) DeleteTagOnFile(tagID, fileID int64) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
result, err := database.stmt.deleteTagOnFile.Exec(tagID, fileID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package database
|
||||
|
||||
func (database *Database) Login(username string, password string) (*User, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
user := &User{}
|
||||
|
||||
// get user from database
|
||||
@@ -12,6 +15,9 @@ func (database *Database) Login(username string, password string) (*User, error)
|
||||
}
|
||||
|
||||
func (database *Database) LoginAsAnonymous() (*User, error) {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
user := &User{}
|
||||
|
||||
// get user from database
|
||||
@@ -38,6 +44,9 @@ func (database *Database) Register(username string, password string, usertype in
|
||||
active = true
|
||||
}
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err = database.stmt.insertUser.Exec(username, password, usertype, active, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -48,6 +57,9 @@ func (database *Database) Register(username string, password string, usertype in
|
||||
func (database *Database) GetUserById(id int64) (*User, error) {
|
||||
user := &User{}
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
// get user from database
|
||||
err := database.stmt.getUserById.QueryRow(id).Scan(&user.ID, &user.Username, &user.Role, &user.Active, &user.AvatarId)
|
||||
if err != nil {
|
||||
@@ -58,6 +70,10 @@ func (database *Database) GetUserById(id int64) (*User, error) {
|
||||
|
||||
func (database *Database) CountAdmin() (int64, error) {
|
||||
var count int64
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
err := database.stmt.countAdmin.QueryRow().Scan(&count)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -68,6 +84,9 @@ func (database *Database) CountAdmin() (int64, error) {
|
||||
func (database *Database) GetUsers() ([]*User, error) {
|
||||
users := make([]*User, 0)
|
||||
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
rows, err := database.stmt.getUsers.Query()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -86,6 +105,9 @@ func (database *Database) GetUsers() ([]*User, error) {
|
||||
}
|
||||
|
||||
func (database *Database) UpdateUserActive(id int64, active bool) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.updateUserActive.Exec(active, id)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -94,6 +116,9 @@ func (database *Database) UpdateUserActive(id int64, active bool) error {
|
||||
}
|
||||
|
||||
func (database *Database) UpdateUsername(id int64, username string) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.updateUsername.Exec(username, id)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -102,6 +127,9 @@ func (database *Database) UpdateUsername(id int64, username string) error {
|
||||
}
|
||||
|
||||
func (database *Database) UpdateUserPassword(id int64, password string) error {
|
||||
database.singleThreadLock.Lock()
|
||||
defer database.singleThreadLock.Unlock()
|
||||
|
||||
_, err := database.stmt.updateUserPassword.Exec(password, id)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user