使用PL/pgSQL编写的规则(包括处理RSCALE)
RRules (yes handling RSCALE) using only PL/pgSQL

原始链接: https://github.com/sirrodgepodge/rrule_plpgsql

## rrule-plpgsql: 一个纯PL/pgSQL iCalendar RRULE实现 rrule-plpgsql 是一个PostgreSQL库,用于根据iCalendar RRULE标准(RFC 5545 & 7529)计算重复事件,完全使用PL/pgSQL实现 – **无需C扩展或编译**。 这确保了在所有PostgreSQL环境(本地、云服务如AlloyDB、Aurora、Azure以及自托管)中的一致性。 主要特性包括完整的时区支持和自动夏令时处理,一个包含187个测试用例的全面测试套件,以及比Node.js快**50-75倍**的单次调度性能,并且批量操作速度更快。 它能够直接在数据库内进行高效的基于集合的操作 – 将重复规则连接到事件表,使用SQL过滤事件,以及批量处理调度。 该库提供生成、查询和计数事件的功能,并提供限制重复次数(COUNT、UNTIL)以及按日、月、年等过滤事件的选项。 安装简单,只需一个SQL文件。 高级功能,如每小时/分钟的重复,可用但需要仔细考虑潜在的性能影响。 这是一个生产就绪的解决方案,通过利用PostgreSQL高效的数据处理能力,提供可扩展性和性能优势。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 RRules (是的,处理RSCALE) 仅使用PL/pgSQL (github.com/sirrodgepodge) 4点 由 sirrodgepodge 1小时前 | 隐藏 | 过去 | 收藏 | 讨论 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

npm version npm downloads License: MIT

Pure PL/pgSQL implementation of iCalendar RRULE (RFC 5545) for PostgreSQL. No C extensions, no compilation, works everywhere.


This library provides complete RRULE recurrence calculation functionality using pure PL/pgSQL. Use this implementation for all environments (local, development, staging, production) to ensure consistency.

Key Features:

  • No C extensions required - Pure PL/pgSQL, works on any PostgreSQL
  • Full timezone support with DST handling - Wall-clock time preserved ("10 AM stays 10 AM" across DST transitions)
  • Consistent everywhere - Same implementation across all environments
  • Production-ready - Comprehensive test suite with 187 tests (including table operation integration tests)
  • RFC 5545 & RFC 7529 compliant - Supports standard RRULE patterns plus SKIP/RSCALE
  • 50-75x faster than Node.js - Excellent performance without compilation
  • Works on managed services - AlloyDB, RDS, Azure Database for PostgreSQL

Computation where your data lives delivers performance impossible with external processing:

  • Set-based operations: JOIN recurrence rules against events, bookings, or any table without data transfer
  • Native WHERE/aggregation: Filter by occurrence dates, COUNT occurrences, GROUP BY - all in SQL
  • Batch processing: Process 100+ schedules in a single query without round trips
  • Memory-efficient streaming: SETOF returns results incrementally, not all at once
  • 50-75x faster than Node.js for single-schedule operations, infinitely faster for multi-schedule batch queries

See Example Usage for practical patterns including subscription billing, batch updates, and conflict detection.

Pure PL/pgSQL means:

  • ✅ No C compiler or build tools required
  • ✅ Install with a single SQL file - no configuration
  • ✅ Consistent behavior across all environments (dev, staging, production)

Universal compatibility:

  • Google AlloyDB - High-performance PostgreSQL with AI integration
  • Google Cloud SQL - Fully managed PostgreSQL service
  • Amazon Aurora PostgreSQL - Serverless PostgreSQL with automatic scaling
  • Amazon RDS PostgreSQL - Managed PostgreSQL without custom extensions
  • Azure Database for PostgreSQL - Fully supported managed service
  • Self-hosted PostgreSQL - No special configuration required
  • Docker PostgreSQL - Standard postgres image compatibility

Option 1: npm (TypeScript/Node.js)

npm install rrule-plpgsql

Then install in your database using your ORM/client. See Installation Guide for TypeScript/ORM integration.

Option 2: Direct SQL Installation

# Install via psql
psql -d your_database -f src/install.sql

# Or use curl for one-line install
curl -sL https://raw.githubusercontent.com/sirrodgepodge/rrule_plpgsql/main/src/install.sql | psql -d your_database

Next Steps: See Example Usage for practical patterns.


🔒 Security & Advanced Features


✅ Production-Ready (Always Enabled):

  • FREQ=DAILY - Daily recurrence with date/time filters
  • FREQ=WEEKLY - Weekly recurrence with day-of-week selection
  • FREQ=MONTHLY - Monthly recurrence with day/week-of-month selection
  • FREQ=YEARLY - Yearly recurrence with month/day/week selection

⚠️ Advanced (Optional, Disabled by Default):

  • FREQ=HOURLY - Hourly recurrence (8,760/year max)
  • FREQ=MINUTELY - Minutely recurrence (525,600/year max)
  • FREQ=SECONDLY - Secondly recurrence (31M/year max)

