Migration script added
This commit is contained in:
parent
ddd9ee5f34
commit
72c5d83108
@ -1,4 +1,4 @@
|
|||||||
package common_utils
|
package commonUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package common_utils
|
package commonUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package common_utils
|
package commonUtils
|
||||||
|
|
||||||
func DefaultIfEqual[T comparable](in T, checkEqualTo T, defaultVal T) T {
|
func DefaultIfEqual[T comparable](in T, checkEqualTo T, defaultVal T) T {
|
||||||
if in == checkEqualTo {
|
if in == checkEqualTo {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package common_utils
|
package commonUtils
|
||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import "sync/atomic"
|
import "sync/atomic"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
Provides useful data structures
|
Provides useful data structures
|
||||||
*/
|
*/
|
||||||
package ds_utils
|
package dbUtils
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import "sync"
|
import "sync"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
// A combination of worker pool and a queue
|
// A combination of worker pool and a queue
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils
|
package dbUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ds_utils_test
|
package dbUtils_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
126
db/migrate.go
126
db/migrate.go
@ -1 +1,127 @@
|
|||||||
package db_utils
|
package db_utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/golang-migrate/migrate/v4"
|
||||||
|
pgx "github.com/golang-migrate/migrate/v4/database/pgx/v5"
|
||||||
|
"github.com/golang-migrate/migrate/v4/database/sqlite3"
|
||||||
|
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
OnNewInstance = errors.New("creating new instance")
|
||||||
|
OnVersionCheck = errors.New("checking DB version")
|
||||||
|
OnDrop = errors.New("dropping DB")
|
||||||
|
)
|
||||||
|
|
||||||
|
type MigrationConfig[InstanceCfgT any] struct {
|
||||||
|
// File path
|
||||||
|
// format: path or /absolutepath
|
||||||
|
MigrationsPath string
|
||||||
|
// format: sqlite3://path/to/db
|
||||||
|
// postgresql://user:password@ip:port/dbname?conn_opts
|
||||||
|
DB *sql.DB
|
||||||
|
// Put -1 for no limit, 0 to down database
|
||||||
|
// and any number > 0 to limit version
|
||||||
|
VersionLimit int
|
||||||
|
// Drop DB before applying migrations
|
||||||
|
Drop bool
|
||||||
|
// Config used for migration connects
|
||||||
|
DriverCfg InstanceCfgT
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMigrateSQLiteInstance is a newInstance function for sqlite3 database driver
|
||||||
|
func NewMigrateSQLiteInstance(db *sql.DB, sourceURL string, cfg *sqlite3.Config) (*migrate.Migrate, error) {
|
||||||
|
driver, err := sqlite3.WithInstance(db, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return migrate.NewWithDatabaseInstance(sourceURL, "sqlite3", driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMigratePgxInstance is a newInstance function for pgx/v5 database driver
|
||||||
|
func NewMigratePgxInstance(db *sql.DB, sourceURL string, cfg *pgx.Config) (*migrate.Migrate, error) {
|
||||||
|
driver, err := pgx.WithInstance(db, cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return migrate.NewWithDatabaseInstance(sourceURL, "pgx/v5", driver)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoMigrate applies migration to a database
|
||||||
|
func DoMigrate[InstanceCfgT any](cfg MigrationConfig[InstanceCfgT],
|
||||||
|
newInstance func(db *sql.DB, sourceURL string, cfg InstanceCfgT) (*migrate.Migrate, error)) (uint, bool, error) {
|
||||||
|
|
||||||
|
var ver uint
|
||||||
|
var dirty bool
|
||||||
|
var sourceURL string = fmt.Sprintf("file://%s", cfg.MigrationsPath)
|
||||||
|
|
||||||
|
m, err := newInstance(cfg.DB, sourceURL, cfg.DriverCfg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false, errors.Join(OnNewInstance, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop db if needed, get current db
|
||||||
|
if cfg.Drop {
|
||||||
|
if err = m.Drop(); err != nil {
|
||||||
|
return 0, false, errors.Join(OnDrop, err)
|
||||||
|
}
|
||||||
|
// After drop, we have to create new migrate instance
|
||||||
|
m, err = newInstance(cfg.DB, sourceURL, cfg.DriverCfg)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false, errors.Join(OnNewInstance, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// It's strange to check DB version after we drop it
|
||||||
|
// So I put version checking into else statement
|
||||||
|
ver, dirty, err = m.Version()
|
||||||
|
if err != nil && !errors.Is(err, migrate.ErrNilVersion) {
|
||||||
|
return 0, false, errors.Join(OnVersionCheck, err)
|
||||||
|
}
|
||||||
|
if dirty {
|
||||||
|
if err = m.Drop(); err != nil {
|
||||||
|
return ver, dirty, errors.Join(OnDrop, err)
|
||||||
|
}
|
||||||
|
// After drop, we have to create new migrate instance
|
||||||
|
m, err = newInstance(cfg.DB, sourceURL, cfg.DriverCfg)
|
||||||
|
if err != nil {
|
||||||
|
return ver, dirty, errors.Join(OnNewInstance, err)
|
||||||
|
}
|
||||||
|
// As we dropped DB
|
||||||
|
ver = 0
|
||||||
|
dirty = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.VersionLimit == int(ver) {
|
||||||
|
return ver, dirty, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
migratingUp := true
|
||||||
|
if cfg.VersionLimit > 0 {
|
||||||
|
if cfg.VersionLimit < int(ver) {
|
||||||
|
migratingUp = false
|
||||||
|
}
|
||||||
|
err = m.Migrate(uint(cfg.VersionLimit))
|
||||||
|
} else if cfg.VersionLimit == 0 {
|
||||||
|
migratingUp = false
|
||||||
|
err = m.Down()
|
||||||
|
} else {
|
||||||
|
err = m.Up()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, migrate.ErrNoChange) {
|
||||||
|
return 0, false, errors.Join(OnNewInstance, err,
|
||||||
|
fmt.Errorf("version limit: %d; migrating up: %v", cfg.VersionLimit, migratingUp))
|
||||||
|
}
|
||||||
|
return ver, dirty, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ver, dirty, err = m.Version()
|
||||||
|
if err != nil {
|
||||||
|
return ver, dirty, errors.Join(OnVersionCheck, err)
|
||||||
|
}
|
||||||
|
return ver, dirty, nil
|
||||||
|
}
|
||||||
|
4
go.mod
4
go.mod
@ -3,9 +3,13 @@ module git.mic.pp.ua/anderson/nettools
|
|||||||
go 1.23.1
|
go 1.23.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1 // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
||||||
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
golang.org/x/crypto v0.27.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/text v0.18.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
)
|
)
|
||||||
|
10
go.sum
10
go.sum
@ -1,4 +1,12 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y=
|
||||||
|
github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks=
|
||||||
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
@ -9,6 +17,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net_utils
|
package netUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
10
net/ip.go
10
net/ip.go
@ -1,4 +1,4 @@
|
|||||||
package net_utils
|
package netUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
common_utils "git.mic.pp.ua/anderson/nettools/common"
|
common "git.mic.pp.ua/anderson/nettools/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -42,7 +42,7 @@ const (
|
|||||||
PRESERVED_IP_RANGE_10 uint32 = IP_10_0_0_0 & MASK8
|
PRESERVED_IP_RANGE_10 uint32 = IP_10_0_0_0 & MASK8
|
||||||
)
|
)
|
||||||
|
|
||||||
func MaskToBytes[T common_utils.Int](mask T) [4]uint8 {
|
func MaskToBytes[T common.Int](mask T) [4]uint8 {
|
||||||
if mask > 32 {
|
if mask > 32 {
|
||||||
panic("mask is invalid: value out of range")
|
panic("mask is invalid: value out of range")
|
||||||
}
|
}
|
||||||
@ -75,13 +75,13 @@ func BytesToUint32(in []uint8) (uint32, error) {
|
|||||||
|
|
||||||
type NetInterfaceNamesT = map[string]struct{}
|
type NetInterfaceNamesT = map[string]struct{}
|
||||||
|
|
||||||
// Those are ones I have on my machine, so they are default, lol
|
// DefaultNetInterfaceNames are interface names that I have on my machine
|
||||||
var DefaultNetInterfaceNames = NetInterfaceNamesT{
|
var DefaultNetInterfaceNames = NetInterfaceNamesT{
|
||||||
"eth0": {},
|
"eth0": {},
|
||||||
"wlan0": {},
|
"wlan0": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts IP which is a byte array to an integer
|
// IpToInt converts IP which is a byte array to an integer
|
||||||
// So it can be used with the bitmasks or be compared fast
|
// So it can be used with the bitmasks or be compared fast
|
||||||
func IpToInt(ip net.IP) uint32 {
|
func IpToInt(ip net.IP) uint32 {
|
||||||
if len(ip) == 16 {
|
if len(ip) == 16 {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net_utils
|
package netUtils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
common_utils "git.mic.pp.ua/anderson/nettools/common"
|
common_utils "git.mic.pp.ua/anderson/nettools/common"
|
||||||
|
Loading…
Reference in New Issue
Block a user