DBBuilder

Struct DBBuilder 

Source
pub struct DBBuilder { /* private fields */ }
Expand description

Builder for creating database instances with custom configuration.

The DBBuilder provides a flexible way to configure databases with options for:

  • Custom AOF (Append-Only File) paths separate from the logical database path
  • In-memory databases
  • Full configuration control
  • Automatic startup replay

§Examples

§Basic usage with custom AOF path

use spatio::DBBuilder;

let temp_path = std::env::temp_dir().join("test_db.aof");
let db = DBBuilder::new()
    .aof_path(&temp_path)
    .build()?;

db.insert("key", b"value", None)?;

§In-memory database

use spatio::DBBuilder;

let db = DBBuilder::new()
    .in_memory()
    .build()?;

§Full configuration

use spatio::{DBBuilder, Config, SyncPolicy};
use std::time::Duration;

let config = Config::with_geohash_precision(10)
    .with_sync_policy(SyncPolicy::Always)
    .with_default_ttl(Duration::from_secs(3600));

let temp_path = std::env::temp_dir().join("high_precision.aof");
let db = DBBuilder::new()
    .aof_path(&temp_path)
    .config(config)
    .build()?;

Implementations§

Source§

impl DBBuilder

Source

pub fn new() -> Self

Create a new database builder with default configuration.

By default, creates an in-memory database. Use aof_path() to enable persistence.

§Examples
use spatio::DBBuilder;

