Skip to content
GitHubRSS

Stored Functions

BigBrotr uses 25 stored functions for all database mutations. Application code never executes raw INSERT, UPDATE, or DELETE statements. All functions accept bulk array parameters for batch efficiency.

FunctionPurpose
tags_to_tagvalues(JSONB)Converts JSONB tag arrays to a searchable TEXT[] format. Used by the tagvalues generated column on the event table.

These handle the core data operations — inserting relays, events, metadata, and service state.

Level 1 — Single-table operations:

FunctionPurpose
relay_insertInsert or update relays (bulk TEXT[], TEXT[], BIGINT[] arrays)
event_insertInsert events (bulk BYTEA[], INTEGER[], JSONB[], TEXT[] arrays)
metadata_insertInsert metadata objects (bulk BYTEA[], TEXT[], JSONB[] arrays)
event_relay_insertInsert event-relay associations
relay_metadata_insertInsert relay-metadata associations
service_state_upsertInsert or update service state checkpoints
service_state_getQuery service state (returns TABLE(state_key, state_value, updated_at))
service_state_deleteRemove service state entries

Level 2 — Cascade operations (atomic multi-table):

FunctionPurpose
event_relay_insert_cascadeAtomic insert across relay + event + event_relay
relay_metadata_insert_cascadeAtomic insert across relay + metadata + relay_metadata

Batched cleanup operations for removing orphaned data.

FunctionPurpose
orphan_metadata_deleteRemove metadata not referenced by any relay (configurable batch size)
orphan_event_deleteRemove events without relay associations (configurable batch size)

One refresh function per materialized view, plus a coordinated refresh-all function. Function names follow the <view_name>_refresh() pattern.

FunctionView
relay_metadata_latest_refreshLatest metadata per relay per type
event_stats_refreshGlobal event statistics
relay_stats_refreshPer-relay statistics
kind_counts_refreshEvent counts by kind
kind_counts_by_relay_refreshEvent counts by kind per relay
pubkey_counts_refreshUnique pubkey counts
pubkey_counts_by_relay_refreshUnique pubkeys per relay
network_stats_refreshPer-network statistics
relay_software_counts_refreshRelay software distribution
supported_nip_counts_refreshNIP support distribution
event_daily_counts_refreshDaily event counts
all_statistics_refreshRefresh all views in dependency order

All stored functions are called through Brotr._call_procedure(), which handles parameter serialization, timeout management, and error handling. Query functions in services/common/queries.py wrap these calls with domain-specific logic.

All CRUD functions accept PostgreSQL array parameters (TEXT[], BYTEA[], INTEGER[], BIGINT[], JSONB[]) for batch operations. This minimizes round trips — a single function call can insert hundreds of records.

All functions use SECURITY INVOKER (PostgreSQL default). They execute with the permissions of the calling user (writer or reader), not the function owner.