See Sub-Day Operations Guide for enabling these safely.

  • COUNT - Limit number of occurrences
  • UNTIL - End date for recurrence
  • INTERVAL - Frequency multiplier (every N days/weeks/months)
  • BYDAY - Filter by day of week (MO, TU, WE, TH, FR, SA, SU)
  • BYDAY with ordinals - Positioned weekdays (2MO = 2nd Monday, -1FR = last Friday)
  • BYMONTHDAY - Filter by day of month (1-31, -1 = last day)
  • BYMONTH - Filter by month (1-12)
  • BYYEARDAY - Filter by day of year (1-366, negative supported)
  • BYWEEKNO - Filter by ISO week number (1-53, YEARLY only)
  • BYSETPOS - Select specific positions from generated set
  • WKST - Week start day (SU, MO, TU, WE, TH, FR, SA)
  • SKIP - Invalid date handling (OMIT, BACKWARD, FORWARD)
  • TZID - Timezone specification with automatic DST handling
  • RSCALE - Calendar system (GREGORIAN supported)

See RFC Spec Compliance for complete feature support matrix and examples.

Full RFC 5545 timezone support with automatic DST handling:

-- Meeting stays at 10 AM wall-clock time across DST boundary
SELECT * FROM rrule.all(
    'FREQ=DAILY;COUNT=3;TZID=America/New_York',
    '2025-03-08 10:00:00'::TIMESTAMP
);
-- Returns: March 8 (EST), March 9 (EDT), March 10 (EDT)
-- All at 10:00 AM wall-clock time

See API Reference for TIMESTAMPTZ API details.


Standard Installation (Recommended)

psql -d your_database -f src/install.sql

Includes:

  • DAILY, WEEKLY, MONTHLY, YEARLY frequencies
  • All standard modifiers and filters
  • Timezone support with DST handling
  • Secure by default (no DoS vectors)

With Sub-Day Frequencies (Advanced)

psql -d your_database -f src/install_with_subday.sql

Includes standard PLUS:

  • HOURLY, MINUTELY, SECONDLY frequencies
  • ⚠️ Security warnings during installation
  • Requires application-level validation

See Sub-Day Operations Guide before using this installation.


Error: "Invalid RRULE: FREQ parameter is required"

  • Every RRULE must start with FREQ
  • Fix: Add FREQ=DAILY (or WEEKLY/MONTHLY/YEARLY)

Error: "COUNT and UNTIL are mutually exclusive"

  • Cannot use both COUNT and UNTIL in same RRULE
  • Fix: Use either COUNT=10 OR UNTIL=20251231T235959

Error: "BYWEEKNO can only be used with FREQ=YEARLY"

  • BYWEEKNO requires YEARLY frequency
  • Fix: Change to FREQ=YEARLY;BYWEEKNO=10

See Validation Rules for complete error reference.


All functions support both TIMESTAMP and TIMESTAMPTZ with automatic timezone handling:

-- Generate occurrences
rrule.all(rrule, dtstart) → SETOF TIMESTAMP
rrule.between(rrule, dtstart, start, end) → SETOF TIMESTAMP

-- Query occurrences
rrule.after(rrule, dtstart, after_date) → TIMESTAMP
rrule.before(rrule, dtstart, before_date) → TIMESTAMP
rrule.next(rrule, dtstart) → TIMESTAMP
rrule.most_recent(rrule, dtstart) → TIMESTAMP

-- Utilities
rrule.count(rrule, dtstart) → INTEGER
rrule.overlaps(dtstart, dtend, rrule, mindate, maxdate) → BOOLEAN
-- Every Monday for 4 weeks
SELECT * FROM rrule.all(
    'FREQ=WEEKLY;BYDAY=MO;COUNT=4',
    '2025-01-06 10:00:00'::TIMESTAMP
);

-- With timezone support
SELECT * FROM rrule.all(
    'FREQ=DAILY;COUNT=5;TZID=America/New_York',
    '2025-03-08 10:00:00'::TIMESTAMP  -- DST handled automatically
);

See API Reference for complete function signatures, timezone handling details, and advanced examples.


Contributions welcome! Please:

  1. Run all tests (all 10 test suites must pass)
  2. Add test coverage for new features
  3. Update documentation
  4. Follow RFC 5545/7529 specifications
  5. Submit pull request

See Development Guide for contribution guidelines and test suite details.


Single schedule: 50-75x faster than Node.js rrule.js Multi-schedule queries: Eliminates application-database round trips entirely

Scalability advantages:

  • Set-based batch operations: Query 100+ schedules in parallel without loops
  • Streaming results: SETOF returns incrementally, not all at once (constant memory)
  • Query planner optimization: PostgreSQL optimizes JOINs and filters with occurrence expansion
  • Early-exit optimizations: Stops computation when COUNT/UNTIL limits reached

See Performance Guide for optimization strategies and Development Guide for benchmarking details.


  • PostgreSQL 12 or higher
  • No C extensions required
  • No external dependencies
  • Works on all PostgreSQL-compatible platforms

See Development Guide for development setup instructions.



联系我们 contact @ memedata.com