uri_register/
lib.rs

1// Copyright TELICENT LTD
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! # URI Register
16//!
17//! A high-performance, async-first URI to integer registration service with PostgreSQL backend.
18//!
19//! This library provides a bidirectional mapping between URIs (strings) and integer IDs,
20//! optimised for batch operations and designed for use in distributed systems where
21//! stateless compute nodes need fast access to a global identifier registry.
22//!
23//! **Note:** This library is async-only and requires an async runtime (e.g., tokio).
24//! It is designed to mirror the API and behaviour of the Python `py-json-register` library.
25//!
26//! ## Features
27//!
28//! - **Async-only** - Built on tokio/sqlx for high concurrency
29//! - **Batch operations** - Efficiently lookup or create thousands of mappings at once
30//! - **PostgreSQL backend** - Durable, scalable, with connection pooling
31//! - **LRU caching** - In-memory cache for frequently accessed URIs
32//! - **Flexible table types** - Support for both logged (durable) and unlogged (faster) tables
33//!
34//! ## Use Cases
35//!
36//! - String interning systems
37//! - URL/URI deduplication and ID assignment
38//! - Global identifier systems
39//! - Any system needing global, persistent string-to-ID mappings
40//!
41//! ## Example
42//!
43//! ```rust,no_run
44//! use uri_register::{UriService, PostgresUriRegister};
45//!
46//! #[tokio::main]
47//! async fn main() -> uri_register::Result<()> {
48//!     // Connect to PostgreSQL (schema must be initialized first)
49//!     let register = PostgresUriRegister::new(
50//!         "postgres://localhost/mydb",
51//!         "uri_register",  // table name
52//!         20,              // max connections
53//!         10_000,          // cache size
54//!         3,               // max retries
55//!         100,             // initial backoff (ms)
56//!         5000             // max backoff (ms)
57//!     ).await?;
58//!
59//!     // Register a single URI
60//!     let id = register.register_uri("http://example.org/resource/1").await?;
61//!     println!("URI registered with ID: {}", id);
62//!
63//!     // Register multiple URIs in batch (much faster!)
64//!     let uris = vec![
65//!         "http://example.org/resource/2".to_string(),
66//!         "http://example.org/resource/3".to_string(),
67//!         "http://example.org/resource/4".to_string(),
68//!     ];
69//!     let ids = register.register_uri_batch(&uris).await?;
70//!
71//!     // IDs maintain order: ids[i] corresponds to uris[i]
72//!     for (uri, id) in uris.iter().zip(ids.iter()) {
73//!         println!("{} -> {}", uri, id);
74//!     }
75//!
76//!     Ok(())
77//! }
78//! ```
79
80mod error;
81mod postgres;
82mod service;
83
84#[cfg(any(test, feature = "test-utils"))]
85mod memory;
86
87#[cfg(feature = "python")]
88mod python;
89
90pub use error::{ConfigurationError, Error, Result};
91pub use postgres::{PostgresUriRegister, RegisterStats};
92pub use service::UriService;
93
94#[cfg(any(test, feature = "test-utils"))]
95pub use memory::InMemoryUriRegister;