let builder = DBBuilder::new();
Examples found in repository?
examples/persistence_lifecycle.rs (line 96)
88fn demo_custom_aof_path() -> Result<(), Box<dyn std::error::Error>> {
89    println!("--- Demo 2: Custom AOF Path ---");
90
91    let aof_path = "/tmp/spatio_custom.aof";
92
93    // First session: Create database with custom AOF path
94    {
95        println!("Session 1: Creating database with custom AOF path...");
96        let db = DBBuilder::new().aof_path(aof_path).build()?;
97
98        db.insert("config:version", b"1.0.0", None)?;
99        db.insert("config:environment", b"production", None)?;
100
101        println!("  ✓ AOF file: {}", aof_path);
102        println!("  ✓ Inserted configuration data");
103
104        // Force sync to ensure data is on disk
105        db.sync()?;
106        println!("  ✓ Manually synced to disk");
107    }
108
109    // Second session: Reopen with same AOF path
110    {
111        println!("Session 2: Reopening database...");
112        let db = DBBuilder::new().aof_path(aof_path).build()?;
113
114        let version = db.get("config:version")?.unwrap();
115        let environment = db.get("config:environment")?.unwrap();
116
117        println!("  ✓ Version: {}", String::from_utf8_lossy(&version));
118        println!("  ✓ Environment: {}", String::from_utf8_lossy(&environment));
119    }
120
121    println!();
122    Ok(())
123}
124
125/// Demo 3: Spatial data persistence and index reconstruction
126fn demo_spatial_persistence() -> Result<(), Box<dyn std::error::Error>> {
127    println!("--- Demo 3: Spatial Data Persistence ---");
128
129    let db_path = "/tmp/spatio_demo_spatial.db";
130
131    // First session: Insert spatial data
132    {
133        println!("Session 1: Inserting spatial data...");
134        let db = Spatio::open(db_path)?;
135
136        // Insert major cities
137        let cities = vec![
138            ("New York", Point::new(40.7128, -74.0060)),
139            ("Los Angeles", Point::new(34.0522, -118.2437)),
140            ("Chicago", Point::new(41.8781, -87.6298)),
141            ("Houston", Point::new(29.7604, -95.3698)),
142            ("Phoenix", Point::new(33.4484, -112.0740)),
143        ];
144
145        for (name, point) in cities {
146            db.insert_point("cities", &point, name.as_bytes(), None)?;
147            println!("  ✓ Inserted city: {}", name);
148        }
149
150        let stats = db.stats()?;
151        println!("  ✓ Total keys: {}", stats.key_count);
152    }
153
154    // Second session: Query spatial data (indexes automatically rebuilt)
155    {
156        println!("Session 2: Querying spatial data (indexes rebuilt)...");
157        let db = Spatio::open(db_path)?;
158
159        // Find cities near New York
160        let nyc = Point::new(40.7128, -74.0060);
161        let nearby = db.query_within_radius("cities", &nyc, 500_000.0, 10)?; // 500km radius
162
163        println!(
164            "  ✓ Found {} cities within 500km of New York:",
165            nearby.len()
166        );
167        for (point, data) in nearby {
168            let name = String::from_utf8_lossy(&data);
169            println!("    - {} at ({:.4}, {:.4})", name, point.lat, point.lon);
170        }
171
172        // Count cities in a bounding box
173        let count = db.count_within_radius("cities", &nyc, 500_000.0)?;
174        println!("  ✓ Count verification: {} cities", count);
175    }
176
177    println!();
178    Ok(())
179}
180
181/// Demo 4: Explicit graceful shutdown with error handling
182fn demo_graceful_shutdown() -> Result<(), Box<dyn std::error::Error>> {
183    println!("--- Demo 4: Graceful Shutdown ---");
184
185    let db_path = "/tmp/spatio_demo_shutdown.db";
186
187    println!("Creating database and inserting critical data...");
188    let mut db = Spatio::open(db_path)?;
189
190    // Insert critical data
191    db.insert("transaction:001", b"payment_processed", None)?;
192    db.insert("transaction:002", b"refund_pending", None)?;
193
194    println!("  ✓ Critical data inserted");
195
196    // Force sync before critical operations
197    db.sync()?;
198    println!("  ✓ Forced sync to disk");
199
200    // Add TTL data
201    let opts = SetOptions::with_ttl(Duration::from_secs(300));
202    db.insert("session:xyz", b"temporary_session", Some(opts))?;
203    println!("  ✓ Added temporary session with 5-minute TTL");
204
205    // Explicit close with error handling
206    println!("Performing explicit graceful shutdown...");
207    match db.close() {
208        Ok(_) => println!("  ✓ Database closed successfully"),
209        Err(e) => {
210            eprintln!("  ✗ Error during close: {}", e);
211            return Err(e.into());
212        }
213    }
214
215    // Verify we can't use closed database
216    match db.insert("should_fail", b"data", None) {
217        Err(e) => println!("  ✓ Correctly rejected operation on closed database: {}", e),
218        Ok(_) => println!("  ✗ Unexpectedly accepted operation on closed database"),
219    }
220
221    println!();
222    Ok(())
223}
224
225/// Demo 5: Configuration-based persistence with different sync policies
226fn demo_config_based_persistence() -> Result<(), Box<dyn std::error::Error>> {
227    println!("--- Demo 5: Configuration-Based Persistence ---");
228
229    // High-durability configuration (sync always)
230    {
231        println!("Config 1: Always sync (maximum durability)");
232        let config = Config::default().with_sync_policy(SyncPolicy::Always);
233
234        let db = DBBuilder::new()
235            .aof_path("/tmp/spatio_always_sync.aof")
236            .config(config)
237            .build()?;
238
239        db.insert("critical:data", b"financial_transaction", None)?;
240        println!("  ✓ Every write immediately synced to disk");
241    }
242
243    // Balanced configuration (sync every second)
244    {
245        println!("Config 2: Sync every second (recommended)");
246        let config = Config::with_geohash_precision(10)
247            .with_sync_policy(SyncPolicy::EverySecond)
248            .with_default_ttl(Duration::from_secs(3600));
249
250        let db = DBBuilder::new()
251            .aof_path("/tmp/spatio_balanced.aof")
252            .config(config)
253            .build()?;
254
255        db.insert("balanced:data", b"application_data", None)?;
256        println!("  ✓ High precision (10) with periodic sync");
257        println!("  ✓ Default TTL: 1 hour");
258    }
259
260    // In-memory configuration (no persistence)
261    {
262        println!("Config 3: In-memory (no persistence)");
263        let db = DBBuilder::new().in_memory().build()?;
264
265        db.insert("cache:key", b"temporary_value", None)?;
266        println!("  ✓ Fast in-memory storage, no disk I/O");
267    }
268
269    println!();
270    Ok(())
271}
Source

