Author: Adam <git@apiote.tk>
delete skips of watched episodes
datastructure/error.go | 9 ++++ db/db.go | 89 +++++++++++++++++++++++++++++++++++-------- libamuse/account.go | 17 +++++--
diff --git a/datastructure/error.go b/datastructure/error.go new file mode 100644 index 0000000000000000000000000000000000000000..39363f86a87f076c5d3041721e3696d836c15277 --- /dev/null +++ b/datastructure/error.go @@ -0,0 +1,9 @@ +package datastructure + +type ValueError struct { + Message string +} + +func (e ValueError) Error() string { + return e.Message +} diff --git a/db/db.go b/db/db.go index 2344eefb8ee25d78e4ab61734b117df3737a186f..b1c88b85f5c5f043839a597ed5464fc4bd0e45df 100644 --- a/db/db.go +++ b/db/db.go @@ -274,43 +274,90 @@ } return times, nil } -func AddToExperiences(username, itemId string, itemType datastructure.ItemType, datetime time.Time) error { +func AddToExperiences(username, itemId string, itemType datastructure.ItemType, datetime time.Time) (int, error) { db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") if err != nil { fmt.Fprintf(os.Stderr, "DB open err\n") - return err + return 0, err } defer db.Close() - _, err = db.Exec(`insert into experiences values(?, ?, ?, ?)`, username, itemType, itemId, datetime) + tx, err := db.Begin() + if err != nil { + fmt.Fprintf(os.Stderr, "Transaction err %s\n", err) + return 0, err + } + defer tx.Rollback() + + rows, err := tx.Query(`select time from experiences where item_type = ? and item_id like ? and username = ?`, itemType, itemId, username) + if err != nil { + fmt.Fprintf(os.Stderr, "Select err %v\n", err) + return 0, err + } + defer rows.Close() + + watchedTimes := []time.Time{} + for rows.Next() { + var t time.Time + err := rows.Scan(&t) + if err != nil { + fmt.Fprintf(os.Stderr, "Scan err %v\n", err) + return 0, err + } + watchedTimes = append(watchedTimes, t) + } + + if datetime.IsZero() && len(watchedTimes) > 0 { + return 0, datastructure.ValueError{Message: "Cannot skip watched item"} + } + + deletedRows, err := tx.Exec(`delete from experiences where username = ? and item_type = ? and item_id = ? and time = '0001-01-01 00:00:00+00:00'`, username, itemType, itemId) + if err != nil { + fmt.Fprintf(os.Stderr, "Delete err %v\n", err) + return 0, err + } + deletedRowsNumber, err := deletedRows.RowsAffected() + if err != nil { + fmt.Fprintf(os.Stderr, "Delete err %v\n", err) + return 0, err + } + + insertedRows, err := tx.Exec(`insert into experiences values(?, ?, ?, ?)`, username, itemType, itemId, datetime) + if err != nil { + fmt.Fprintf(os.Stderr, "Insert err %v\n", err) + return 0, err + } + insertedRowsNumber, err := insertedRows.RowsAffected() if err != nil { fmt.Fprintf(os.Stderr, "Insert err %v\n", err) - return err + return 0, err } - //todo if !datetime.IsZero() then delete all datetime that .IsZero() where itemId = itemId - return nil + + tx.Commit() + + return int(insertedRowsNumber - deletedRowsNumber), nil } -func SkipSpecials(username, itemId string, episodesNumber int, itemType datastructure.ItemType, datetime time.Time) error { +func SkipSpecials(username, itemId string, episodesNumber int, itemType datastructure.ItemType, datetime time.Time) (int, error) { db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") if err != nil { fmt.Fprintf(os.Stderr, "DB open err\n") - return err + return 0, err } defer db.Close() tx, err := db.Begin() if err != nil { fmt.Fprintf(os.Stderr, "Transaction err %s\n", err) - return err + return 0, err } defer tx.Rollback() rows, err := tx.Query(`select item_id from experiences where item_type = ? and item_id like ? || '/%' and username = ?`, itemType, itemId, username) if err != nil { fmt.Fprintf(os.Stderr, "Select err %v\n", err) - return err + return 0, err } defer rows.Close() @@ -320,10 +367,12 @@ var watchedId string err := rows.Scan(&watchedId) if err != nil { fmt.Fprintf(os.Stderr, "Scan err %v\n", err) - return err + return 0, err } watched[watchedId]++ } + + modifiedRows := 0 for e := 1; e <= episodesNumber; e++ { episodeId := fmt.Sprintf("%s/S00E%02d", itemId, e) @@ -334,20 +383,21 @@ _, err = tx.Exec(`insert into experiences values(?, ?, ?, ?)`, username, itemType, episodeId, datetime) if err != nil { if err.Error()[:6] != "UNIQUE" { fmt.Fprintf(os.Stderr, "Insert err %v\n", err) - return err + return 0, err } else { fmt.Fprintf(os.Stderr, "WARNING: Insert err: Unique constraint violation\n") } } + modifiedRows++ } err = tx.Commit() if err != nil { fmt.Fprintf(os.Stderr, "Commit err %v\n", err) - return err + return 0, err } - return nil + return modifiedRows, nil } func AddToWantList(username, itemId string, itemType datastructure.ItemType) error { @@ -411,7 +461,12 @@ return isOnlist, nil } -func SaveCacheItem(itemType datastructure.ItemType, itemId string, itemInfo datastructure.ItemInfo) error { +func SaveCacheItem(itemType datastructure.ItemType, itemId string, itemInfo datastructure.ItemInfo, refs int) error { + fmt.Println(refs) + if refs == 0 { + return nil + } + db, err := sql.Open("sqlite3", utils.DataHome+"/amuse.db") if err != nil { fmt.Fprintf(os.Stderr, "DB open err\n") @@ -420,8 +475,8 @@ } defer db.Close() _, err = db.Exec(`insert into item_cache values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - on conflict(item_type, item_id) do update set ref_count = ref_count + 1`, - itemType, itemId, itemInfo.Cover, itemInfo.Status, itemInfo.Title, itemInfo.YearStart, itemInfo.YearEnd, itemInfo.BasedOn, itemInfo.Genres, itemInfo.Runtime, itemInfo.Collection, itemInfo.Part, 1) + on conflict(item_type, item_id) do update set ref_count = ref_count + ?`, + itemType, itemId, itemInfo.Cover, itemInfo.Status, itemInfo.Title, itemInfo.YearStart, itemInfo.YearEnd, itemInfo.BasedOn, itemInfo.Genres, itemInfo.Runtime, itemInfo.Collection, itemInfo.Part, refs, refs) if err != nil { return err } diff --git a/libamuse/account.go b/libamuse/account.go index 6ecb085bca57c66e44997a1c48ee6b2715cd7668..f584c8e60b8aa7375de466f8db045b4428b26868 100644 --- a/libamuse/account.go +++ b/libamuse/account.go @@ -53,6 +53,7 @@ result := args[1].(*Result) itemType := args[2].(string) err := db.AddToWantList(result.user.Username, data.id, datastructure.ItemType(itemType)) + result.result2 = 1 return gott.Tuple(args), err } @@ -86,12 +87,14 @@ func cacheItem(args ...interface{}) (interface{}, error) { data := args[0].(*RequestData) result := args[1].(*Result) + fmt.Println(result.result2) + refs := result.result2.(int) item := result.result.(datastructure.Item) itemInfo := item.GetItemInfo() - err := db.SaveCacheItem(item.GetItemType(), data.id, itemInfo) + err := db.SaveCacheItem(item.GetItemType(), data.id, itemInfo, refs) return gott.Tuple(args), err } @@ -103,8 +106,8 @@ Bind(parseLanguage). Bind(verifyToken). Bind(verifyUser). Bind(getItem). - Bind(cacheItem). Bind(addToWantlist). + Bind(cacheItem). Finish() return err @@ -134,7 +137,10 @@ data := args[0].(*RequestData) result := args[1].(*Result) itemType := args[2].(string) t := result.result.(time.Time) - var err error = nil + var ( + err error = nil + refs int + ) id := strings.Split(data.id, "/") if len(id) > 1 && id[1][3] == 'A' { @@ -143,10 +149,11 @@ _, err := fmt.Sscanf(id[1][4:], "%d", &episodesNumber) if err != nil { return gott.Tuple(args), err } - err = db.SkipSpecials(result.user.Username, id[0], episodesNumber, datastructure.ItemType(itemType), t) + refs, err = db.SkipSpecials(result.user.Username, id[0], episodesNumber, datastructure.ItemType(itemType), t) } else { - err = db.AddToExperiences(result.user.Username, data.id, datastructure.ItemType(itemType), t) + refs, err = db.AddToExperiences(result.user.Username, data.id, datastructure.ItemType(itemType), t) } + result.result2 = refs data.id = id[0] if len(id) > 1 {