-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b9ec17d
commit f86c903
Showing
19 changed files
with
1,136 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/.project | ||
/.vscode | ||
/.tmp |
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,71 @@ | ||
# Nixys Support Bot Migrate | ||
|
||
This tool helps you to migrate the DB from latest version of [nxs-chat-srv](https://github.com/nixys/nxs-chat-srv) to [Nixys Support Bot](github.com/nixys/nxs-support-bot) v1.0.0. | ||
|
||
In text below lets use following conventions: | ||
- [nxs-chat-srv](https://github.com/nixys/nxs-chat-srv) DB it's an `old` DB | ||
- [Nixys Support Bot](github.com/nixys/nxs-support-bot) DB it's a `new` DB | ||
|
||
What this tool do: | ||
- Cleans up a data in `new` DB | ||
- Migrates necessary data from `old` MySQL to `new` | ||
- Migrates necessary data from `old` Redis to `new` | ||
- While migration all incorrect data from `old` to `new` will be skipped | ||
|
||
## Quickstart | ||
|
||
### Install | ||
|
||
This app is a helper for [Nixys Support Bot](github.com/nixys/nxs-support-bot). Please see Nixys Support Bot readme for installation. | ||
|
||
### Settings | ||
|
||
#### General settings | ||
|
||
| Option | Type | Required | Default value | Description | | ||
|--- | :---: | :---: | :---: |--- | | ||
| `logfile` | String | No | `stdout` | Log file path. Also you may use `stdout` and `stderr` | | ||
| `loglevel` | String | No | `info` | Log level. Available values: `debug`, `warn`, `error` and `info` | | ||
| `pidfile` | String | No | - | Pid file path. If `pidfile` is not set it will not be created | | ||
| `src` | [Src](#src-settings) | Yes | - | Source (`old`) databases settings | | ||
| `dst` | [Dst](#dst-settings) | Yes | - | Destination (`new`) databases settings | | ||
|
||
##### Src settings | ||
|
||
| Option | Type | Required | Default value | Description | | ||
|--- | :---: | :---: | :---: |--- | | ||
| `mysql` | [MySQL](#mysql-settings) | Yes | - | MySQL settings | | ||
| `redis` | [Redis](#redis-settings) | Yes | - | Redis settings | | ||
|
||
##### Dst settings | ||
|
||
| Option | Type | Required | Default value | Description | | ||
|--- | :---: | :---: | :---: |--- | | ||
| `mysql` | [MySQL](#mysql-settings) | Yes | - | MySQL settings | | ||
|
||
##### MySQL settings | ||
|
||
| Option | Type | Required | Default value | Description | | ||
|--- | :---: | :---: | :---: |--- | | ||
| `host` | String | Yes | - | Host to connect | | ||
| `port` | Int | Yes | - | Port to connect | | ||
| `db` | String | Yes | - | DB name to connect | | ||
| `user` | String | Yes | - | User to connect | | ||
| `password` | String | Yes | - | Password to connect | | ||
|
||
##### Redis settings | ||
|
||
| Option | Type | Required | Default value | Description | | ||
|--- | :---: | :---: | :---: |--- | | ||
| `host` | String | Yes | - | Host to connect | | ||
| `port` | Int | Yes | - | Port to connect | | ||
|
||
## Feedback | ||
|
||
For support and feedbak please contact me: | ||
- telegram: [@borisershov](https://t.me/borisershov) | ||
- e-mail: b.ershov@nixys.ru | ||
|
||
## License | ||
|
||
Nixys Support Bot Migrate tool is released under the [GPLv3](LICENSE). |
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,72 @@ | ||
package ctx | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/pborman/getopt/v2" | ||
) | ||
|
||
const ( | ||
confPathDefault = "nxs-support-bot-migrate.conf" | ||
) | ||
|
||
// Args contains arguments value read from command line | ||
type Args struct { | ||
ConfigPath string | ||
} | ||
|
||
// ArgsRead reads arguments from command line | ||
func ArgsRead() Args { | ||
|
||
var a Args | ||
|
||
args := getopt.New() | ||
|
||
helpFlag := args.BoolLong( | ||
"help", | ||
'h', | ||
"Show help") | ||
|
||
versionFlag := args.BoolLong( | ||
"version", | ||
'v', | ||
"Show program version") | ||
|
||
confPath := args.StringLong( | ||
"conf", | ||
'c', | ||
"", | ||
"Config file path") | ||
|
||
args.Parse(os.Args) | ||
|
||
/* Show help */ | ||
if *helpFlag == true { | ||
argsHelp(args) | ||
os.Exit(0) | ||
} | ||
|
||
/* Show version */ | ||
if *versionFlag == true { | ||
argsVersion() | ||
os.Exit(0) | ||
} | ||
|
||
/* Config path */ | ||
if args.IsSet("conf") == true { | ||
a.ConfigPath = *confPath | ||
} else { | ||
a.ConfigPath = confPathDefault | ||
} | ||
|
||
return a | ||
} | ||
|
||
func argsHelp(args *getopt.Set) { | ||
args.PrintUsage(os.Stdout) | ||
} | ||
|
||
func argsVersion() { | ||
fmt.Println("Not specified") | ||
} |
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,51 @@ | ||
package ctx | ||
|
||
import ( | ||
conf "github.com/nixys/nxs-go-conf" | ||
) | ||
|
||
type confOpts struct { | ||
LogFile string `conf:"logfile" conf_extraopts:"default=stdout"` | ||
LogLevel string `conf:"loglevel" conf_extraopts:"default=info"` | ||
PidFile string `conf:"pidfile"` | ||
Src srcConf `conf:"src" conf_extraopts:"required"` | ||
Dst dstConf `conf:"dst" conf_extraopts:"required"` | ||
} | ||
|
||
type srcConf struct { | ||
MySQL mysqlConf `conf:"mysql" conf_extraopts:"required"` | ||
Redis redisConf `conf:"redis" conf_extraopts:"required"` | ||
} | ||
|
||
type dstConf struct { | ||
MySQL mysqlConf `conf:"mysql" conf_extraopts:"required"` | ||
} | ||
|
||
type mysqlConf struct { | ||
Host string `conf:"host" conf_extraopts:"required"` | ||
Port int `conf:"port" conf_extraopts:"required"` | ||
DB string `conf:"db" conf_extraopts:"required"` | ||
User string `conf:"user" conf_extraopts:"required"` | ||
Password string `conf:"password" conf_extraopts:"required"` | ||
} | ||
|
||
type redisConf struct { | ||
Host string `conf:"host" conf_extraopts:"required"` | ||
Port int `conf:"port" conf_extraopts:"required"` | ||
} | ||
|
||
func confRead(confPath string) (confOpts, error) { | ||
|
||
var c confOpts | ||
|
||
err := conf.Load(&c, conf.Settings{ | ||
ConfPath: confPath, | ||
ConfType: conf.ConfigTypeYAML, | ||
UnknownDeny: true, | ||
}) | ||
if err != nil { | ||
return c, err | ||
} | ||
|
||
return c, 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,105 @@ | ||
package ctx | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/nixys/nxs-support-bot-migrate/ds/mysql" | ||
"github.com/nixys/nxs-support-bot-migrate/ds/redis" | ||
|
||
appctx "github.com/nixys/nxs-go-appctx/v2" | ||
) | ||
|
||
// Ctx defines application custom context | ||
type Ctx struct { | ||
Conf confOpts | ||
Src SrcCtx | ||
Dst DstCtx | ||
} | ||
|
||
type SrcCtx struct { | ||
MySQL mysql.MySQL | ||
Redis redis.Redis | ||
} | ||
|
||
type DstCtx struct { | ||
MySQL mysql.MySQL | ||
} | ||
|
||
// Init initiates application custom context | ||
func (c *Ctx) Init(opts appctx.CustomContextFuncOpts) (appctx.CfgData, error) { | ||
|
||
//a := opts.Args.(*Args) | ||
|
||
// Read config file | ||
conf, err := confRead(opts.Config) | ||
if err != nil { | ||
return appctx.CfgData{}, err | ||
} | ||
|
||
// Set application context | ||
c.Conf = conf | ||
|
||
redisHost := fmt.Sprintf("%s:%d", c.Conf.Src.Redis.Host, c.Conf.Src.Redis.Port) | ||
|
||
// Connect to source MySQL | ||
c.Src.MySQL, err = mysql.Connect(mysql.Settings{ | ||
Host: c.Conf.Src.MySQL.Host, | ||
Port: c.Conf.Src.MySQL.Port, | ||
Database: c.Conf.Src.MySQL.DB, | ||
User: c.Conf.Src.MySQL.User, | ||
Password: c.Conf.Src.MySQL.Password, | ||
}) | ||
if err != nil { | ||
return appctx.CfgData{}, err | ||
} | ||
|
||
// Connect to source Redis | ||
c.Src.Redis, err = redis.Connect(redisHost) | ||
if err != nil { | ||
return appctx.CfgData{}, err | ||
} | ||
|
||
// Connect to destination MySQL | ||
c.Dst.MySQL, err = mysql.Connect(mysql.Settings{ | ||
Host: c.Conf.Dst.MySQL.Host, | ||
Port: c.Conf.Dst.MySQL.Port, | ||
Database: c.Conf.Dst.MySQL.DB, | ||
User: c.Conf.Dst.MySQL.User, | ||
Password: c.Conf.Dst.MySQL.Password, | ||
}) | ||
if err != nil { | ||
return appctx.CfgData{}, err | ||
} | ||
|
||
return appctx.CfgData{ | ||
LogFile: c.Conf.LogFile, | ||
LogLevel: c.Conf.LogLevel, | ||
PidFile: c.Conf.PidFile, | ||
}, nil | ||
} | ||
|
||
// Reload reloads application custom context | ||
func (c *Ctx) Reload(opts appctx.CustomContextFuncOpts) (appctx.CfgData, error) { | ||
|
||
opts.Log.Debug("reloading context") | ||
|
||
c.Src.MySQL.Close() | ||
c.Src.Redis.Close() | ||
|
||
c.Dst.MySQL.Close() | ||
|
||
return c.Init(opts) | ||
} | ||
|
||
// Free frees application custom context | ||
func (c *Ctx) Free(opts appctx.CustomContextFuncOpts) int { | ||
|
||
opts.Log.Debug("freeing context") | ||
|
||
c.Src.MySQL.Close() | ||
c.Src.Redis.Close() | ||
|
||
c.Dst.MySQL.Close() | ||
|
||
return 0 | ||
} |
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,61 @@ | ||
package mysql | ||
|
||
const dstFeedbackIssuesTableName = "feedback_issues" | ||
|
||
type DstFeedbackIssue struct { | ||
TgUserID int64 `gorm:"column:tlgrm_userid"` | ||
RdmnIssueID int64 `gorm:"column:rdmn_issue_id"` | ||
} | ||
|
||
type DstFeedbackIssueInsertData struct { | ||
TgUserID int64 `gorm:"column:tlgrm_userid"` | ||
RdmnIssueID int64 `gorm:"column:rdmn_issue_id"` | ||
} | ||
|
||
func (DstFeedbackIssue) TableName() string { | ||
return dstFeedbackIssuesTableName | ||
} | ||
|
||
func (DstFeedbackIssueInsertData) TableName() string { | ||
return dstFeedbackIssuesTableName | ||
} | ||
|
||
func (m *MySQL) DstFeedbackIssuesSave(issues []DstFeedbackIssueInsertData) error { | ||
|
||
if len(issues) == 0 { | ||
return nil | ||
} | ||
|
||
r := m.client. | ||
Create(&issues) | ||
if r.Error != nil { | ||
return r.Error | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (m *MySQL) DstFeedbackIssuesGet() ([]DstFeedbackIssue, error) { | ||
|
||
issues := []DstFeedbackIssue{} | ||
|
||
r := m.client. | ||
Find(&issues) | ||
if r.Error != nil { | ||
return nil, r.Error | ||
} | ||
|
||
return issues, nil | ||
} | ||
|
||
func (m *MySQL) DstFeedbackIssuesDeleteAll() error { | ||
|
||
r := m.client. | ||
Where("1 = 1"). | ||
Delete(DstFeedbackIssue{}) | ||
if r.Error != nil { | ||
return r.Error | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.