Browse Source

Better post insert/update action

Vova Tkach 6 years ago
parent
commit
081f3261d1
2 changed files with 203 additions and 5 deletions
  1. 146 5
      modules/module_blog.go
  2. 57 0
      utils/utils.go

+ 146 - 5
modules/module_blog.go

@@ -508,8 +508,20 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 		}
 
 		if pf_id == "0" {
-			// Add new post
-			_, err := wrap.DB.Exec(
+			// Start transaction with table lock
+			_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE, blog_cat_post_rel WRITE;")
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+			tx, err := wrap.DB.Begin()
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+
+			// Insert row
+			res, err := tx.Exec(
 				`INSERT INTO blog_posts SET
 					user = ?,
 					name = ?,
@@ -526,13 +538,84 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 				pf_active,
 			)
 			if err != nil {
+				tx.Rollback()
 				wrap.MsgError(err.Error())
 				return
 			}
+
+			lastID, err := res.LastInsertId()
+			if err != nil {
+				tx.Rollback()
+				wrap.MsgError(err.Error())
+				return
+			}
+
+			// Insert post and categories relations
+			catids := utils.GetPostArrayInt("cats[]", wrap.R)
+			if len(catids) > 0 {
+				var catsCount int
+				err = tx.QueryRow(`
+					SELECT
+						COUNT(*)
+					FROM
+						blog_cats
+					WHERE
+						id IN(` + strings.Join(utils.ArrayOfIntToArrayOfString(catids), ",") + `)
+					;`,
+				).Scan(
+					&catsCount,
+				)
+				if err != nil {
+					tx.Rollback()
+					wrap.MsgError(err.Error())
+					return
+				}
+				if len(catids) != catsCount {
+					tx.Rollback()
+					wrap.MsgError(`Inner system error`)
+					return
+				}
+				var balkInsertArr []string
+				for _, el := range catids {
+					balkInsertArr = append(balkInsertArr, `(NULL,`+utils.Int64ToStr(lastID)+`,`+utils.IntToStr(el)+`)`)
+				}
+				if _, err = tx.Exec(
+					`INSERT INTO blog_cat_post_rel (id,post_id,category_id) VALUES ` + strings.Join(balkInsertArr, ",") + `;`,
+				); err != nil {
+					tx.Rollback()
+					wrap.MsgError(err.Error())
+					return
+				}
+			}
+
+			// Commit all changes and unlock table
+			err = tx.Commit()
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+			_, err = wrap.DB.Exec("UNLOCK TABLES;")
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+
 			wrap.Write(`window.location='/cp/blog/';`)
 		} else {
-			// Update post
-			_, err := wrap.DB.Exec(
+			// Start transaction with table lock
+			_, err := wrap.DB.Exec("LOCK TABLE blog_cats WRITE, blog_cat_post_rel WRITE;")
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+			tx, err := wrap.DB.Begin()
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+
+			// Update row
+			if _, err = tx.Exec(
 				`UPDATE blog_posts SET
 					name = ?,
 					alias = ?,
@@ -546,11 +629,69 @@ func (this *Modules) RegisterAction_BlogModify() *Action {
 				pf_content,
 				pf_active,
 				utils.StrToInt(pf_id),
-			)
+			); err != nil {
+				tx.Rollback()
+				wrap.MsgError(err.Error())
+				return
+			}
+
+			// Delete post and categories relations
+			if _, err = tx.Exec("DELETE FROM blog_cat_post_rel WHERE post_id = ?;", pf_id); err != nil {
+				tx.Rollback()
+				wrap.MsgError(err.Error())
+				return
+			}
+
+			// Insert post and categories relations
+			catids := utils.GetPostArrayInt("cats[]", wrap.R)
+			if len(catids) > 0 {
+				var catsCount int
+				err = tx.QueryRow(`
+					SELECT
+						COUNT(*)
+					FROM
+						blog_cats
+					WHERE
+						id IN(` + strings.Join(utils.ArrayOfIntToArrayOfString(catids), ",") + `)
+					;`,
+				).Scan(
+					&catsCount,
+				)
+				if err != nil {
+					tx.Rollback()
+					wrap.MsgError(err.Error())
+					return
+				}
+				if len(catids) != catsCount {
+					tx.Rollback()
+					wrap.MsgError(`Inner system error`)
+					return
+				}
+				var balkInsertArr []string
+				for _, el := range catids {
+					balkInsertArr = append(balkInsertArr, `(NULL,`+pf_id+`,`+utils.IntToStr(el)+`)`)
+				}
+				if _, err = tx.Exec(
+					`INSERT INTO blog_cat_post_rel (id,post_id,category_id) VALUES ` + strings.Join(balkInsertArr, ",") + `;`,
+				); err != nil {
+					tx.Rollback()
+					wrap.MsgError(err.Error())
+					return
+				}
+			}
+
+			// Commit all changes and unlock table
+			err = tx.Commit()
 			if err != nil {
 				wrap.MsgError(err.Error())
 				return
 			}
+			_, err = wrap.DB.Exec("UNLOCK TABLES;")
+			if err != nil {
+				wrap.MsgError(err.Error())
+				return
+			}
+
 			wrap.Write(`window.location='/cp/blog/modify/` + pf_id + `/';`)
 		}
 	})

+ 57 - 0
utils/utils.go

@@ -223,6 +223,10 @@ func IntToStr(num int) string {
 	return fmt.Sprintf("%d", num)
 }
 
+func Int64ToStr(num int64) string {
+	return fmt.Sprintf("%d", num)
+}
+
 func StrToInt(str string) int {
 	num, err := strconv.Atoi(str)
 	if err == nil {
@@ -310,3 +314,56 @@ func InArrayInt(slice []int, value int) bool {
 	}
 	return false
 }
+
+func InArrayString(slice []string, value string) bool {
+	for _, item := range slice {
+		if item == value {
+			return true
+		}
+	}
+	return false
+}
+
+func GetPostArrayInt(name string, r *http.Request) []int {
+	var ids []int
+	if arr, ok := r.PostForm[name]; ok {
+		for _, el := range arr {
+			if IsNumeric(el) {
+				if !InArrayInt(ids, StrToInt(el)) {
+					ids = append(ids, StrToInt(el))
+				}
+			}
+		}
+	}
+	return ids
+}
+
+func GetPostArrayString(name string, r *http.Request) []string {
+	var ids []string
+	if arr, ok := r.PostForm[name]; ok {
+		for _, el := range arr {
+			if !InArrayString(ids, el) {
+				ids = append(ids, el)
+			}
+		}
+	}
+	return ids
+}
+
+func ArrayOfIntToArrayOfString(arr []int) []string {
+	var res []string
+	for _, el := range arr {
+		res = append(res, IntToStr(el))
+	}
+	return res
+}
+
+func ArrayOfStringToArrayOfInt(arr []string) []int {
+	var res []int
+	for _, el := range arr {
+		if IsNumeric(el) {
+			res = append(res, StrToInt(el))
+		}
+	}
+	return res
+}