pub fn aof_path<P: Into<PathBuf>>(self, path: P) -> Self

Set the AOF (Append-Only File) path for persistence.

When an AOF path is set:

  • The database will persist all writes to this file
  • On startup, the AOF will be replayed to restore state
  • The database is durable across restarts

If the file doesn’t exist, it will be created. If it exists, it will be opened and replayed to restore previous state.

§Arguments
  • path - File system path for the AOF file
§Examples
use spatio::DBBuilder;

let temp_path = std::env::temp_dir().join("myapp_data.aof");
let db = DBBuilder::new()
    .aof_path(&temp_path)
    .build()?;
Examples found in repository?
examples/persistence_lifecycle.rs (line 96)
88fn demo_custom_aof_path() -> Result<(), Box<dyn std::error::Error>> {
89    println!("--- Demo 2: Custom AOF Path ---");
90
91    let aof_path = "/tmp/spatio_custom.aof";
92
93    // First session: Create database with custom AOF path
94    {
95        println!("Session 1: Creating database with custom AOF path...");
96        let db = DBBuilder::new().aof_path(aof_path).build()?;
97
98        db.insert("config:version", b"1.0.0", None)?;
99        db.insert("config:environment", b"production", None)?;
100
101        println!("  ✓ AOF file: {}", aof_path);
102        println!("  ✓ Inserted configuration data");
103
104        // Force sync to ensure data is on disk
105        db.sync()?;
106        println!("  ✓ Manually synced to disk");
107    }
108
109    // Second session: Reopen with same AOF path
110    {
111        println!("Session 2: Reopening database...");
112        let db = DBBuilder::new().aof_path(aof_path).build()?;
113
114        let version = db.get("config:version")?.unwrap();
115        let environment = db.get("config:environment")?.unwrap();
116
117        println!("  ✓ Version: {}", String::from_utf8_lossy(&version));
118        println!("  ✓ Environment: {}", String::from_utf8_lossy(&environment));
119    }
120
121    println!();
122    Ok(())
123}
124
125/// Demo 3: Spatial data persistence and index reconstruction
126fn demo_spatial_persistence() -> Result<(), Box<dyn std::error::Error>> {
127    println!("--- Demo 3: Spatial Data Persistence ---");
128
129    let db_path = "/tmp/spatio_demo_spatial.db";
130
131    // First session: Insert spatial data
132    {
133        println!("Session 1: Inserting spatial data...");
134        let db = Spatio::open(db_path)?;
135
136        // Insert major cities
137        let cities = vec![
138            ("New York", Point::new(40.7128, -74.0060)),
139            ("Los Angeles", Point::new(34.0522, -118.2437)),
140            ("Chicago", Point::new(41.8781, -87.6298)),
141            ("Houston", Point::new(29.7604, -95.3698)),
142            ("Phoenix", Point::new(33.4484, -112.0740)),
143        ];
144
145        for (name, point) in cities {
146            db.insert_point("cities", &point, name.as_bytes(), None)?;
147            println!("  ✓ Inserted city: {}", name);
148        }
149
150        let stats = db.stats()?;
151        println!("  ✓ Total keys: {}", stats.key_count);
152    }
153
154    // Second session: Query spatial data (indexes automatically rebuilt)
155    {
156        println!("Session 2: Querying spatial data (indexes rebuilt)...");
157        let db = Spatio::open(db_path)?;
158
159        // Find cities near New York
160        let nyc = Point::new(40.7128, -74.0060);
161        let nearby = db.query_within_radius("cities", &nyc, 500_000.0, 10)?; // 500km radius
162
163        println!(
164            "  ✓ Found {} cities within 500km of New York:",
165            nearby.len()
166        );
167        for (point, data) in nearby {
168            let name = String::from_utf8_lossy(&data);
169            println!("    - {} at ({:.4}, {:.4})", name, point.lat, point.lon);
170        }
171
172        // Count cities in a bounding box
173        let count = db.count_within_radius("cities", &nyc, 500_000.0)?;
174        println!("  ✓ Count verification: {} cities", count);
175    }
176
177    println!();
178    Ok(())
179}
180
181/// Demo 4: Explicit graceful shutdown with error handling
182fn demo_graceful_shutdown() -> Result<(), Box<dyn std::error::Error>> {
183    println!("--- Demo 4: Graceful Shutdown ---");
184
185    let db_path = "/tmp/spatio_demo_shutdown.db";
186
187    println!("Creating database and inserting critical data...");
188    let mut db = Spatio::open(db_path)?;
189
190    // Insert critical data
191    db.insert("transaction:001", b"payment_processed", None)?;
192    db.insert("transaction:002", b"refund_pending", None)?;
193
194    println!("  ✓ Critical data inserted");
195
196    // Force sync before critical operations
197    db.sync()?;
198    println!("  ✓ Forced sync to disk");
199
200    // Add TTL data
201    let opts = SetOptions::with_ttl(Duration::from_secs(300));
202    db.insert("session:xyz", b"temporary_session", Some(opts))?;
203    println!("  ✓ Added temporary session with 5-minute TTL");
204
205    // Explicit close with error handling
206    println!("Performing explicit graceful shutdown...");
207    match db.close() {
208        Ok(_) => println!("  ✓ Database closed successfully"),
209        Err(e) => {
210            eprintln!("  ✗ Error during close: {}", e);
211            return Err(e.into());
212        }
213    }
214
215    // Verify we can't use closed database
216    match db.insert("should_fail", b"data", None) {
217        Err(e) => println!("  ✓ Correctly rejected operation on closed database: {}", e),
218        Ok(_) => println!("  ✗ Unexpectedly accepted operation on closed database"),
219    }
220
221    println!();
222    Ok(())
223}
224
225/// Demo 5: Configuration-based persistence with different sync policies
226fn demo_config_based_persistence() -> Result<(), Box<dyn std::error::Error>> {
227    println!("--- Demo 5: Configuration-Based Persistence ---");
228
229    // High-durability configuration (sync always)
230    {
231        println!("Config 1: Always sync (maximum durability)");
232        let config = Config::default().with_sync_policy(SyncPolicy::Always);
233
234        let db = DBBuilder::new()
235            .aof_path("/tmp/spatio_always_sync.aof")
236            .config(config)
237            .build()?;
238
239        db.insert("critical:data", b"financial_transaction", None)?;
240        println!("  ✓ Every write immediately synced to disk");
241    }
242
243    // Balanced configuration (sync every second)
244    {
245        println!("Config 2: Sync every second (recommended)");
246        let config = Config::with_geohash_precision(10)
247            .with_sync_policy(SyncPolicy::EverySecond)
248            .with_default_ttl(Duration::from_secs(3600));
249
250        let db = DBBuilder::new()
251            .aof_path("/tmp/spatio_balanced.aof")
252            .config(config)
253            .build()?;
254
255        db.insert("balanced:data", b"application_data", None)?;
256        println!("  ✓ High precision (10) with periodic sync");
257        println!("  ✓ Default TTL: 1 hour");
258    }
259
260    // In-memory configuration (no persistence)
261    {
262        println!("Config 3: In-memory (no persistence)");
263        let db = DBBuilder::new().in_memory().build()?;
264
265        db.insert("cache:key", b"temporary_value", None)?;
266        println!("  ✓ Fast in-memory storage, no disk I/O");
267    }
268
269    println!();
270    Ok(())
271}
Source

