Skip to content

Commit

Permalink
Init code
Browse files Browse the repository at this point in the history
  • Loading branch information
borisershov committed Jun 15, 2023
1 parent b9ec17d commit f86c903
Show file tree
Hide file tree
Showing 19 changed files with 1,136 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.project
/.vscode
/.tmp
71 changes: 71 additions & 0 deletions README.md
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).
72 changes: 72 additions & 0 deletions ctx/args.go
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")
}
51 changes: 51 additions & 0 deletions ctx/conf.go
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
}
105 changes: 105 additions & 0 deletions ctx/context.go
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
}
61 changes: 61 additions & 0 deletions ds/mysql/dst_feedback_issue.go
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
}
Loading

0 comments on commit f86c903

Please sign in to comment.