amuse.git

commit 1244940585f3db749a91973bac469e90c7752f86

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 {