crawshaw / sqlite

Go SQLite3 driver

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

table created with one connection does not exists on the others

omar-polo opened this issue · comments

Hi,

I don't have much experience with sqlite, so I don't know if this is expected or not. I've used sqlite in the past, but with a different language and only one connection open at time.

I'm trying to create a table in one connection and then use that table from (possibly) another connection on the same goroutine, but I get "no such table". If I create the pool with a size of 1 this does not happen.

This seems the minimum in order to reproduce:

package main

import (
	"fmt"
	"runtime"

	"crawshaw.io/sqlite/sqlitex"
)

func main() {
	pool, err := sqlitex.Open("", 0, runtime.NumCPU()) // = 8
	if err != nil {
		panic(err)
	}
	defer pool.Close()

	{
		conn := pool.Get(nil)
		stmt := conn.Prep("create table posts(fname varchar)")
		if _, err := stmt.Step(); err != nil {
			panic(err)
		}
		pool.Put(conn)
	}

	{
		conn := pool.Get(nil)
		stmt := conn.Prep("select * from posts") // it will panic
		for {
			if h, err := stmt.Step(); err != nil {
				panic(err)
			} else if !h {
				break
			}

			fmt.Println(stmt.GetText("fname"))
		}
		pool.Put(conn)
	}
}
$ go run m.go 
panic: sqlite.Conn.Prepare: SQLITE_ERROR: no such table: posts (select * from posts)

goroutine 1 [running]:
crawshaw.io/sqlite.(*Conn).Prep(0xc0000ae240, 0x5c7e28, 0x13, 0xc0000ae240)
        /home/yumh/go/src/crawshaw.io/sqlite/sqlite.go:367 +0x17e
main.main()
        /tmp/foo/m.go:28 +0x17f
exit status 2

The workaround I'm using is to migrate the database, then open the pool.

The reason this is occurring is because by default in memory databases are per-connection. This means that in your example the table created on the first connection is not visible to any other connection.

Your example will not panic if you use an actual path for the database instead of an empty string.

It is also possible to use a shared-cache in-memory database using the URI "file::memory:?cache=shared".

More information from the official SQLite docs can be found here:
https://sqlite.org/inmemorydb.html

Oh, thank you!

The documentation for sqlite3_open_v2 confused me: I didn't realized that with sqlitex n different connection would be opened to different private databases. In fact, as a workaround I started using a file to hold the db and then migrate/reopen the pool, without thinking of why it worked.

So, thank you again and sorry for the noise :)