summaryrefslogtreecommitdiff
path: root/vendor/github.com/jackc/pgconn/stmtcache
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jackc/pgconn/stmtcache')
-rw-r--r--vendor/github.com/jackc/pgconn/stmtcache/lru.go165
-rw-r--r--vendor/github.com/jackc/pgconn/stmtcache/stmtcache.go58
2 files changed, 0 insertions, 223 deletions
diff --git a/vendor/github.com/jackc/pgconn/stmtcache/lru.go b/vendor/github.com/jackc/pgconn/stmtcache/lru.go
deleted file mode 100644
index 90fb76c2f..000000000
--- a/vendor/github.com/jackc/pgconn/stmtcache/lru.go
+++ /dev/null
@@ -1,165 +0,0 @@
-package stmtcache
-
-import (
- "container/list"
- "context"
- "fmt"
- "sync/atomic"
-
- "github.com/jackc/pgconn"
-)
-
-var lruCount uint64
-
-// LRU implements Cache with a Least Recently Used (LRU) cache.
-type LRU struct {
- conn *pgconn.PgConn
- mode int
- cap int
- prepareCount int
- m map[string]*list.Element
- l *list.List
- psNamePrefix string
- stmtsToClear []string
-}
-
-// NewLRU creates a new LRU. mode is either ModePrepare or ModeDescribe. cap is the maximum size of the cache.
-func NewLRU(conn *pgconn.PgConn, mode int, cap int) *LRU {
- mustBeValidMode(mode)
- mustBeValidCap(cap)
-
- n := atomic.AddUint64(&lruCount, 1)
-
- return &LRU{
- conn: conn,
- mode: mode,
- cap: cap,
- m: make(map[string]*list.Element),
- l: list.New(),
- psNamePrefix: fmt.Sprintf("lrupsc_%d", n),
- }
-}
-
-// Get returns the prepared statement description for sql preparing or describing the sql on the server as needed.
-func (c *LRU) Get(ctx context.Context, sql string) (*pgconn.StatementDescription, error) {
- if ctx != context.Background() {
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- default:
- }
- }
-
- // flush an outstanding bad statements
- txStatus := c.conn.TxStatus()
- if (txStatus == 'I' || txStatus == 'T') && len(c.stmtsToClear) > 0 {
- for _, stmt := range c.stmtsToClear {
- err := c.clearStmt(ctx, stmt)
- if err != nil {
- return nil, err
- }
- }
- }
-
- if el, ok := c.m[sql]; ok {
- c.l.MoveToFront(el)
- return el.Value.(*pgconn.StatementDescription), nil
- }
-
- if c.l.Len() == c.cap {
- err := c.removeOldest(ctx)
- if err != nil {
- return nil, err
- }
- }
-
- psd, err := c.prepare(ctx, sql)
- if err != nil {
- return nil, err
- }
-
- el := c.l.PushFront(psd)
- c.m[sql] = el
-
- return psd, nil
-}
-
-// Clear removes all entries in the cache. Any prepared statements will be deallocated from the PostgreSQL session.
-func (c *LRU) Clear(ctx context.Context) error {
- for c.l.Len() > 0 {
- err := c.removeOldest(ctx)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *LRU) StatementErrored(sql string, err error) {
- pgErr, ok := err.(*pgconn.PgError)
- if !ok {
- return
- }
-
- isInvalidCachedPlanError := pgErr.Severity == "ERROR" &&
- pgErr.Code == "0A000" &&
- pgErr.Message == "cached plan must not change result type"
- if isInvalidCachedPlanError {
- c.stmtsToClear = append(c.stmtsToClear, sql)
- }
-}
-
-func (c *LRU) clearStmt(ctx context.Context, sql string) error {
- elem, inMap := c.m[sql]
- if !inMap {
- // The statement probably fell off the back of the list. In that case, we've
- // ensured that it isn't in the cache, so we can declare victory.
- return nil
- }
-
- c.l.Remove(elem)
-
- psd := elem.Value.(*pgconn.StatementDescription)
- delete(c.m, psd.SQL)
- if c.mode == ModePrepare {
- return c.conn.Exec(ctx, fmt.Sprintf("deallocate %s", psd.Name)).Close()
- }
- return nil
-}
-
-// Len returns the number of cached prepared statement descriptions.
-func (c *LRU) Len() int {
- return c.l.Len()
-}
-
-// Cap returns the maximum number of cached prepared statement descriptions.
-func (c *LRU) Cap() int {
- return c.cap
-}
-
-// Mode returns the mode of the cache (ModePrepare or ModeDescribe)
-func (c *LRU) Mode() int {
- return c.mode
-}
-
-func (c *LRU) prepare(ctx context.Context, sql string) (*pgconn.StatementDescription, error) {
- var name string
- if c.mode == ModePrepare {
- name = fmt.Sprintf("%s_%d", c.psNamePrefix, c.prepareCount)
- c.prepareCount += 1
- }
-
- return c.conn.Prepare(ctx, name, sql, nil)
-}
-
-func (c *LRU) removeOldest(ctx context.Context) error {
- oldest := c.l.Back()
- c.l.Remove(oldest)
- psd := oldest.Value.(*pgconn.StatementDescription)
- delete(c.m, psd.SQL)
- if c.mode == ModePrepare {
- return c.conn.Exec(ctx, fmt.Sprintf("deallocate %s", psd.Name)).Close()
- }
- return nil
-}
diff --git a/vendor/github.com/jackc/pgconn/stmtcache/stmtcache.go b/vendor/github.com/jackc/pgconn/stmtcache/stmtcache.go
deleted file mode 100644
index d083e1b4f..000000000
--- a/vendor/github.com/jackc/pgconn/stmtcache/stmtcache.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Package stmtcache is a cache that can be used to implement lazy prepared statements.
-package stmtcache
-
-import (
- "context"
-
- "github.com/jackc/pgconn"
-)
-
-const (
- ModePrepare = iota // Cache should prepare named statements.
- ModeDescribe // Cache should prepare the anonymous prepared statement to only fetch the description of the statement.
-)
-
-// Cache prepares and caches prepared statement descriptions.
-type Cache interface {
- // Get returns the prepared statement description for sql preparing or describing the sql on the server as needed.
- Get(ctx context.Context, sql string) (*pgconn.StatementDescription, error)
-
- // Clear removes all entries in the cache. Any prepared statements will be deallocated from the PostgreSQL session.
- Clear(ctx context.Context) error
-
- // StatementErrored informs the cache that the given statement resulted in an error when it
- // was last used against the database. In some cases, this will cause the cache to maer that
- // statement as bad. The bad statement will instead be flushed during the next call to Get
- // that occurs outside of a failed transaction.
- StatementErrored(sql string, err error)
-
- // Len returns the number of cached prepared statement descriptions.
- Len() int
-
- // Cap returns the maximum number of cached prepared statement descriptions.
- Cap() int
-
- // Mode returns the mode of the cache (ModePrepare or ModeDescribe)
- Mode() int
-}
-
-// New returns the preferred cache implementation for mode and cap. mode is either ModePrepare or ModeDescribe. cap is
-// the maximum size of the cache.
-func New(conn *pgconn.PgConn, mode int, cap int) Cache {
- mustBeValidMode(mode)
- mustBeValidCap(cap)
-
- return NewLRU(conn, mode, cap)
-}
-
-func mustBeValidMode(mode int) {
- if mode != ModePrepare && mode != ModeDescribe {
- panic("mode must be ModePrepare or ModeDescribe")
- }
-}
-
-func mustBeValidCap(cap int) {
- if cap < 1 {
- panic("cache must have cap of >= 1")
- }
-}