pub fn in_memory(self) -> Self

Create an in-memory database with no persistence.

In-memory databases:

  • Are extremely fast (no disk I/O)
  • Do not persist data across restarts
  • Are ideal for caching, testing, and ephemeral data
§Examples
use spatio::DBBuilder;

let db = DBBuilder::new()
    .in_memory()
    .build()?;
Examples found in repository?
examples/persistence_lifecycle.rs (line 263)
226fn demo_config_based_persistence() -> Result<(), Box<dyn std::error::Error>> {
227    println!("--- Demo 5: Configuration-Based Persistence ---");
228
229    // High-durability configuration (sync always)
230    {
231        println!("Config 1: Always sync (maximum durability)");
232        let config = Config::default().with_sync_policy(SyncPolicy::Always);
233
234        let db = DBBuilder::new()
235            .aof_path("/tmp/spatio_always_sync.aof")
236            .config(config)
237            .build()?;
238
239        db.insert("critical:data", b"financial_transaction", None)?;
240        println!("  ✓ Every write immediately synced to disk");
241    }
242
243    // Balanced configuration (sync every second)
244    {
245        println!("Config 2: Sync every second (recommended)");
246        let config = Config::with_geohash_precision(10)
247            .with_sync_policy(SyncPolicy::EverySecond)
248            .with_default_ttl(Duration::from_secs(3600));
249
250        let db = DBBuilder::new()
251            .aof_path("/tmp/spatio_balanced.aof")
252            .config(config)
253            .build()?;
254
255        db.insert("balanced:data", b"application_data", None)?;
256        println!("  ✓ High precision (10) with periodic sync");
257        println!("  ✓ Default TTL: 1 hour");
258    }
259
260    // In-memory configuration (no persistence)
261    {
262        println!("Config 3: In-memory (no persistence)");
263        let db = DBBuilder::new().in_memory().build()?;
264
265        db.insert("cache:key", b"temporary_value", None)?;
266        println!("  ✓ Fast in-memory storage, no disk I/O");
267    }
268
269    println!();
270    Ok(())
271}
Source

