From 8417704af8fd6699739d80e08163967b1a6121a4 Mon Sep 17 00:00:00 2001 From: Geapefurit <670884108@qq.com> Date: Wed, 22 Nov 2023 14:59:19 +0800 Subject: [PATCH] support auto increment id --- go.mod | 3 - go.sum | 5 - pkg/db/ent/entql.go | 203 ++++++++++++++ pkg/db/ent/internal/schema.go | 9 + pkg/db/ent/privacy/privacy.go | 226 ++++++++++++++++ pkg/db/mixin/mixin.go | 21 ++ pkg/db/mixin/mixindef.go | 9 + pkg/db/rule/rule.go | 15 ++ pkg/migrator/migrator.go | 480 ++++++++++++++++++++++++++++++++++ 9 files changed, 963 insertions(+), 8 deletions(-) create mode 100644 pkg/db/ent/entql.go create mode 100644 pkg/db/ent/internal/schema.go create mode 100644 pkg/db/ent/privacy/privacy.go create mode 100644 pkg/db/mixin/mixin.go create mode 100644 pkg/db/mixin/mixindef.go create mode 100644 pkg/db/rule/rule.go create mode 100644 pkg/migrator/migrator.go diff --git a/go.mod b/go.mod index 3934054..7a09cd2 100644 --- a/go.mod +++ b/go.mod @@ -144,7 +144,6 @@ require ( github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/hashicorp/serf v0.9.7 // indirect github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-block-format v0.0.3 // indirect github.com/ipfs/go-blockservice v0.2.1 // indirect @@ -220,7 +219,6 @@ require ( github.com/myxtype/filecoin-client v0.3.2 // indirect github.com/nkovacs/streamquote v1.0.0 // indirect github.com/oklog/ulid v1.3.1 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -245,7 +243,6 @@ require ( github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.12.0 // indirect diff --git a/go.sum b/go.sum index f0da7e4..189e9b9 100644 --- a/go.sum +++ b/go.sum @@ -770,7 +770,6 @@ github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 h1:9tcYMdi+7Rb1y0 github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94/go.mod h1:GYeBD1CF7AqnKZK+UCytLcY3G+UKo0ByXX/3xfdNyqQ= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= @@ -1530,7 +1529,6 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= @@ -1693,7 +1691,6 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1919,8 +1916,6 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= diff --git a/pkg/db/ent/entql.go b/pkg/db/ent/entql.go new file mode 100644 index 0000000..ec4e499 --- /dev/null +++ b/pkg/db/ent/entql.go @@ -0,0 +1,203 @@ +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent/transaction" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/entql" + "entgo.io/ent/schema/field" +) + +// schemaGraph holds a representation of ent/schema at runtime. +var schemaGraph = func() *sqlgraph.Schema { + graph := &sqlgraph.Schema{Nodes: make([]*sqlgraph.Node, 1)} + graph.Nodes[0] = &sqlgraph.Node{ + NodeSpec: sqlgraph.NodeSpec{ + Table: transaction.Table, + Columns: transaction.Columns, + ID: &sqlgraph.FieldSpec{ + Type: field.TypeUint32, + Column: transaction.FieldID, + }, + }, + Type: "Transaction", + Fields: map[string]*sqlgraph.FieldSpec{ + transaction.FieldEntID: {Type: field.TypeUUID, Column: transaction.FieldEntID}, + transaction.FieldCoinType: {Type: field.TypeInt32, Column: transaction.FieldCoinType}, + transaction.FieldNonce: {Type: field.TypeUint64, Column: transaction.FieldNonce}, + transaction.FieldUtxo: {Type: field.TypeJSON, Column: transaction.FieldUtxo}, + transaction.FieldPre: {Type: field.TypeJSON, Column: transaction.FieldPre}, + transaction.FieldTransactionType: {Type: field.TypeInt8, Column: transaction.FieldTransactionType}, + transaction.FieldRecentBhash: {Type: field.TypeString, Column: transaction.FieldRecentBhash}, + transaction.FieldTxData: {Type: field.TypeBytes, Column: transaction.FieldTxData}, + transaction.FieldTransactionID: {Type: field.TypeString, Column: transaction.FieldTransactionID}, + transaction.FieldCid: {Type: field.TypeString, Column: transaction.FieldCid}, + transaction.FieldExitCode: {Type: field.TypeInt64, Column: transaction.FieldExitCode}, + transaction.FieldName: {Type: field.TypeString, Column: transaction.FieldName}, + transaction.FieldFrom: {Type: field.TypeString, Column: transaction.FieldFrom}, + transaction.FieldTo: {Type: field.TypeString, Column: transaction.FieldTo}, + transaction.FieldMemo: {Type: field.TypeString, Column: transaction.FieldMemo}, + transaction.FieldAmount: {Type: field.TypeUint64, Column: transaction.FieldAmount}, + transaction.FieldPayload: {Type: field.TypeBytes, Column: transaction.FieldPayload}, + transaction.FieldState: {Type: field.TypeUint8, Column: transaction.FieldState}, + transaction.FieldCreatedAt: {Type: field.TypeUint32, Column: transaction.FieldCreatedAt}, + transaction.FieldUpdatedAt: {Type: field.TypeUint32, Column: transaction.FieldUpdatedAt}, + transaction.FieldDeletedAt: {Type: field.TypeUint32, Column: transaction.FieldDeletedAt}, + }, + } + return graph +}() + +// predicateAdder wraps the addPredicate method. +// All update, update-one and query builders implement this interface. +type predicateAdder interface { + addPredicate(func(s *sql.Selector)) +} + +// addPredicate implements the predicateAdder interface. +func (tq *TransactionQuery) addPredicate(pred func(s *sql.Selector)) { + tq.predicates = append(tq.predicates, pred) +} + +// Filter returns a Filter implementation to apply filters on the TransactionQuery builder. +func (tq *TransactionQuery) Filter() *TransactionFilter { + return &TransactionFilter{config: tq.config, predicateAdder: tq} +} + +// addPredicate implements the predicateAdder interface. +func (m *TransactionMutation) addPredicate(pred func(s *sql.Selector)) { + m.predicates = append(m.predicates, pred) +} + +// Filter returns an entql.Where implementation to apply filters on the TransactionMutation builder. +func (m *TransactionMutation) Filter() *TransactionFilter { + return &TransactionFilter{config: m.config, predicateAdder: m} +} + +// TransactionFilter provides a generic filtering capability at runtime for TransactionQuery. +type TransactionFilter struct { + predicateAdder + config +} + +// Where applies the entql predicate on the query filter. +func (f *TransactionFilter) Where(p entql.P) { + f.addPredicate(func(s *sql.Selector) { + if err := schemaGraph.EvalP(schemaGraph.Nodes[0].Type, p, s); err != nil { + s.AddError(err) + } + }) +} + +// WhereID applies the entql uint32 predicate on the id field. +func (f *TransactionFilter) WhereID(p entql.Uint32P) { + f.Where(p.Field(transaction.FieldID)) +} + +// WhereEntID applies the entql [16]byte predicate on the ent_id field. +func (f *TransactionFilter) WhereEntID(p entql.ValueP) { + f.Where(p.Field(transaction.FieldEntID)) +} + +// WhereCoinType applies the entql int32 predicate on the coin_type field. +func (f *TransactionFilter) WhereCoinType(p entql.Int32P) { + f.Where(p.Field(transaction.FieldCoinType)) +} + +// WhereNonce applies the entql uint64 predicate on the nonce field. +func (f *TransactionFilter) WhereNonce(p entql.Uint64P) { + f.Where(p.Field(transaction.FieldNonce)) +} + +// WhereUtxo applies the entql json.RawMessage predicate on the utxo field. +func (f *TransactionFilter) WhereUtxo(p entql.BytesP) { + f.Where(p.Field(transaction.FieldUtxo)) +} + +// WherePre applies the entql json.RawMessage predicate on the pre field. +func (f *TransactionFilter) WherePre(p entql.BytesP) { + f.Where(p.Field(transaction.FieldPre)) +} + +// WhereTransactionType applies the entql int8 predicate on the transaction_type field. +func (f *TransactionFilter) WhereTransactionType(p entql.Int8P) { + f.Where(p.Field(transaction.FieldTransactionType)) +} + +// WhereRecentBhash applies the entql string predicate on the recent_bhash field. +func (f *TransactionFilter) WhereRecentBhash(p entql.StringP) { + f.Where(p.Field(transaction.FieldRecentBhash)) +} + +// WhereTxData applies the entql []byte predicate on the tx_data field. +func (f *TransactionFilter) WhereTxData(p entql.BytesP) { + f.Where(p.Field(transaction.FieldTxData)) +} + +// WhereTransactionID applies the entql string predicate on the transaction_id field. +func (f *TransactionFilter) WhereTransactionID(p entql.StringP) { + f.Where(p.Field(transaction.FieldTransactionID)) +} + +// WhereCid applies the entql string predicate on the cid field. +func (f *TransactionFilter) WhereCid(p entql.StringP) { + f.Where(p.Field(transaction.FieldCid)) +} + +// WhereExitCode applies the entql int64 predicate on the exit_code field. +func (f *TransactionFilter) WhereExitCode(p entql.Int64P) { + f.Where(p.Field(transaction.FieldExitCode)) +} + +// WhereName applies the entql string predicate on the name field. +func (f *TransactionFilter) WhereName(p entql.StringP) { + f.Where(p.Field(transaction.FieldName)) +} + +// WhereFrom applies the entql string predicate on the from field. +func (f *TransactionFilter) WhereFrom(p entql.StringP) { + f.Where(p.Field(transaction.FieldFrom)) +} + +// WhereTo applies the entql string predicate on the to field. +func (f *TransactionFilter) WhereTo(p entql.StringP) { + f.Where(p.Field(transaction.FieldTo)) +} + +// WhereMemo applies the entql string predicate on the memo field. +func (f *TransactionFilter) WhereMemo(p entql.StringP) { + f.Where(p.Field(transaction.FieldMemo)) +} + +// WhereAmount applies the entql uint64 predicate on the amount field. +func (f *TransactionFilter) WhereAmount(p entql.Uint64P) { + f.Where(p.Field(transaction.FieldAmount)) +} + +// WherePayload applies the entql []byte predicate on the payload field. +func (f *TransactionFilter) WherePayload(p entql.BytesP) { + f.Where(p.Field(transaction.FieldPayload)) +} + +// WhereState applies the entql uint8 predicate on the state field. +func (f *TransactionFilter) WhereState(p entql.Uint8P) { + f.Where(p.Field(transaction.FieldState)) +} + +// WhereCreatedAt applies the entql uint32 predicate on the created_at field. +func (f *TransactionFilter) WhereCreatedAt(p entql.Uint32P) { + f.Where(p.Field(transaction.FieldCreatedAt)) +} + +// WhereUpdatedAt applies the entql uint32 predicate on the updated_at field. +func (f *TransactionFilter) WhereUpdatedAt(p entql.Uint32P) { + f.Where(p.Field(transaction.FieldUpdatedAt)) +} + +// WhereDeletedAt applies the entql uint32 predicate on the deleted_at field. +func (f *TransactionFilter) WhereDeletedAt(p entql.Uint32P) { + f.Where(p.Field(transaction.FieldDeletedAt)) +} diff --git a/pkg/db/ent/internal/schema.go b/pkg/db/ent/internal/schema.go new file mode 100644 index 0000000..117f555 --- /dev/null +++ b/pkg/db/ent/internal/schema.go @@ -0,0 +1,9 @@ +// Code generated by ent, DO NOT EDIT. + +//go:build tools +// +build tools + +// Package internal holds a loadable version of the latest schema. +package internal + +const Schema = `{"Schema":"github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent/schema","Package":"github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent","Schemas":[{"name":"Transaction","config":{"Table":""},"fields":[{"name":"id","type":{"Type":16,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"position":{"Index":0,"MixedIn":true,"MixinIndex":0}},{"name":"ent_id","type":{"Type":4,"Ident":"uuid.UUID","PkgPath":"github.com/google/uuid","PkgName":"uuid","Nillable":false,"RType":{"Name":"UUID","Ident":"uuid.UUID","Kind":17,"PkgPath":"github.com/google/uuid","Methods":{"ClockSequence":{"In":[],"Out":[{"Name":"int","Ident":"int","Kind":2,"PkgPath":"","Methods":null}]},"Domain":{"In":[],"Out":[{"Name":"Domain","Ident":"uuid.Domain","Kind":8,"PkgPath":"github.com/google/uuid","Methods":null}]},"ID":{"In":[],"Out":[{"Name":"uint32","Ident":"uint32","Kind":10,"PkgPath":"","Methods":null}]},"MarshalBinary":{"In":[],"Out":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null},{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"MarshalText":{"In":[],"Out":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null},{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"NodeID":{"In":[],"Out":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null}]},"Scan":{"In":[{"Name":"","Ident":"interface {}","Kind":20,"PkgPath":"","Methods":null}],"Out":[{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"String":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"Time":{"In":[],"Out":[{"Name":"Time","Ident":"uuid.Time","Kind":6,"PkgPath":"github.com/google/uuid","Methods":null}]},"URN":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"UnmarshalBinary":{"In":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null}],"Out":[{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"UnmarshalText":{"In":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null}],"Out":[{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"Value":{"In":[],"Out":[{"Name":"Value","Ident":"driver.Value","Kind":20,"PkgPath":"database/sql/driver","Methods":null},{"Name":"error","Ident":"error","Kind":20,"PkgPath":"","Methods":null}]},"Variant":{"In":[],"Out":[{"Name":"Variant","Ident":"uuid.Variant","Kind":8,"PkgPath":"github.com/google/uuid","Methods":null}]},"Version":{"In":[],"Out":[{"Name":"Version","Ident":"uuid.Version","Kind":8,"PkgPath":"github.com/google/uuid","Methods":null}]}}}},"unique":true,"default":true,"default_kind":19,"position":{"Index":1,"MixedIn":true,"MixinIndex":0}},{"name":"coin_type","type":{"Type":11,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":0,"default_kind":5,"position":{"Index":0,"MixedIn":false,"MixinIndex":0}},{"name":"nonce","type":{"Type":18,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":0,"default_kind":11,"position":{"Index":1,"MixedIn":false,"MixinIndex":0},"comment":"--will remove"},{"name":"utxo","type":{"Type":3,"Ident":"[]*sphinxplugin.Unspent","PkgPath":"github.com/NpoolPlatform/message/npool/sphinxplugin","PkgName":"sphinxplugin","Nillable":true,"RType":{"Name":"","Ident":"[]*sphinxplugin.Unspent","Kind":23,"PkgPath":"","Methods":{}}},"optional":true,"default":true,"default_value":[],"default_kind":23,"position":{"Index":2,"MixedIn":false,"MixinIndex":0},"comment":"only for btc--will remove"},{"name":"pre","type":{"Type":3,"Ident":"*sphinxplugin.Unspent","PkgPath":"github.com/NpoolPlatform/message/npool/sphinxplugin","PkgName":"sphinxplugin","Nillable":true,"RType":{"Name":"Unspent","Ident":"sphinxplugin.Unspent","Kind":22,"PkgPath":"github.com/NpoolPlatform/message/npool/sphinxplugin","Methods":{"Descriptor":{"In":[],"Out":[{"Name":"","Ident":"[]uint8","Kind":23,"PkgPath":"","Methods":null},{"Name":"","Ident":"[]int","Kind":23,"PkgPath":"","Methods":null}]},"GetAccount":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"GetAddress":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"GetAmount":{"In":[],"Out":[{"Name":"float64","Ident":"float64","Kind":14,"PkgPath":"","Methods":null}]},"GetConfirmations":{"In":[],"Out":[{"Name":"int64","Ident":"int64","Kind":6,"PkgPath":"","Methods":null}]},"GetRedeemScript":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"GetScriptPubKey":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"GetSpendable":{"In":[],"Out":[{"Name":"bool","Ident":"bool","Kind":1,"PkgPath":"","Methods":null}]},"GetTxID":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]},"GetVout":{"In":[],"Out":[{"Name":"uint32","Ident":"uint32","Kind":10,"PkgPath":"","Methods":null}]},"ProtoMessage":{"In":[],"Out":[]},"ProtoReflect":{"In":[],"Out":[{"Name":"Message","Ident":"protoreflect.Message","Kind":20,"PkgPath":"google.golang.org/protobuf/reflect/protoreflect","Methods":null}]},"Reset":{"In":[],"Out":[]},"String":{"In":[],"Out":[{"Name":"string","Ident":"string","Kind":24,"PkgPath":"","Methods":null}]}}}},"optional":true,"default":true,"default_value":{},"default_kind":22,"position":{"Index":3,"MixedIn":false,"MixinIndex":0},"comment":"--will remove"},{"name":"transaction_type","type":{"Type":9,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":0,"default_kind":3,"position":{"Index":4,"MixedIn":false,"MixinIndex":0},"comment":"--will remove"},{"name":"recent_bhash","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":5,"MixedIn":false,"MixinIndex":0},"comment":"--will remove"},{"name":"tx_data","type":{"Type":5,"Ident":"","PkgPath":"","PkgName":"","Nillable":true,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":23,"position":{"Index":6,"MixedIn":false,"MixinIndex":0},"comment":"--will remove"},{"name":"transaction_id","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"unique":true,"position":{"Index":7,"MixedIn":false,"MixinIndex":0}},{"name":"cid","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":8,"MixedIn":false,"MixinIndex":0}},{"name":"exit_code","type":{"Type":13,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":-1,"default_kind":6,"position":{"Index":9,"MixedIn":false,"MixinIndex":0}},{"name":"name","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":10,"MixedIn":false,"MixinIndex":0}},{"name":"from","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":11,"MixedIn":false,"MixinIndex":0}},{"name":"to","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":12,"MixedIn":false,"MixinIndex":0}},{"name":"memo","type":{"Type":7,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":"","default_kind":24,"position":{"Index":13,"MixedIn":false,"MixinIndex":0}},{"name":"amount","type":{"Type":18,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":0,"default_kind":11,"position":{"Index":14,"MixedIn":false,"MixinIndex":0}},{"name":"payload","type":{"Type":5,"Ident":"","PkgPath":"","PkgName":"","Nillable":true,"RType":null},"size":4294967295,"optional":true,"default":true,"default_value":"","default_kind":23,"validators":1,"position":{"Index":15,"MixedIn":false,"MixinIndex":0},"comment":"save nonce or sign info"},{"name":"state","type":{"Type":14,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_value":0,"default_kind":8,"position":{"Index":16,"MixedIn":false,"MixinIndex":0}},{"name":"created_at","type":{"Type":16,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_kind":19,"position":{"Index":17,"MixedIn":false,"MixinIndex":0}},{"name":"updated_at","type":{"Type":16,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_kind":19,"update_default":true,"position":{"Index":18,"MixedIn":false,"MixinIndex":0}},{"name":"deleted_at","type":{"Type":16,"Ident":"","PkgPath":"","PkgName":"","Nillable":false,"RType":null},"optional":true,"default":true,"default_kind":19,"position":{"Index":19,"MixedIn":false,"MixinIndex":0}}],"indexes":[{"unique":true,"fields":["ent_id"]},{"fields":["state","coin_type","created_at"]}]}],"Features":["entql","sql/lock","sql/execquery","sql/upsert","privacy","schema/snapshot","sql/modifier"]}` diff --git a/pkg/db/ent/privacy/privacy.go b/pkg/db/ent/privacy/privacy.go new file mode 100644 index 0000000..9ad4110 --- /dev/null +++ b/pkg/db/ent/privacy/privacy.go @@ -0,0 +1,226 @@ +// Code generated by ent, DO NOT EDIT. + +package privacy + +import ( + "context" + "fmt" + + "github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent" + + "entgo.io/ent/entql" + "entgo.io/ent/privacy" +) + +var ( + // Allow may be returned by rules to indicate that the policy + // evaluation should terminate with allow decision. + Allow = privacy.Allow + + // Deny may be returned by rules to indicate that the policy + // evaluation should terminate with deny decision. + Deny = privacy.Deny + + // Skip may be returned by rules to indicate that the policy + // evaluation should continue to the next rule. + Skip = privacy.Skip +) + +// Allowf returns an formatted wrapped Allow decision. +func Allowf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Allow)...) +} + +// Denyf returns an formatted wrapped Deny decision. +func Denyf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Deny)...) +} + +// Skipf returns an formatted wrapped Skip decision. +func Skipf(format string, a ...interface{}) error { + return fmt.Errorf(format+": %w", append(a, Skip)...) +} + +// DecisionContext creates a new context from the given parent context with +// a policy decision attach to it. +func DecisionContext(parent context.Context, decision error) context.Context { + return privacy.DecisionContext(parent, decision) +} + +// DecisionFromContext retrieves the policy decision from the context. +func DecisionFromContext(ctx context.Context) (error, bool) { + return privacy.DecisionFromContext(ctx) +} + +type ( + // Policy groups query and mutation policies. + Policy = privacy.Policy + + // QueryRule defines the interface deciding whether a + // query is allowed and optionally modify it. + QueryRule = privacy.QueryRule + // QueryPolicy combines multiple query rules into a single policy. + QueryPolicy = privacy.QueryPolicy + + // MutationRule defines the interface which decides whether a + // mutation is allowed and optionally modifies it. + MutationRule = privacy.MutationRule + // MutationPolicy combines multiple mutation rules into a single policy. + MutationPolicy = privacy.MutationPolicy +) + +// QueryRuleFunc type is an adapter to allow the use of +// ordinary functions as query rules. +type QueryRuleFunc func(context.Context, ent.Query) error + +// Eval returns f(ctx, q). +func (f QueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error { + return f(ctx, q) +} + +// MutationRuleFunc type is an adapter which allows the use of +// ordinary functions as mutation rules. +type MutationRuleFunc func(context.Context, ent.Mutation) error + +// EvalMutation returns f(ctx, m). +func (f MutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error { + return f(ctx, m) +} + +// QueryMutationRule is an interface which groups query and mutation rules. +type QueryMutationRule interface { + QueryRule + MutationRule +} + +// AlwaysAllowRule returns a rule that returns an allow decision. +func AlwaysAllowRule() QueryMutationRule { + return fixedDecision{Allow} +} + +// AlwaysDenyRule returns a rule that returns a deny decision. +func AlwaysDenyRule() QueryMutationRule { + return fixedDecision{Deny} +} + +type fixedDecision struct { + decision error +} + +func (f fixedDecision) EvalQuery(context.Context, ent.Query) error { + return f.decision +} + +func (f fixedDecision) EvalMutation(context.Context, ent.Mutation) error { + return f.decision +} + +type contextDecision struct { + eval func(context.Context) error +} + +// ContextQueryMutationRule creates a query/mutation rule from a context eval func. +func ContextQueryMutationRule(eval func(context.Context) error) QueryMutationRule { + return contextDecision{eval} +} + +func (c contextDecision) EvalQuery(ctx context.Context, _ ent.Query) error { + return c.eval(ctx) +} + +func (c contextDecision) EvalMutation(ctx context.Context, _ ent.Mutation) error { + return c.eval(ctx) +} + +// OnMutationOperation evaluates the given rule only on a given mutation operation. +func OnMutationOperation(rule MutationRule, op ent.Op) MutationRule { + return MutationRuleFunc(func(ctx context.Context, m ent.Mutation) error { + if m.Op().Is(op) { + return rule.EvalMutation(ctx, m) + } + return Skip + }) +} + +// DenyMutationOperationRule returns a rule denying specified mutation operation. +func DenyMutationOperationRule(op ent.Op) MutationRule { + rule := MutationRuleFunc(func(_ context.Context, m ent.Mutation) error { + return Denyf("ent/privacy: operation %s is not allowed", m.Op()) + }) + return OnMutationOperation(rule, op) +} + +// The TransactionQueryRuleFunc type is an adapter to allow the use of ordinary +// functions as a query rule. +type TransactionQueryRuleFunc func(context.Context, *ent.TransactionQuery) error + +// EvalQuery return f(ctx, q). +func (f TransactionQueryRuleFunc) EvalQuery(ctx context.Context, q ent.Query) error { + if q, ok := q.(*ent.TransactionQuery); ok { + return f(ctx, q) + } + return Denyf("ent/privacy: unexpected query type %T, expect *ent.TransactionQuery", q) +} + +// The TransactionMutationRuleFunc type is an adapter to allow the use of ordinary +// functions as a mutation rule. +type TransactionMutationRuleFunc func(context.Context, *ent.TransactionMutation) error + +// EvalMutation calls f(ctx, m). +func (f TransactionMutationRuleFunc) EvalMutation(ctx context.Context, m ent.Mutation) error { + if m, ok := m.(*ent.TransactionMutation); ok { + return f(ctx, m) + } + return Denyf("ent/privacy: unexpected mutation type %T, expect *ent.TransactionMutation", m) +} + +type ( + // Filter is the interface that wraps the Where function + // for filtering nodes in queries and mutations. + Filter interface { + // Where applies a filter on the executed query/mutation. + Where(entql.P) + } + + // The FilterFunc type is an adapter that allows the use of ordinary + // functions as filters for query and mutation types. + FilterFunc func(context.Context, Filter) error +) + +// EvalQuery calls f(ctx, q) if the query implements the Filter interface, otherwise it is denied. +func (f FilterFunc) EvalQuery(ctx context.Context, q ent.Query) error { + fr, err := queryFilter(q) + if err != nil { + return err + } + return f(ctx, fr) +} + +// EvalMutation calls f(ctx, q) if the mutation implements the Filter interface, otherwise it is denied. +func (f FilterFunc) EvalMutation(ctx context.Context, m ent.Mutation) error { + fr, err := mutationFilter(m) + if err != nil { + return err + } + return f(ctx, fr) +} + +var _ QueryMutationRule = FilterFunc(nil) + +func queryFilter(q ent.Query) (Filter, error) { + switch q := q.(type) { + case *ent.TransactionQuery: + return q.Filter(), nil + default: + return nil, Denyf("ent/privacy: unexpected query type %T for query filter", q) + } +} + +func mutationFilter(m ent.Mutation) (Filter, error) { + switch m := m.(type) { + case *ent.TransactionMutation: + return m.Filter(), nil + default: + return nil, Denyf("ent/privacy: unexpected mutation type %T for mutation filter", m) + } +} diff --git a/pkg/db/mixin/mixin.go b/pkg/db/mixin/mixin.go new file mode 100644 index 0000000..fde4411 --- /dev/null +++ b/pkg/db/mixin/mixin.go @@ -0,0 +1,21 @@ +package mixin + +import ( + "entgo.io/ent" + "github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent/privacy" + "github.com/NpoolPlatform/sphinx-proxy/pkg/db/rule" +) + +func (TimeMixin) Mixin() []ent.Mixin { + return []ent.Mixin{ + TimeMixin{}, + } +} + +func (TimeMixin) Policy() ent.Policy { + return privacy.Policy{ + Query: privacy.QueryPolicy{ + rule.FilterTimeRule(), + }, + } +} diff --git a/pkg/db/mixin/mixindef.go b/pkg/db/mixin/mixindef.go new file mode 100644 index 0000000..65e7847 --- /dev/null +++ b/pkg/db/mixin/mixindef.go @@ -0,0 +1,9 @@ +package mixin + +import ( + crudermixin "github.com/NpoolPlatform/libent-cruder/pkg/mixin" +) + +type TimeMixin struct { + crudermixin.TimeMixin +} diff --git a/pkg/db/rule/rule.go b/pkg/db/rule/rule.go new file mode 100644 index 0000000..80a789d --- /dev/null +++ b/pkg/db/rule/rule.go @@ -0,0 +1,15 @@ +package rule + +import ( + "context" + + "entgo.io/ent/entql" + "github.com/NpoolPlatform/sphinx-proxy/pkg/db/ent/privacy" +) + +func FilterTimeRule() privacy.QueryMutationRule { + return privacy.FilterFunc(func(ctx context.Context, f privacy.Filter) error { + f.Where(entql.FieldEQ("deleted_at", 0)) + return privacy.Skip + }) +} diff --git a/pkg/migrator/migrator.go b/pkg/migrator/migrator.go new file mode 100644 index 0000000..ab664d1 --- /dev/null +++ b/pkg/migrator/migrator.go @@ -0,0 +1,480 @@ +// nolint +package migrator + +import ( + "context" + "database/sql" + "fmt" + "strings" + "time" + + "github.com/NpoolPlatform/go-service-framework/pkg/config" + "github.com/NpoolPlatform/go-service-framework/pkg/logger" + constant "github.com/NpoolPlatform/go-service-framework/pkg/mysql/const" + redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" + basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" + servicename "github.com/NpoolPlatform/sphinx-proxy/pkg/servicename" + + "github.com/google/uuid" +) + +const ( + keyUsername = "username" + keyPassword = "password" + keyDBName = "database_name" + maxOpen = 5 + maxIdle = 2 + MaxLife = 0 + keyServiceID = "serviceid" +) + +func lockKey() string { + serviceID := config.GetStringValueWithNameSpace(servicename.ServiceDomain, keyServiceID) + return fmt.Sprintf("%v:%v", basetypes.Prefix_PrefixMigrate, serviceID) +} + +func dsn(hostname string) (string, error) { + username := config.GetStringValueWithNameSpace(constant.MysqlServiceName, keyUsername) + password := config.GetStringValueWithNameSpace(constant.MysqlServiceName, keyPassword) + dbname := config.GetStringValueWithNameSpace(hostname, keyDBName) + + svc, err := config.PeekService(constant.MysqlServiceName) + if err != nil { + logger.Sugar().Warnw("dsn", "error", err) + return "", err + } + + return fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?parseTime=true&interpolateParams=true", + username, password, + svc.Address, + svc.Port, + dbname, + ), nil +} + +func open(hostname string) (conn *sql.DB, err error) { + hdsn, err := dsn(hostname) + if err != nil { + return nil, err + } + + logger.Sugar().Warnw("open", "hdsn", hdsn) + + conn, err = sql.Open("mysql", hdsn) + if err != nil { + return nil, err + } + + // https://github.com/go-sql-driver/mysql + // See "Important settings" section. + + conn.SetConnMaxLifetime(time.Minute * MaxLife) + conn.SetMaxOpenConns(maxOpen) + conn.SetMaxIdleConns(maxIdle) + + return conn, nil +} + +func tables(ctx context.Context, dbName string, tx *sql.DB) ([]string, error) { + tables := []string{} + rows, err := tx.QueryContext( + ctx, + fmt.Sprintf("select table_name from information_schema.tables where table_schema = '%v'", dbName), + ) + if err != nil { + return nil, err + } + for rows.Next() { + table := []byte{} + if err := rows.Scan(&table); err != nil { + return nil, err + } + tables = append(tables, string(table)) + } + logger.Sugar().Warnw( + "tables", + "Tables", tables, + ) + return tables, nil +} + +func existIDInt(ctx context.Context, dbName, table string, tx *sql.DB) (bool, bool, bool, error) { + _type := []byte{} + rc := 0 + + rows, err := tx.QueryContext( + ctx, + fmt.Sprintf("select column_type,1 from information_schema.columns where table_name='%v' and column_name='id' and table_schema='%v'", table, dbName), + ) + if err != nil { + return false, false, false, err + } + for rows.Next() { + if err := rows.Scan(&_type, &rc); err != nil { + return false, false, false, err + } + } + return rc == 1, strings.Contains(string(_type), "int"), strings.Contains(string(_type), "unsigned"), nil +} + +func setIDUnsigned(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "setIDUnsigned", + "db", dbName, + "table", table, + "State", "INT UNSIGNED", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v change id id int unsigned not null auto_increment", dbName, table), + ) + if err != nil { + return err + } + + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "setIDUnsigned", + "db", dbName, + "table", table, + "State", "INT UNSIGNED", + "rowsAffected", rowsAffected, + ) + return nil +} + +func existEntIDUnique(ctx context.Context, dbName, table string, tx *sql.DB) (bool, bool, error) { + key := "" + rc := 0 + rows, err := tx.QueryContext( + ctx, + fmt.Sprintf("select column_key,1 from information_schema.columns where table_schema='%v' and table_name='%v' and column_name='ent_id'", dbName, table), + ) + if err != nil { + return false, false, err + } + for rows.Next() { + if err := rows.Scan(&key, &rc); err != nil { + return false, false, err + } + } + return rc == 1, key == "UNI", nil +} + +func setEmptyEntID(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "setEmptyEntID", + "db", dbName, + "table", table, + "State", "ENT_ID UUID", + ) + rows, err := tx.QueryContext( + ctx, + fmt.Sprintf("select id, ent_id from %v.%v", dbName, table), + ) + if err != nil { + return err + } + for rows.Next() { + var id uint32 + var entID string + if err := rows.Scan(&id, &entID); err != nil { + return err + } + if _, err := uuid.Parse(entID); err == nil { + continue + } + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("update %v.%v set ent_id='%v' where id=%v", dbName, table, uuid.New(), id), + ) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "setEmptyEntID", + "db", dbName, + "table", table, + "State", "ENT_ID UUID", + "rowsAffected", rowsAffected, + ) + } + return nil +} + +func setEntIDUnique(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "setEntIDUnique", + "db", dbName, + "table", table, + "State", "ENT_ID UNIQUE", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v change column ent_id ent_id char(36) unique", dbName, table), + ) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "setEntIDUnique", + "db", dbName, + "table", table, + "State", "ENT_ID UNIQUE", + "rowsAffected", rowsAffected, + ) + return nil +} + +func id2EntID(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "id2EntID", + "db", dbName, + "table", table, + "State", "ID -> EntID", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v change column id ent_id char(36) unique", dbName, table), + ) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "id2EntID", + "db", dbName, + "table", table, + "State", "ID -> EntID", + "rowsAffected", rowsAffected, + ) + return nil +} + +func addIDColumn(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "addIDColumn", + "db", dbName, + "table", table, + "State", "ID INT", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v add id int unsigned not null auto_increment, add primary key(id)", dbName, table), + ) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "addIDColumn", + "db", dbName, + "table", table, + "State", "ID INT", + "rowsAffected", rowsAffected, + ) + return nil +} + +func dropPrimaryKey(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "dropPrimaryKey", + "db", dbName, + "table", table, + "State", "DROP PRIMARY", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v drop primary key", dbName, table), + ) + if err != nil { + logger.Sugar().Warnw( + "dropPrimaryKey", + "db", dbName, + "table", table, + "Error", err, + ) + return nil + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "dropPrimaryKey", + "db", dbName, + "table", table, + "State", "DROP PRIMARY", + "rowsAffected", rowsAffected, + ) + return nil +} + +func addEntIDColumn(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "addEntIDColumn", + "db", dbName, + "table", table, + "State", "ADD ENT_ID", + ) + result, err := tx.ExecContext( + ctx, + fmt.Sprintf("alter table %v.%v add ent_id char(36) not null", dbName, table), + ) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + logger.Sugar().Warnw( + "addEntIDColumn", + "db", dbName, + "table", table, + "State", "ADD ENT_ID", + "rowsAffected", rowsAffected, + ) + return nil +} + +func migrateEntID(ctx context.Context, dbName, table string, tx *sql.DB) error { + logger.Sugar().Warnw( + "migrateEntID", + "db", dbName, + "table", table, + ) + + idExist, idInt, idUnsigned, err := existIDInt(ctx, dbName, table, tx) + if err != nil { + return err + } + + if idInt && !idUnsigned { + if err := setIDUnsigned(ctx, dbName, table, tx); err != nil { + return err + } + } + + entIDExist, entIDUnique, err := existEntIDUnique(ctx, dbName, table, tx) + if err != nil { + return err + } + + if entIDExist && idInt { + if err := setEmptyEntID(ctx, dbName, table, tx); err != nil { + return err + } + if !entIDUnique { + if err := setEntIDUnique(ctx, dbName, table, tx); err != nil { + return err + } + } + return nil + } + if idExist && !idInt { + if err := id2EntID(ctx, dbName, table, tx); err != nil { + return err + } + } + if !idInt { + if err := dropPrimaryKey(ctx, dbName, table, tx); err != nil { + return err + } + if err := addIDColumn(ctx, dbName, table, tx); err != nil { + return err + } + } + + entIDExist, _, err = existEntIDUnique(ctx, dbName, table, tx) + if err != nil { + return err + } + if !entIDExist { + if err := addEntIDColumn(ctx, dbName, table, tx); err != nil { + return err + } + } + if err := setEmptyEntID(ctx, dbName, table, tx); err != nil { + return err + } + if err := setEntIDUnique(ctx, dbName, table, tx); err != nil { + return err + } + logger.Sugar().Warnw( + "migrateEntID", + "db", dbName, + "table", table, + "State", "Migrated", + ) + return err +} + +func Migrate(ctx context.Context) error { + var err error + var conn *sql.DB + + logger.Sugar().Warnw("Migrate", "Start", "...") + err = redis2.TryLock(lockKey(), 0) + if err != nil { + return err + } + defer func(err *error) { + _ = redis2.Unlock(lockKey()) + logger.Sugar().Warnw("Migrate", "Done", "...", "error", *err) + }(&err) + + conn, err = open(servicename.ServiceDomain) + if err != nil { + return err + } + defer func() { + if err := conn.Close(); err != nil { + logger.Sugar().Errorw("Close", "Error", err) + } + }() + + dbname := config.GetStringValueWithNameSpace(servicename.ServiceDomain, keyDBName) + _tables, err := tables(ctx, dbname, conn) + if err != nil { + return err + } + + logger.Sugar().Warnw( + "Migrate", + "Round", 1, + ) + for _, table := range _tables { + if err = migrateEntID(ctx, dbname, table, conn); err != nil { + return err + } + } + + logger.Sugar().Warnw( + "Migrate", + "Round", 2, + ) + for _, table := range _tables { + if err = migrateEntID(ctx, dbname, table, conn); err != nil { + return err + } + } + return nil +}