1
0
Fork 0

Thread through foreign key constraint controls

master
Philip O'Toole 3 years ago
parent 70d174f276
commit deb4dabf2e

@ -10,6 +10,7 @@ import (
"io"
"math/rand"
"os"
"strconv"
"strings"
"time"
@ -92,8 +93,8 @@ type Rows struct {
}
// Open opens a file-based database, creating it if it does not exist.
func Open(dbPath string) (*DB, error) {
rwDSN := fmt.Sprintf("file:%s", dbPath)
func Open(dbPath string, fkEnabled bool) (*DB, error) {
rwDSN := fmt.Sprintf("file:%s?_fk=%s", dbPath, strconv.FormatBool(fkEnabled))
rwDB, err := sql.Open("sqlite3", rwDSN)
if err != nil {
return nil, err
@ -101,6 +102,7 @@ func Open(dbPath string) (*DB, error) {
roOpts := []string{
"mode=ro",
fmt.Sprintf("_fk=%s", strconv.FormatBool(fkEnabled)),
}
roDSN := fmt.Sprintf("file:%s?%s", dbPath, strings.Join(roOpts, "&"))
@ -130,13 +132,14 @@ func Open(dbPath string) (*DB, error) {
}
// OpenInMemory returns a new in-memory database.
func OpenInMemory() (*DB, error) {
func OpenInMemory(fkEnabled bool) (*DB, error) {
inMemPath := fmt.Sprintf("file:/%s", randomString())
rwOpts := []string{
"mode=rw",
"vfs=memdb",
"_txlock=immediate",
fmt.Sprintf("_fk=%s", strconv.FormatBool(fkEnabled)),
}
rwDSN := fmt.Sprintf("%s?%s", inMemPath, strings.Join(rwOpts, "&"))
@ -156,6 +159,7 @@ func OpenInMemory() (*DB, error) {
"mode=ro",
"vfs=memdb",
"_txlock=deferred",
fmt.Sprintf("_fk=%s", strconv.FormatBool(fkEnabled)),
}
roDSN := fmt.Sprintf("%s?%s", inMemPath, strings.Join(roOpts, "&"))
@ -181,13 +185,13 @@ func OpenInMemory() (*DB, error) {
// LoadIntoMemory loads an in-memory database with that at the path.
// Not safe to call while other operations are happening with the
// source database.
func LoadIntoMemory(dbPath string) (*DB, error) {
dstDB, err := OpenInMemory()
func LoadIntoMemory(dbPath string, fkEnabled bool) (*DB, error) {
dstDB, err := OpenInMemory(fkEnabled)
if err != nil {
return nil, err
}
srcDB, err := Open(dbPath)
srcDB, err := Open(dbPath, false)
if err != nil {
return nil, err
}
@ -206,7 +210,7 @@ func LoadIntoMemory(dbPath string) (*DB, error) {
// DeserializeIntoMemory loads an in-memory database with that contained
// in the byte slide. The byte slice must not be changed or garbage-collected
// until after this function returns.
func DeserializeIntoMemory(b []byte) (retDB *DB, retErr error) {
func DeserializeIntoMemory(b []byte, fkEnabled bool) (retDB *DB, retErr error) {
// Get a plain-ol' in-memory database.
tmpDB, err := sql.Open("sqlite3", ":memory:")
if err != nil {
@ -221,7 +225,7 @@ func DeserializeIntoMemory(b []byte) (retDB *DB, retErr error) {
// tmpDB will still be using memory in Go space, so tmpDB needs to be explicitly
// copied to a new database, which we create now.
db, err := OpenInMemory()
db, err := OpenInMemory(fkEnabled)
if err != nil {
return nil, fmt.Errorf("DeserializeIntoMemory: %s", err.Error())
}
@ -609,7 +613,7 @@ func (db *DB) queryWithConn(req *command.Request, xTime bool, conn *sql.Conn) ([
// Backup writes a consistent snapshot of the database to the given file.
// This function can be called when changes to the database are in flight.
func (db *DB) Backup(path string) error {
dstDB, err := Open(path)
dstDB, err := Open(path, false)
if err != nil {
return err
}

@ -24,7 +24,7 @@ func Test_DbFileCreation(t *testing.T) {
defer os.RemoveAll(dir)
dbPath := path.Join(dir, "test_db")
db, err := Open(dbPath)
db, err := Open(dbPath, false)
if err != nil {
t.Fatalf("failed to open new database: %s", err.Error())
}
@ -150,7 +150,7 @@ func Test_LoadIntoMemory(t *testing.T) {
t.Fatalf("unexpected results for query, expected %s, got %s", exp, got)
}
inmem, err := LoadIntoMemory(path)
inmem, err := LoadIntoMemory(path, false)
if err != nil {
t.Fatalf("failed to create loaded in-memory database: %s", err.Error())
}
@ -204,7 +204,7 @@ func Test_DeserializeIntoMemory(t *testing.T) {
t.Fatalf("failed to read database on disk: %s", err.Error())
}
newDB, err := DeserializeIntoMemory(b)
newDB, err := DeserializeIntoMemory(b, false)
if err != nil {
t.Fatalf("failed to deserialize database: %s", err.Error())
}
@ -1068,7 +1068,7 @@ func Test_Backup(t *testing.T) {
t.Fatalf("failed to backup database: %s", err.Error())
}
newDB, err := Open(dstDB)
newDB, err := Open(dstDB, false)
if err != nil {
t.Fatalf("failed to open backup database: %s", err.Error())
}
@ -1117,7 +1117,7 @@ func Test_Copy(t *testing.T) {
dstFile := mustTempFile()
defer os.Remove(dstFile)
dstDB, err := Open(dstFile)
dstDB, err := Open(dstFile, false)
if err != nil {
t.Fatalf("failed to open destination database: %s", err)
}
@ -1186,7 +1186,7 @@ func Test_Serialize(t *testing.T) {
t.Fatalf("failed to write serialized database to file: %s", err.Error())
}
newDB, err := Open(dstDB.Name())
newDB, err := Open(dstDB.Name(), false)
if err != nil {
t.Fatalf("failed to open on-disk serialized database: %s", err.Error())
}
@ -1230,7 +1230,7 @@ func Test_DumpMemory(t *testing.T) {
defer db.Close()
defer os.Remove(path)
inmem, err := LoadIntoMemory(path)
inmem, err := LoadIntoMemory(path, false)
if err != nil {
t.Fatalf("failed to create loaded in-memory database: %s", err.Error())
}
@ -1409,7 +1409,7 @@ func Test_JSON1(t *testing.T) {
func mustCreateDatabase() (*DB, string) {
var err error
f := mustTempFile()
db, err := Open(f)
db, err := Open(f, false)
if err != nil {
panic("failed to open database")
}
@ -1418,7 +1418,7 @@ func mustCreateDatabase() (*DB, string) {
}
func mustCreateInMemoryDatabase() *DB {
db, err := OpenInMemory()
db, err := OpenInMemory(false)
if err != nil {
panic("failed to open in-memory database")
}
@ -1433,7 +1433,7 @@ func mustWriteAndOpenDatabase(b []byte) (*DB, string) {
panic("failed to write file")
}
db, err := Open(f)
db, err := Open(f, false)
if err != nil {
panic("failed to open database")
}

@ -803,9 +803,9 @@ func (s *Store) Noop(id string) error {
// database will be initialized with the contents of b.
func (s *Store) createInMemory(b []byte) (db *sql.DB, err error) {
if b == nil {
db, err = sql.OpenInMemory()
db, err = sql.OpenInMemory(s.dbConf.FKConstraints)
} else {
db, err = sql.DeserializeIntoMemory(b)
db, err = sql.DeserializeIntoMemory(b, s.dbConf.FKConstraints)
}
return
}
@ -822,7 +822,7 @@ func (s *Store) createOnDisk(b []byte) (*sql.DB, error) {
return nil, err
}
}
return sql.Open(s.dbPath)
return sql.Open(s.dbPath, s.dbConf.FKConstraints)
}
// setLogInfo records some key indexs about the log.

Loading…
Cancel
Save