github.com/PDOK/gokoala@v0.50.6/internal/ogc/features/datasources/geopackage/stmtcache.go (about) 1 package geopackage 2 3 import ( 4 "context" 5 "log" 6 7 lru "github.com/hashicorp/golang-lru/v2" 8 "github.com/jmoiron/sqlx" 9 ) 10 11 var preparedStmtCacheSize = 25 12 13 // PreparedStatementCache is thread safe 14 type PreparedStatementCache struct { 15 cache *lru.Cache[string, *sqlx.NamedStmt] 16 } 17 18 // NewCache creates a new PreparedStatementCache that will evict least-recently used (LRU) statements. 19 func NewCache() *PreparedStatementCache { 20 cache, _ := lru.NewWithEvict[string, *sqlx.NamedStmt](preparedStmtCacheSize, 21 func(_ string, stmt *sqlx.NamedStmt) { 22 if stmt != nil { 23 _ = stmt.Close() 24 } 25 }) 26 27 return &PreparedStatementCache{cache: cache} 28 } 29 30 // Lookup gets a prepared statement from the cache for the given query, or creates a new one and adds it to the cache 31 func (c *PreparedStatementCache) Lookup(ctx context.Context, db *sqlx.DB, query string) (*sqlx.NamedStmt, error) { 32 cachedStmt, ok := c.cache.Get(query) 33 if !ok { 34 stmt, err := db.PrepareNamedContext(ctx, query) 35 if err != nil { 36 return nil, err 37 } 38 c.cache.Add(query, stmt) 39 return stmt, nil 40 } 41 return cachedStmt, nil 42 } 43 44 // Close purges the cache, and closes remaining prepared statements 45 func (c *PreparedStatementCache) Close() { 46 log.Printf("closing %d prepared statements", c.cache.Len()) 47 c.cache.Purge() 48 }