Skip to content

Commit 745261a

Browse files
committed
refactor: 修改为基于SqlStorage实现
1 parent 52e39f0 commit 745261a

File tree

4 files changed

+49
-245
lines changed

4 files changed

+49
-245
lines changed

go.mod

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@ go 1.19
44

55
require (
66
github.com/go-sql-driver/mysql v1.7.1
7-
github.com/golang-infrastructure/go-iterator v0.0.0-20230524171120-56988a9b127c
7+
github.com/storage-lock/go-sql-based-storage v0.0.0-20230815152553-e6057f9c32e7
88
github.com/storage-lock/go-storage v0.0.2
9-
github.com/storage-lock/go-storage-lock v0.0.2
109
github.com/storage-lock/go-storage-test-helper v0.0.2
1110
github.com/stretchr/testify v1.8.4
1211
)
1312

1413
require (
1514
github.com/davecgh/go-spew v1.1.1 // indirect
1615
github.com/golang-infrastructure/go-goroutine-id v0.0.0-20230331174358-98b48a64077b // indirect
16+
github.com/golang-infrastructure/go-iterator v0.0.0-20230524171120-56988a9b127c // indirect
1717
github.com/golang-infrastructure/go-pointer v0.0.5 // indirect
1818
github.com/golang-infrastructure/go-reflect-utils v0.0.0-20221130143747-965ef2eb09c3 // indirect
1919
github.com/google/uuid v1.3.0 // indirect
2020
github.com/pmezard/go-difflib v1.0.0 // indirect
21-
github.com/storage-lock/go-events v0.0.1 // indirect
22-
github.com/storage-lock/go-storage-events v0.0.2 // indirect
21+
github.com/storage-lock/go-events v0.0.3 // indirect
22+
github.com/storage-lock/go-storage-events v0.0.5 // indirect
23+
github.com/storage-lock/go-storage-lock v0.0.3 // indirect
2324
github.com/storage-lock/go-utils v0.0.2 // indirect
2425
gopkg.in/yaml.v3 v3.0.1 // indirect
2526
)

go.sum

