k3s/vendor/github.com/rancher/kine/pkg/drivers/sqlite/sqlite.go

103 lines
2.4 KiB
Go
Raw Normal View History

2019-12-16 18:45:21 +00:00
// +build cgo
2019-08-22 05:12:46 +00:00
package sqlite
import (
"context"
"database/sql"
"os"
2019-12-12 01:27:03 +00:00
"time"
2019-08-22 05:12:46 +00:00
2019-11-13 06:05:20 +00:00
"github.com/mattn/go-sqlite3"
2019-12-12 01:27:03 +00:00
"github.com/pkg/errors"
2019-08-22 05:12:46 +00:00
"github.com/rancher/kine/pkg/drivers/generic"
"github.com/rancher/kine/pkg/logstructured"
"github.com/rancher/kine/pkg/logstructured/sqllog"
"github.com/rancher/kine/pkg/server"
2019-12-12 01:27:03 +00:00
"github.com/sirupsen/logrus"
2019-08-22 05:12:46 +00:00
// sqlite db driver
_ "github.com/mattn/go-sqlite3"
)
var (
schema = []string{
`CREATE TABLE IF NOT EXISTS kine
(
id INTEGER primary key autoincrement,
name INTEGER,
created INTEGER,
deleted INTEGER,
create_revision INTEGER,
prev_revision INTEGER,
lease INTEGER,
value BLOB,
old_value BLOB
)`,
`CREATE INDEX IF NOT EXISTS kine_name_index ON kine (name)`,
`CREATE UNIQUE INDEX IF NOT EXISTS kine_name_prev_revision_uindex ON kine (name, prev_revision)`,
}
)
2019-12-12 01:27:03 +00:00
func New(ctx context.Context, dataSourceName string) (server.Backend, error) {
backend, _, err := NewVariant(ctx, "sqlite3", dataSourceName)
2019-11-08 21:45:10 +00:00
return backend, err
}
2019-12-12 01:27:03 +00:00
func NewVariant(ctx context.Context, driverName, dataSourceName string) (server.Backend, *generic.Generic, error) {
2019-08-22 05:12:46 +00:00
if dataSourceName == "" {
if err := os.MkdirAll("./db", 0700); err != nil {
2019-11-08 21:45:10 +00:00
return nil, nil, err
2019-08-22 05:12:46 +00:00
}
dataSourceName = "./db/state.db?_journal=WAL&cache=shared"
}
2019-12-12 01:27:03 +00:00
dialect, err := generic.Open(ctx, driverName, dataSourceName, "?", false)
2019-08-22 05:12:46 +00:00
if err != nil {
2019-11-08 21:45:10 +00:00
return nil, nil, err
2019-08-22 05:12:46 +00:00
}
dialect.LastInsertID = true
2019-11-13 06:05:20 +00:00
dialect.TranslateErr = func(err error) error {
if err, ok := err.(sqlite3.Error); ok && err.ExtendedCode == sqlite3.ErrConstraintUnique {
return server.ErrKeyExists
}
return err
}
2019-08-22 05:12:46 +00:00
2019-12-12 01:27:03 +00:00
// this is the first SQL that will be executed on a new DB conn so
// loop on failure here because in the case of dqlite it could still be initializing
for i := 0; i < 300; i++ {
err = setup(dialect.DB)
if err == nil {
break
}
logrus.Errorf("failed to setup db: %v", err)
select {
case <-ctx.Done():
return nil, nil, ctx.Err()
case <-time.After(time.Second):
}
time.Sleep(time.Second)
}
if err != nil {
return nil, nil, errors.Wrap(err, "setup db")
2019-08-22 05:12:46 +00:00
}
2019-12-12 01:27:03 +00:00
//if err := setup(dialect.DB); err != nil {
// return nil, nil, errors.Wrap(err, "setup db")
//}
2019-08-22 05:12:46 +00:00
dialect.Migrate(context.Background())
2019-11-08 21:45:10 +00:00
return logstructured.New(sqllog.New(dialect)), dialect, nil
2019-08-22 05:12:46 +00:00
}
func setup(db *sql.DB) error {
for _, stmt := range schema {
_, err := db.Exec(stmt)
if err != nil {
return err
}
}
return nil
}