# Maintainer: Jakub Jirutka <jakub@jirutka.cz>
# Contributor: G.J.R. Timmer <gjr.timmer@gmail.com>
# Contributor: Jakub Jirutka <jakub@jirutka.cz>
_pkgname=postgresql
pkgver=15.13
pkgrel=0
_majorver=${pkgver%%[_.]*}
# Should this aport provide libpq* and libecpg*? true/false
# Exactly one postgresql aport must be the default one!
_default_ver=false
pkgname=$_pkgname$_majorver
pkgdesc="A sophisticated object-relational DBMS, version $_majorver"
url="https://www.postgresql.org/"
arch="all !riscv64 !loongarch64"
license="PostgreSQL"
_llvmver=16
depends="$pkgname-client postgresql-common tzdata"
depends_dev="
	libpq-dev
	libecpg-dev
	clang$_llvmver
	icu-dev
	llvm$_llvmver
	lz4-dev
	openssl-dev
	zstd-dev
	"
checkdepends="
	diffutils
	icu-data-full
	perl-ipc-run
	"
makedepends="$depends_dev
	bison
	docbook-xsl-nons
	flex
	libxml2-dev
	linux-headers
	llvm$_llvmver-dev
	openldap-dev
	perl-dev
	python3-dev
	readline-dev
	tcl-dev
	util-linux-dev
	zlib-dev
	"
pkgusers="postgres"
pkggroups="postgres"
install="$pkgname.post-install $pkgname.pre-deinstall"
provider_priority=$_majorver
provides="postgresql"
replaces="postgresql"  # for backward compatibility
$_default_ver && subpackages="
	libpq
	libpq-dev:libpq_dev
	libecpg
	libecpg-dev:libecpg_dev
	"
subpackages="
	$subpackages
	$pkgname-client
	$pkgname-jit
	$pkgname-contrib
	$pkgname-plperl
	$pkgname-plperl-contrib:plperl_contrib
	$pkgname-plpython3
	$pkgname-plpython3-contrib:plpython3_contrib
	$pkgname-pltcl
	$pkgname-contrib-jit:contrib_jit
	$pkgname-dev
	$pkgname-doc
	$pkgname-openrc
	"
source="https://ftp.postgresql.org/pub/source/v$pkgver/postgresql-$pkgver.tar.bz2
	initdb.patch
	perl-rpath.patch
	per-version-dirs.patch
	unix_socket_directories.patch
	disable-html-docs.patch
	remove-libecpg_compat.patch
	czech-snowball-stemmer.patch
	make-split-headers.patch
	jit-datalayout-mismatch-on-s390x-and-x86.patch
	pg_config-add-major-version.patch
	dont-use-locale-a-on-musl.patch
	icu-collations-hack.patch
	fix-test-check_guc.patch
	fix-test-postgres_fdw.patch
	libpgport-pkglibdir.patch.txt
	external-libpq.patch.txt

	pltcl_create_tables.sql
	"
builddir="$srcdir/$_pkgname-$pkgver"
options="net"

# secfixes:
#   15.13-r0:
#     - CVE-2025-4207
#   15.11-r0:
#     - CVE-2025-1094
#   15.9-r0:
#     - CVE-2024-10976
#     - CVE-2024-10977
#     - CVE-2024-10978
#     - CVE-2024-10979
#   15.8-r0:
#     - CVE-2024-7348
#   15.6-r0:
#     - CVE-2024-0985
#   15.5-r0:
#     - CVE-2023-5868
#     - CVE-2023-5869
#     - CVE-2023-5870
#   15.4-r0:
#     - CVE-2023-39418
#     - CVE-2023-39417
#   15.3-r0:
#     - CVE-2023-2454
#     - CVE-2023-2455
#   15.2-r0:
#     - CVE-2022-41862

