jspg doc update
This commit is contained in:
15
GEMINI.md
15
GEMINI.md
@ -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`.
|
||||||
Reference in New Issue
Block a user