3
0
corteza/store/sqlite/sqlite.go

101 lines
2.1 KiB
Go

package sqlite
import (
"context"
"fmt"
"github.com/Masterminds/squirrel"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/store/rdbms"
"github.com/mattn/go-sqlite3"
"go.uber.org/zap"
"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 NewInMemory(ctx context.Context) (s *Store, err error) {
var (
dsn = "sqlite3://file::memory:?cache=shared"
cfg *rdbms.Config
)
if cfg, err = ProcDataSourceName(dsn); err != nil {
return nil, err
}
cfg.PlaceholderFormat = squirrel.Dollar
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 sqlite schema: %w", err)
}
return nil
}
// ProcDataSourceName validates given DSN and ensures
// params are present and correct
func ProcDataSourceName(in string) (*rdbms.Config, error) {
const (
schemeDel = "://"
validScheme = "sqlite3"
)
var (
endOfSchema = strings.Index(in, schemeDel)
c = &rdbms.Config{}
)
if endOfSchema > 0 && (in[:endOfSchema] == validScheme || strings.HasPrefix(in[:endOfSchema], validScheme+"+")) {
c.DriverName = in[:endOfSchema]
c.DataSourceName = in[endOfSchema+len(schemeDel):]
} else {
return nil, fmt.Errorf("expecting valid schema (sqlite3://) at the beginning of the DSN (%s)", in)
}
return c, nil
}
func errorHandler(err error) error {
if err != nil {
if implErr, ok := err.(sqlite3.Error); ok {
switch implErr.ExtendedCode {
case sqlite3.ErrConstraintUnique:
return store.ErrNotUnique.Wrap(implErr)
}
}
}
return err
}