_bindir=usr/libexec/$pkgname
_datadir=usr/share/$pkgname
_docdir=usr/share/doc/$pkgname
_mandir=$_datadir/man
_includedir=usr/include/postgresql
# Directory for server-related libraries. This is hard-coded in
# per-version-dirs.patch.
_srvlibdir=usr/lib/$pkgname

# Programs to be included in the -client subpackage.
# TODO: This was probably originally copied from Debian and I have no idea
#   why these are considered as front-end (client) programs and the rest of
#   the programs are not. So it should be reviewed.
_client_cmds="
	clusterdb
	createdb
	createuser
	dropdb
	dropuser
	pg_amcheck
	pg_basebackup
	pg_dump
	pg_dumpall
	pg_isready
	pg_receivewal
	pg_recvlogical
	pg_restore
	pg_verifybackup
	pgbench
	psql
	reindexdb
	vacuumdb
	"

prepare() {
	default_prepare

	# FIXME: This test is broken, skip it for now.
	sed -i '/test_pg_dump/d' src/test/modules/Makefile

	if $_default_ver; then
		cp -rl "$builddir" "$builddir-ifaces"
	else
		msg 'external-libpq.patch'
		patch -p1 < "$srcdir"/external-libpq.patch.txt
	fi
	# Note: This must be applied after clonning $builddir-ifaces.
	patch -p1 < "$srcdir"/libpgport-pkglibdir.patch.txt
}

build() {
	export LLVM_CONFIG="/usr/lib/llvm$_llvmver/bin/llvm-config"
	export PYTHON=/usr/bin/python3
	export CFLAGS="${CFLAGS/-Os/-O2}"
	export CPPFLAGS="${CPPFLAGS/-Os/-O2}"
	# older clang versions don't have a 'clang' exe anymore.
	export CLANG=clang-$_llvmver

	_configure --with-ldap
	make world

	if $_default_ver; then
		cd "$builddir-ifaces"

		_configure --without-ldap
		local dir; for dir in include common port interfaces bin/pg_config; do
			make -C src/$dir
		done
	fi
}

_configure() {
	local _extra_opts
	# When disable-spinlocks is no longer required - check postgresql-bdr package.
	case "$CARCH" in
		riscv64) _extra_opts='--disable-spinlocks';;
	esac
	want_check && _extra_opts="$_extra_opts --enable-tap-tests"

	./configure \
		--build=$CBUILD \
		--host=$CHOST \
		--prefix=/usr \
		--bindir=/$_bindir \
		--datarootdir=/usr/share \
		--datadir=/$_datadir \
		--docdir=/$_docdir \
		--includedir=/$_includedir \
		--libdir=/usr/lib \
		--mandir=/$_mandir \
		--sysconfdir=/etc/postgresql \
		--disable-rpath \
		--with-system-tzdata=/usr/share/zoneinfo \
		--with-libxml \
		--with-openssl \
		--with-uuid=e2fs \
		--with-llvm \
		--with-icu \
		--with-perl \
		--with-python \
		--with-tcl \
		--with-lz4 \
		--with-zstd \
		$_extra_opts \
		"$@"
}

check() {
	_run_tests src/test
	_run_tests src/pl
	_run_tests contrib

	if $_default_ver; then
		_run_tests src/interfaces/libpq
	fi
}

package() {
	make DESTDIR="$pkgdir" install install-docs

	if $_default_ver; then
		cd "$builddir-ifaces"

		# Override libpq and libecpg files with the build without LDAP support.
		local dir; for dir in common port interfaces bin/pg_config; do
			make -C src/$dir DESTDIR="$pkgdir" bindir=/usr/bin install
		done
		make -C src/include DESTDIR="$pkgdir" install-interfaces
	fi

	cd "$pkgdir"

	# Duplicate of usr/bin/ecpg.
	rm -f ./$_bindir/ecpg

	mkdir -p ./usr/bin
	ln -s /$_bindir/postgres ./usr/bin/postgres$_majorver

	# This file is used by pg_versions and init script.
	echo "$_majorver" > ./$_bindir/PG_VERSION

	install -d -m750 -o postgres -g postgres \
		./etc/postgresql$_majorver \
		./var/lib/postgresql \
		./var/log/postgresql

	local server_cmds=$(_setdiff "$(ls -1 $_bindir)" "$_client_cmds pg_config ecpg PG_VERSION")
	[ "$server_cmds" ] || die 'package: variable server_cmds is empty'

	# These commands are symlinked to /usr/bin by pg_versions script after
	# installation.
	provides="$provides $(echo "$server_cmds" | sed 's/^/cmd:&/')"
}

libpq() {
	pkgdesc="PostgreSQL client library"
	depends=""
	replaces=""

	amove usr/lib/libpq.so.*
}

libpq_dev() {
	pkgdesc="PostgreSQL client library (development files)"
	depends=""
	replaces=""

	amove usr/bin/pg_config

	amove $_includedir/internal/*
	amove $_includedir/libpq-*.h
	amove $_includedir/libpq/*
	amove $_includedir/pg_config*.h
	amove $_includedir/postgres_ext.h

	amove usr/lib/libpq.*
	amove usr/lib/libpgcommon*.a
	amove usr/lib/libpgport*.a
	amove usr/lib/pkgconfig/libpq.pc
}

libecpg() {
	pkgdesc="ECPG - Embedded SQL in C"
	depends=""
	provides="postgresql-libs"  # for backward compatibility (Alpine <3.15)
	replaces="$provides"  # for backward compatibility (Alpine <3.15)

	amove usr/lib/libecpg.so.*
	amove usr/lib/libpgtypes.so.*
}

libecpg_dev() {
	pkgdesc="ECPG - Embedded SQL in C (development files)"
	depends="libpq-dev=$pkgver-r$pkgrel"
	replaces=""

	amove usr/bin/ecpg

	amove $_includedir/ecpg*.h
	amove $_includedir/informix/*
	amove $_includedir/pgtypes*.h
	amove $_includedir/sql3types.h
	amove $_includedir/sqlca.h
	amove $_includedir/sqlda*.h

	amove usr/lib/libecpg.*
	amove usr/lib/libpgtypes.*
	amove usr/lib/pkgconfig/libecpg.pc
	amove usr/lib/pkgconfig/libpgtypes.pc
}

client() {
	pkgdesc="PostgreSQL client"
	depends="postgresql-common"
	_subpkg_common

	local cmd; for cmd in $_client_cmds; do
		amove $_bindir/$cmd
		# These commands are symlinked to /usr/bin by pg_versions script after
		# installation.
		provides="$provides cmd:$cmd"
	done
	amove $_bindir/PG_VERSION
}

jit() {
	pkgdesc="Just-in-time compilation support for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/bitcode/*
	amove $_srvlibdir/llvmjit.so
	amove $_srvlibdir/llvmjit_types.bc
}

contrib() {
	pkgdesc="Extension modules distributed with PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	cd "$builddir"

	# Avoid installing plperl and plpython extensions, these will be
	# installed into separate subpackages.
	sed -Ei -e 's/(.*_plperl)/#\1/' \
		-e 's/(.*_plpython)/#\1/' \
		contrib/Makefile

	make -C contrib DESTDIR="$subpkgdir" install

	_contrib_common

	provides="$provides $(ls -1 "$subpkgdir"/$_bindir | sed 's/^/cmd:&/')"
}

pltcl() {
	pkgdesc="PL/Tcl procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel pgtcl"
	_subpkg_common

	amove $_srvlibdir/pltcl.so
	amove $_datadir/extension/pltcl*

	install -m 644 "$srcdir"/pltcl_create_tables.sql -t "$subpkgdir"/$_datadir/
}

plperl() {
	pkgdesc="PL/Perl procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/plperl.so
	amove $_datadir/extension/plperl*
}

plperl_contrib() {
	_plcontrib plperl "PL/Perl"

	cd "$builddir"
	make -C contrib/hstore_plperl DESTDIR="$subpkgdir" install

	_contrib_common
}

plpython3() {
	pkgdesc="PL/Python3 procedural language for PostgreSQL"
	depends="$pkgname=$pkgver-r$pkgrel python3"
	_subpkg_common

	amove $_srvlibdir/plpython3.so
	amove $_datadir/extension/plpython*
}

plpython3_contrib() {
	_plcontrib plpython3 "PL/Python 3"

	cd "$builddir"
	make -C contrib/hstore_plpython DESTDIR="$subpkgdir" install
	make -C contrib/ltree_plpython DESTDIR="$subpkgdir" install

	_contrib_common
}

contrib_jit() {
	pkgdesc="Extension modules distributed with PostgreSQL (JIT support)"
	depends="$pkgname-contrib=$pkgver-r$pkgrel"
	install_if="$pkgname-jit $pkgname-contrib=$pkgver-r$pkgrel"
	_subpkg_common

	amove $_srvlibdir/bitcode/*
}

dev() {
	default_dev
	_subpkg_common
	replaces=""

	amove $_srvlibdir/pgxs/*
}

doc() {
	default_doc
	_subpkg_common

	amove $_mandir
}

openrc() {
	default_openrc
	depends="postgresql-common-openrc"

	mkdir -p "$subpkgdir"
}

_plcontrib() {
	local subname="$1"
	pkgdesc="$2 extension modules distributed with PostgreSQL"
	depends="$pkgname-$subname=$pkgver-r$pkgrel"
	install_if="$pkgname-$subname=$pkgver-r$pkgrel $pkgname-contrib=$pkgver-r$pkgrel"
	_subpkg_common
}

_subpkg_common() {
	provides="postgresql${subpkgname#$pkgname}"
	replaces="$provides"  # for backward compatibility
}

_contrib_common() {
	# Move headers, bitcode and docs from subpackage back to pkgdir, so it
	# can be catched by subsequent split functions.
	local dir; for dir in $_includedir $_srvlibdir/bitcode $_docdir; do
		[ -d "$subpkgdir"/$dir ] || continue

		mkdir -p "$pkgdir"/$dir
		cp -rf "$subpkgdir"/$dir/* "$pkgdir"/$dir/
		rm -rf "$subpkgdir"/$dir/*
		rmdir -p "$subpkgdir"/$dir || true
	done
}

_run_tests() {
	local path="$1"; shift

	msg "Running test suite at $path..."
	# Note: some tests fail when running in parallel.
	make -k -j 1 -C "$path" "$@" check MAX_CONNECTIONS=5 || {
		printf "\n%s\n\n" "Trying to find all regression.diffs files in build directory..." >&2
		find "$path" -name regression.diffs | while read -r file; do
			echo "=== test failure: $file ===" >&2
			cat "$file" >&2
		done
		return 1
	}
}

# $1: whitespace-separated items of set A
# $2: whitespace-separated items of set B
# stdout: newline-separated items of A - B
_setdiff() {
	python3 -c 'import sys;print("\n".join(set(sys.argv[1].split()).difference(set(sys.argv[2].split()))))' "$@"
}

sha512sums="
dd16bc331f6e33cd8ba7a6f19582d4e94d66e4cf4b89b8fe1872f16854401b9f7caf0900478b64a05047d22d2ca07aea5ba71fd5c96fa04bd45713235acdd686  postgresql-15.13.tar.bz2
73080f61ae274a214966d2d010de49c8c90eb3180e4f56d86a9e23063eaddbe7f8d2c40ed414591c16bc9cfe88577866af2a965c2b6effb54965d19ef96a3fa9  initdb.patch
42e7ff5e4114390ec7f0f69b037ebcbc9a7739b239d992bc6f4d13561e188f9027e896892230a5d7cbf1ec0a1ad68deacdd414dcfc7d919bfc368442a220d352  perl-rpath.patch
6d992f53bf8b3e914933f89bc3f01591de2b707cf809aeee4210f9d59e2dc11e3fce697f50a7660f54925a2f0a6154eaeab0f59a969f76572dac5ff6f08faa71  per-version-dirs.patch
d0040599d7646b709af4e3413bf0c228090f256395e806f3fee230ccc6037ed9c0df1cd160d01b6a73b25a742fdd3fb070733a14a78f53d297fbdbbb44f6f878  unix_socket_directories.patch
2e33e1ae38d60e0daf3ed18e6eaa9ddf6762b4b1bb7e51f1d2690e3df9d602aa1a700e603ba3ee69314a75a963131c7dc67c1b1f8b7eb5564e9c4253e81a4db4  disable-html-docs.patch
d8eb4274a54b94bed4a2ded7ae775c5a95ca0f051b831b859ccf78bf6d2ea6fe89a9a0611771f6ad85573995a7e3af1fdf5859e20cae3267a52239f12e1b61c3  remove-libecpg_compat.patch
673707b331cd09c105d18f39e83ec39371886d5d8cf706b6ebbd30ace294fa3377c391bea1ab409c001644c90ac718e3250cbc4acd9224bc0e7ac1f86c832424  czech-snowball-stemmer.patch
5262f4944844bccc839c4441570b9eb2e0792390234ebfdb8ebb7b83380ce5f5de84b038cb03045526da202a185af9c3972c2ae1b9e0e743a95c6e84f4621cf9  make-split-headers.patch
c24986becfd73546a062612335e53b4da34829e42a0c30e85ed7481924f13b1fd0a0e5079d680905a52afea1e99f2210cc3692c529a34a74cd6961c88cce9163  jit-datalayout-mismatch-on-s390x-and-x86.patch
7790e4e4374f7bdc6b4484ba87a5fa709d30d3cbdce61ee7bf9c5dfce40cb51c7bd54ab42f4050fb48eede08ef573624d819128e57cc8c976e01202854740308  pg_config-add-major-version.patch
b0688d66fdd7d612c24d9aa69bdd80d30787d2d6409b4524c79b41797144fc743213460e6de9c536bfb72da089f92cf89731f15137b1407fd04ca97fd393bfd2  dont-use-locale-a-on-musl.patch
a98e5ecdd421f68f11b55bf07bf60280cf80508f89c5d21a084c7e7aa3be0a22c88b8e2ce611a13dd5c11efdd052eb9018271b549040c30663b9fd9b7c4fc611  icu-collations-hack.patch
b64e75778fcb7a8221cf1a3d81c6a1ade3910e3398f63dd6f9be743b1dd7e392ea626dda8da976f4149f838c18ba536e7c9f9da268ae7e03b78268304d89bafc  fix-test-check_guc.patch
54c97d2b8f881deb796988119a1d11c3ed6cc30bec5463e5ad7e196a424d3a6f02db65a72e15b188246253ecd058900a2532ea409d8bf2fe44b300c4db59b6d8  fix-test-postgres_fdw.patch
cde5fbf5a39e5de18a40ec1d9ac919dcf166e0ca178a6b9dbdfded8d16b4969b91917a2550bbf33eccd1ecb3bd9e0753a47012e60f4efe720bbef2a2c5368529  libpgport-pkglibdir.patch.txt
6078defb3da67e7df96665cc130d32b69eebfcaf49d92eef368ea8eea8bb311fab56064c104bc97f53da9cd925301bef696b506af33e0b66d65bc6cd41ec7499  external-libpq.patch.txt
5c9bfd9e295dcf678298bf0aa974347a7c311d6e7c2aa76a6920fcb751d01fd1ab77abbec11f3c672f927ad9deaa88e04e370c0b5cd1b60087554c474b748731  pltcl_create_tables.sql
"
