-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: add sequencer api component by mysql #509
Closed
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
c0768f5
feature: add sequencer api component by mysql
GimmeCyy 05e6e7c
Merge branch 'main' into feature/mysql
seeflood 70751ae
Merge branch 'main' into feature/mysql
seeflood 70b0751
Merge branch 'main' into feature/mysql
seeflood 37f7442
Merge branch 'main' into feature/mysql
seeflood 4acc0ef
feature: add sequencer api component by mysql
GimmeCyy 152a815
Merge remote-tracking branch 'origin/feature/mysql' into feature/mysql
GimmeCyy 04e6bdc
feature: add sequencer api component by mysql
GimmeCyy 810b6fc
feature: add sequencer api component by mysql
GimmeCyy 90f272f
feature: add sequencer api component by mysql
GimmeCyy 0eb449e
feature: add sequencer api component by mysql
GimmeCyy dae9d55
Merge branch 'main' into feature/mysql
seeflood 47dc077
Merge branch 'main' into feature/mysql
seeflood f32884d
feature: add sequencer api component by mysql
GimmeCyy ba9bd33
Merge remote-tracking branch 'origin/feature/mysql' into feature/mysql
GimmeCyy ae98100
Merge branch 'main' into feature/mysql
seeflood 4e37ef9
fix: sequencer api component by mysql
GimmeCyy 9fc22e9
Merge remote-tracking branch 'origin/feature/mysql' into feature/mysql
GimmeCyy 2bdeef7
fix: sequencer api component by mysql
GimmeCyy 131a665
Merge branch 'main' into feature/mysql
seeflood 77fba98
Merge branch 'main' into feature/mysql
seeflood 681ed86
Merge branch 'main' into feature/mysql
seeflood d35ec1a
Merge branch 'main' into feature/mysql
seeflood File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// | ||
// Copyright 2021 Layotto Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
package utils | ||
|
||
import ( | ||
"database/sql" | ||
_ "github.com/go-sql-driver/mysql" | ||
) | ||
|
||
var ( | ||
Db *sql.DB | ||
) | ||
|
||
const ( | ||
defaultTableName = "tableName" | ||
tableNameKey = "tableName" | ||
connectionStringKey = "connectionString" | ||
dataBaseName = "dataBaseName" | ||
) | ||
|
||
type MySQLMetadata struct { | ||
TableName string | ||
ConnectionString string | ||
DataBaseName string | ||
Db *sql.DB | ||
} | ||
|
||
func ParseMySQLMetadata(properties map[string]string, db *sql.DB) (MySQLMetadata, error) { | ||
m := MySQLMetadata{} | ||
|
||
if val, ok := properties[tableNameKey]; ok && val != "" { | ||
m.TableName = val | ||
} | ||
|
||
if val, ok := properties[connectionStringKey]; ok && val != "" { | ||
m.ConnectionString = val | ||
} | ||
|
||
if val, ok := properties[dataBaseName]; ok && val != "" { | ||
m.DataBaseName = val | ||
} | ||
m.Db = db | ||
return m, nil | ||
} | ||
|
||
func NewMySQLClient(meta MySQLMetadata) error { | ||
|
||
val := meta | ||
|
||
if val.TableName == "" { | ||
val.TableName = defaultTableName | ||
} | ||
|
||
return tableExists(meta) | ||
} | ||
|
||
func tableExists(meta MySQLMetadata) error { | ||
exists := "" | ||
|
||
query := `SELECT EXISTS ( | ||
SELECT * FROM ? WHERE TABLE_NAME = ? | ||
) AS 'exists'` | ||
err := meta.Db.QueryRow(query, meta.DataBaseName, meta.TableName).Scan(&exists) | ||
|
||
if exists == "1" { | ||
return nil | ||
} else { | ||
return err | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// | ||
// Copyright 2021 Layotto Authors | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
package mysql | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"mosn.io/layotto/components/pkg/utils" | ||
"mosn.io/layotto/components/sequencer" | ||
"mosn.io/pkg/log" | ||
) | ||
|
||
type MySQLSequencer struct { | ||
metadata utils.MySQLMetadata | ||
biggerThan map[string]int64 | ||
logger log.ErrorLogger | ||
ctx context.Context | ||
cancel context.CancelFunc | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
func NewMySQLSequencer(logger log.ErrorLogger) *MySQLSequencer { | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s := &MySQLSequencer{ | ||
logger: logger, | ||
} | ||
|
||
return s | ||
} | ||
|
||
func (e *MySQLSequencer) Init(config sequencer.Configuration, db *sql.DB) error { | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
m, err := utils.ParseMySQLMetadata(config.Properties, db) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
e.metadata = m | ||
e.biggerThan = config.BiggerThan | ||
|
||
if err = utils.NewMySQLClient(e.metadata); err != nil { | ||
return err | ||
} | ||
e.ctx, e.cancel = context.WithCancel(context.Background()) | ||
|
||
if len(e.biggerThan) > 0 { | ||
var Key string | ||
var Value int64 | ||
for k, bt := range e.biggerThan { | ||
if bt <= 0 { | ||
continue | ||
} else { | ||
m.Db.QueryRow(fmt.Sprintf("SELECT * FROM %s WHERE sequencer_key = ?", m.TableName), k).Scan(&Key, &Value) | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if Value < bt { | ||
return fmt.Errorf("MySQL sequencer error: can not satisfy biggerThan guarantee.key: %s,key in MySQL: %s", k, Key) | ||
} | ||
} | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (e *MySQLSequencer) GetNextId(req *sequencer.GetNextIdRequest, db *sql.DB) (*sequencer.GetNextIdResponse, error) { | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
metadata, err := utils.ParseMySQLMetadata(req.Metadata, db) | ||
|
||
var Key string | ||
var Value int64 | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
begin, err := metadata.Db.Begin() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = begin.QueryRow("SELECT sequencer_key,sequencer_value FROM ? WHERE sequencer_key = ?", metadata.TableName, req.Key).Scan(&Key, &Value) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
Value += 1 | ||
_, err1 := begin.Exec("UPDATE ? SET sequencer_value = ? WHERE sequencer_key = ?", metadata.TableName, Value, req.Key) | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if err1 != nil { | ||
return nil, err1 | ||
} | ||
|
||
Value += 1 | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if _, err2 := begin.Exec("INSERT INTO ?(sequencer_key, sequencer_value) VALUES(?,?)", metadata.TableName, req.Key, Value); err2 != nil { | ||
return nil, err2 | ||
} | ||
|
||
e.Close(metadata.Db) | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return &sequencer.GetNextIdResponse{ | ||
NextId: Value, | ||
}, nil | ||
} | ||
|
||
func (e *MySQLSequencer) GetSegment(req *sequencer.GetSegmentRequest, db *sql.DB) (support bool, result *sequencer.GetSegmentResponse, err error) { | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if req.Size == 0 { | ||
return true, nil, nil | ||
} | ||
|
||
metadata, err := utils.ParseMySQLMetadata(req.Metadata, db) | ||
|
||
var Key string | ||
var Value int64 | ||
if err != nil { | ||
return false, nil, err | ||
} | ||
|
||
begin, err := metadata.Db.Begin() | ||
if err != nil { | ||
return false, nil, err | ||
} | ||
|
||
err = begin.QueryRow("SELECT sequencer_key,sequencer_value FROM ? WHERE sequencer_key = ?", metadata.TableName, req.Key).Scan(&Key, &Value) | ||
if err != nil { | ||
return false, nil, err | ||
} | ||
Value += int64(req.Size) | ||
|
||
_, err1 := begin.Exec("UPDATE ? SET sequencer_value = ? WHERE sequencer_key = ?", metadata.TableName, Value, req.Key) | ||
if err1 != nil { | ||
return false, nil, err1 | ||
} | ||
|
||
if _, err2 := begin.Exec("INSERT INTO ?(sequencer_key, sequencer_value) VALUES(?,?)", metadata.TableName, req.Key, Value+1); err2 != nil { | ||
return false, nil, err2 | ||
} | ||
|
||
e.Close(metadata.Db) | ||
GimmeCyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return false, &sequencer.GetSegmentResponse{ | ||
From: Value - int64(req.Size) + 1, | ||
To: Value, | ||
}, nil | ||
} | ||
|
||
func (e *MySQLSequencer) Close(db *sql.DB) error { | ||
|
||
return db.Close() | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change defaultTableName to another? such as
layotto_sequencer