Skip to content

Instantly share code, notes, and snippets.

@neetsdkasu
Last active May 23, 2022
Embed
What would you like to do?
Goのsqlパッケージの挙動みてみる
package main
import (
"context"
"database/sql"
"database/sql/driver"
"fmt"
"log"
"sync/atomic"
"time"
)
func main() {
log.Println("Drivers")
for _, s := range sql.Drivers() {
log.Println(s)
}
log.Println("-------")
db, err := sql.Open("unkodb", "unkodb THE SOURCE")
if err != nil {
log.Println("ERROR desu:", err.Error())
return
}
defer func() {
log.Println("CloseClose")
err = db.Close()
if err != nil {
log.Println("ERROR DEFER:", err.Error())
}
log.Println("Done.")
}()
for i := 0; i < 5; i++ {
log.Println("-------", i)
go func(k int) {
for p := 0; p < 3; p++ {
log.Println("=====", k, p, "(", k*3+p, ")")
go func(x int) {
err = db.Ping()
if err != nil {
log.Println("ERROR ping:", err.Error())
return
}
switch x % 2 {
case 0:
result, err := db.Exec("CREATE TABLE ? x=?", "hoge", x)
if err != nil {
log.Println("ERROR exec:", err.Error())
} else {
_ = result
}
case 1:
rows, err := db.Query("SELECT value FROM ? WHERE x=?", "FUGA", x)
if err != nil {
log.Println("ERROR query:", err.Error())
} else {
rows.Close()
}
}
stats := db.Stats()
log.Printf("%d: %#v\n", x, stats)
}(k*3 + p)
}
}(i)
}
log.Println("Ok")
<-time.After(time.Second)
log.Println("OkOk")
log.Printf("Stats: %#v\n", db.Stats())
}
func init() {
sql.Register("unkodb", &UnkoDBDriver{})
}
type UnkoDBDriver struct{}
var connid int32 = 0
func (*UnkoDBDriver) Open(name string) (driver.Conn, error) {
id := atomic.AddInt32(&connid, 1)
log.Println("Call UnkoDBDriver.Open:", name, "new ID:", id)
return &UnkoDBConn{id}, nil
// return nil, fmt.Errorf("UnkoDBDriver Open ERROR")
}
func (d *UnkoDBDriver) OpenConnector(name string) (driver.Connector, error) {
log.Println("Call UnkoDBDriver.OpenConnector:", name)
return &UnkoDBConnector{d, name}, nil
// return nil, fmt.Errorf("UnkoDBDriver OpenConnector ERROR")
}
type UnkoDBConnector struct {
driver *UnkoDBDriver
name string
}
func (c *UnkoDBConnector) Connect(ctx context.Context) (driver.Conn, error) {
id := atomic.AddInt32(&connid, 1)
log.Println("Call UnkoDBConnector.Connect:", c.name, "new ID:", id)
return &UnkoDBConn{id}, nil
// return nil, fmt.Errorf("UnkoDBConnector Connect ERROR")
}
func (c *UnkoDBConnector) Driver() driver.Driver {
return c.driver
}
type UnkoDBConn struct {
id int32
}
func (c *UnkoDBConn) Prepare(query string) (driver.Stmt, error) {
log.Println("Call UnkoDBConn.Prepare:", query, "ID:", c.id)
return &UnkoDBStmt{c.id}, nil
// return nil, fmt.Errorf("UnkoDBConn Prepare ERROR (%d)", c.id)
}
func (c *UnkoDBConn) Close() error {
log.Println("Call UnkoDBConn.Close", "ID:", c.id)
return nil
// return fmt.Errorf("UnkoDBConn Close ERROR (%d)", c.id)
}
func (c *UnkoDBConn) Begin() (driver.Tx, error) {
log.Println("Call UnkoDBConn.Begin", "ID:", c.id)
return nil, fmt.Errorf("UnkoDBConn Begin ERROR (%d)", c.id)
}
type UnkoDBStmt struct {
connId int32
}
func (s *UnkoDBStmt) Close() error {
log.Println("Call UnkoDBStmt.Close", "ID:", s.connId)
return nil
// return fmt.Errorf("UnkoDBStmt Close ERROR (%d)", s.connId)
}
func (s *UnkoDBStmt) NumInput() int {
log.Println("Call UnkoDBStmt.NumInput", "ID:", s.connId)
return -1
}
func (s *UnkoDBStmt) Exec(args []driver.Value) (driver.Result, error) {
log.Println("Call UnkoDBStmt.Exec", args, "ID:", s.connId)
return nil, fmt.Errorf("UnkoDBStmt Exec ERROR (%d)", s.connId)
}
func (s *UnkoDBStmt) Query(args []driver.Value) (driver.Rows, error) {
log.Println("Call UnkoDBStmt.Query", args, "ID:", s.connId)
return nil, fmt.Errorf("UnkoDBStmt Query ERROR (%d)", s.connId)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment