upper / db

Data Access Layer (DAL) for PostgreSQL, CockroachDB, MySQL, SQLite and MongoDB with ORM-like features.
https://upper.io/
MIT License
3.54k stars 235 forks source link

sqlite.New panics #633

Closed mem closed 3 years ago

mem commented 3 years ago

reading the docs for sqlite.New, I'm not sure if I'm misunderstanding the docs, or if there's a bug.

From the function signature I expect this code to work:

package main

import (
        "database/sql"

        _ "github.com/mattn/go-sqlite3"

        "github.com/upper/db/v4/adapter/sqlite"
)

func test() {
        h, err := sql.Open("sqlite3", "file:test.db?mode=memory")
        if err != nil {
                panic(err)
        }

        sess, err := sqlite.New(h) // this panics
        if err != nil {
                panic(err)
        }

        if err := sess.Close(); err != nil {
                panic(err)
        }
}

but it does in fact panic:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x7c3fdf]

goroutine 1 [running]:
github.com/upper/db/v4/adapter/sqlite.(*database).LookupName(0xd8c490, 0xa00af0, 0xc00026d930, 0x0, 0x0, 0xc0001ff680, 0xc0001ff5f0)
        $GOPATH/pkg/mod/github.com/upper/db/v4@v4.2.0/adapter/sqlite/database.go:100 +0x3f
github.com/upper/db/v4/internal/sqladapter.(*session).BindDB(0xc00026d930, 0xc00026d860, 0x9fcf98, 0xd8c490)
        $GOPATH/pkg/mod/github.com/upper/db/v4@v4.2.0/internal/sqladapter/session.go:518 +0xf2
github.com/upper/db/v4/internal/sqladapter.(*sqlAdapterWrapper).New(0xc0002a6220, 0xc00026d860, 0x97ed69, 0x18, 0xc00026d860, 0x0)
        $GOPATH/pkg/mod/github.com/upper/db/v4@v4.2.0/internal/sqladapter/sqladapter.go:72 +0x72
github.com/upper/db/v4/adapter/sqlite.New(...)
        $GOPATH/pkg/mod/github.com/upper/db/v4@v4.2.0/adapter/sqlite/sqlite.go:51
main.test()
        $PWD/test.go:17 +0x96
main.main()
        $PWD/main.go:151 +0x25

it seems to be looking for the connection URL, which isn't available because Open was not called?

The reason why I'm trying to do this is because I have a database migration tool which is in charge of creating tables, etc, but since database is in memory, if I close the sql.DB handle that I used to run the migrations, the database is lost.

I have figured out a solution for that problem (use sqlite.ParseURL to obtain a ConnectionURL, use the resulting DSN with sql.Open, and pass it as the settings argument to sqlite.Open before closing the connection, so that the database is reused). What I'm wondering here is if the above program is supposed to work or not, and if not, why not?