package stmtcache

import (
	
	
	
	

	
)

var lruCount uint64
LRU implements Cache with a Least Recently Used (LRU) cache.
NewLRU creates a new LRU. mode is either ModePrepare or ModeDescribe. cap is the maximum size of the cache.
func ( *pgconn.PgConn,  int,  int) *LRU {
	mustBeValidMode()
	mustBeValidCap()

	 := atomic.AddUint64(&lruCount, 1)

	return &LRU{
		conn:         ,
		mode:         ,
		cap:          ,
		m:            make(map[string]*list.Element),
		l:            list.New(),
		psNamePrefix: fmt.Sprintf("lrupsc_%d", ),
	}
}
Get returns the prepared statement description for sql preparing or describing the sql on the server as needed.
flush an outstanding bad statements
	 := .conn.TxStatus()
	if ( == 'I' ||  == 'T') && len(.stmtsToClear) > 0 {
		for ,  := range .stmtsToClear {
			 := .clearStmt(, )
			if  != nil {
				return nil, 
			}
		}
	}

	if ,  := .m[];  {
		.l.MoveToFront()
		return .Value.(*pgconn.StatementDescription), nil
	}

	if .l.Len() == .cap {
		 := .removeOldest()
		if  != nil {
			return nil, 
		}
	}

	,  := .prepare(, )
	if  != nil {
		return nil, 
	}

	 := .l.PushFront()
	.m[] = 

	return , nil
}
Clear removes all entries in the cache. Any prepared statements will be deallocated from the PostgreSQL session.
func ( *LRU) ( context.Context) error {
	for .l.Len() > 0 {
		 := .removeOldest()
		if  != nil {
			return 
		}
	}

	return nil
}

func ( *LRU) ( string,  error) {
	,  := .(*pgconn.PgError)
	if ! {
		return
	}

	 := .Severity == "ERROR" &&
		.Code == "0A000" &&
		.Message == "cached plan must not change result type"
	if  {
		.stmtsToClear = append(.stmtsToClear, )
	}
}

func ( *LRU) ( context.Context,  string) error {
	,  := .m[]
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
	}

	.l.Remove()

	 := .Value.(*pgconn.StatementDescription)
	delete(.m, .SQL)
	if .mode == ModePrepare {
		return .conn.Exec(, fmt.Sprintf("deallocate %s", .Name)).Close()
	}
	return nil
}
Len returns the number of cached prepared statement descriptions.
func ( *LRU) () int {
	return .l.Len()
}
Cap returns the maximum number of cached prepared statement descriptions.
func ( *LRU) () int {
	return .cap
}
Mode returns the mode of the cache (ModePrepare or ModeDescribe)
func ( *LRU) () int {
	return .mode
}

func ( *LRU) ( context.Context,  string) (*pgconn.StatementDescription, error) {
	var  string
	if .mode == ModePrepare {
		 = fmt.Sprintf("%s_%d", .psNamePrefix, .prepareCount)
		.prepareCount += 1
	}

	return .conn.Prepare(, , , nil)
}

func ( *LRU) ( context.Context) error {
	 := .l.Back()
	.l.Remove()
	 := .Value.(*pgconn.StatementDescription)
	delete(.m, .SQL)
	if .mode == ModePrepare {
		return .conn.Exec(, fmt.Sprintf("deallocate %s", .Name)).Close()
	}
	return nil