add struct, slice, map scan for db
This commit is contained in:
parent
2f86968e94
commit
8c5763bb3a
32
core/db.go
32
core/db.go
|
@ -27,17 +27,33 @@ type Rows struct {
|
|||
}
|
||||
|
||||
// scan data to a struct's pointer according field index
|
||||
func (rs *Rows) ScanStruct(dest interface{}) error {
|
||||
vv := reflect.ValueOf(dest)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("dest should be a struct's pointer")
|
||||
func (rs *Rows) ScanStruct(dest ...interface{}) error {
|
||||
if len(dest) == 0 {
|
||||
return errors.New("at least one struct")
|
||||
}
|
||||
|
||||
vvv := vv.Elem()
|
||||
newDest := make([]interface{}, vvv.NumField())
|
||||
vvvs := make([]reflect.Value, len(dest))
|
||||
for i, s := range dest {
|
||||
vv := reflect.ValueOf(s)
|
||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||
return errors.New("dest should be a struct's pointer")
|
||||
}
|
||||
|
||||
for j := 0; j < vvv.NumField(); j++ {
|
||||
newDest[j] = vvv.Field(j).Addr().Interface()
|
||||
vvvs[i] = vv.Elem()
|
||||
}
|
||||
|
||||
cols, err := rs.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newDest := make([]interface{}, len(cols))
|
||||
|
||||
var i = 0
|
||||
for _, vvv := range vvvs {
|
||||
for j := 0; j < vvv.NumField(); j++ {
|
||||
newDest[i] = vvv.Field(j).Addr().Interface()
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
return rs.Rows.Scan(newDest...)
|
||||
|
|
288
core/db_test.go
288
core/db_test.go
|
@ -1,10 +1,8 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
@ -22,209 +20,305 @@ type User struct {
|
|||
NickName string
|
||||
}
|
||||
|
||||
func TestOriQuery(t *testing.T) {
|
||||
func BenchmarkOriQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
b.StartTimer()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for rows.Next() {
|
||||
var Id int64
|
||||
var Name, Title, Alias, NickName string
|
||||
var Age float32
|
||||
err = rows.Scan(&Id, &Name, &Title, &Age, &Alias, &NickName)
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
fmt.Println(Id, Name, Title, Age, Alias, NickName)
|
||||
}
|
||||
|
||||
fmt.Println("ori ------", time.Now().Sub(start), "ns")
|
||||
for rows.Next() {
|
||||
var Id int64
|
||||
var Name, Title, Alias, NickName string
|
||||
var Age float32
|
||||
err = rows.Scan(&Id, &Name, &Title, &Age, &Alias, &NickName)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
//fmt.Println(Id, Name, Title, Age, Alias, NickName)
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestStructQuery(t *testing.T) {
|
||||
func BenchmarkStructQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
start := time.Now()
|
||||
b.StartTimer()
|
||||
|
||||
for rows.Next() {
|
||||
var user User
|
||||
err = rows.ScanStruct(&user)
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
fmt.Println(user)
|
||||
|
||||
for rows.Next() {
|
||||
var user User
|
||||
err = rows.ScanStruct(&user)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
//fmt.Println(user)
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
fmt.Println("struct ------", time.Now().Sub(start))
|
||||
}
|
||||
|
||||
func TestStruct2Query(t *testing.T) {
|
||||
func BenchmarkStruct2Query(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
db.Mapper = &SnakeMapper{}
|
||||
b.StartTimer()
|
||||
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
start := time.Now()
|
||||
|
||||
for rows.Next() {
|
||||
var user User
|
||||
err = rows.ScanStruct2(&user)
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
fmt.Println(user)
|
||||
|
||||
for rows.Next() {
|
||||
var user User
|
||||
err = rows.ScanStruct2(&user)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
//fmt.Println(user)
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
fmt.Println("struct2 ------", time.Now().Sub(start))
|
||||
}
|
||||
|
||||
func TestSliceQuery(t *testing.T) {
|
||||
func BenchmarkSliceQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
cols, err := rows.Columns()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for rows.Next() {
|
||||
slice := make([]interface{}, len(cols))
|
||||
err = rows.ScanSlice(&slice)
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
fmt.Println(slice)
|
||||
}
|
||||
|
||||
fmt.Println("slice ------", time.Now().Sub(start))
|
||||
cols, err := rows.Columns()
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
slice := make([]interface{}, len(cols))
|
||||
err = rows.ScanSlice(&slice)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
//fmt.Println(slice)
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func TestMapQuery(t *testing.T) {
|
||||
func BenchmarkMapInterfaceQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
b.StartTimer()
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
for rows.Next() {
|
||||
m := make(map[string]interface{})
|
||||
err = rows.ScanMap(&m)
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
b.Error(err)
|
||||
}
|
||||
fmt.Println(m)
|
||||
|
||||
for rows.Next() {
|
||||
m := make(map[string]interface{})
|
||||
err = rows.ScanMap(&m)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
//fmt.Println(m)
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMapBytesQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
fmt.Println("map ------", time.Now().Sub(start))
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
m := make(map[string][]byte)
|
||||
err = rows.ScanMap(&m)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
/*for k, v := range m {
|
||||
fmt.Printf("%v - %v\n", k, string(v))
|
||||
}*/
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMapStringQuery(b *testing.B) {
|
||||
b.StopTimer()
|
||||
os.Remove("./test.db")
|
||||
db, err := Open("sqlite3", "./test.db")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
_, err = db.Exec(createTableSqlite3)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 50; i++ {
|
||||
_, err = db.Exec("insert into user (name, title, age, alias, nick_name) values (?,?,?,?,?)",
|
||||
"xlw", "tester", 1.2, "lunny", "lunny xiao")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
rows, err := db.Query("select * from user")
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
for rows.Next() {
|
||||
m := make(map[string]string)
|
||||
err = rows.ScanMap(&m)
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
/*for k, v := range m {
|
||||
fmt.Printf("%v - %v\n", k, v)
|
||||
}*/
|
||||
}
|
||||
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue