feat(canvas): 画布同步 - 新增操作事务、预演保存与并发恢复能力
This commit is contained in:
1 parent
6dedc5973c
commit
5f359f2b1d
63 files changed
+3234
-6192
No files matched your search
@@ -0,0 +1,47 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"yingce/backend/internal/model"
|
||||
)
|
||||
|
||||
// LockCanvasMutation serializes all operations for an existing canvas, including
|
||||
// deletion. On SQLite this first write also avoids a deferred read transaction
|
||||
// trying to upgrade its stale snapshot to a write lock.
|
||||
func (r *Repository) LockCanvasMutation(userID, canvasID string) error {
|
||||
return r.db.Model(&model.CanvasProject{}).Where("id = ? AND user_id = ?", canvasID, userID).
|
||||
UpdateColumn("revision", gorm.Expr("revision")).Error
|
||||
}
|
||||
|
||||
func (r *Repository) CanvasMutationReceiptForUser(userID, canvasID, mutationID string) (*model.CanvasMutationReceipt, error) {
|
||||
var receipt model.CanvasMutationReceipt
|
||||
err := r.db.First(&receipt, "user_id = ? AND canvas_id = ? AND mutation_id = ?", userID, canvasID, mutationID).Error
|
||||
return &receipt, err
|
||||
}
|
||||
|
||||
func (r *Repository) TryCreateCanvasMutationReceipt(receipt *model.CanvasMutationReceipt) (bool, error) {
|
||||
if receipt.CreatedAt.IsZero() {
|
||||
receipt.CreatedAt = time.Now().UTC()
|
||||
}
|
||||
result := r.db.Clauses(clause.OnConflict{Columns: []clause.Column{{Name: "user_id"}, {Name: "canvas_id"}, {Name: "mutation_id"}}, DoNothing: true}).Create(receipt)
|
||||
return result.RowsAffected == 1, result.Error
|
||||
}
|
||||
|
||||
func (r *Repository) FinalizeCanvasMutationReceipt(receipt *model.CanvasMutationReceipt) error {
|
||||
if receipt.ResultJSON == "" {
|
||||
return errors.New("canvas mutation receipt requires a committed result")
|
||||
}
|
||||
result := r.db.Model(&model.CanvasMutationReceipt{}).Where("id = ? AND payload_digest = ?", receipt.ID, receipt.PayloadDigest).
|
||||
Updates(map[string]any{"result_json": receipt.ResultJSON, "revision": receipt.Revision})
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
if result.RowsAffected != 1 {
|
||||
return errors.New("canvas mutation receipt was not finalized")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user