mirror of
https://gitlab.com/cznic/sqlite.git
synced 2025-04-27 23:07:44 +00:00
188 lines
3.3 KiB
Go
188 lines
3.3 KiB
Go
// Copyright 2032 The Sqlite Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
|
|
"modernc.org/sqlite/tpch/driver"
|
|
)
|
|
|
|
func cpDB(sut driver.SUT, src, dest *sql.DB) error {
|
|
for _, v := range []struct {
|
|
t, i string
|
|
int
|
|
}{
|
|
{"customer", sut.InsertCustomer(), 8},
|
|
{"lineitem", sut.InsertLineItem(), 16},
|
|
{"nation", sut.InsertNation(), 4},
|
|
{"orders", sut.InsertOrders(), 9},
|
|
{"part", sut.InsertPart(), 9},
|
|
{"partsupp", sut.InsertPartSupp(), 5},
|
|
{"region", sut.InsertRegion(), 3},
|
|
{"supplier", sut.InsertSupplier(), 7},
|
|
} {
|
|
if err := cpTable(src, dest, v.t, v.i, v.int); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func cpTable(src, dest *sql.DB, tn, ins string, ncols int) (err error) {
|
|
rows, err := src.Query(fmt.Sprintf("select * from %s", tn))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if e := rows.Close(); e != nil && err == nil {
|
|
err = e
|
|
}
|
|
}()
|
|
|
|
var tx *sql.Tx
|
|
var stmt *sql.Stmt
|
|
row := make([]interface{}, ncols)
|
|
data := make([]interface{}, ncols)
|
|
for i := range data {
|
|
data[i] = &row[i]
|
|
}
|
|
for i := 0; rows.Next(); i++ {
|
|
if i%1000 == 0 {
|
|
if i != 0 {
|
|
if err = tx.Commit(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if tx, err = dest.Begin(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if stmt, err = tx.Prepare(ins); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err = rows.Scan(data...); err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, v := range row {
|
|
switch x := v.(type) {
|
|
case time.Time:
|
|
case int64:
|
|
case []byte:
|
|
row[i] = string(x)
|
|
default:
|
|
panic("TODO")
|
|
}
|
|
}
|
|
if _, err = stmt.Exec(row...); err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
if err = rows.Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return tx.Commit()
|
|
}
|
|
|
|
func run(sut driver.SUT, mem bool, n, sf int, verbose bool) (err error) {
|
|
pth := pthForSUT(sut, sf)
|
|
if err := sut.SetWD(pth); err != nil {
|
|
return err
|
|
}
|
|
|
|
db, err := sut.OpenDB()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func(db *sql.DB) {
|
|
if cerr := db.Close(); cerr != nil && err == nil {
|
|
err = cerr
|
|
}
|
|
}(db)
|
|
|
|
if mem {
|
|
msut, mdb, err := sut.OpenMem()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = msut.CreateTables(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = cpDB(sut, db, mdb); err != nil {
|
|
return err
|
|
}
|
|
|
|
sut, db = msut, mdb
|
|
}
|
|
|
|
rng := newRng(0, math.MaxInt64)
|
|
rng.r.Seed(time.Now().UnixNano())
|
|
t0 := time.Now()
|
|
|
|
defer func() {
|
|
fmt.Println(time.Since(t0))
|
|
}()
|
|
|
|
switch n {
|
|
case 1:
|
|
return exec(db, 10, sut.Q1(), verbose, rng.randomValue(60, 120))
|
|
case 2:
|
|
return exec(db, 8, sut.Q2(), verbose, rng.randomValue(1, 50), rng.types(), rng.regions())
|
|
default:
|
|
return fmt.Errorf("No query/test #%d", n)
|
|
}
|
|
}
|
|
|
|
func exec(db *sql.DB, ncols int, q string, verbose bool, arg ...interface{}) error {
|
|
rec := make([]interface{}, ncols)
|
|
data := make([]interface{}, ncols)
|
|
for i := range data {
|
|
data[i] = &rec[i]
|
|
}
|
|
|
|
rows, err := db.Query(q, arg...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if e := rows.Close(); e != nil && err == nil {
|
|
err = e
|
|
}
|
|
}()
|
|
|
|
for rows.Next() {
|
|
if !verbose {
|
|
continue
|
|
}
|
|
|
|
if err = rows.Scan(data...); err != nil {
|
|
return err
|
|
}
|
|
|
|
for i, v := range rec {
|
|
if b, ok := v.([]byte); ok {
|
|
rec[i] = string(b)
|
|
}
|
|
}
|
|
|
|
fmt.Println(rec)
|
|
}
|
|
return rows.Err()
|
|
}
|