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  }