-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmain.go
127 lines (102 loc) · 2.58 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"context"
"database/sql"
"fmt"
"log"
"time"
"github.com/prashanthpai/sqlcache"
"github.com/prashanthpai/sqlcache/cache"
"github.com/dgraph-io/ristretto"
"github.com/jackc/pgx/v4/stdlib"
// "github.com/redis/go-redis/v9"
)
const (
defaultMaxRowsToCache = 100
)
func newRistrettoCache(maxRowsToCache int64) (cache.Cacher, error) {
c, err := ristretto.NewCache(&ristretto.Config{
NumCounters: 10 * maxRowsToCache,
MaxCost: maxRowsToCache,
BufferItems: 64,
})
if err != nil {
return nil, err
}
return sqlcache.NewRistretto(c), nil
}
/*
func newRedisCache() (cache.Cacher, error) {
r := redis.NewUniversalClient(&redis.UniversalOptions{
Addrs: []string{"127.0.0.1:6379"},
})
if _, err := r.Ping(context.Background()).Result(); err != nil {
return nil, err
}
return sqlcache.NewRedis(r, "sqc:"), nil
}
*/
func main() {
cache, err := newRistrettoCache(defaultMaxRowsToCache)
if err != nil {
log.Fatalf("newRistrettoCache() failed: %v", err)
}
/*
cache, err = newRedisCache()
if err != nil {
log.Fatalf("newRedisCache() failed: %v", err)
}
*/
interceptor, err := sqlcache.NewInterceptor(&sqlcache.Config{
Cache: cache, // pick a Cacher interface implementation of your choice (redis or ristretto)
})
if err != nil {
log.Fatalf("sqlcache.NewInterceptor() failed: %v", err)
}
defer func() {
fmt.Printf("\nInterceptor metrics: %+v\n", interceptor.Stats())
}()
// install the wrapper which wraps pgx driver
sql.Register("pgx-sqlcache", interceptor.Driver(stdlib.GetDefaultDriver()))
if err := run(); err != nil {
log.Fatalf("run() failed: %v", err)
}
}
func run() error {
db, err := sql.Open("pgx-sqlcache",
"host=localhost user=postgres dbname=postgres password=postgres")
if err != nil {
return err
}
defer db.Close()
if err = db.PingContext(context.TODO()); err != nil {
return fmt.Errorf("db.PingContext() failed: %w", err)
}
for i := 0; i < 15; i++ {
start := time.Now()
if err := doQuery(db); err != nil {
return fmt.Errorf("doQuery() failed: %w", err)
}
fmt.Printf("i=%d; t=%s\n", i, time.Since(start))
time.Sleep(1 * time.Second)
}
return nil
}
func doQuery(db *sql.DB) error {
rows, err := db.QueryContext(context.TODO(), `
-- @cache-ttl 5
-- @cache-max-rows 10
SELECT name, pages FROM books WHERE pages > $1`, 10)
if err != nil {
return fmt.Errorf("db.QueryContext() failed: %w", err)
}
defer rows.Close()
for rows.Next() {
var name string
var pages int
if err := rows.Scan(&name, &pages); err != nil {
return fmt.Errorf("rows.Scan() failed: %w", err)
}
}
return rows.Err()
}