Skip to content

Commit

Permalink
feature: supporting sqlite :memory: and mode=memory on the sqlite dri…
Browse files Browse the repository at this point in the history
…ver (#717)
  • Loading branch information
paganotoni authored May 21, 2022
1 parent 1c3fa0f commit db86847
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ testdata/migrations/schema.sql
vendor/
.env
.release-env
.vscode

# test data
cockroach-data/
24 changes: 17 additions & 7 deletions dialect_sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,22 +182,32 @@ func (m *sqlite) locker(l *sync.Mutex, fn func() error) error {
}

func (m *sqlite) CreateDB() error {
_, err := os.Stat(m.ConnectionDetails.Database)
durl := m.ConnectionDetails.Database

// Checking whether the url specifies in-memory mode
// as specified in https://github.com/mattn/go-sqlite3#faq
if strings.Contains(durl, ":memory:") || strings.Contains(durl, "mode=memory") {
log(logging.Info, "in memory db selected, no database file created.")

return nil
}

_, err := os.Stat(durl)
if err == nil {
return fmt.Errorf("could not create SQLite database '%s'; database exists", m.ConnectionDetails.Database)
return fmt.Errorf("could not create SQLite database '%s'; database exists", durl)
}
dir := filepath.Dir(m.ConnectionDetails.Database)
dir := filepath.Dir(durl)
err = os.MkdirAll(dir, 0766)
if err != nil {
return fmt.Errorf("could not create SQLite database '%s': %w", m.ConnectionDetails.Database, err)
return fmt.Errorf("could not create SQLite database '%s': %w", durl, err)
}
f, err := os.Create(m.ConnectionDetails.Database)
f, err := os.Create(durl)
if err != nil {
return fmt.Errorf("could not create SQLite database '%s': %w", m.ConnectionDetails.Database, err)
return fmt.Errorf("could not create SQLite database '%s': %w", durl, err)
}
_ = f.Close()

log(logging.Info, "created database '%s'", m.ConnectionDetails.Database)
log(logging.Info, "created database '%s'", durl)
return nil
}

Expand Down
52 changes: 43 additions & 9 deletions dialect_sqlite_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build sqlite
// +build sqlite

package pop
Expand Down Expand Up @@ -144,18 +145,51 @@ func Test_ConnectionDetails_FinalizeOSPath(t *testing.T) {

func TestSqlite_CreateDB(t *testing.T) {
r := require.New(t)
dir := t.TempDir()
p := filepath.Join(dir, "testdb.sqlite")
cd := &ConnectionDetails{
Dialect: "sqlite",
Database: p,
}

cd := &ConnectionDetails{Dialect: "sqlite"}
dialect, err := newSQLite(cd)
r.NoError(err)
r.NoError(dialect.CreateDB())

// Creating DB twice should produce an error
r.EqualError(dialect.CreateDB(), fmt.Sprintf("could not create SQLite database '%s'; database exists", p))
t.Run("CreateFile", func(t *testing.T) {
dir := t.TempDir()
cd.Database = filepath.Join(dir, "testdb.sqlite")

r.NoError(dialect.CreateDB())
r.FileExists(cd.Database)
})

t.Run("MemoryDB_tag", func(t *testing.T) {
dir := t.TempDir()
cd.Database = filepath.Join(dir, "file::memory:?cache=shared")

r.NoError(dialect.CreateDB())
r.NoFileExists(cd.Database)
})

t.Run("MemoryDB_only", func(t *testing.T) {
dir := t.TempDir()
cd.Database = filepath.Join(dir, ":memory:")

r.NoError(dialect.CreateDB())
r.NoFileExists(cd.Database)
})

t.Run("MemoryDB_param", func(t *testing.T) {
dir := t.TempDir()
cd.Database = filepath.Join(dir, "file:foobar?mode=memory&cache=shared")

r.NoError(dialect.CreateDB())
r.NoFileExists(cd.Database)
})

t.Run("CreateFile_ExistingDB", func(t *testing.T) {
dir := t.TempDir()
cd.Database = filepath.Join(dir, "testdb.sqlite")

r.NoError(dialect.CreateDB())
r.EqualError(dialect.CreateDB(), fmt.Sprintf("could not create SQLite database '%s'; database exists", cd.Database))
})

}

func TestSqlite_NewDriver(t *testing.T) {
Expand Down

0 comments on commit db86847

Please sign in to comment.