+8-14
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,16 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
1717
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1818
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1919
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
20-
github.com/storage-lock/go-events v0.0.1 h1:8abGhlhmJGzn8Pq/LjAbPfAyGs70ZNjwoc7/OITMmUg=
21-
github.com/storage-lock/go-events v0.0.1/go.mod h1:DKwPgfuq8T8CyPLipH+0XHsNt8hEN4g9krUGfosU2oY=
22-
github.com/storage-lock/go-storage v0.0.1 h1:BmIoykW2elNnw5EircFroo353YoIudLXO6LhOuk3xYs=
23-
github.com/storage-lock/go-storage v0.0.1/go.mod h1:tfqgPpnU+NQrcor2WQL4XIbhux4vfue9XzT9ETTd5Ig=
20+
github.com/storage-lock/go-events v0.0.3 h1:QuNbaREe5m1WYC0meKs7SRJ5lY11a18jCJJS/mGD3SA=
21+
github.com/storage-lock/go-events v0.0.3/go.mod h1:DKwPgfuq8T8CyPLipH+0XHsNt8hEN4g9krUGfosU2oY=
22+
github.com/storage-lock/go-sql-based-storage v0.0.0-20230815152553-e6057f9c32e7 h1:WbtCSU+1NC4eO0QwehH4aQNLGBm9SUyvo39aMEYLFjE=
23+
github.com/storage-lock/go-sql-based-storage v0.0.0-20230815152553-e6057f9c32e7/go.mod h1:kKR7bTZ59cP7jK0tFhQ4yz2hD2XAL8A97Haql9NAygI=
2424
github.com/storage-lock/go-storage v0.0.2 h1:N5glUlrr1bbJ8ixYsPmOv+TuhIOObX/65+hrNMPWFDc=
2525
github.com/storage-lock/go-storage v0.0.2/go.mod h1:4vuU2nLdbmzj2UIBKpwB5lj8RI+GnPDZ4YHZ7QAcFHE=
26-
github.com/storage-lock/go-storage-events v0.0.1 h1:NIwf0u8HEzY6Azw2wukvMQLglN5r4xPS/AcjUJiZ1qc=
27-
github.com/storage-lock/go-storage-events v0.0.1/go.mod h1:Ph6p2Nbi5VuB0aGRRIBNkn5G3xvSyhZIEqhRf3gc12Y=
28-
github.com/storage-lock/go-storage-events v0.0.2 h1:gXGiltZvRzZOXsjqhlyessa+Zpk4qI2kjyRGAGsknwM=
29-
github.com/storage-lock/go-storage-events v0.0.2/go.mod h1:+8kr/WdyaVUJiCqi2MKZkWxeIF8DmhTm+s0OkE+XKaw=
30-
github.com/storage-lock/go-storage-lock v0.0.1 h1:60lvEHQkSqbn0kJY930ZyaygHRz8aIbxHWNSST32ctg=
31-
github.com/storage-lock/go-storage-lock v0.0.1/go.mod h1:SVAbvdYubsZHm8/MgPHKjsHuKLSERB00+clT/QLzoMM=
32-
github.com/storage-lock/go-storage-lock v0.0.2 h1:bN2UG+PFwBToRtTSv4QjwSg/C3ytr7GASMnW1r4X8ZM=
33-
github.com/storage-lock/go-storage-lock v0.0.2/go.mod h1:M+938bLIuzkC6kvIrOimWPtQyoj8mHcERvRMabtuabk=
34-
github.com/storage-lock/go-storage-test-helper v0.0.1 h1:GxCCHIlLuQuPWXzX+Uow+BmKy5P94JkQaSEzcA5A4n0=
35-
github.com/storage-lock/go-storage-test-helper v0.0.1/go.mod h1:XgwQ2cn8NQTW1VfE1XmQjwFuKlqUWJbumK5av7mH5h0=
26+
github.com/storage-lock/go-storage-events v0.0.5 h1:qUgB/VZIQNM0PIos67T9D1JIqu3Yiu3+YDpuHEal3FI=
27+
github.com/storage-lock/go-storage-events v0.0.5/go.mod h1:aBMVsOSr61+BLxO3QnU5FwKd5bdMGE4IpV0oDrAg8uQ=
28+
github.com/storage-lock/go-storage-lock v0.0.3 h1:eobL73fhfAjLKNk4msQNTYFcilrPKwySXY/5ympfeRU=
29+
github.com/storage-lock/go-storage-lock v0.0.3/go.mod h1:kzyjFhgPmiYMwLuuVoQfYxXPUOIGNETA+Z/wDnRc/iw=
3630
github.com/storage-lock/go-storage-test-helper v0.0.2 h1:6uipDmyxhncEJJSVwPiydKJrGVLoFARwbnkarDfhWSY=
3731
github.com/storage-lock/go-storage-test-helper v0.0.2/go.mod h1:JrQptW0yJZVqDsObE9vWSoyZxhQHdQDM8/eh4vz7Tls=
3832
github.com/storage-lock/go-utils v0.0.2 h1:pdacTOlD+AHqwWVmDqZLcjKF+7p8TjsmlvZ9bmmkIfE=

mysql_storage.go

+22-227
Original file line numberDiff line numberDiff line change
@@ -2,255 +2,50 @@ package mysql_storage
22

33
import (
44
"context"
5-
"errors"
6-
"fmt"
7-
"github.com/golang-infrastructure/go-iterator"
8-
"github.com/storage-lock/go-storage"
9-
storage_lock "github.com/storage-lock/go-storage-lock"
10-
"time"
11-
125
_ "github.com/go-sql-driver/mysql"
6+
sql_based_storage "github.com/storage-lock/go-sql-based-storage"
7+
"github.com/storage-lock/go-storage"
138
)
149

1510
type MySQLStorage struct {
16-
options *MySQLStorageOptions
17-
tableFullName string
11+
*sql_based_storage.SqlBasedStorage
12+
options *MySQLStorageOptions
1813
}
1914

2015
var _ storage.Storage = &MySQLStorage{}
2116

