forked from sqliteai/sqlite-sync
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile.postgresql
More file actions
361 lines (326 loc) · 15.3 KB
/
Makefile.postgresql
File metadata and controls
361 lines (326 loc) · 15.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
# PostgreSQL Extension Build Configuration
# This file is included by the root Makefile
# Detect pg_config
PG_CONFIG ?= pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs 2>/dev/null)
# PostgreSQL directories
PG_SHAREDIR := $(shell $(PG_CONFIG) --sharedir 2>/dev/null)
PG_PKGLIBDIR := $(shell $(PG_CONFIG) --pkglibdir 2>/dev/null)
PG_INCLUDEDIR := $(shell $(PG_CONFIG) --includedir-server 2>/dev/null)
# Extension metadata
EXTENSION = cloudsync
EXTVERSION = 1.0
# Source files - core platform-agnostic code
PG_CORE_SRC = \
src/cloudsync.c \
src/dbutils.c \
src/pk.c \
src/utils.c \
src/lz4.c \
src/block.c \
modules/fractional-indexing/fractional_indexing.c
# PostgreSQL-specific implementation
PG_IMPL_SRC = \
src/postgresql/database_postgresql.c \
src/postgresql/cloudsync_postgresql.c \
src/postgresql/pgvalue.c \
src/postgresql/sql_postgresql.c
# All source files
PG_ALL_SRC = $(PG_CORE_SRC) $(PG_IMPL_SRC)
PG_OBJS = $(PG_ALL_SRC:.c=.o)
# Compiler flags
# Define POSIX macros as compiler flags to ensure they're defined before any includes
PG_CPPFLAGS = -I$(PG_INCLUDEDIR) -Isrc -Isrc/postgresql -Imodules/fractional-indexing -DCLOUDSYNC_POSTGRESQL_BUILD -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE
PG_CFLAGS = -fPIC -Wall -Wextra -Wno-unused-parameter -std=c11 -O2
PG_DEBUG ?= 0
ifeq ($(PG_DEBUG),1)
PG_CFLAGS = -fPIC -Wall -Wextra -Wno-unused-parameter -std=c11 -g -O0 -fno-omit-frame-pointer
endif
PG_LDFLAGS = -shared
# Output files
PG_EXTENSION_SO = $(EXTENSION).so
PG_EXTENSION_SQL = src/postgresql/$(EXTENSION)--$(EXTVERSION).sql
PG_EXTENSION_CONTROL = docker/postgresql/$(EXTENSION).control
# ============================================================================
# PostgreSQL Build Targets
# ============================================================================
.PHONY: postgres-check postgres-build postgres-install postgres-clean postgres-test \
postgres-docker-build postgres-docker-build-asan postgres-docker-run postgres-docker-run-asan postgres-docker-stop postgres-docker-rebuild \
postgres-docker-debug-build postgres-docker-debug-run postgres-docker-debug-rebuild \
postgres-docker-shell postgres-dev-rebuild postgres-help unittest-pg \
postgres-supabase-build postgres-supabase-rebuild postgres-supabase-run-smoke-test \
postgres-docker-run-smoke-test
# Check if PostgreSQL is available
postgres-check:
@echo "Checking PostgreSQL installation..."
@which $(PG_CONFIG) > /dev/null || (echo "Error: pg_config not found. Install postgresql-server-dev." && exit 1)
@echo "PostgreSQL version: $$($(PG_CONFIG) --version)"
@echo "Extension directory: $(PG_PKGLIBDIR)"
@echo "Share directory: $(PG_SHAREDIR)"
@echo "Include directory: $(PG_INCLUDEDIR)"
# Build PostgreSQL extension
postgres-build: postgres-check
@echo "Building PostgreSQL extension..."
@echo "Compiling source files..."
@for src in $(PG_ALL_SRC); do \
echo " CC $$src"; \
$(CC) $(PG_CPPFLAGS) $(PG_CFLAGS) -c $$src -o $${src%.c}.o || exit 1; \
done
@echo "Linking $(PG_EXTENSION_SO)..."
$(CC) $(PG_LDFLAGS) -o $(PG_EXTENSION_SO) $(PG_OBJS)
@echo "Build complete: $(PG_EXTENSION_SO)"
# Install extension to PostgreSQL
postgres-install: postgres-build
@echo "Installing CloudSync extension to PostgreSQL..."
@echo "Installing shared library to $(PG_PKGLIBDIR)/"
install -d $(PG_PKGLIBDIR)
install -m 755 $(PG_EXTENSION_SO) $(PG_PKGLIBDIR)/
@echo "Installing SQL script to $(PG_SHAREDIR)/extension/"
install -d $(PG_SHAREDIR)/extension
install -m 644 $(PG_EXTENSION_SQL) $(PG_SHAREDIR)/extension/
@echo "Installing control file to $(PG_SHAREDIR)/extension/"
install -m 644 $(PG_EXTENSION_CONTROL) $(PG_SHAREDIR)/extension/
@echo ""
@echo "Installation complete!"
@echo "To use the extension, run in psql:"
@echo " CREATE EXTENSION $(EXTENSION);"
# Clean PostgreSQL build artifacts
postgres-clean:
@echo "Cleaning PostgreSQL build artifacts..."
rm -f $(PG_OBJS) $(PG_EXTENSION_SO)
@echo "Clean complete"
# Test extension (requires running PostgreSQL)
postgres-test: postgres-install
@echo "Testing CloudSync extension..."
@echo "Dropping existing extension (if any)..."
-psql -U postgres -d postgres -c "DROP EXTENSION IF EXISTS $(EXTENSION) CASCADE;" 2>/dev/null
@echo "Creating extension..."
psql -U postgres -d postgres -c "CREATE EXTENSION $(EXTENSION);"
@echo "Testing version function..."
psql -U postgres -d postgres -c "SELECT $(EXTENSION)_version();"
@echo "Listing extension functions..."
psql -U postgres -d postgres -c "\\df $(EXTENSION)_*"
# ============================================================================
# Docker Targets
# ============================================================================
DOCKER_IMAGE = sqliteai/sqlite-sync-pg
DOCKER_TAG ?= latest
DOCKER_BUILD_ARGS ?=
SUPABASE_CLI_IMAGE ?= $(shell docker ps --format '{{.Image}} {{.Names}}' | awk '/supabase_db/ {print $$1; exit}')
SUPABASE_CLI_DOCKERFILE ?= docker/postgresql/Dockerfile.supabase
SUPABASE_POSTGRES_TAG ?= 17.6.1.071
SUPABASE_WORKDIR ?=
SUPABASE_WORKDIR_ARG = $(if $(SUPABASE_WORKDIR),--workdir $(SUPABASE_WORKDIR),)
SUPABASE_DB_HOST ?= 127.0.0.1
SUPABASE_DB_PORT ?= 54322
SUPABASE_DB_PASSWORD ?= postgres
PG_DOCKER_DB_HOST ?= localhost
PG_DOCKER_DB_PORT ?= 5432
PG_DOCKER_DB_NAME ?= postgres
PG_DOCKER_DB_USER ?= postgres
PG_DOCKER_DB_PASSWORD ?= postgres
# Build Docker image with pre-installed extension
postgres-docker-build:
@echo "Building Docker image via docker compose (rebuilt when sources change)..."
# To force plaintext BuildKit logs, run: make postgres-docker-build DOCKER_BUILD_ARGS="--progress=plain"
cd docker/postgresql && docker compose build $(DOCKER_BUILD_ARGS)
@echo ""
@echo "Docker image built successfully!"
# Build Docker image with AddressSanitizer enabled (override compose file)
postgres-docker-build-asan:
@echo "Building Docker image with ASAN via docker compose..."
# To force plaintext BuildKit logs, run: make postgres-docker-build-asan DOCKER_BUILD_ARGS=\"--progress=plain\"
cd docker/postgresql && docker compose -f docker-compose.debug.yml -f docker-compose.asan.yml build $(DOCKER_BUILD_ARGS)
@echo ""
@echo "ASAN Docker image built successfully!"
# Build Docker image using docker-compose.debug.yml
postgres-docker-debug-build:
@echo "Building debug Docker image via docker compose..."
# To force plaintext BuildKit logs, run: make postgres-docker-debug-build DOCKER_BUILD_ARGS=\"--progress=plain\"
cd docker/postgresql && docker compose -f docker-compose.debug.yml build $(DOCKER_BUILD_ARGS)
@echo ""
@echo "Debug Docker image built successfully!"
# Run PostgreSQL container with CloudSync
postgres-docker-run:
@echo "Starting PostgreSQL with CloudSync..."
cd docker/postgresql && docker compose up -d --build
@echo ""
@echo "Container started successfully!"
@echo ""
@echo "Connect with psql:"
@echo " docker exec -it cloudsync-postgres psql -U postgres -d cloudsync_test"
@echo ""
@echo "Or from host:"
@echo " psql postgresql://postgres:postgres@localhost:5432/cloudsync_test"
@echo ""
@echo "Enable extension:"
@echo " CREATE EXTENSION cloudsync;"
@echo " SELECT cloudsync_version();"
# Run PostgreSQL container with CloudSync and AddressSanitizer enabled
postgres-docker-run-asan:
@echo "Starting PostgreSQL with CloudSync (ASAN enabled)..."
cd docker/postgresql && docker compose -f docker-compose.debug.yml -f docker-compose.asan.yml up -d --build
@echo ""
@echo "Container started successfully!"
@echo ""
@echo "Connect with psql:"
@echo " docker exec -it cloudsync-postgres psql -U postgres -d cloudsync_test"
@echo ""
@echo "Or from host:"
@echo " psql postgresql://postgres:postgres@localhost:5432/cloudsync_test"
@echo ""
@echo "Enable extension:"
@echo " CREATE EXTENSION cloudsync;"
@echo " SELECT cloudsync_version();"
# Run PostgreSQL container using docker-compose.debug.yml
postgres-docker-debug-run:
@echo "Starting PostgreSQL with CloudSync (debug compose)..."
cd docker/postgresql && docker compose -f docker-compose.debug.yml up -d --build
@echo ""
@echo "Container started successfully!"
@echo ""
@echo "Connect with psql:"
@echo " docker exec -it cloudsync-postgres psql -U postgres -d cloudsync_test"
@echo ""
@echo "Or from host:"
@echo " psql postgresql://postgres:postgres@localhost:5432/cloudsync_test"
@echo ""
@echo "Enable extension:"
@echo " CREATE EXTENSION cloudsync;"
@echo " SELECT cloudsync_version();"
# Stop PostgreSQL container
postgres-docker-stop:
@echo "Stopping PostgreSQL container..."
cd docker/postgresql && docker compose down
@echo "Container stopped"
# Rebuild and restart container
postgres-docker-rebuild: postgres-docker-build
@echo "Rebuilding and restarting container..."
cd docker/postgresql && docker compose down
cd docker/postgresql && docker compose up -d --build
@echo "Container restarted with new image"
# Rebuild and restart container using docker-compose.debug.yml
postgres-docker-debug-rebuild: postgres-docker-debug-build
@echo "Rebuilding and restarting debug container..."
cd docker/postgresql && docker compose -f docker-compose.debug.yml down
cd docker/postgresql && docker compose -f docker-compose.debug.yml up -d --build
@echo "Debug container restarted with new image"
# Interactive shell in container
postgres-docker-shell:
@echo "Opening shell in PostgreSQL container..."
docker exec -it cloudsync-postgres bash
# Build CloudSync into the Supabase CLI postgres image tag
postgres-supabase-build:
@echo "Building CloudSync image for Supabase CLI..."
@tmp_dockerfile="$$(mktemp ./cloudsync-supabase-cli.XXXXXX)"; \
src_dockerfile="$(SUPABASE_CLI_DOCKERFILE)"; \
supabase_cli_image="$(SUPABASE_CLI_IMAGE)"; \
if [ -z "$$supabase_cli_image" ]; then \
supabase_cli_image="public.ecr.aws/supabase/postgres:$(SUPABASE_POSTGRES_TAG)"; \
fi; \
if [ -z "$$supabase_cli_image" ]; then \
echo "Error: Supabase CLI postgres image not found."; \
echo "Run 'supabase start' first, or set SUPABASE_CLI_IMAGE=public.ecr.aws/supabase/postgres:<tag>."; \
exit 1; \
fi; \
if [ ! -f "$$src_dockerfile" ]; then \
if [ -f "docker/postgresql/Dockerfile.supabase" ]; then \
src_dockerfile="docker/postgresql/Dockerfile.supabase"; \
else \
echo "Error: Supabase Dockerfile not found (expected $$src_dockerfile)."; \
rm -f "$$tmp_dockerfile"; \
exit 1; \
fi; \
fi; \
sed -e "s|^FROM supabase/postgres:[^ ]*|FROM $$supabase_cli_image|" \
-e "s|^FROM public.ecr.aws/supabase/postgres:[^ ]*|FROM $$supabase_cli_image|" \
"$$src_dockerfile" > "$$tmp_dockerfile"; \
if [ ! -s "$$tmp_dockerfile" ]; then \
echo "Error: Generated Dockerfile is empty."; \
rm -f "$$tmp_dockerfile"; \
exit 1; \
fi; \
echo "Using base image: $$supabase_cli_image"; \
echo "Pulling fresh base image to avoid layer accumulation..."; \
docker pull "$$supabase_cli_image" 2>/dev/null || true; \
docker build --build-arg SUPABASE_POSTGRES_TAG="$(SUPABASE_POSTGRES_TAG)" -f "$$tmp_dockerfile" -t "$$supabase_cli_image" .; \
rm -f "$$tmp_dockerfile"; \
echo "Build complete: $$supabase_cli_image"
# Rebuild CloudSync image and restart Supabase CLI stack
postgres-supabase-rebuild: postgres-supabase-build
@echo "Restarting Supabase CLI stack..."
@command -v supabase >/dev/null 2>&1 || (echo "Error: supabase CLI not found in PATH." && exit 1)
@supabase stop $(SUPABASE_WORKDIR_ARG)
@supabase start $(SUPABASE_WORKDIR_ARG)
@echo "Supabase CLI stack restarted."
# Run smoke test against Supabase CLI local database
postgres-supabase-run-test:
@echo "Running Supabase CLI test..."
@PGPASSWORD="$(SUPABASE_DB_PASSWORD)" psql postgresql://supabase_admin@$(SUPABASE_DB_HOST):$(SUPABASE_DB_PORT)/postgres -f test/postgresql/full_test.sql
@echo "Test completed."
# Run smoke test against Docker standalone database
postgres-docker-run-test:
@echo "Running Docker test..."
@PGPASSWORD="$(PG_DOCKER_DB_PASSWORD)" psql postgresql://$(PG_DOCKER_DB_USER)@$(PG_DOCKER_DB_HOST):$(PG_DOCKER_DB_PORT)/$(PG_DOCKER_DB_NAME) -f test/postgresql/full_test.sql
@echo "Test completed."
# ============================================================================
# Development Workflow Targets
# ============================================================================
# Quick rebuild inside running container
postgres-dev-rebuild:
@echo "Rebuilding extension inside running container..."
@echo "This is faster than rebuilding the entire Docker image"
docker exec -it cloudsync-postgres bash -c "cd /tmp/cloudsync && make postgres-clean && make postgres-build && make postgres-install"
@echo ""
@echo "Extension rebuilt successfully!"
@echo ""
@echo "To reload the extension in psql, run:"
@echo " DROP EXTENSION cloudsync CASCADE;"
@echo " CREATE EXTENSION cloudsync;"
# Help target
postgres-help:
@echo "PostgreSQL Extension Build Targets"
@echo "==================================="
@echo ""
@echo "Build & Install:"
@echo " postgres-check - Verify PostgreSQL installation"
@echo " postgres-build - Build extension (.so file)"
@echo " postgres-install - Install extension to PostgreSQL"
@echo " postgres-clean - Clean build artifacts"
@echo " postgres-test - Test extension (requires running PostgreSQL)"
@echo ""
@echo "Docker Targets:"
@echo " postgres-docker-build - Build Docker image with pre-installed extension"
@echo " postgres-docker-build-asan - Build Docker image with ASAN enabled"
@echo " postgres-docker-run-asan - Run container with ASAN enabled"
@echo " postgres-docker-debug-build - Build image via docker-compose.debug.yml"
@echo " postgres-docker-debug-run - Run container via docker-compose.debug.yml"
@echo " postgres-docker-debug-rebuild - Rebuild and run docker-compose.debug.yml"
@echo " postgres-docker-run - Start PostgreSQL container"
@echo " postgres-docker-stop - Stop PostgreSQL container"
@echo " postgres-docker-rebuild - Rebuild image and restart container"
@echo " postgres-docker-shell - Open bash shell in running container"
@echo " postgres-supabase-build - Build CloudSync into Supabase CLI postgres image"
@echo " postgres-supabase-rebuild - Build CloudSync image and restart Supabase CLI stack"
@echo " postgres-supabase-run-smoke-test - Run smoke test against Supabase CLI database"
@echo " postgres-docker-run-smoke-test - Run smoke test against Docker database"
@echo ""
@echo "Development:"
@echo " postgres-dev-rebuild - Rebuild extension in running container (fast)"
@echo " unittest-pg - Rebuild container and run smoke test (create extension + version)"
@echo ""
@echo "Examples:"
@echo " make postgres-docker-build # Build image"
@echo " make postgres-docker-build-asan # Build image with ASAN"
@echo " make postgres-docker-run-asan # Run container with ASAN"
@echo " make postgres-docker-debug-build # Build debug compose image"
@echo " make postgres-docker-debug-run # Run debug compose container"
@echo " make postgres-docker-debug-rebuild # Rebuild debug compose container"
@echo " make postgres-docker-run # Start container"
@echo " make postgres-docker-shell # Open shell"
@echo " make postgres-dev-rebuild # Rebuild after code changes"
# Simple smoke test: rebuild image/container, create extension, and query version
unittest-pg: postgres-docker-rebuild
@echo "Running PostgreSQL extension smoke test..."
cd docker/postgresql && docker compose exec -T postgres psql -U postgres -d cloudsync_test -f /tmp/cloudsync/docker/postgresql/smoke_test.sql
@echo "Smoke test completed."