pg_orrery/src/eph_provider.h
Ryan Malloy 3915d1784f Rename pg_orbit to pg_orrery
An existing product called PG Orbit (a mobile PostgreSQL client)
creates a naming conflict. pg_orrery — a database orrery built from
Keplerian parameters and SQL instead of brass gears.

Build system: control file, Makefile, Dockerfile, docker init script.
C source: GUC prefix, PG_FUNCTION_INFO_V1 symbol, header guards,
ereport prefixes, comments across ~30 files including vendored SGP4.
SQL: all 5 install/migration scripts, function name pg_orrery_ephemeris_info.
Tests: 9 SQL suites, 8 expected outputs, standalone DE reader test.
Documentation: CLAUDE.md, README.md, DESIGN.md, Starlight site infra,
36 MDX pages, OG renderer, logo SVG, docker-compose, agent threads.

All 13 regression suites pass. Docs site builds (37 pages).
2026-02-17 13:36:22 -07:00

111 lines
2.8 KiB
C

/*
* eph_provider.h -- Ephemeris provider dispatch for pg_orrery
*
* Manages the optional JPL DE ephemeris alongside the compiled-in
* VSOP87 and ELP2000-82B theories.
*
* Key design constraints:
* - Per-backend lazy initialization (never in _PG_init/postmaster)
* - ICRS equatorial -> ecliptic J2000 frame rotation at the boundary
* - Automatic VSOP87 fallback on any DE error
* - No shared state between PostgreSQL backends
*/
#ifndef PG_ORRERY_EPH_PROVIDER_H
#define PG_ORRERY_EPH_PROVIDER_H
#include "postgres.h"
#include "types.h"
/*
* Ephemeris provider identifiers.
*/
typedef enum
{
EPH_VSOP87, /* compiled-in VSOP87 / ELP2000-82B (always available) */
EPH_JPL_DE /* JPL DE binary file (optional, STABLE) */
} EphProvider;
/*
* Initialize the GUC variable (pg_orrery.ephemeris_path).
* Called from _PG_init(). Does NOT open the DE file.
*/
void eph_register_gucs(void);
/*
* Cleanup callback for on_proc_exit.
* Closes the DE file descriptor if open.
*/
void eph_cleanup(int code, Datum arg);
/*
* Attempt to initialize the DE reader for this backend.
* Returns true if DE is available and ready, false otherwise.
* On first call, opens the file and validates. On subsequent calls,
* returns cached status.
*
* Thread-safe per backend (each backend has its own static state).
*/
bool eph_de_available(void);
/*
* Which provider is currently active?
*/
EphProvider eph_current_provider(void);
/*
* Get the configured ephemeris file path (or NULL if not set).
*/
const char *eph_get_path(void);
/*
* Get planet heliocentric ecliptic J2000 position via DE.
*
* body_id: pg_orrery body ID (1=Mercury..8=Neptune)
* jd: Julian date (TDB)
* xyz[6]: output position (AU) in ecliptic J2000 frame
* (xyz[3..5] are zero — velocity not yet implemented)
*
* Returns true on success. On failure, xyz is unchanged and
* caller should fall back to VSOP87.
*/
bool eph_de_planet(int body_id, double jd, double xyz[6]);
/*
* Get Earth heliocentric ecliptic J2000 position via DE.
*
* jd: Julian date (TDB)
* xyz[6]: output position (AU) in ecliptic J2000 frame
*
* Returns true on success.
*/
bool eph_de_earth(double jd, double xyz[6]);
/*
* Get Moon geocentric ecliptic J2000 position via DE.
*
* jd: Julian date (TDB)
* xyz[3]: output position (AU) in ecliptic J2000 frame
*
* Returns true on success. On failure, caller falls back to ELP2000-82B.
*/
bool eph_de_moon(double jd, double xyz[3]);
/*
* Get Sun "heliocentric" position (always 0,0,0 but consistent API).
*/
bool eph_de_sun(double jd, double xyz[6]);
/*
* DE metadata accessors (for pg_orrery_ephemeris_info).
* Return 0/0.0 if DE is not loaded.
*/
double eph_de_start_jd(void);
double eph_de_end_jd(void);
int eph_de_version(void);
double eph_de_au_km(void);
#endif /* PG_ORRERY_EPH_PROVIDER_H */