Migration script added
This commit is contained in:
parent
ddd9ee5f34
commit
72c5d83108
@ -1,4 +1,4 @@
|
||||
package common_utils
|
||||
package commonUtils
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package common_utils
|
||||
package commonUtils
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package common_utils
|
||||
package commonUtils
|
||||
|
||||
func DefaultIfEqual[T comparable](in T, checkEqualTo T, defaultVal T) T {
|
||||
if in == checkEqualTo {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package common_utils
|
||||
package commonUtils
|
||||
|
||||
import "context"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
Provides useful data structures
|
||||
*/
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import "sync"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
// A combination of worker pool and a queue
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils
|
||||
package dbUtils
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package ds_utils_test
|
||||
package dbUtils_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
126
db/migrate.go
126
db/migrate.go
@ -1 +1,127 @@
|
||||
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
|
||||
|
||||
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/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // 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/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.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/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
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/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
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/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net_utils
|
||||
package netUtils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
10
net/ip.go
10
net/ip.go
@ -1,4 +1,4 @@
|
||||
package net_utils
|
||||
package netUtils
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
common_utils "git.mic.pp.ua/anderson/nettools/common"
|
||||
common "git.mic.pp.ua/anderson/nettools/common"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -42,7 +42,7 @@ const (
|
||||
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 {
|
||||
panic("mask is invalid: value out of range")
|
||||
}
|
||||
@ -75,13 +75,13 @@ func BytesToUint32(in []uint8) (uint32, error) {
|
||||
|
||||
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{
|
||||
"eth0": {},
|
||||
"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
|
||||
func IpToInt(ip net.IP) uint32 {
|
||||
if len(ip) == 16 {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net_utils
|
||||
package netUtils
|
||||
|
||||
import (
|
||||
common_utils "git.mic.pp.ua/anderson/nettools/common"
|
||||
|
Loading…
Reference in New Issue
Block a user