ForwardWidgets
Widgets for Douban and Trakt watchlists plus personalized recommendations, live TV streaming including PlutoTV, Yatu ra…
A PostgreSQL extension that provides infinite calendar functionality for recurring schedules with exceptions.
git clone https://github.com/h4kbas/pgcalendar.gith4kbas/pgcalendarA powerful PostgreSQL extension for managing recurring events with infinite projections, multiple schedule configurations, and exception handling.
pgcalendar provides a robust system for managing recurring events where:
pip install pgxnclient pgxn install pgcalendar
# Clone the repository git clone https://github.com/h4kbas/pgcalendar.git cd pgcalendar # Build and install make sudo make install # Create extension in your database psql -d your_database -c "CREATE EXTENSION pgcalendar;"
# Copy files to PostgreSQL extensions directory sudo cp pgcalendar.control /usr/share/postgresql/15/extension/ sudo cp pgcalendar.sql /usr/share/postgresql/15/extension/pgcalendar--1.0.1.sql sudo cp pgcalendar--uninstall.sql /usr/share/postgresql/15/extension/pgcalendar--1.0.1--uninstall.sql # Create extension in your database psql -d your_database -c "CREATE EXTENSION pgcalendar;"
# Run SQL file directly (simpler, but not using CREATE EXTENSION) psql -d your_database -f pgcalendar.sql
-- Check if extension is installed SELECT * FROM pg_extension WHERE extname = 'pgcalendar'; -- Test basic functionality SELECT * FROM pgcalendar.event_calendar LIMIT 5;
-- 1. Create an event
INSERT INTO pgcalendar.events (name, description, category)
VALUES ('Daily Standup', 'Team daily standup meeting', 'meeting');
-- 2. Get the event_id
SELECT event_id FROM pgcalendar.events WHERE name = 'Daily Standup';
-- 3. Create a schedule (replace X with actual event_id)
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval
) VALUES (
X, '2024-01-01 09:00:00', '2024-01-07 23:59:59', 'daily', 1
);
-- 4. Get projections
SELECT * FROM pgcalendar.get_event_projections(X, '2024-01-01'::date, '2024-01-07'::date);
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval
) VALUES (
1, '2024-01-01 09:00:00', '2024-01-07 23:59:59', 'daily', 1
);
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval, recurrence_day_of_week
) VALUES (
1, '2024-01-01 10:00:00', '2024-12-31 23:59:59', 'weekly', 1, 1
);
-- recurrence_day_of_week: 0=Sunday, 1=Monday, etc.
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval, recurrence_day_of_month
) VALUES (
1, '2024-01-01 10:00:00', '2024-12-31 23:59:59', 'monthly', 1, 15
);
-- recurrence_day_of_month: 1-31
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval, recurrence_month, recurrence_day_of_month
) VALUES (
1, '2024-01-01 10:00:00', '2030-12-31 23:59:59', 'yearly', 1, 1, 1
);
-- recurrence_month: 1-12, recurrence_day_of_month: 1-31
-- Cancel a specific occurrence
INSERT INTO pgcalendar.exceptions (
schedule_id, exception_date, exception_type, notes
) VALUES (
1, '2024-01-15', 'cancelled', 'Holiday - meeting cancelled'
);
-- Modify time only
INSERT INTO pgcalendar.exceptions (
schedule_id, exception_date, exception_type, modified_start_time, modified_end_time, notes
) VALUES (
1, '2024-01-22', 'modified', '2024-01-22 11:00:00', '2024-01-22 12:00:00', 'Moved to 11 AM'
);
-- Modify date and time
INSERT INTO pgcalendar.exceptions (
schedule_id, exception_date, exception_type, modified_date, modified_start_time, modified_end_time, notes
) VALUES (
1, '2024-01-22', 'modified', '2024-01-23', '2024-01-23 14:00:00', '2024-01-23 15:00:00', 'Moved to next day'
);
-- First schedule: Daily for first week
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval
) VALUES (1, '2024-01-01 09:00:00', '2024-01-07 23:59:59', 'daily', 1);
-- Second schedule: Every other day for second week (no overlap!)
INSERT INTO pgcalendar.schedules (
event_id, start_date, end_date, recurrence_type, recurrence_interval
) VALUES (1, '2024-01-08 09:00:00', '2024-01-14 23:59:59', 'daily', 2);
Safely transition to a new schedule configuration without overlaps:
SELECT pgcalendar.transition_event_schedule(
p_event_id := 1,
p_new_start_date := '2024-01-15 09:00:00',
p_new_end_date := '2024-01-31 23:59:59',
p_recurrence_type := 'weekly',
p_recurrence_interval := 2,
p_recurrence_day_of_week := 1,
p_description := 'Changed to bi-weekly schedule'
);
Check if a schedule would overlap with existing schedules:
SELECT pgcalendar.check_schedule_overlap(
p_event_id := 1,
p_start_date := '2024-01-05 09:00:00',
p_end_date := '2024-01-10 23:59:59'
);
SELECT * FROM pgcalendar.get_event_projections(
p_event_id := 1,
p_start_date := '2024-01-01'::date,
p_end_date := '2024-01-31'::date
);
SELECT * FROM pgcalendar.get_events_detailed(
p_start_date := '2024-01-01'::date,
p_end_date := '2024-01-31'::date
);
SELECT * FROM pgcalendar.event_calendar;
events - Main event definitionsschedules - Non-overlapping schedule configurationsexceptions - Individual projection modificationsget_event_projections(event_id, start_date, end_date) - Get projections for specific eventget_events_detailed(start_date, end_date) - Get all events with exception handlingtransition_event_schedule(...) - Safely change schedule configurationcheck_schedule_overlap(event_id, start_date, end_date) - Validate schedule timingevent_calendar - Current year's calendar viewThe project includes comprehensive Node.js/TypeScript tests using Jest.
# Install dependencies npm install # Start test database (using Docker) npm run test:db:start # Or set environment variables export PG_HOST=localhost export PG_PORT=5433 export PG_USER=postgres export PG_PASSWORD=postgres export PG_DB=pgcalendar_test
# Run all tests npm test # Run with coverage npm run test:coverage # Type check npm run type-check
# Start PostgreSQL container docker run -d --name pgcalendar-test \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=pgcalendar_test \ -p 5433:5432 \ postgres:15 # Install extension docker exec -i pgcalendar-test psql -U postgres -d pgcalendar_test -f pgcalendar.sql # Run tests npm test # Cleanup docker stop pgcalendar-test && docker rm pgcalendar-test
DROP EXTENSION pgcalendar;
# Check if files are in the right location ls -la /usr/share/postgresql/*/extension/pgcalendar* # Verify PostgreSQL version pg_config --version
# Fix permissions if needed sudo chmod 644 /usr/share/postgresql/*/extension/pgcalendar*
DROP SCHEMA IF EXISTS pgcalendar CASCADE; CREATE EXTENSION pgcalendar;
This extension is licensed under the MIT License. See the LICENSE file for details.
more like this
Widgets for Douban and Trakt watchlists plus personalized recommendations, live TV streaming including PlutoTV, Yatu ra…
A lightweight, simplified, RedNotebook-inspired journal/diary app. Built with Electron. Makes dated text files.
View and plan your life in an online calendar by visually by seeing it from days to decades
Simple and lightweight time tracking for individuals and teams, for the cloud in the cloud.
search projects, people, and tags