Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,44 @@ See [godoc examples](https://pkg.go.dev/github.com/akm/sql-slog#example-Open) fo

## EXAMPLES

### [examples/with-sqlc](./examples/with-sqlc/)

An example showing how sql-slog works with [sqlc](https://sqlc.dev/).
This example is almost same as [Getting started with SQLite](https://docs.sqlc.dev/en/latest/tutorials/getting-started-sqlite.html) but uses [sqlslog.Open](https://pkg.go.dev/github.com/akm/sql-slog#Open) instead of [sql.Open](https://pkg.go.dev/database/sql#Open).

<details><summary> Stdout with sqlslog package </summary>

```
$ make -C examples/with-sqlc run
go build ./...
go run .
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Open driver=sqlite dsn=:memory: duration=22083
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Driver.Open dsn=:memory: duration=274042 conn_id=_hMZDi7TQfEgBKN_
time=2025-03-19T21:23:36.992+09:00 level=INFO msg=Connector.Connect duration=294292
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.ExecContext conn_id=_hMZDi7TQfEgBKN_ query="CREATE TABLE authors (\n id INTEGER PRIMARY KEY,\n name text NOT NULL,\n bio text\n);\n" args=[] duration=537125
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: ListAuthors :many\nSELECT id, name, bio FROM authors\nORDER BY name\n" args=[] duration=23250
2025/03/19 21:23:36 []
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: CreateAuthor :one\nINSERT INTO authors (\n name, bio\n) VALUES (\n ?, ?\n)\nRETURNING id, name, bio\n" args="[{Name: Ordinal:1 Value:Brian Kernighan} {Name: Ordinal:2 Value:Co-author of The C Programming Language and The Go Programming Language}]" duration=20375
2025/03/19 21:23:36 {1 Brian Kernighan {Co-author of The C Programming Language and The Go Programming Language true}}
time=2025-03-19T21:23:36.993+09:00 level=INFO msg=Conn.QueryContext conn_id=_hMZDi7TQfEgBKN_ query="-- name: GetAuthor :one\nSELECT id, name, bio FROM authors\nWHERE id = ? LIMIT 1\n" args="[{Name: Ordinal:1 Value:1}]" duration=8083
2025/03/19 21:23:36 true
```

</details>

<details><summary> Stdout without sqlslog package </summary>

```
$ SKIP_SQLSLOG=1 make -C examples/with-sqlc run
go build ./...
go run .
2025/03/19 21:23:19 []
2025/03/19 21:23:19 {1 Brian Kernighan {Co-author of The C Programming Language and The Go Programming Language true}}
2025/03/19 21:23:19 true
```

</details>

### [examples/with-go-requestid](./examples/with-go-requestid/)

An example showing how sql-slog works with [go-requestid](https://github.com/akm/go-requestid).
Expand Down
48 changes: 33 additions & 15 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,24 @@ func wrapConn(original driver.Conn, logger *stepLogger, options *connOptions) dr
if original == nil {
return nil
}
if _, ok := original.(*connWithContextWrapper); ok {
switch original.(type) {
case *connWrapper:
return original
// case *connNvcWrapper:
// return original
case *connWithContextWrapper:
return original
case *connNvcWithContextWrapper:
return original
}

connWrapper := connWrapper{original: original, logger: logger, options: options}
if cwc, ok := original.(connWithContext); ok {
return &connWithContextWrapper{connWrapper, cwc}
connWrapper2 := connWithContextWrapper{connWrapper, cwc}
if nvc, ok := original.(driver.NamedValueChecker); ok {
return &connNvcWithContextWrapper{connWrapper2, nvc}
}
return &connWrapper2
}

// Commented out because it's not used.
Expand Down Expand Up @@ -109,11 +120,6 @@ var (
_ driver.Validator = (*connWrapper)(nil)
)

// To support custom data types, implement NamedValueChecker.
// NamedValueChecker also allows queries to accept per-query
// options as a parameter by returning ErrRemoveArgument from CheckNamedValue.
var _ driver.NamedValueChecker = (*connWrapper)(nil)

// Begin implements driver.Conn.
func (c *connWrapper) Begin() (driver.Tx, error) {
var origTx driver.Tx
Expand Down Expand Up @@ -172,14 +178,6 @@ func (c *connWrapper) IsValid() bool {
return true
}

// CheckNamedValue implements driver.NamedValueChecker.
func (c *connWrapper) CheckNamedValue(namedValue *driver.NamedValue) error {
if v, ok := c.original.(driver.NamedValueChecker); ok {
return v.CheckNamedValue(namedValue)
}
return nil
}

type connWithContext interface {
driver.Conn
driver.ExecerContext
Expand Down Expand Up @@ -349,3 +347,23 @@ func ConnQueryContextErrorHandler(driverName string) func(err error) (bool, []sl
return nil
}
}

type connNvcWrapper struct {
connWrapper
driver.NamedValueChecker
}

var (
_ driver.Conn = (*connNvcWrapper)(nil)
_ driver.NamedValueChecker = (*connNvcWrapper)(nil)
)

type connNvcWithContextWrapper struct {
connWithContextWrapper
driver.NamedValueChecker
}

var (
_ driver.Conn = (*connNvcWithContextWrapper)(nil)
_ driver.NamedValueChecker = (*connNvcWithContextWrapper)(nil)
)
7 changes: 7 additions & 0 deletions conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ func TestWrapConn(t *testing.T) {
if conn == nil {
t.Fatal("Expected non-nil")
}

t.Run("skip wrapped driver.Conn object", func(t *testing.T) {
res := wrapConn(conn, logger, connOptions)
if res != conn {
t.Fatal("Expected same object")
}
})
})
}

Expand Down
10 changes: 10 additions & 0 deletions examples/with-sqlc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: default
default: run

.PHONY: build
build:
go build ./...

.PHONY: run
run: build
go run .
20 changes: 20 additions & 0 deletions examples/with-sqlc/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module tutorial.sqlc.dev/app

go 1.23.2

require (
github.com/akm/sql-slog v0.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 // indirect
golang.org/x/sys v0.30.0 // indirect
modernc.org/libc v1.61.13 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.8.2 // indirect
modernc.org/sqlite v1.36.1 // indirect
)

replace github.com/akm/sql-slog => ../..
23 changes: 23 additions & 0 deletions examples/with-sqlc/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI=
modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU=
modernc.org/sqlite v1.36.1 h1:bDa8BJUH4lg6EGkLbahKe/8QqoF8p9gArSc6fTqYhyQ=
modernc.org/sqlite v1.36.1/go.mod h1:7MPwH7Z6bREicF9ZVUR78P1IKuxfZ8mRIDHD0iD+8TU=
25 changes: 25 additions & 0 deletions examples/with-sqlc/query.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = ? LIMIT 1;

-- name: ListAuthors :many
SELECT * FROM authors
ORDER BY name;

-- name: CreateAuthor :one
INSERT INTO authors (
name, bio
) VALUES (
?, ?
)
RETURNING *;

-- name: UpdateAuthor :exec
UPDATE authors
set name = ?,
bio = ?
WHERE id = ?;

-- name: DeleteAuthor :exec
DELETE FROM authors
WHERE id = ?;
5 changes: 5 additions & 0 deletions examples/with-sqlc/schema.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE authors (
id INTEGER PRIMARY KEY,
name text NOT NULL,
bio text
);
9 changes: 9 additions & 0 deletions examples/with-sqlc/sqlc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: "2"
sql:
- engine: "sqlite"
queries: "query.sql"
schema: "schema.sql"
gen:
go:
package: "tutorial"
out: "tutorial"
73 changes: 73 additions & 0 deletions examples/with-sqlc/tutorial.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"context"
"database/sql"
_ "embed"
"log"
"os"
"reflect"

sqlslog "github.com/akm/sql-slog"
_ "modernc.org/sqlite"

"tutorial.sqlc.dev/app/tutorial"
)

//go:embed schema.sql
var ddl string

func run() error {
ctx := context.Background()

var db *sql.DB
var err error
if os.Getenv("SKIP_SQLSLOG") != "" {
db, err = sql.Open("sqlite", ":memory:")
} else {
db, _, err = sqlslog.Open(ctx, "sqlite", ":memory:")
}
if err != nil {
return err
}

// create tables
if _, err := db.ExecContext(ctx, ddl); err != nil {
return err
}

queries := tutorial.New(db)

// list all authors
authors, err := queries.ListAuthors(ctx)
if err != nil {
return err
}
log.Println(authors)

// create an author
insertedAuthor, err := queries.CreateAuthor(ctx, tutorial.CreateAuthorParams{
Name: "Brian Kernighan",
Bio: sql.NullString{String: "Co-author of The C Programming Language and The Go Programming Language", Valid: true},
})
if err != nil {
return err
}
log.Println(insertedAuthor)

// get the author we just inserted
fetchedAuthor, err := queries.GetAuthor(ctx, insertedAuthor.ID)
if err != nil {
return err
}

// prints true
log.Println(reflect.DeepEqual(insertedAuthor, fetchedAuthor))
return nil
}

func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
31 changes: 31 additions & 0 deletions examples/with-sqlc/tutorial/db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions examples/with-sqlc/tutorial/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading