Skip to content

Commit 3d4dcb3

Browse files
committed
feat: support multiple versions of the pgroonga extension
Build multiple versions of the pgroonga extension on different PostgreSQL versions. Add test for the extensions and their upgrade on PostgreSQL 15 and 17.
1 parent c57842f commit 3d4dcb3

File tree

8 files changed

+531
-70
lines changed

8 files changed

+531
-70
lines changed

flake.nix

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
paramiko
101101
]);
102102
sfcgal = pkgs.callPackage ./nix/ext/sfcgal/sfcgal.nix { };
103-
supabase-groonga = pkgs.callPackage ./nix/supabase-groonga.nix { };
103+
supabase-groonga = pkgs.callPackage ./nix/ext/pgroonga/supabase-groonga-14.0.5.nix { };
104104
mecab-naist-jdic = pkgs.callPackage ./nix/ext/mecab-naist-jdic/default.nix { };
105105
inherit (pkgs.callPackage ./nix/wal-g.nix { }) wal-g-2 wal-g-3;
106106
# Our list of PostgreSQL extensions which come from upstream Nixpkgs.
@@ -132,7 +132,7 @@
132132
./nix/ext/rum.nix
133133
./nix/ext/timescaledb.nix
134134
./nix/ext/timescaledb-2.9.1.nix
135-
./nix/ext/pgroonga.nix
135+
./nix/ext/pgroonga
136136
./nix/ext/index_advisor.nix
137137
./nix/ext/wal2json.nix
138138
./nix/ext/pgmq.nix
@@ -1384,6 +1384,8 @@
13841384
devShell = devShells.default;
13851385
} // pkgs.lib.optionalAttrs (system == "aarch64-linux") {
13861386
inherit (basePackages) postgresql_15_debug postgresql_15_src postgresql_orioledb-17_debug postgresql_orioledb-17_src postgresql_17_debug postgresql_17_src;
1387+
} // pkgs.lib.optionalAttrs (system == "x86_64-linux") {
1388+
pgroonga = import ./nix/ext/tests/pgroonga.nix { inherit self; inherit pkgs; };
13871389
};
13881390

13891391
# Apps is a list of names of things that can be executed with 'nix run';

nix/ext/pgroonga.nix

Lines changed: 170 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,181 @@
1-
{ lib, stdenv, fetchurl, pkg-config, postgresql, msgpack-c, callPackage, mecab, makeWrapper, xxHash }:
1+
{
2+
lib,
3+
stdenv,
4+
fetchurl,
5+
pkg-config,
6+
postgresql,
7+
msgpack-c,
8+
callPackage,
9+
mecab,
10+
makeWrapper,
11+
xxHash,
12+
buildEnv,
13+
}:
214
let
3-
supabase-groonga = callPackage ../supabase-groonga.nix { };
4-
in
5-
stdenv.mkDerivation rec {
15+
supabase-groonga = callPackage ./supabase-groonga { };
616
pname = "pgroonga";
7-
version = "3.2.5";
8-
src = fetchurl {
9-
url = "https://packages.groonga.org/source/${pname}/${pname}-${version}.tar.gz";
10-
sha256 = "sha256-GM9EOQty72hdE4Ecq8jpDudhZLiH3pP9ODLxs8DXcSY=";
11-
};
12-
nativeBuildInputs = [ pkg-config makeWrapper ];
13-
14-
buildInputs = [ postgresql msgpack-c supabase-groonga mecab ] ++ lib.optionals stdenv.isDarwin [
15-
xxHash
16-
];
1717

18-
propagatedBuildInputs = [ supabase-groonga ];
19-
configureFlags = [
20-
"--with-mecab=${mecab}"
21-
"--enable-mecab"
22-
"--with-groonga=${supabase-groonga}"
23-
"--with-groonga-plugin-dir=${supabase-groonga}/lib/groonga/plugins"
24-
];
18+
# Load version configuration from external file
19+
allVersions = (builtins.fromJSON (builtins.readFile ./versions.json)).${pname};
2520

26-
makeFlags = [
27-
"HAVE_MSGPACK=1"
28-
"MSGPACK_PACKAGE_NAME=msgpack-c"
29-
"HAVE_MECAB=1"
21+
# Filter versions compatible with current PostgreSQL version
22+
supportedVersions = lib.filterAttrs (
23+
_: value: builtins.elem (lib.versions.major postgresql.version) value.postgresql
24+
) allVersions;
25+
26+
# Derived version information
27+
versions = lib.naturalSort (lib.attrNames supportedVersions);
28+
latestVersion = lib.last versions;
29+
numberOfVersions = builtins.length versions;
30+
packages = builtins.attrValues (
31+
lib.mapAttrs (name: value: build name value.hash) supportedVersions
32+
);
33+
34+
# List of C extensions to be included in the build
35+
cExtensions = [
36+
"pgroonga"
37+
"pgroonga_database"
3038
];
3139

32-
NIX_CFLAGS_COMPILE = lib.optionalString stdenv.isDarwin (builtins.concatStringsSep " " [
33-
"-Wno-error=incompatible-function-pointer-types"
34-
"-Wno-error=format"
35-
"-Wno-format"
36-
"-I${supabase-groonga}/include/groonga"
37-
"-I${xxHash}/include"
38-
"-DPGRN_VERSION=\"${version}\""
39-
]);
40-
41-
preConfigure = ''
42-
export GROONGA_LIBS="-L${supabase-groonga}/lib -lgroonga"
43-
export GROONGA_CFLAGS="-I${supabase-groonga}/include"
44-
export MECAB_CONFIG="${mecab}/bin/mecab-config"
45-
${lib.optionalString stdenv.isDarwin ''
46-
export CPPFLAGS="-I${supabase-groonga}/include/groonga -I${xxHash}/include -DPGRN_VERSION=\"${version}\""
47-
export CFLAGS="-I${supabase-groonga}/include/groonga -I${xxHash}/include -DPGRN_VERSION=\"${version}\""
48-
export PG_CPPFLAGS="-Wno-error=incompatible-function-pointer-types -Wno-error=format"
49-
''}
50-
'';
40+
# Build function for individual versions
41+
build =
42+
version: hash:
43+
stdenv.mkDerivation rec {
44+
inherit pname version;
45+
46+
src = fetchurl {
47+
url = "https://packages.groonga.org/source/${pname}/${pname}-${version}.tar.gz";
48+
inherit hash;
49+
};
50+
nativeBuildInputs = [
51+
pkg-config
52+
makeWrapper
53+
];
54+
55+
buildInputs =
56+
[
57+
postgresql
58+
msgpack-c
59+
supabase-groonga
60+
mecab
61+
]
62+
++ lib.optionals stdenv.isDarwin [
63+
xxHash
64+
];
65+
66+
propagatedBuildInputs = [ supabase-groonga ];
67+
configureFlags = [
68+
"--with-mecab=${mecab}"
69+
"--enable-mecab"
70+
"--with-groonga=${supabase-groonga}"
71+
"--with-groonga-plugin-dir=${supabase-groonga}/lib/groonga/plugins"
72+
];
73+
74+
makeFlags = [
75+
"HAVE_MSGPACK=1"
76+
"MSGPACK_PACKAGE_NAME=msgpack-c"
77+
"HAVE_MECAB=1"
78+
];
79+
80+
NIX_CFLAGS_COMPILE = lib.optionalString stdenv.isDarwin (
81+
builtins.concatStringsSep " " [
82+
"-Wno-error=incompatible-function-pointer-types"
83+
"-Wno-error=format"
84+
"-Wno-format"
85+
"-I${supabase-groonga}/include/groonga"
86+
"-I${xxHash}/include"
87+
"-DPGRN_VERSION=\"${version}\""
88+
]
89+
);
90+
91+
preConfigure = ''
92+
export GROONGA_LIBS="-L${supabase-groonga}/lib -lgroonga"
93+
export GROONGA_CFLAGS="-I${supabase-groonga}/include"
94+
export MECAB_CONFIG="${mecab}/bin/mecab-config"
95+
${lib.optionalString stdenv.isDarwin ''
96+
export CPPFLAGS="-I${supabase-groonga}/include/groonga -I${xxHash}/include -DPGRN_VERSION=\"${version}\""
97+
export CFLAGS="-I${supabase-groonga}/include/groonga -I${xxHash}/include -DPGRN_VERSION=\"${version}\""
98+
export PG_CPPFLAGS="-Wno-error=incompatible-function-pointer-types -Wno-error=format"
99+
''}
100+
'';
101+
102+
installPhase = ''
103+
runHook preInstall
104+
105+
mkdir -p $out/{lib,share/postgresql/extension}
106+
107+
for ext in ${lib.concatStringsSep " " cExtensions}; do
108+
# Install shared library with version suffix
109+
mv $ext${postgresql.dlSuffix} $out/lib/$ext-${version}${postgresql.dlSuffix}
110+
111+
# Create version-specific control file
112+
sed -e "/^default_version =/d" \
113+
-e "s|^module_pathname = .*|module_pathname = '\$libdir/$ext'|" \
114+
$ext.control > $out/share/postgresql/extension/$ext--${version}.control
115+
116+
# Copy SQL file to install the specific version
117+
cp data/$ext--${version}.sql $out/share/postgresql/extension
118+
119+
# Create versioned control file with modified module path
120+
sed -e "/^default_version =/d" \
121+
-e "s|^module_pathname = .*|module_pathname = '\$libdir/$ext'|" \
122+
$ext.control > $out/share/postgresql/extension/$ext--${version}.control
123+
124+
# For the latest version, create default control file and symlink and copy SQL upgrade scripts
125+
if [[ "${version}" == "${latestVersion}" ]]; then
126+
{
127+
echo "default_version = '${version}'"
128+
cat $out/share/postgresql/extension/$ext--${version}.control
129+
} > $out/share/postgresql/extension/$ext.control
130+
ln -sfn $ext-${version}${postgresql.dlSuffix} $out/lib/$ext${postgresql.dlSuffix}
131+
cp data/$ext--*--*.sql $out/share/postgresql/extension
132+
fi
133+
done
134+
135+
echo "Debug: Groonga plugins directory contents:"
136+
ls -l ${supabase-groonga}/lib/groonga/plugins/tokenizers/
137+
'';
138+
139+
meta = with lib; {
140+
description = "A PostgreSQL extension to use Groonga as the index";
141+
longDescription = ''
142+
PGroonga is a PostgreSQL extension to use Groonga as the index.
143+
PostgreSQL supports full text search against languages that use only alphabet and digit.
144+
It means that PostgreSQL doesn't support full text search against Japanese, Chinese and so on.
145+
You can use super fast full text search feature against all languages by installing PGroonga into your PostgreSQL.
146+
'';
147+
homepage = "https://pgroonga.github.io/";
148+
changelog = "https://github.com/pgroonga/pgroonga/releases/tag/${version}";
149+
license = licenses.postgresql;
150+
inherit (postgresql.meta) platforms;
151+
};
152+
};
153+
in
154+
buildEnv {
155+
name = pname;
156+
paths = packages;
157+
158+
pathsToLink = [
159+
"/lib"
160+
"/share/postgresql/extension"
161+
];
162+
postBuild = ''
163+
# Verify all expected library files are present
164+
expectedFiles=${toString ((numberOfVersions + 1) * (builtins.length cExtensions))}
165+
actualFiles=$(ls -l $out/lib/${pname}*${postgresql.dlSuffix} | wc -l)
51166
52-
installPhase = ''
53-
mkdir -p $out/lib $out/share/postgresql/extension $out/bin
54-
install -D pgroonga${postgresql.dlSuffix} -t $out/lib/
55-
install -D pgroonga.control -t $out/share/postgresql/extension
56-
install -D data/pgroonga-*.sql -t $out/share/postgresql/extension
57-
install -D pgroonga_database${postgresql.dlSuffix} -t $out/lib/
58-
install -D pgroonga_database.control -t $out/share/postgresql/extension
59-
install -D data/pgroonga_database-*.sql -t $out/share/postgresql/extension
60-
61-
echo "Debug: Groonga plugins directory contents:"
62-
ls -l ${supabase-groonga}/lib/groonga/plugins/tokenizers/
167+
if [[ "$actualFiles" != "$expectedFiles" ]]; then
168+
echo "Error: Expected $expectedFiles library files, found $actualFiles"
169+
echo "Files found:"
170+
ls -la $out/lib/*${postgresql.dlSuffix} || true
171+
exit 1
172+
fi
63173
'';
64174

65-
meta = with lib; {
66-
description = "A PostgreSQL extension to use Groonga as the index";
67-
longDescription = ''
68-
PGroonga is a PostgreSQL extension to use Groonga as the index.
69-
PostgreSQL supports full text search against languages that use only alphabet and digit.
70-
It means that PostgreSQL doesn't support full text search against Japanese, Chinese and so on.
71-
You can use super fast full text search feature against all languages by installing PGroonga into your PostgreSQL.
72-
'';
73-
homepage = "https://pgroonga.github.io/";
74-
changelog = "https://github.com/pgroonga/pgroonga/releases/tag/${version}";
75-
license = licenses.postgresql;
76-
platforms = postgresql.meta.platforms;
175+
passthru = {
176+
inherit versions numberOfVersions;
177+
pname = "${pname}-all";
178+
version =
179+
"multi-" + lib.concatStringsSep "-" (map (v: lib.replaceStrings [ "." ] [ "-" ] v) versions);
77180
};
78181
}

0 commit comments

Comments
 (0)