2217
func NewMySQLStorage(ctx context.Context, options *MySQLStorageOptions) (*MySQLStorage, error) {
23-
s := &MySQLStorage{
24-
options: options,
25-
}
2618

27-
err := s.Init(ctx)
28-
if err != nil {
19+
// 参数检查
20+
if err := options.Check(); err != nil {
2921
return nil, err
3022
}
3123

32-
return s, nil
33-
}
34-
35-
const StorageName = "mysql-storage"
36-
37-
func (x *MySQLStorage) GetName() string {
38-
return StorageName
39-
}
40-
41-
func (x *MySQLStorage) Init(ctx context.Context) (returnError error) {
42-
db, err := x.options.ConnectionManager.Take(ctx)
43-
if err != nil {
44-
return err
45-
}
46-
defer func() {
47-
err := x.options.ConnectionManager.Return(ctx, db)
48-
if returnError == nil {
49-
returnError = err
50-
}
51-
}()
52-
53-
// TODO 要不要自动创建数据库呢?这是一个值得讨论的问题。
54-
// 用户有可能是想把数据库连接放到当前的数据库下,也可能是想放到别的数据库下
55-
// 如果想放到别的数据库下,用户应该为其创建专门的数据库
56-
// 如果是复用连接的话,则有可能会有需求是切换数据库,也许这里只应该标记一下,作为能够用之后的优化项
57-
58-
// 创建存储锁信息需要的表
59-
// TODO 这个参数后面涉及到多处拼接sql,可能会有sql注入,是否需要做一些安全措施?
60-
tableFullName := x.options.TableName
61-
if tableFullName == "" {
62-
tableFullName = fmt.Sprintf("`%s`.`%s`", storage.DefaultStorageDatabaseName, storage.DefaultStorageTableName)
63-
}
64-
createTableSql := `CREATE TABLE IF NOT EXISTS %s (
65-
lock_id VARCHAR(255) NOT NULL PRIMARY KEY,
66-
owner_id VARCHAR(255) NOT NULL,
67-
version BIGINT NOT NULL,
68-
lock_information_json_string VARCHAR(255) NOT NULL
69-
)`
70-
_, err = db.Exec(fmt.Sprintf(createTableSql, tableFullName))
71-
if err != nil {
72-
return err
73-
}
74-
75-
x.tableFullName = tableFullName
76-
77-
return nil
78-
}
79-
80-
func (x *MySQLStorage) UpdateWithVersion(ctx context.Context, lockId string, exceptedVersion, newVersion storage.Version, lockInformation *storage.LockInformation) (returnError error) {
81-
82-
db, err := x.options.ConnectionManager.Take(ctx)
83-
if err != nil {
84-
return err
85-
}
86-
defer func() {
87-
err := x.options.ConnectionManager.Return(ctx, db)
88-
if returnError == nil {
89-
returnError = err
90-
}
91-
}()
92-
93-
insertSql := fmt.Sprintf(`UPDATE %s SET version = ?, lock_information_json_string = ? WHERE lock_id = ? AND owner_id = ? AND version = ?`, x.tableFullName)
94-
execContext, err := db.ExecContext(ctx, insertSql, newVersion, lockInformation.ToJsonString(), lockId, lockInformation.OwnerId, exceptedVersion)
95-
if err != nil {
96-
return err
97-
}
98-
affected, err := execContext.RowsAffected()
99-
if err != nil {
100-
return err
101-
}
102-
if affected == 0 {
103-
return storage_lock.ErrVersionMiss
104-
}
105-
return nil
106-
}
107-
108-
func (x *MySQLStorage) CreateWithVersion(ctx context.Context, lockId string, version storage.Version, lockInformation *storage.LockInformation) (returnError error) {
109-
110-
db, err := x.options.ConnectionManager.Take(ctx)
111-
if err != nil {
112-
return err
113-
}
114-
defer func() {
115-
err := x.options.ConnectionManager.Return(ctx, db)
116-
if returnError == nil {
117-
returnError = err
118-
}
119-
}()
120-
121-
insertSql := fmt.Sprintf(`INSERT INTO %s (lock_id, owner_id, version, lock_information_json_string) VALUES (?, ?, ?, ?)`, x.tableFullName)
122-
execContext, err := db.ExecContext(ctx, insertSql, lockId, lockInformation.OwnerId, version, lockInformation.ToJsonString())
123-
if err != nil {
124-
return err
125-
}
126-
affected, err := execContext.RowsAffected()
127-
if err != nil {
128-
return err
129-
}
130-
if affected == 0 {
131-
return storage_lock.ErrVersionMiss
132-
}
133-
return nil
134-
}
135-
136-
func (x *MySQLStorage) DeleteWithVersion(ctx context.Context, lockId string, exceptedVersion storage.Version, lockInformation *storage.LockInformation) (returnError error) {
137-
138-
db, err := x.options.ConnectionManager.Take(ctx)
139-
if err != nil {
140-
return err
141-
}
142-
defer func() {
143-
err := x.options.ConnectionManager.Return(ctx, db)
144-
if returnError == nil {
145-
returnError = err
146-
}
147-
}()
148-
149-
deleteSql := fmt.Sprintf(`DELETE FROM %s WHERE lock_id = ? AND owner_id = ? AND version = ?`, x.tableFullName)
150-
execContext, err := db.ExecContext(ctx, deleteSql, lockId, lockInformation.OwnerId, exceptedVersion)
151-
if err != nil {
152-
return err
153-
}
154-
affected, err := execContext.RowsAffected()
155-
if err != nil {
156-
return err
157-
}
158-
if affected == 0 {
159-
return storage_lock.ErrVersionMiss
160-
}
161-
return nil
162-
}
163-
164-
func (x *MySQLStorage) Get(ctx context.Context, lockId string) (lockInformationJsonString string, returnError error) {
165-
166-
db, err := x.options.ConnectionManager.Take(ctx)
167-
if err != nil {
168-
return "", err
169-
}
170-
defer func() {
171-
err := x.options.ConnectionManager.Return(ctx, db)
172-
if returnError == nil {
173-
returnError = err
174-
}
175-
}()
176-
177-
getLockSql := fmt.Sprintf("SELECT lock_information_json_string FROM %s WHERE lock_id = ?", x.tableFullName)
178-
rs, err := db.Query(getLockSql, lockId)
179-
if err != nil {
180-
return "", err
181-
}
182-
defer func() {
183-
_ = rs.Close()
184-
}()
185-
if !rs.Next() {
186-
return "", storage_lock.ErrLockNotFound
187-
}
188-
err = rs.Scan(&lockInformationJsonString)
24+
// sql storage的基础Storage
25+
baseStorageOption := sql_based_storage.NewSqlBasedStorageOptions().
26+
SetConnectionManager(options.ConnectionManager).
27+
SetSqlProvider(sql_based_storage.NewSql97Provider()).
28+
SetTableFullName(options.TableName)
29+
baseStorage, err := sql_based_storage.NewSqlBasedStorage(baseStorageOption)
18930
if err != nil {
190-
return "", err
31+
return nil, err
19132
}
192-
return lockInformationJsonString, nil
193-
}
194-
195-
func (x *MySQLStorage) GetTime(ctx context.Context) (now time.Time, returnError error) {
19633

197-
db, err := x.options.ConnectionManager.Take(ctx)
198-
if err != nil {
199-
return time.Time{}, err
34+
s := &MySQLStorage{
35+
SqlBasedStorage: baseStorage,
36+
options: options,
20037
}
201-
defer func() {
202-
err := x.options.ConnectionManager.Return(ctx, db)
203-
if returnError == nil {
204-
returnError = err
205-
}
206-
}()
20738

208-
var zero time.Time
209-
// TODO 多实例的情况下可能会有问题,允许其能够比较方便的切换到NTP TimeProvider
210-
rs, err := db.Query("SELECT UNIX_TIMESTAMP(NOW())")
39+
err = s.Init(ctx)
21140
if err != nil {
212-
return zero, err
213-
}
214-
defer func() {
215-
err := rs.Close()
216-
if returnError == nil {
217-
returnError = err
218-
}
219-
}()
220-
if !rs.Next() {
221-
return zero, errors.New("rs server time failed")
222-
}
223-
var databaseTimestamp uint64
224-
err = rs.Scan(&databaseTimestamp)
225-
if err != nil {
226-
return zero, err
41+
return nil, err
22742
}
22843

229-
// TODO 时区
230-
return time.Unix(int64(databaseTimestamp), 0), nil
231-
}
232-
233-
func (x *MySQLStorage) Close(ctx context.Context) error {
234-
// 没有Storage级别的资源好回收的
235-
return nil
44+
return s, nil
23645
}
23746

238-
func (x *MySQLStorage) List(ctx context.Context) (iterator iterator.Iterator[*storage.LockInformation], returnError error) {
239-
240-
db, err := x.options.ConnectionManager.Take(ctx)
241-
if err != nil {
242-
return nil, err
243-
}
244-
defer func() {
245-
err := x.options.ConnectionManager.Return(ctx, db)
246-
if returnError == nil {
247-
returnError = err
248-
}
249-
}()
47+
const StorageName = "mysql-storage"
25048

251-
rows, err := db.Query("SELECT * FROM %s", x.tableFullName)
252-
if err != nil {
253-
return nil, err
254-
}
255-
return storage.NewSqlRowsIterator(rows), nil
49+
func (x *MySQLStorage) GetName() string {
50+
return StorageName
25651
}

mysql_storage_options.go

+14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mysql_storage
22

33
import (
44
"database/sql"
5+
"fmt"
56
"github.com/storage-lock/go-storage"
67
)
78

@@ -30,3 +31,16 @@ func (x *MySQLStorageOptions) SetTableName(tableName string) *MySQLStorageOption
3031
x.TableName = tableName
3132
return x
3233
}
34+
35+
func (x *MySQLStorageOptions) Check() error {
36+
37+
if x.TableName == "" {
38+
x.TableName = storage.DefaultStorageDatabaseName
39+
}
40+
41+
if x.ConnectionManager == nil {
42+
return fmt.Errorf("MySQLStorageOptions.ConnectionManager can not nil")
43+
}
44+
45+
return nil
46+
}

0 commit comments

Comments
 (0)