pub fn config(self, config: Config) -> Self

Set the database configuration.

The configuration controls:

  • Geohash precision for spatial indexing
  • Sync policy (durability vs performance tradeoff)
  • Default TTL for automatic expiration
§Arguments
  • config - Database configuration
§Examples
use spatio::{DBBuilder, Config, SyncPolicy};
use std::time::Duration;

let config = Config::with_geohash_precision(10)
    .with_sync_policy(SyncPolicy::Always)
    .with_default_ttl(Duration::from_secs(3600));

let temp_path = std::env::temp_dir().join("high_precision.aof");
let db = DBBuilder::new()
    .aof_path(&temp_path)
    .config(config)
    .build()?;
Examples found in repository?
examples/persistence_lifecycle.rs (line 236)
226fn demo_config_based_persistence() -> Result<(), Box<dyn std::error::Error>> {
227    println!("--- Demo 5: Configuration-Based Persistence ---");
228
229    // High-durability configuration (sync always)
230    {
231        println!("Config 1: Always sync (maximum durability)");
232        let config = Config::default().with_sync_policy(SyncPolicy::Always);
233
234        let db = DBBuilder::new()
235            .aof_path("/tmp/spatio_always_sync.aof")
236            .config(config)
237            .build()?;
238
239        db.insert("critical:data", b"financial_transaction", None)?;
240        println!("  ✓ Every write immediately synced to disk");
241    }
242
243    // Balanced configuration (sync every second)
244    {
245        println!("Config 2: Sync every second (recommended)");
246        let config = Config::with_geohash_precision(10)
247            .with_sync_policy(SyncPolicy::EverySecond)
248            .with_default_ttl(Duration::from_secs(3600));
249
250        let db = DBBuilder::new()
251            .aof_path("/tmp/spatio_balanced.aof")
252            .config(config)
253            .build()?;
254
255        db.insert("balanced:data", b"application_data", None)?;
256        println!("  ✓ High precision (10) with periodic sync");
257        println!("  ✓ Default TTL: 1 hour");
258    }
259
260    // In-memory configuration (no persistence)
261    {
262        println!("Config 3: In-memory (no persistence)");
263        let db = DBBuilder::new().in_memory().build()?;
264
265        db.insert("cache:key", b"temporary_value", None)?;
266        println!("  ✓ Fast in-memory storage, no disk I/O");
267    }
268
269    println!();
270    Ok(())
271}
Source

