86 lines
1.6 KiB
Go
86 lines
1.6 KiB
Go
package pgsql
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/Masterminds/squirrel"
|
|
"github.com/cortezaproject/corteza-server/store"
|
|
"github.com/cortezaproject/corteza-server/store/rdbms"
|
|
"github.com/lib/pq"
|
|
"go.uber.org/zap"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
type (
|
|
Store struct {
|
|
*rdbms.Store
|
|
}
|
|
)
|
|
|
|
func New(ctx context.Context, dsn string) (s *Store, err error) {
|
|
var cfg *rdbms.Config
|
|
|
|
if cfg, err = ProcDataSourceName(dsn); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cfg.PlaceholderFormat = squirrel.Dollar
|
|
cfg.ErrorHandler = errorHandler
|
|
|
|
s = new(Store)
|
|
if s.Store, err = rdbms.New(ctx, cfg); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
|
|
if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
|
|
return fmt.Errorf("can not upgrade postgresql schema: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProcDataSourceName validates given DSN and ensures
|
|
// params are present and correct
|
|
func ProcDataSourceName(dsn string) (c *rdbms.Config, err error) {
|
|
const (
|
|
validScheme = "postgres"
|
|
)
|
|
var (
|
|
scheme string
|
|
u *url.URL
|
|
)
|
|
|
|
if u, err = url.Parse(dsn); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if strings.HasPrefix(dsn, "postgres") {
|
|
scheme = u.Scheme
|
|
u.Scheme = validScheme
|
|
}
|
|
|
|
return &rdbms.Config{
|
|
DriverName: scheme,
|
|
DataSourceName: u.String(),
|
|
DBName: strings.Trim(u.Path, "/"),
|
|
}, nil
|
|
}
|
|
|
|
func errorHandler(err error) error {
|
|
if err != nil {
|
|
if implErr, ok := err.(*pq.Error); ok {
|
|
switch implErr.Code.Name() {
|
|
case "unique_violation":
|
|
return store.ErrNotUnique.Wrap(implErr)
|
|
}
|
|
}
|
|
}
|
|
|
|
return err
|
|
}
|