jspg doc update

This commit is contained in:
2026-02-18 01:40:25 -05:00
parent 53a40d1099
commit 944675d669

View File

@ -18,7 +18,7 @@ The extension exposes the following functions to PostgreSQL:
### `cache_json_schemas(enums jsonb, types jsonb, puncs jsonb) -> jsonb` ### `cache_json_schemas(enums jsonb, types jsonb, puncs jsonb) -> jsonb`
Loads and compiles the entire schema registry into the session's memory. Loads and compiles the entire schema registry into the session's memory, atomically replacing the previous validator.
* **Inputs**: * **Inputs**:
* `enums`: Array of enum definitions. * `enums`: Array of enum definitions.
@ -80,7 +80,6 @@ JSPG enforces a "Secure by Default" philosophy. All schemas are treated as if `u
* **Ref Boundaries**: Strictness is reset when crossing `$ref` boundaries. The referenced schema's strictness is determined by its own definition (strict by default unless `extensible: true`), ignoring the caller's state. * **Ref Boundaries**: Strictness is reset when crossing `$ref` boundaries. The referenced schema's strictness is determined by its own definition (strict by default unless `extensible: true`), ignoring the caller's state.
* **Inheritance**: Strictness is inherited. A schema extending a strict parent will also be strict unless it declares itself `extensible: true`. Conversely, a schema extending a loose parent will also be loose unless it declares itself `extensible: false`. * **Inheritance**: Strictness is inherited. A schema extending a strict parent will also be strict unless it declares itself `extensible: true`. Conversely, a schema extending a loose parent will also be loose unless it declares itself `extensible: false`.
### 4. Format Leniency for Empty Strings ### 4. Format Leniency for Empty Strings
To simplify frontend form logic, the format validators for `uuid`, `date-time`, and `email` explicitly allow empty strings (`""`). This treats an empty string as "present but unset" rather than "invalid format". To simplify frontend form logic, the format validators for `uuid`, `date-time`, and `email` explicitly allow empty strings (`""`). This treats an empty string as "present but unset" rather than "invalid format".
@ -92,8 +91,18 @@ The extension is written in Rust using `pgrx` and structures its schema parser t
* **Compiler Phase**: schema JSONs are parsed into this struct, linked (references resolved), and then compiled into an efficient validation tree. * **Compiler Phase**: schema JSONs are parsed into this struct, linked (references resolved), and then compiled into an efficient validation tree.
* **Validation Phase**: The compiled validators traverse the JSON instance using `serde_json::Value`. * **Validation Phase**: The compiled validators traverse the JSON instance using `serde_json::Value`.
### Concurrency & Threading ("Atomic Swap")
To support high-throughput validation while allowing for runtime schema updates (e.g., during development or hot-reloading), JSPG uses an **Atomic Swap** pattern.
1. **Immutable Validator**: The `Validator` struct immutably owns the `Registry`. Once created, a validator instance (and its registry) never changes.
2. **Global Pointer**: A global `RwLock<Option<Arc<Validator>>>` holds the current active validator.
3. **Lock-Free Reads**: Validation requests acquire a read lock just long enough to clone the `Arc` (incrementing a reference count), then release the lock immediately. Validation proceeds on the snapshot, ensuring no blocking during schema updates.
4. **Atomic Updates**: When schemas are reloaded (`cache_json_schemas`), a new `Registry` and `Validator` are built entirely on the stack. The global pointer is then atomically swapped to the new instance under a write lock.
## 🧪 Testing ## 🧪 Testing
Testing is driven by standard Rust unit tests that load JSON fixtures. Testing is driven by standard Rust unit tests that load JSON fixtures.
The tests are located in `tests/fixtures/*.json` and are executed via `cargo test`. * **Isolation**: Each test file runs with its own isolated `Registry` and `Validator` instance, created on the stack. This eliminates global state interference and allows tests to run in parallel.
* **Fixtures**: The tests are located in `tests/fixtures/*.json` and are executed via `cargo test`.