增加file驱动

This commit is contained in:
ayflying
2025-05-22 18:11:26 +08:00
parent f22c9df605
commit d8243542fb
3 changed files with 203 additions and 71 deletions

4
go.mod
View File

@@ -4,7 +4,7 @@ go 1.24.0
require ( require (
github.com/apolloconfig/agollo/v4 v4.4.0 github.com/apolloconfig/agollo/v4 v4.4.0
github.com/ayflying/excel2json v1.1.7 github.com/ayflying/excel2json v1.1.8
github.com/elastic/go-elasticsearch/v8 v8.18.0 github.com/elastic/go-elasticsearch/v8 v8.18.0
github.com/go-pay/crypto v0.0.1 github.com/go-pay/crypto v0.0.1
github.com/go-pay/gopay v1.5.109 github.com/go-pay/gopay v1.5.109
@@ -12,7 +12,6 @@ require (
github.com/goccy/go-json v0.10.5 github.com/goccy/go-json v0.10.5
github.com/gogf/gf/contrib/config/apollo/v2 v2.9.0 github.com/gogf/gf/contrib/config/apollo/v2 v2.9.0
github.com/gogf/gf/v2 v2.9.0 github.com/gogf/gf/v2 v2.9.0
github.com/gorilla/websocket v1.5.3
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230 github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20241220152942-06eb5c6e8230
github.com/minio/minio-go/v7 v7.0.91 github.com/minio/minio-go/v7 v7.0.91
github.com/prometheus/client_golang v1.22.0 github.com/prometheus/client_golang v1.22.0
@@ -45,6 +44,7 @@ require (
github.com/golang/protobuf v1.5.4 // indirect github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/gax-go/v2 v2.0.5 // indirect github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/compress v1.18.0 // indirect

1
go.sum
View File

@@ -52,6 +52,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/ayflying/excel2json v1.1.7 h1:gp4Ls6hNXd1EuT2MEiDQ6yPLaSKIFWkGyaNajMTc59c= github.com/ayflying/excel2json v1.1.7 h1:gp4Ls6hNXd1EuT2MEiDQ6yPLaSKIFWkGyaNajMTc59c=
github.com/ayflying/excel2json v1.1.7/go.mod h1:GjXYP2cDzeTgQxssQ3ba8QRa9JsScAeJMwCrZ7QTlQo= github.com/ayflying/excel2json v1.1.7/go.mod h1:GjXYP2cDzeTgQxssQ3ba8QRa9JsScAeJMwCrZ7QTlQo=
github.com/ayflying/excel2json v1.1.8/go.mod h1:GjXYP2cDzeTgQxssQ3ba8QRa9JsScAeJMwCrZ7QTlQo=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=

View File

@@ -3,120 +3,251 @@ package drive
import ( import (
"context" "context"
"github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/container/gvar"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/encoding/gjson"
"github.com/gogf/gf/v2/os/gcache" "github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gconv"
"path" "path"
"strconv"
"strings" "strings"
"sync"
"time" "time"
) )
var (
fileIndex = "index.txt"
)
type FileIndex struct {
File string `json:"file"`
Duration time.Duration `json:"duration"`
}
type FileData struct {
Data interface{} `json:"data"`
Time int64 `json:"time"`
}
type AdapterFile struct { type AdapterFile struct {
FilePath string FilePath string
Lock sync.Mutex
} }
func (a AdapterFile) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error { func (a *AdapterFile) Key2Name(key interface{}) string {
arr := strings.Split(":", gconv.String(key)) md5Str, _ := gmd5.Encrypt(key)
fileName := path.Join(arr...) fileName := path.Join(md5Str[0:2], md5Str[2:4], md5Str[4:6], md5Str[16:])
return gfile.PutBytes(fileName, gconv.Bytes(value)) fileNameAll := path.Join(a.FilePath, fileName)
return fileNameAll
} }
func (a AdapterFile) SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error { func (a *AdapterFile) AddIndex(FileName interface{}, duration time.Duration) {
var isEdit bool
var setTime int64
if duration == 0 {
setTime = 0
} else {
setTime = gtime.Now().Add(duration).Unix()
}
saveArr := []string{
gconv.String(FileName),
strconv.FormatInt(setTime, 10),
}
saveStr := strings.Join(saveArr, "|")
gfile.ReadLines(fileIndex, func(text string) (err error) {
arr := strings.Split(text, "|")
if arr[0] == FileName {
isEdit = true
gfile.ReplaceFile(text, saveStr, fileIndex)
return
}
return
})
if isEdit {
return
}
gfile.PutContentsAppend(fileIndex, saveStr+"\n")
}
func (a *AdapterFile) DelIndex(FileName interface{}) {
//var save bool
gfile.ReadLines(fileIndex, func(text string) (err error) {
arr := strings.Split(text, "|")
if arr[0] == FileName {
//save = true
err = gfile.ReplaceFile(text, "", fileIndex)
return
}
return
})
}
func (a *AdapterFile) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (err error) {
fileNameAll := a.Key2Name(key)
var send = &FileData{
Data: value,
Time: gtime.Now().Add(duration).Unix(),
}
err = gfile.PutBytes(fileNameAll, gjson.MustEncode(send))
if err != nil {
return
}
a.AddIndex(key, duration)
return
}
func (a *AdapterFile) SetMap(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) (err error) {
for k, v := range data {
//fileNameAll := a.Key2Name(k)
//var send = &FileData{
// Data: v,
// Time: gtime.Now().Add(duration).Unix(),
//}
//
//err = gfile.PutBytes(fileNameAll, gconv.Bytes(send))
a.Set(ctx, k, v, duration)
}
return
}
func (a *AdapterFile) SetIfNotExist(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (ok bool, err error) {
err = a.Set(ctx, key, value, duration)
return
}
func (a *AdapterFile) SetIfNotExistFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (ok bool, err error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) SetIfNotExist(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (ok bool, err error) { func (a *AdapterFile) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (ok bool, err error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) SetIfNotExistFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (ok bool, err error) { func (a *AdapterFile) Get(ctx context.Context, key interface{}) (res *gvar.Var, err error) {
var data *FileData
name := a.Key2Name(key)
if !gfile.IsFile(name) {
return
}
file := gfile.GetBytes(name)
gjson.DecodeTo(file, &data)
if data.Time < time.Now().Unix() {
a.Remove(ctx, key)
return
}
res = gvar.New(data.Data)
return
}
func (a *AdapterFile) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) {
a.Set(ctx, key, value, duration)
result, err = a.Get(ctx, key)
return
}
func (a *AdapterFile) GetOrSetFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
value := f
a.Set(ctx, key, value, duration)
result, err = a.Get(ctx, key)
return
}
func (a *AdapterFile) GetOrSetFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) {
a.Lock.Lock()
defer a.Lock.Unlock()
result, err = a.GetOrSetFunc(ctx, key, f, duration)
return
}
func (a *AdapterFile) Contains(ctx context.Context, key interface{}) (bool, error) {
return gfile.IsFile(a.FilePath), nil
}
func (a *AdapterFile) Size(ctx context.Context) (size int, err error) {
size = int(gfile.Size(a.FilePath))
return
}
func (a *AdapterFile) Data(ctx context.Context) (data map[interface{}]interface{}, err error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (ok bool, err error) { func (a *AdapterFile) Keys(ctx context.Context) (keys []interface{}, err error) {
gfile.ReadLines(fileIndex, func(text string) (err error) {
return
})
return
}
func (a *AdapterFile) Values(ctx context.Context) (values []interface{}, err error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) Get(ctx context.Context, key interface{}) (*gvar.Var, error) { func (a *AdapterFile) Update(ctx context.Context, key interface{}, value interface{}) (oldValue *gvar.Var, exist bool, err error) {
fileNameAll := a.Key2Name(key)
getFile := gfile.GetBytes(fileNameAll)
var data *FileData
gconv.Scan(getFile, &data)
oldValue.Set(data.Data)
var send = &FileData{
Data: value,
Time: data.Time,
}
err = gfile.PutBytes(fileNameAll, gconv.Bytes(send))
if err != nil {
return
}
a.AddIndex(key, time.Duration(data.Time-gtime.Now().Unix()))
return
}
func (a *AdapterFile) UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) { func (a *AdapterFile) GetExpire(ctx context.Context, key interface{}) (time.Duration, error) {
//TODO implement me //TODO implement me
panic("implement me") panic("implement me")
} }
func (a AdapterFile) GetOrSetFunc(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) { func (a *AdapterFile) Remove(ctx context.Context, keys ...interface{}) (lastValue *gvar.Var, err error) {
//TODO implement me for _, v := range keys {
panic("implement me") fileNameAll := a.Key2Name(v)
lastValue, err = a.Get(ctx, fileNameAll)
err = gfile.RemoveFile(fileNameAll)
//删除索引文件
a.DelIndex(v)
}
return nil, nil
} }
func (a AdapterFile) GetOrSetFuncLock(ctx context.Context, key interface{}, f gcache.Func, duration time.Duration) (result *gvar.Var, err error) { func (a *AdapterFile) Clear(ctx context.Context) error {
//TODO implement me return gfile.RemoveAll(a.FilePath)
panic("implement me")
} }
func (a AdapterFile) Contains(ctx context.Context, key interface{}) (bool, error) { func (a *AdapterFile) Close(ctx context.Context) error {
//TODO implement me return nil
panic("implement me")
}
func (a AdapterFile) Size(ctx context.Context) (size int, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Data(ctx context.Context) (data map[interface{}]interface{}, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Keys(ctx context.Context) (keys []interface{}, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Values(ctx context.Context) (values []interface{}, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Update(ctx context.Context, key interface{}, value interface{}) (oldValue *gvar.Var, exist bool, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) GetExpire(ctx context.Context, key interface{}) (time.Duration, error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Remove(ctx context.Context, keys ...interface{}) (lastValue *gvar.Var, err error) {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Clear(ctx context.Context) error {
//TODO implement me
panic("implement me")
}
func (a AdapterFile) Close(ctx context.Context) error {
//TODO implement me
panic("implement me")
} }
func NewAdapterFile(filePath string) gcache.Adapter { func NewAdapterFile(filePath string) gcache.Adapter {
fileIndex = path.Join(filePath, fileIndex)
return &AdapterFile{ return &AdapterFile{
FilePath: filePath, FilePath: filePath,
} }