pub fn history_capacity(self, capacity: usize) -> Self

Enable update history tracking with a fixed per-key capacity.

Each key retains at most capacity recent operations (set/delete).

Source

pub fn build(self) -> Result<DB>

Build the database with the configured options.

This method:

  1. Creates the database instance
  2. Opens the AOF file (if persistence is enabled)
  3. Replays the AOF to restore previous state (startup replay)
  4. Rebuilds spatial indexes
  5. Returns a ready-to-use database
§Errors

Returns an error if:

  • The AOF file cannot be opened or created
  • The AOF file is corrupted and cannot be replayed
  • File system permissions prevent access
§Examples
use spatio::DBBuilder;

let temp_path = std::env::temp_dir().join("my_data.aof");
let db = DBBuilder::new()
    .aof_path(&temp_path)
    .build()?;

db.insert("key", b"value", None)?;
Examples found in repository?
examples/persistence_lifecycle.rs (line 96)
88fn demo_custom_aof_path() -> Result<(), Box<dyn std::error::Error>> {
89    println!("--- Demo 2: Custom AOF Path ---");
90
91    let aof_path = "/tmp/spatio_custom.aof";
92
93    // First session: Create database with custom AOF path
94    {
95        println!("Session 1: Creating database with custom AOF path...");
96        let db = DBBuilder::new().aof_path(aof_path).build()?;
97
98        db.insert("config:version", b"1.0.0", None)?;
99        db.insert("config:environment", b"production", None)?;
100
101        println!("  ✓ AOF file: {}", aof_path);
102        println!("  ✓ Inserted configuration data");
103
104        // Force sync to ensure data is on disk
105        db.sync()?;
106        println!("  ✓ Manually synced to disk");
107    }
108
109    // Second session: Reopen with same AOF path
110    {
111        println!("Session 2: Reopening database...");
112        let db = DBBuilder::new().aof_path(aof_path).build()?;
113
114        let version = db.get("config:version")?.unwrap();
115        let environment = db.get("config:environment")?.unwrap();
116
117        println!("  ✓ Version: {}", String::from_utf8_lossy(&version));
118        println!("  ✓ Environment: {}", String::from_utf8_lossy(&environment));
119    }
120
121    println!();
122    Ok(())
123}
124
125/// Demo 3: Spatial data persistence and index reconstruction
126fn demo_spatial_persistence() -> Result<(), Box<dyn std::error::Error>> {
127    println!("--- Demo 3: Spatial Data Persistence ---");
128
129    let db_path = "/tmp/spatio_demo_spatial.db";
130
131    // First session: Insert spatial data
132    {
133        println!("Session 1: Inserting spatial data...");
134        let db = Spatio::open(db_path)?;
135
136        // Insert major cities
137        let cities = vec![
138            ("New York", Point::new(40.7128, -74.0060)),
139            ("Los Angeles", Point::new(34.0522, -118.2437)),
140            ("Chicago", Point::new(41.8781, -87.6298)),
141            ("Houston", Point::new(29.7604, -95.3698)),
142            ("Phoenix", Point::new(33.4484, -112.0740)),
143        ];
144
145        for (name, point) in cities {
146            db.insert_point("cities", &point, name.as_bytes(), None)?;
147            println!("  ✓ Inserted city: {}", name);
148        }
149
150        let stats = db.stats()?;
151        println!("  ✓ Total keys: {}", stats.key_count);
152    }
153
154    // Second session: Query spatial data (indexes automatically rebuilt)
155    {
156        println!("Session 2: Querying spatial data (indexes rebuilt)...");
157        let db = Spatio::open(db_path)?;
158
159        // Find cities near New York
160        let nyc = Point::new(40.7128, -74.0060);
161        let nearby = db.query_within_radius("cities", &nyc, 500_000.0, 10)?; // 500km radius
162
163        println!(
164            "  ✓ Found {} cities within 500km of New York:",
165            nearby.len()
166        );
167        for (point, data) in nearby {
168            let name = String::from_utf8_lossy(&data);
169            println!("    - {} at ({:.4}, {:.4})", name, point.lat, point.lon);
170        }
171
172        // Count cities in a bounding box
173        let count = db.count_within_radius("cities", &nyc, 500_000.0)?;
174        println!("  ✓ Count verification: {} cities", count);
175    }
176
177    println!();
178    Ok(())
179}
180
181/// Demo 4: Explicit graceful shutdown with error handling
182fn demo_graceful_shutdown() -> Result<(), Box<dyn std::error::Error>> {
183    println!("--- Demo 4: Graceful Shutdown ---");
184
185    let db_path = "/tmp/spatio_demo_shutdown.db";
186
187    println!("Creating database and inserting critical data...");
188    let mut db = Spatio::open(db_path)?;
189
190    // Insert critical data
191    db.insert("transaction:001", b"payment_processed", None)?;
192    db.insert("transaction:002", b"refund_pending", None)?;
193
194    println!("  ✓ Critical data inserted");
195
196    // Force sync before critical operations
197    db.sync()?;
198    println!("  ✓ Forced sync to disk");
199
200    // Add TTL data
201    let opts = SetOptions::with_ttl(Duration::from_secs(300));
202    db.insert("session:xyz", b"temporary_session", Some(opts))?;
203    println!("  ✓ Added temporary session with 5-minute TTL");
204
205    // Explicit close with error handling
206    println!("Performing explicit graceful shutdown...");
207    match db.close() {
208        Ok(_) => println!("  ✓ Database closed successfully"),
209        Err(e) => {
210            eprintln!("  ✗ Error during close: {}", e);
211            return Err(e.into());
212        }
213    }
214
215    // Verify we can't use closed database
216    match db.insert("should_fail", b"data", None) {
217        Err(e) => println!("  ✓ Correctly rejected operation on closed database: {}", e),
218        Ok(_) => println!("  ✗ Unexpectedly accepted operation on closed database"),
219    }
220
221    println!();
222    Ok(())
223}
224
225/// Demo 5: Configuration-based persistence with different sync policies
226fn demo_config_based_persistence() -> Result<(), Box<dyn std::error::Error>> {
227    println!("--- Demo 5: Configuration-Based Persistence ---");
228
229    // High-durability configuration (sync always)
230    {
231        println!("Config 1: Always sync (maximum durability)");
232        let config = Config::default().with_sync_policy(SyncPolicy::Always);
233
234        let db = DBBuilder::new()
235            .aof_path("/tmp/spatio_always_sync.aof")
236            .config(config)
237            .build()?;
238
239        db.insert("critical:data", b"financial_transaction", None)?;
240        println!("  ✓ Every write immediately synced to disk");
241    }
242
243    // Balanced configuration (sync every second)
244    {
245        println!("Config 2: Sync every second (recommended)");
246        let config = Config::with_geohash_precision(10)
247            .with_sync_policy(SyncPolicy::EverySecond)
248            .with_default_ttl(Duration::from_secs(3600));
249
250        let db = DBBuilder::new()
251            .aof_path("/tmp/spatio_balanced.aof")
252            .config(config)
253            .build()?;
254
255        db.insert("balanced:data", b"application_data", None)?;
256        println!("  ✓ High precision (10) with periodic sync");
257        println!("  ✓ Default TTL: 1 hour");
258    }
259
260    // In-memory configuration (no persistence)
261    {
262        println!("Config 3: In-memory (no persistence)");
263        let db = DBBuilder::new().in_memory().build()?;
264
265        db.insert("cache:key", b"temporary_value", None)?;
266        println!("  ✓ Fast in-memory storage, no disk I/O");
267    }
268
269    println!();
270    Ok(())
271}

Trait Implementations§

Source§

impl Debug for DBBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for DBBuilder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<G1, G2> Within<G2> for G1
where G2: Contains<G1>,

Source§

fn is_within(&self, b: &G2) -> bool