# prefix-register
[](https://crates.io/crates/prefix-register)
[](https://docs.rs/prefix-register)
[](LICENSE)
**Status: Beta** - API may change before 1.0 release.
A PostgreSQL-backed namespace prefix registry for CURIE expansion and prefix management.
## Features
- **Async-only** - Built on tokio for high concurrency
- **In-memory caching** - Prefixes loaded on startup for fast CURIE expansion
- **First-prefix-wins** - Each URI can only have one registered prefix
- **Batch operations** - Efficiently store multiple prefixes at once
- **PostgreSQL backend** - Durable, scalable storage with connection pooling
## Use Cases
- CURIE expansion in RDF processing
- Namespace prefix management for semantic web applications
- Prefix discovery from Turtle, JSON-LD, XML documents
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
prefix-register = "0.1"
tokio = { version = "1", features = ["rt-multi-thread"] }
```
## Database Setup
Create the namespaces table in your PostgreSQL database:
```sql
CREATE TABLE IF NOT EXISTS namespaces (
uri TEXT PRIMARY KEY,
prefix TEXT NOT NULL UNIQUE
);
```
## Usage
```rust
use prefix_register::PrefixRegistry;
#[tokio::main]
async fn main() -> prefix_register::Result<()> {
// Connect to PostgreSQL
let registry = PrefixRegistry::new(
"postgres://localhost/mydb",
10, // max connections
).await?;
// Store a prefix (only if URI doesn't already have one)
let stored = registry.store_prefix_if_new(
"foaf",
"http://xmlns.com/foaf/0.1/"
).await?;
println!("Prefix stored: {}", stored);
// Expand a CURIE
if let Some(uri) = registry.expand_curie("foaf", "Person").await? {
println!("foaf:Person = {}", uri);
// Output: foaf:Person = http://xmlns.com/foaf/0.1/Person
}
// Batch store prefixes - returns detailed result for logging
let prefixes = vec![
("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"),
("rdfs", "http://www.w3.org/2000/01/rdf-schema#"),
("schema", "https://schema.org/"),
];
let result = registry.store_prefixes_if_new(prefixes).await?;
println!("Stored {}, skipped {}", result.stored, result.skipped);
Ok(())
}
```
## API
### PrefixRegistry
- `new(database_url, max_connections)` - Connect to PostgreSQL and load existing prefixes
- `get_uri_for_prefix(prefix)` - Get the URI for a prefix (cache-first)
- `get_prefix_for_uri(uri)` - Get the prefix for a URI
- `store_prefix_if_new(prefix, uri)` - Store a prefix if the URI doesn't have one (returns `bool`)
- `store_prefixes_if_new(prefixes)` - Batch store prefixes (returns `BatchStoreResult`)
- `expand_curie(prefix, local_name)` - Expand a CURIE to a full URI
- `get_all_prefixes()` - Get all registered prefix mappings
- `prefix_count()` - Get the number of registered prefixes
### BatchStoreResult
Returned by `store_prefixes_if_new()` for detailed reporting:
- `stored: usize` - Number of new prefixes stored
- `skipped: usize` - Number of prefixes skipped (URI already had a prefix)
- `total()` - Total prefixes processed
- `all_stored()` - Returns true if all were stored
- `none_stored()` - Returns true if none were stored
## License
Apache-2.0