package pgdriver

import (
	
	
	
)

// Error represents an error returned by PostgreSQL server
// using PostgreSQL ErrorResponse protocol.
//
// https://www.postgresql.org/docs/current/static/protocol-message-formats.html
type Error struct {
	m map[byte]string
}

// Field returns a string value associated with an error field.
//
// https://www.postgresql.org/docs/current/static/protocol-error-fields.html
func ( Error) ( byte) string {
	return .m[]
}

// IntegrityViolation reports whether an error is a part of
// Integrity Constraint Violation class of errors.
//
// https://www.postgresql.org/docs/current/static/errcodes-appendix.html
func ( Error) () bool {
	switch .Field('C') {
	case "23000", "23001", "23502", "23503", "23505", "23514", "23P01":
		return true
	default:
		return false
	}
}

func ( Error) () string {
	return fmt.Sprintf("%s #%s %s",
		.Field('S'), .Field('C'), .Field('M'))
}

func ( error,  bool) bool {
	switch  {
	case nil:
		return false
	case driver.ErrBadConn:
		return true
	}

	if ,  := .(Error);  {
		switch .Field('V') {
		case "FATAL", "PANIC":
			return true
		}
		switch .Field('C') {
		case "25P02", // current transaction is aborted
			"57014": // canceling statement due to user request
			return true
		}
		return false
	}

	if  {
		if ,  := .(net.Error);  && .Timeout() {
			return !.Temporary()
		}
	}

	return true
}