mirror of
https://github.com/chaisql/chai.git
synced 2025-10-05 07:36:56 +08:00
268 lines
6.5 KiB
Go
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)
|
|
}
|