package pgxpool

import (
	
	

	
	
	
)

// Conn is an acquired *pgx.Conn from a Pool.
type Conn struct {
	res *puddle.Resource[*connResource]
	p   *Pool
}

// Release returns c to the pool it was acquired from. Once Release has been called, other methods must not be called.
// However, it is safe to call Release multiple times. Subsequent calls after the first will be ignored.
func ( *Conn) () {
	if .res == nil {
		return
	}

	 := .Conn()
	 := .res
	.res = nil

	if .p.releaseTracer != nil {
		.p.releaseTracer.TraceRelease(.p, TraceReleaseData{Conn: })
	}

	if .IsClosed() || .PgConn().IsBusy() || .PgConn().TxStatus() != 'I' {
		.Destroy()
		// Signal to the health check to run since we just destroyed a connections
		// and we might be below minConns now
		.p.triggerHealthCheck()
		return
	}

	// If the pool is consistently being used, we might never get to check the
	// lifetime of a connection since we only check idle connections in checkConnsHealth
	// so we also check the lifetime here and force a health check
	if .p.isExpired() {
		atomic.AddInt64(&.p.lifetimeDestroyCount, 1)
		.Destroy()
		// Signal to the health check to run since we just destroyed a connections
		// and we might be below minConns now
		.p.triggerHealthCheck()
		return
	}

	if .p.afterRelease == nil {
		.Release()
		return
	}

	go func() {
		if .p.afterRelease() {
			.Release()
		} else {
			.Destroy()
			// Signal to the health check to run since we just destroyed a connections
			// and we might be below minConns now
			.p.triggerHealthCheck()
		}
	}()
}

// Hijack assumes ownership of the connection from the pool. Caller is responsible for closing the connection. Hijack
// will panic if called on an already released or hijacked connection.
func ( *Conn) () *pgx.Conn {
	if .res == nil {
		panic("cannot hijack already released or hijacked connection")
	}

	 := .Conn()
	 := .res
	.res = nil

	.Hijack()

	return 
}

func ( *Conn) ( context.Context,  string,  ...any) (pgconn.CommandTag, error) {
	return .Conn().Exec(, , ...)
}

func ( *Conn) ( context.Context,  string,  ...any) (pgx.Rows, error) {
	return .Conn().Query(, , ...)
}

func ( *Conn) ( context.Context,  string,  ...any) pgx.Row {
	return .Conn().QueryRow(, , ...)
}

func ( *Conn) ( context.Context,  *pgx.Batch) pgx.BatchResults {
	return .Conn().SendBatch(, )
}

func ( *Conn) ( context.Context,  pgx.Identifier,  []string,  pgx.CopyFromSource) (int64, error) {
	return .Conn().CopyFrom(, , , )
}

// Begin starts a transaction block from the *Conn without explicitly setting a transaction mode (see BeginTx with TxOptions if transaction mode is required).
func ( *Conn) ( context.Context) (pgx.Tx, error) {
	return .Conn().Begin()
}

// BeginTx starts a transaction block from the *Conn with txOptions determining the transaction mode.
func ( *Conn) ( context.Context,  pgx.TxOptions) (pgx.Tx, error) {
	return .Conn().BeginTx(, )
}

func ( *Conn) ( context.Context) error {
	return .Conn().Ping()
}

func ( *Conn) () *pgx.Conn {
	return .connResource().conn
}

func ( *Conn) () *connResource {
	return .res.Value()
}

func ( *Conn) ( pgx.Row) *poolRow {
	return .connResource().getPoolRow(, )
}

func ( *Conn) ( pgx.Rows) *poolRows {
	return .connResource().getPoolRows(, )
}