func (db *PostgresDB) Backup(fileName string) error {
	return errs.DBError(errs.Unsupported, "backup is not supported "+
		"for postgres database")
}
Backup is not implemented for postgres database.
package pool
import (
	"database/sql"
	"encoding/hex"
	"errors"
	"fmt"
	"math/big"
	"net/http"
	"time"
	"github.com/decred/dcrd/dcrutil/v3"
	"github.com/lib/pq"
	errs "github.com/decred/dcrpool/errors"
)
func InitPostgresDB(host string, port uint32, user, pass, dbName string, purgeDB bool) (*PostgresDB, error) {
	const funcName = "InitPostgresDB"
	psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
		"password=%s dbname=%s sslmode=disable",
		host, port, user, pass, dbName)
	db, err := sql.Open("postgres", psqlInfo)
	if err != nil {
		desc := fmt.Sprintf("%s: unable to open postgres: %v", funcName, err)
		return nil, errs.DBError(errs.DBOpen, desc)
	}
	pdb := &PostgresDB{db}
	if purgeDB {
		err := pdb.purge()
		if err != nil {
			return nil, err
		}
	}
	err = db.Ping()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to connect to postgres: %v", funcName, err)
		return nil, errs.DBError(errs.DBOpen, desc)
	}
	makeErr := func(table string, err error) error {
		desc := fmt.Sprintf("%s: unable to create %s table: %v",
			funcName, table, err)
		return errs.DBError(errs.CreateStorage, desc)
	}
	_, err = db.Exec(createTableMetadata)
	if err != nil {
		return nil, makeErr("metadata", err)
	}
	_, err = db.Exec(createTableAccounts)
	if err != nil {
		return nil, makeErr("accounts", err)
	}
	_, err = db.Exec(createTablePayments)
	if err != nil {
		return nil, makeErr("payments", err)
	}
	_, err = db.Exec(createTableArchivedPayments)
	if err != nil {
		return nil, makeErr("archived payments", err)
	}
	_, err = db.Exec(createTableJobs)
	if err != nil {
		return nil, makeErr("jobs", err)
	}
	_, err = db.Exec(createTableShares)
	if err != nil {
		return nil, makeErr("shares", err)
	}
	_, err = db.Exec(createTableAcceptedWork)
	if err != nil {
		return nil, makeErr("accepted work", err)
	}
	_, err = db.Exec(createTableHashData)
	if err != nil {
		return nil, makeErr("hashrate", err)
	}
	return &PostgresDB{db}, nil
}
func (db *PostgresDB) Close() error {
	funcName := "Close"
	err := db.DB.Close()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to close db: %v", funcName, err)
		return errs.DBError(errs.DBClose, desc)
	}
	return nil
}
func (db *PostgresDB) purge() error {
	funcName := "purge"
	_, err := db.DB.Exec(purgeDB)
	if err != nil {
		desc := fmt.Sprintf("%s: unable to purge db: %v", funcName, err)
		return errs.DBError(errs.DeleteEntry, desc)
	}
	return nil
}
func decodePaymentRows(rows *sql.Rows) ([]*Payment, error) {
	const funcName = "decodePaymentRows"
	var toReturn []*Payment
	for rows.Next() {
		var uuid, account, transactionID, sourceBlockHash, sourceCoinbase string
		var estimatedMaturity, height, paidOnHeight uint32
		var amount, createdon int64
		err := rows.Scan(&uuid, &account, &estimatedMaturity,
			&height, &amount, &createdon, &paidOnHeight, &transactionID,
			&sourceBlockHash, &sourceCoinbase)
		if err != nil {
			desc := fmt.Sprintf("%s: unable to scan payment entry: %v",
				funcName, err)
			return nil, errs.DBError(errs.Decode, desc)
		}
		payment := &Payment{uuid, account, estimatedMaturity,
			height, dcrutil.Amount(amount), createdon, paidOnHeight, transactionID,
			&PaymentSource{sourceBlockHash, sourceCoinbase}}
		toReturn = append(toReturn, payment)
	}
	err := rows.Err()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to decode payments: %v",
			funcName, err)
		return nil, errs.DBError(errs.Decode, desc)
	}
	return toReturn, nil
}
func decodeWorkRows(rows *sql.Rows) ([]*AcceptedWork, error) {
	const funcName = "decodeWorkRows"
	var toReturn []*AcceptedWork
	for rows.Next() {
		var uuid, blockhash, prevhash, minedby, miner string
		var confirmed bool
		var height uint32
		var createdOn int64
		err := rows.Scan(&uuid, &blockhash, &prevhash, &height,
			&minedby, &miner, &createdOn, &confirmed)
		if err != nil {
			desc := fmt.Sprintf("%s: unable to scan work entry: %v",
				funcName, err)
			return nil, errs.DBError(errs.Decode, desc)
		}
		work := &AcceptedWork{uuid, blockhash, prevhash, height,
			minedby, miner, createdOn, confirmed}
		toReturn = append(toReturn, work)
	}
	err := rows.Err()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to decode work: %v",
			funcName, err)
		return nil, errs.DBError(errs.Decode, desc)
	}
	return toReturn, nil
}
func decodeShareRows(rows *sql.Rows) ([]*Share, error) {
	const funcName = "decodeShareRows"
	var toReturn []*Share
	for rows.Next() {
		var uuid, account, weight string
		var createdon int64
		err := rows.Scan(&uuid, &account, &weight, &createdon)
		if err != nil {
			desc := fmt.Sprintf("%s: unable to scan share entry: %v",
				funcName, err)
			return nil, errs.DBError(errs.Decode, desc)
		}
		weightRat, ok := new(big.Rat).SetString(weight)
		if !ok {
			desc := fmt.Sprintf("unable to decode big.Rat string: %v", err)
			return nil, errs.DBError(errs.Parse, desc)
		}
		share := &Share{uuid, account, weightRat, createdon}
		toReturn = append(toReturn, share)
	}
	err := rows.Err()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to decode shares: %v",
			funcName, err)
		return nil, errs.DBError(errs.Decode, desc)
	}
	return toReturn, nil
}
func decodeHashDataRows(rows *sql.Rows) (map[string]*HashData, error) {
	const funcName = "decodeHashDataRows"
	toReturn := make(map[string]*HashData)
	for rows.Next() {
		var uuid, accountID, miner, ip, hashRate string
		var updatedOn int64
		err := rows.Scan(&uuid, &accountID, &miner, &ip,
			&hashRate, &updatedOn)
		if err != nil {
			desc := fmt.Sprintf("%s: unable to scan hash data entry: %v",
				funcName, err)
			return nil, errs.DBError(errs.Decode, desc)
		}
		hashRat, ok := new(big.Rat).SetString(hashRate)
		if !ok {
			desc := fmt.Sprintf("%s: unable to decode big.Rat string: %v",
				funcName, err)
			return nil, errs.DBError(errs.Parse, desc)
		}
		hashData := &HashData{uuid, accountID, miner, ip, hashRat, updatedOn}
		toReturn[hashData.UUID] = hashData
	}
	err := rows.Err()
	if err != nil {
		desc := fmt.Sprintf("%s: unable to decode hash data: %v",
			funcName, err)
		return nil, errs.DBError(errs.Decode, desc)
	}
	return toReturn, nil
}
func (db *PostgresDB) httpBackup(w http.ResponseWriter) error {
	return errs.DBError(errs.Unsupported, "httpBackup is not supported "+
		"for postgres database")
}