initial import
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
parent
c08ab26cf9
commit
973f9ac822
55
.github/workflows/build.yml
vendored
Normal file
55
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
test:
|
||||
name: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: setup
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: gitconfig
|
||||
run: git config --global url."https://${{ secrets.TOKEN }}:x-oauth-basic@github.com/".insteadOf https://github.com/
|
||||
- name: deps
|
||||
env:
|
||||
GOINSECURE: github.com/unistack-org/cms*
|
||||
GONOPROXY: github.com/unistack-org/cms*
|
||||
GONOSUMDB: github.com/unistack-org/cms*
|
||||
GOPRIVATE: github.com/unistack-org/cms*
|
||||
run: go get -v -t -d ./...
|
||||
- name: test
|
||||
env:
|
||||
INTEGRATION_TESTS: yes
|
||||
run: go test -mod readonly -v ./...
|
||||
lint:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: gitconfig
|
||||
run: git config --global url."https://${{ secrets.TOKEN }}:x-oauth-basic@github.com/".insteadOf https://github.com/
|
||||
- name: lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.30
|
||||
# Optional: working directory, useful for monorepos
|
||||
# working-directory: somedir
|
||||
# Optional: golangci-lint command line arguments.
|
||||
# args: --issues-exit-code=0
|
||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||
# only-new-issues: true
|
55
.github/workflows/pr.yml
vendored
Normal file
55
.github/workflows/pr.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: prbuild
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
test:
|
||||
name: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: setup
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/go/pkg
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: gitconfig
|
||||
run: git config --global url."https://${{ secrets.TOKEN }}:x-oauth-basic@github.com/".insteadOf https://github.com/
|
||||
- name: deps
|
||||
env:
|
||||
GOINSECURE: github.com/unistack-org/cms*
|
||||
GONOPROXY: github.com/unistack-org/cms*
|
||||
GONOSUMDB: github.com/unistack-org/cms*
|
||||
GOPRIVATE: github.com/unistack-org/cms*
|
||||
run: go get -v -t -d ./...
|
||||
- name: test
|
||||
env:
|
||||
INTEGRATION_TESTS: yes
|
||||
run: go test -mod readonly -v ./...
|
||||
lint:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: gitconfig
|
||||
run: git config --global url."https://${{ secrets.TOKEN }}:x-oauth-basic@github.com/".insteadOf https://github.com/
|
||||
- name: lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
continue-on-error: true
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.30
|
||||
# Optional: working directory, useful for monorepos
|
||||
# working-directory: somedir
|
||||
# Optional: golangci-lint command line arguments.
|
||||
# args: --issues-exit-code=0
|
||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
||||
# only-new-issues: true
|
44
.golangci.yml
Normal file
44
.golangci.yml
Normal file
@ -0,0 +1,44 @@
|
||||
run:
|
||||
concurrency: 4
|
||||
deadline: 5m
|
||||
issues-exit-code: 1
|
||||
tests: true
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
enable:
|
||||
- fieldalignment
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- govet
|
||||
- deadcode
|
||||
- errcheck
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
- bodyclose
|
||||
- gci
|
||||
- goconst
|
||||
- gocritic
|
||||
- gosimple
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- golint
|
||||
- gosec
|
||||
- makezero
|
||||
- misspell
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- noctx
|
||||
- prealloc
|
||||
- unconvert
|
||||
- unparam
|
||||
disable-all: false
|
20
Makefile
Normal file
20
Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
DATE?=$(shell date -u "+%Y-%m-%d %H:%M:%S")
|
||||
LDFLAGS=-s -w -X 'main.AppVersion=${app_version}' -X 'main.BuildDate=${DATE}'
|
||||
LDFLAGS=-X 'main.AppVersion=${app_version}' -X 'main.BuildDate=${DATE}'
|
||||
GOPATH=$(shell go env GOPATH)
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
GOWORK=off CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -gcflags=-trimpath=$(GOPATH) -asmflags=-trimpath=$(GOPATH) -trimpath -mod=readonly -o bin/cms-template
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -mod=readonly -race -v ./... -cover
|
||||
|
||||
.PHONY: generate
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
.PHONY: docker
|
||||
docker:
|
||||
docker build -v $(CURDIR):/build -t cms-template .
|
51
config/config.go
Normal file
51
config/config.go
Normal file
@ -0,0 +1,51 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
service "go.unistack.org/cms-service"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
TLSCrt string `flag:"name=account.tls_crt,desc='tls crt file'"`
|
||||
TLSKey string `flag:"name=account.tls_key,desc='tls key file'"`
|
||||
Address string `flag:"name=account.address,desc='listen address',default=':0'"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
App *App
|
||||
Storage *service.ConfigStorage
|
||||
Logger *service.ConfigLogger
|
||||
Service *service.ConfigService
|
||||
Core *service.ConfigCore
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
Service: &service.ConfigService{
|
||||
Name: ServiceName,
|
||||
Version: ServiceVersion,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c *App) Validate() error {
|
||||
_, port, err := net.SplitHostPort(c.Address)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid address: %s, err: %w", c.Address, err)
|
||||
}
|
||||
|
||||
if port == "443" && (c.TLSCrt == "" || c.TLSKey == "") {
|
||||
return fmt.Errorf("use secured connection without tls crt/key")
|
||||
}
|
||||
|
||||
if v, err := strconv.Atoi(port); err != nil {
|
||||
return fmt.Errorf("invalid address/port: %v", c.Address)
|
||||
} else if v < 0 || v > 65535 {
|
||||
return fmt.Errorf("invalid address/port: %v", c.Address)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
6
config/variables.go
Normal file
6
config/variables.go
Normal file
@ -0,0 +1,6 @@
|
||||
package config
|
||||
|
||||
var (
|
||||
ServiceName = "account"
|
||||
ServiceVersion = "0.0.1"
|
||||
)
|
60
go.mod
Normal file
60
go.mod
Normal file
@ -0,0 +1,60 @@
|
||||
module go.unistack.org/cms-template
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/golang-migrate/migrate/v4 v4.15.2
|
||||
go.unistack.org/cms-account-proto v0.0.1
|
||||
go.unistack.org/cms-service v0.0.1
|
||||
go.unistack.org/micro-server-grpc/v3 v3.10.3
|
||||
go.unistack.org/micro/v3 v3.10.18
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
|
||||
github.com/jackc/pgx/v5 v5.3.1 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/sijms/go-ora/v2 v2.6.7 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.unistack.org/cms-api-proto v0.0.4 // indirect
|
||||
go.unistack.org/micro-broker-service/v3 v3.8.2 // indirect
|
||||
go.unistack.org/micro-codec-yaml/v3 v3.10.0 // indirect
|
||||
go.unistack.org/micro-config-env/v3 v3.8.5 // indirect
|
||||
go.unistack.org/micro-config-file/v3 v3.8.3 // indirect
|
||||
go.unistack.org/micro-config-flag/v3 v3.8.9 // indirect
|
||||
go.unistack.org/micro-config-service/v3 v3.8.1 // indirect
|
||||
go.unistack.org/micro-proto/v3 v3.3.1 // indirect
|
||||
go.unistack.org/micro-server-http/v3 v3.10.13 // indirect
|
||||
golang.org/x/crypto v0.7.0 // indirect
|
||||
golang.org/x/mod v0.9.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230323212658-478b75c54725 // indirect
|
||||
google.golang.org/grpc v1.54.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
lukechampine.com/uint128 v1.3.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.3 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.21.0 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
42
handler/handler.go
Normal file
42
handler/handler.go
Normal file
@ -0,0 +1,42 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
cmsstorage "go.unistack.org/cms-service/storage"
|
||||
mpb "go.unistack.org/cms-template-proto"
|
||||
templatepb "go.unistack.org/cms-template-proto/micro"
|
||||
"go.unistack.org/cms-template/storage"
|
||||
"go.unistack.org/micro/v3"
|
||||
)
|
||||
|
||||
var _ templatepb.AccountServiceServer = (*Handler)(nil)
|
||||
|
||||
type Handler struct {
|
||||
svc micro.Service
|
||||
store storage.Storage
|
||||
}
|
||||
|
||||
func NewHandler(svc micro.Service) *Handler {
|
||||
return &Handler{svc: svc}
|
||||
}
|
||||
|
||||
func (h *Handler) Init(ctx context.Context) error {
|
||||
store := cmsstorage.InterfaceFromContext(h.svc.Options().Context)
|
||||
if store == nil {
|
||||
return cmsstorage.ErrMissingStorage
|
||||
}
|
||||
|
||||
st, ok := store.(storage.Storage)
|
||||
if !ok {
|
||||
return cmsstorage.ErrInvalidStorage
|
||||
}
|
||||
|
||||
h.store = st
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *Handler) Call(ctx context.Context, req *mpb.CallReq, rsp *mpb.CallRsp) error {
|
||||
return nil
|
||||
}
|
0
local.yaml
Normal file
0
local.yaml
Normal file
24
main.go
Normal file
24
main.go
Normal file
@ -0,0 +1,24 @@
|
||||
//go:build !single
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.unistack.org/cms-template/service"
|
||||
"go.unistack.org/micro/v3/logger"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
|
||||
svc, err := service.NewService(ctx)
|
||||
if err != nil {
|
||||
logger.Fatalf(ctx, "failed to create service: %v", err)
|
||||
}
|
||||
|
||||
// start server
|
||||
if err := svc.Run(); err != nil {
|
||||
logger.Fatal(ctx, err)
|
||||
}
|
||||
}
|
11
service/embed.go
Normal file
11
service/embed.go
Normal file
@ -0,0 +1,11 @@
|
||||
//go:build single
|
||||
|
||||
package service
|
||||
|
||||
import (
|
||||
service "go.unistack.org/cms-service"
|
||||
)
|
||||
|
||||
func init() {
|
||||
service.RegisterService("template", NewService)
|
||||
}
|
149
service/service.go
Normal file
149
service/service.go
Normal file
@ -0,0 +1,149 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
cmsservice "go.unistack.org/cms-service"
|
||||
cmsstorage "go.unistack.org/cms-service/storage"
|
||||
mpb "go.unistack.org/cms-template-proto/micro"
|
||||
serviceConfig "go.unistack.org/cms-template/config"
|
||||
"go.unistack.org/cms-template/handler"
|
||||
storage "go.unistack.org/cms-template/storage"
|
||||
grpcsrv "go.unistack.org/micro-server-grpc/v3"
|
||||
"go.unistack.org/micro/v3"
|
||||
"go.unistack.org/micro/v3/broker"
|
||||
"go.unistack.org/micro/v3/config"
|
||||
"go.unistack.org/micro/v3/logger"
|
||||
"go.unistack.org/micro/v3/register"
|
||||
"go.unistack.org/micro/v3/router"
|
||||
"go.unistack.org/micro/v3/server"
|
||||
)
|
||||
|
||||
func NewService(ctx context.Context) (micro.Service, error) {
|
||||
var err error
|
||||
var svc micro.Service
|
||||
var reg register.Register
|
||||
var brk broker.Broker
|
||||
var rtr router.Router
|
||||
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
cfg := serviceConfig.NewConfig()
|
||||
cs := cmsservice.NewConfigLocal(cfg) // service.NewConfigRemote(cfg)...)
|
||||
|
||||
if r, ok := register.FromContext(ctx); ok && r != nil {
|
||||
reg = r
|
||||
} else {
|
||||
reg = register.NewRegister()
|
||||
}
|
||||
if b, ok := broker.FromContext(ctx); ok && b != nil {
|
||||
brk = b
|
||||
} else {
|
||||
brk = broker.NewBroker()
|
||||
}
|
||||
if r, ok := router.FromContext(ctx); ok && r != nil {
|
||||
rtr = r
|
||||
} else {
|
||||
rtr = router.NewRouter()
|
||||
}
|
||||
|
||||
// create grpc server
|
||||
mgsrv := grpcsrv.NewServer(
|
||||
server.Register(reg),
|
||||
)
|
||||
|
||||
// create service
|
||||
svc = micro.NewService(
|
||||
micro.Server(mgsrv),
|
||||
micro.Register(reg),
|
||||
micro.Broker(brk),
|
||||
micro.Router(rtr),
|
||||
micro.Config(cs...),
|
||||
)
|
||||
|
||||
h := handler.NewHandler(svc)
|
||||
|
||||
// init service
|
||||
if err := svc.Init(
|
||||
micro.AfterStart(func(_ context.Context) error {
|
||||
return h.Init(svc.Options().Context)
|
||||
}),
|
||||
micro.BeforeStart(func(ctx context.Context) error {
|
||||
if err = config.Load(ctx, cs, config.LoadOverride(true)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = config.Validate(ctx, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = svc.Init(
|
||||
micro.Name(cfg.Service.Name),
|
||||
micro.Version(cfg.Service.Version),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = svc.Server("grpc").Init(
|
||||
server.Address(cfg.App.Address),
|
||||
server.Name(cfg.Service.Name),
|
||||
server.Version(cfg.Service.Version),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}),
|
||||
micro.BeforeStart(func(_ context.Context) error {
|
||||
level := logger.InfoLevel
|
||||
if v, ok := cfg.Logger.Level[cfg.Service.Name]; ok {
|
||||
level = logger.ParseLevel(v)
|
||||
} else if v, ok := cfg.Logger.Level["all"]; ok {
|
||||
level = logger.ParseLevel(v)
|
||||
}
|
||||
log := logger.NewLogger(
|
||||
logger.WithLevel(level),
|
||||
logger.WithCallerSkipCount(3),
|
||||
)
|
||||
return svc.Init(micro.Logger(log))
|
||||
}),
|
||||
micro.BeforeStart(func(_ context.Context) error {
|
||||
var scheme string
|
||||
var connstr string
|
||||
var dsn string
|
||||
if v, ok := cfg.Storage.DSN[cfg.Service.Name]; ok {
|
||||
connstr = v
|
||||
} else if v, ok := cfg.Storage.DSN["all"]; ok {
|
||||
connstr = v
|
||||
}
|
||||
fmt.Printf("SSSS %s\n", connstr)
|
||||
scheme, dsn, err = cmsstorage.StorageOptions(connstr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
db, dbok := cmsstorage.FromContext(svc.Options().Context)
|
||||
if !dbok {
|
||||
var err error
|
||||
db, err = cmsstorage.NewStorage(scheme, dsn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
store, err := storage.NewStorage(scheme, db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return svc.Init(micro.Context(cmsstorage.InterfaceNewContext(svc.Options().Context, store)))
|
||||
}),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = mpb.RegisterAccountServiceServer(mgsrv, h); err != nil {
|
||||
logger.Fatalf(ctx, "failed to register handler: %v", err)
|
||||
}
|
||||
|
||||
return svc, nil
|
||||
}
|
0
storage/migrations/postgres/.gitkeep
Normal file
0
storage/migrations/postgres/.gitkeep
Normal file
0
storage/migrations/sqlite/.gitkeep
Normal file
0
storage/migrations/sqlite/.gitkeep
Normal file
3
storage/models.go
Normal file
3
storage/models.go
Normal file
@ -0,0 +1,3 @@
|
||||
package storage
|
||||
|
||||
// TODO: create models
|
75
storage/postgres/postgres.go
Normal file
75
storage/postgres/postgres.go
Normal file
@ -0,0 +1,75 @@
|
||||
// go:build postgres
|
||||
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"embed"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||
)
|
||||
|
||||
type PostgresStorage struct {
|
||||
db *sql.DB
|
||||
fs embed.FS
|
||||
}
|
||||
|
||||
func NewStoragePostgres(fs embed.FS) func(*sql.DB) (interface{}, error) {
|
||||
return func(db *sql.DB) (interface{}, error) {
|
||||
return &PostgresStorage{db: db, fs: fs}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) MigrateUp() error {
|
||||
driver, err := postgres.WithInstance(s.db, &postgres.Config{
|
||||
MigrationsTable: postgres.DefaultMigrationsTable,
|
||||
DatabaseName: "template",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
source, err := iofs.New(s.fs, "migrations/postgres")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: pass own logger
|
||||
m, err := migrate.NewWithInstance("fs", source, "template", driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = m.Up(); err != nil && err != migrate.ErrNoChange {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PostgresStorage) MigrateDown() error {
|
||||
driver, err := postgres.WithInstance(s.db, &postgres.Config{
|
||||
MigrationsTable: postgres.DefaultMigrationsTable,
|
||||
DatabaseName: "template",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
source, err := iofs.New(s.fs, "migrations/postgres")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: pass own logger
|
||||
m, err := migrate.NewWithInstance("fs", source, "template", driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = m.Down(); err != nil && err != migrate.ErrNoChange {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
5
storage/postgres/query.go
Normal file
5
storage/postgres/query.go
Normal file
@ -0,0 +1,5 @@
|
||||
package postgres
|
||||
|
||||
const (
|
||||
// TODO: fill queries
|
||||
)
|
5
storage/sqlite/query.go
Normal file
5
storage/sqlite/query.go
Normal file
@ -0,0 +1,5 @@
|
||||
package sqlite
|
||||
|
||||
const (
|
||||
// TODO: fill queries
|
||||
)
|
75
storage/sqlite/sqlite.go
Normal file
75
storage/sqlite/sqlite.go
Normal file
@ -0,0 +1,75 @@
|
||||
// go:build sqlite
|
||||
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"embed"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/sqlite"
|
||||
"github.com/golang-migrate/migrate/v4/source/iofs"
|
||||
)
|
||||
|
||||
type SqliteStorage struct {
|
||||
db *sql.DB
|
||||
fs embed.FS
|
||||
}
|
||||
|
||||
func NewStorageSqlite(fs embed.FS) func(*sql.DB) (interface{}, error) {
|
||||
return func(db *sql.DB) (interface{}, error) {
|
||||
return &SqliteStorage{db: db, fs: fs}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SqliteStorage) MigrateUp() error {
|
||||
driver, err := sqlite.WithInstance(s.db, &sqlite.Config{
|
||||
MigrationsTable: sqlite.DefaultMigrationsTable,
|
||||
DatabaseName: "template",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
source, err := iofs.New(s.fs, "migrations/sqlite")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: pass own logger
|
||||
m, err := migrate.NewWithInstance("fs", source, "template", driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = m.Up(); err != nil && err != migrate.ErrNoChange {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SqliteStorage) MigrateDown() error {
|
||||
driver, err := sqlite.WithInstance(s.db, &sqlite.Config{
|
||||
MigrationsTable: sqlite.DefaultMigrationsTable,
|
||||
DatabaseName: "template",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
source, err := iofs.New(s.fs, "migrations/sqlite")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: pass own logger
|
||||
m, err := migrate.NewWithInstance("fs", source, "template", driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = m.Down(); err != nil && err != migrate.ErrNoChange {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
29
storage/storage.go
Normal file
29
storage/storage.go
Normal file
@ -0,0 +1,29 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"embed"
|
||||
|
||||
store "go.unistack.org/cms-service/storage"
|
||||
"go.unistack.org/cms-template/storage/sqlite"
|
||||
)
|
||||
|
||||
//go:embed all:migrations
|
||||
var fs embed.FS
|
||||
|
||||
var storages = store.NewStorageInterface()
|
||||
|
||||
func init() {
|
||||
storages.RegisterStorage("sqlite", sqlite.NewStorageSqlite(fs))
|
||||
}
|
||||
|
||||
type Storage interface {
|
||||
Auth(ctx context.Context, login, passw string) error
|
||||
Delete(ctx context.Context, uuid string) error
|
||||
store.Migrator
|
||||
}
|
||||
|
||||
func NewStorage(name string, db *sql.DB) (interface{}, error) {
|
||||
return storages.NewStorage(name, db)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user