2023-06-15 21:22:51 +08:00
|
|
|
//
|
|
|
|
// base_test.go
|
|
|
|
// Copyright (C) 2022 tiglog <me@tiglog.com>
|
|
|
|
//
|
|
|
|
// Distributed under terms of the MIT license.
|
|
|
|
//
|
|
|
|
|
|
|
|
package sqldb_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
_ "github.com/lib/pq"
|
2023-06-15 21:38:12 +08:00
|
|
|
"git.hexq.cn/tiglog/golib/gdb/sqldb"
|
2023-06-15 21:22:51 +08:00
|
|
|
// _ "github.com/go-sql-driver/mysql"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Schema struct {
|
|
|
|
create string
|
|
|
|
drop string
|
|
|
|
}
|
|
|
|
|
|
|
|
var defaultSchema = Schema{
|
|
|
|
create: `
|
|
|
|
CREATE TABLE person (
|
|
|
|
id serial,
|
|
|
|
first_name text,
|
|
|
|
last_name text,
|
|
|
|
email text,
|
|
|
|
added_at int default 0,
|
|
|
|
PRIMARY KEY (id)
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE place (
|
|
|
|
country text,
|
|
|
|
city text NULL,
|
|
|
|
telcode integer
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE capplace (
|
|
|
|
country text,
|
|
|
|
city text NULL,
|
|
|
|
telcode integer
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE nullperson (
|
|
|
|
first_name text NULL,
|
|
|
|
last_name text NULL,
|
|
|
|
email text NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
CREATE TABLE employees (
|
|
|
|
name text,
|
|
|
|
id integer,
|
|
|
|
boss_id integer
|
|
|
|
);
|
|
|
|
|
|
|
|
`,
|
|
|
|
drop: `
|
|
|
|
drop table person;
|
|
|
|
drop table place;
|
|
|
|
drop table capplace;
|
|
|
|
drop table nullperson;
|
|
|
|
drop table employees;
|
|
|
|
`,
|
|
|
|
}
|
|
|
|
|
|
|
|
type Person struct {
|
|
|
|
Id int64 `db:"id"`
|
|
|
|
FirstName string `db:"first_name"`
|
|
|
|
LastName string `db:"last_name"`
|
|
|
|
Email string `db:"email"`
|
|
|
|
AddedAt int64 `db:"added_at"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Person2 struct {
|
|
|
|
FirstName sql.NullString `db:"first_name"`
|
|
|
|
LastName sql.NullString `db:"last_name"`
|
|
|
|
Email sql.NullString
|
|
|
|
}
|
|
|
|
|
|
|
|
type Place struct {
|
|
|
|
Country string
|
|
|
|
City sql.NullString
|
|
|
|
TelCode int
|
|
|
|
}
|
|
|
|
|
|
|
|
type PlacePtr struct {
|
|
|
|
Country string
|
|
|
|
City *string
|
|
|
|
TelCode int
|
|
|
|
}
|
|
|
|
|
|
|
|
type PersonPlace struct {
|
|
|
|
Person
|
|
|
|
Place
|
|
|
|
}
|
|
|
|
|
|
|
|
type PersonPlacePtr struct {
|
|
|
|
*Person
|
|
|
|
*Place
|
|
|
|
}
|
|
|
|
|
|
|
|
type EmbedConflict struct {
|
|
|
|
FirstName string `db:"first_name"`
|
|
|
|
Person
|
|
|
|
}
|
|
|
|
|
|
|
|
type SliceMember struct {
|
|
|
|
Country string
|
|
|
|
City sql.NullString
|
|
|
|
TelCode int
|
|
|
|
People []Person `db:"-"`
|
|
|
|
Addresses []Place `db:"-"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadDefaultFixture(db *sqldb.Engine, t *testing.T) {
|
|
|
|
tx := db.MustBegin()
|
|
|
|
|
|
|
|
s1 := "INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Jason", "Moiron", "jmoiron@jmoiron.net")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "John", "Doe", "johndoeDNE@gmail.net")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "United States", "New York", "1")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO place (country, telcode) VALUES (?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Hong Kong", "852")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO place (country, telcode) VALUES (?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Singapore", "65")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO capplace (country, telcode) VALUES (?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Sarf Efrica", "27")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO employees (name, id) VALUES (?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Peter", "4444")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Joe", "1", "4444")
|
|
|
|
|
|
|
|
s1 = "INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)"
|
|
|
|
tx.MustExec(db.Rebind(s1), "Martin", "2", "4444")
|
|
|
|
tx.Commit()
|
|
|
|
}
|
|
|
|
|
|
|
|
func MultiExec(e *sqldb.Engine, query string) {
|
|
|
|
stmts := strings.Split(query, ";\n")
|
|
|
|
if len(strings.Trim(stmts[len(stmts)-1], " \n\t\r")) == 0 {
|
|
|
|
stmts = stmts[:len(stmts)-1]
|
|
|
|
}
|
|
|
|
for _, s := range stmts {
|
|
|
|
_, err := e.Exec(s)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err, s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func RunDbTest(t *testing.T, test func(db *sqldb.Engine, t *testing.T)) {
|
|
|
|
// 先初始化数据库
|
|
|
|
url := os.Getenv("DB_URL")
|
|
|
|
var db = sqldb.New(url)
|
|
|
|
|
|
|
|
// 再注册清空数据库
|
|
|
|
defer func() {
|
|
|
|
MultiExec(db, defaultSchema.drop)
|
|
|
|
}()
|
|
|
|
// 再加入一些数据
|
|
|
|
MultiExec(db, defaultSchema.create)
|
|
|
|
loadDefaultFixture(db, t)
|
|
|
|
// 最后测试
|
|
|
|
test(db, t)
|
|
|
|
}
|