Files
chaisql/internal/sql/driver/driver_test.go
Asdine El Hrychy 613ca304f4 remove rowid
2025-09-07 23:29:43 +08:00

268 lines
6.5 KiB
Go

package driver_test
import (
"context"
"database/sql"
"fmt"
"testing"
"time"
_ "github.com/chaisql/chai"
"github.com/stretchr/testify/require"
)
type rowtest struct {
A int
B string
C bool
}
func TestDriver(t *testing.T) {
db, err := sql.Open("chai", ":memory:")
require.NoError(t, err)
defer db.Close()
res, err := db.Exec("CREATE TABLE test(a INT PRIMARY KEY, b TEXT, c BOOL)")
require.NoError(t, err)
n, err := res.RowsAffected()
require.Error(t, err)
require.EqualValues(t, 0, n)
for i := 0; i < 10; i++ {
_, err = db.Exec("INSERT INTO test (a, b, c) VALUES ($1, $2, $3)", i, fmt.Sprintf("foo%d", i), i%2 == 0)
require.NoError(t, err)
}
t.Run("Wildcard", func(t *testing.T) {
rows, err := db.Query("SELECT * FROM test")
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Multiple columns", func(t *testing.T) {
rows, err := db.Query("SELECT a, c FROM test")
require.NoError(t, err)
defer rows.Close()
var count int
var a int
var c bool
for rows.Next() {
err = rows.Scan(&a, &c)
require.NoError(t, err)
require.Equal(t, count, a)
require.Equal(t, count%2 == 0, c)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Multiple columns with ORDER BY", func(t *testing.T) {
rows, err := db.Query("SELECT a, c FROM test ORDER BY a")
require.NoError(t, err)
defer rows.Close()
var count int
var a int
var c bool
for rows.Next() {
err = rows.Scan(&a, &c)
require.NoError(t, err)
require.Equal(t, count, a)
require.Equal(t, count%2 == 0, c)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Wilcards with ORDER BY", func(t *testing.T) {
rows, err := db.Query("SELECT * FROM test ORDER BY a")
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Wilcards with ORDER BY and LIMIT", func(t *testing.T) {
rows, err := db.Query("SELECT * FROM test ORDER BY a LIMIT 5")
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 5, count)
})
t.Run("Multiple columns and wildcards", func(t *testing.T) {
rows, err := db.Query("SELECT a, a, *, b, c, * FROM test")
require.NoError(t, err)
defer rows.Close()
var count int
var a int
var aa int
var b string
var c bool
var dt1, dt2 rowtest
for rows.Next() {
err = rows.Scan(&a, &aa, &dt1.A, &dt1.B, &dt1.C, &b, &c, &dt2.A, &dt2.B, &dt2.C)
require.NoError(t, err)
require.Equal(t, count, a)
require.Equal(t, fmt.Sprintf("foo%d", count), b)
require.Equal(t, count%2 == 0, c)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, dt1)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, dt2)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Params", func(t *testing.T) {
rows, err := db.Query("SELECT a FROM test WHERE a = $1", 5)
require.NoError(t, err)
defer rows.Close()
var count int
var a int
for rows.Next() {
err = rows.Scan(&a)
require.NoError(t, err)
require.Equal(t, 5, a)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 1, count)
})
t.Run("Transactions", func(t *testing.T) {
tx, err := db.Begin()
require.NoError(t, err)
defer func() { _ = tx.Rollback() }()
rows, err := tx.Query("SELECT * FROM test")
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 10, count)
})
t.Run("Multiple queries", func(t *testing.T) {
rows, err := db.Query(`
SELECT * FROM test;;;
INSERT INTO test (a, b, c) VALUES (10, 'foo10', true);
SELECT * FROM test;
`)
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 11, count)
})
t.Run("Multiple queries in transaction", func(t *testing.T) {
tx, err := db.Begin()
require.NoError(t, err)
defer func() { _ = tx.Rollback() }()
rows, err := tx.Query(`
SELECT * FROM test;;;
INSERT INTO test (a, b, c) VALUES (11, 'foo11', false);
SELECT * FROM test;
`)
require.NoError(t, err)
defer rows.Close()
var count int
var rt rowtest
for rows.Next() {
err = rows.Scan(&rt.A, &rt.B, &rt.C)
require.NoError(t, err)
require.Equal(t, rowtest{count, fmt.Sprintf("foo%d", count), count%2 == 0}, rt)
count++
}
require.NoError(t, rows.Err())
require.Equal(t, 12, count)
})
t.Run("Multiple queries in read only transaction", func(t *testing.T) {
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
require.NoError(t, err)
defer func() { _ = tx.Rollback() }()
_, err = tx.Query(`
SELECT * FROM test;;;
INSERT INTO test (a, b, c) VALUES (12, 13, 14);
SELECT * FROM test;
`)
require.EqualError(t, err, "cannot put in read-only mode")
})
}
func TestDriverWithTimeValues(t *testing.T) {
db, err := sql.Open("chai", ":memory:")
require.NoError(t, err)
defer db.Close()
now := time.Now().UTC().Truncate(time.Microsecond)
_, err = db.Exec("CREATE TABLE test(a TIMESTAMP PRIMARY KEY); INSERT INTO test (a) VALUES ($1)", now)
require.NoError(t, err)
tx, err := db.BeginTx(context.Background(), &sql.TxOptions{ReadOnly: true})
require.NoError(t, err)
defer func() { _ = tx.Rollback() }()
var tt time.Time
err = tx.QueryRow(`SELECT a FROM test`).Scan(&tt)
require.NoError(t, err)
require.Equal(t, now, tt)
}