mirror of
https://github.com/mayswind/ezbookkeeping.git
synced 2026-05-18 16:54:25 +08:00
support using duplicate checker to prevent duplicate submissions for new transaction record
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
package duplicatechecker
|
||||
|
||||
// DuplicateChecker is common duplicate checker interface
|
||||
type DuplicateChecker interface {
|
||||
Get(checkerType DuplicateCheckerType, uid int64, identification string) (bool, string)
|
||||
Set(checkerType DuplicateCheckerType, uid int64, identification string, remark string)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package duplicatechecker
|
||||
|
||||
import (
|
||||
"github.com/mayswind/ezbookkeeping/pkg/errs"
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
)
|
||||
|
||||
// DuplicateCheckerContainer contains the current duplicate checker
|
||||
type DuplicateCheckerContainer struct {
|
||||
Current DuplicateChecker
|
||||
}
|
||||
|
||||
// Initialize a duplicate checker container singleton instance
|
||||
var (
|
||||
Container = &DuplicateCheckerContainer{}
|
||||
)
|
||||
|
||||
// InitializeDuplicateChecker initializes the current duplicate checker according to the config
|
||||
func InitializeDuplicateChecker(config *settings.Config) error {
|
||||
if config.DuplicateCheckerType == settings.InMemoryDuplicateCheckerType {
|
||||
checker, err := NewInMemoryDuplicateChecker(config)
|
||||
Container.Current = checker
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return errs.ErrInvalidDuplicateCheckerType
|
||||
}
|
||||
|
||||
// Get returns whether the same submission has been processed and related remark by the current duplicate checker
|
||||
func (c *DuplicateCheckerContainer) Get(checkerType DuplicateCheckerType, uid int64, identification string) (bool, string) {
|
||||
return c.Current.Get(checkerType, uid, identification)
|
||||
}
|
||||
|
||||
// Set saves the identification and remark to in-memory cache by the current duplicate checker
|
||||
func (c *DuplicateCheckerContainer) Set(checkerType DuplicateCheckerType, uid int64, identification string, remark string) {
|
||||
c.Current.Set(checkerType, uid, identification, remark)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package duplicatechecker
|
||||
|
||||
// DuplicateCheckerType represents duplicate checker type
|
||||
type DuplicateCheckerType uint8
|
||||
|
||||
// Types of uuid
|
||||
const (
|
||||
DUPLICATE_CHECKER_TYPE_DEFAULT DuplicateCheckerType = 0
|
||||
DUPLICATE_CHECKER_TYPE_NEW_ACCOUNT DuplicateCheckerType = 1
|
||||
DUPLICATE_CHECKER_TYPE_NEW_CATEGORY DuplicateCheckerType = 2
|
||||
DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION DuplicateCheckerType = 3
|
||||
)
|
||||
@@ -0,0 +1,43 @@
|
||||
package duplicatechecker
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/patrickmn/go-cache"
|
||||
|
||||
"github.com/mayswind/ezbookkeeping/pkg/settings"
|
||||
)
|
||||
|
||||
// InMemoryDuplicateChecker represents in-memory duplicate checker
|
||||
type InMemoryDuplicateChecker struct {
|
||||
cache *cache.Cache
|
||||
}
|
||||
|
||||
// NewInMemoryDuplicateChecker returns a new in-memory duplicate checker
|
||||
func NewInMemoryDuplicateChecker(config *settings.Config) (*InMemoryDuplicateChecker, error) {
|
||||
checker := &InMemoryDuplicateChecker{
|
||||
cache: cache.New(config.DuplicateSubmissionsIntervalDuration, config.InMemoryDuplicateCheckerCleanupIntervalDuration),
|
||||
}
|
||||
|
||||
return checker, nil
|
||||
}
|
||||
|
||||
// Get returns whether the same submission has been processed and related remark
|
||||
func (c *InMemoryDuplicateChecker) Get(checkerType DuplicateCheckerType, uid int64, identification string) (bool, string) {
|
||||
existedRemark, found := c.cache.Get(c.getCacheKey(checkerType, uid, identification))
|
||||
|
||||
if found {
|
||||
return true, existedRemark.(string)
|
||||
}
|
||||
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// Set saves the identification and remark to in-memory cache
|
||||
func (c *InMemoryDuplicateChecker) Set(checkerType DuplicateCheckerType, uid int64, identification string, remark string) {
|
||||
c.cache.Set(c.getCacheKey(checkerType, uid, identification), remark, cache.DefaultExpiration)
|
||||
}
|
||||
|
||||
func (c *InMemoryDuplicateChecker) getCacheKey(checkerType DuplicateCheckerType, uid int64, identification string) string {
|
||||
return fmt.Sprintf("%d|%d|%s", checkerType, uid, identification)
|
||||
}
|
||||
Reference in New Issue
Block a user