Skip to main content

oxigdal_postgis/
lib.rs

1//! OxiGDAL PostGIS - PostgreSQL/PostGIS Integration
2//!
3//! This crate provides PostgreSQL/PostGIS integration for the OxiGDAL ecosystem,
4//! enabling spatial database workflows with connection pooling and async operations.
5//!
6//! # Features
7//!
8//! - **Connection Pooling**: Efficient connection management with deadpool-postgres
9//! - **Spatial Queries**: Fluent API for building spatial queries
10//! - **Streaming**: Stream large result sets efficiently
11//! - **Batch Operations**: Batch inserts for high performance
12//! - **Transaction Support**: Full transaction management with savepoints
13//! - **Type Safety**: Strong type conversions between OxiGDAL and PostGIS
14//! - **WKB Support**: Efficient Well-Known Binary encoding/decoding
15//!
16//! # Example
17//!
18//! ```ignore
19//! use oxigdal_postgis::*;
20//! use oxigdal_core::types::BoundingBox;
21//!
22//! # async fn example() -> Result<()> {
23//! // Create connection pool
24//! let config = ConnectionConfig::new("gis_database")
25//!     .host("localhost")
26//!     .user("postgres")
27//!     .password("password");
28//!
29//! let pool = ConnectionPool::new(config)?;
30//!
31//! // Check PostGIS is available
32//! let health = pool.health_check().await?;
33//! if !health.postgis_installed {
34//!     eprintln!("PostGIS is not installed!");
35//!     return Ok(());
36//! }
37//!
38//! // Query features within bounding box
39//! let bbox = BoundingBox::new(-180.0, -90.0, 180.0, 90.0)?;
40//! let features = SpatialQuery::new("buildings")?
41//!     .where_bbox(&bbox)?
42//!     .limit(1000)
43//!     .execute(&pool)
44//!     .await?;
45//!
46//! println!("Found {} features", features.len());
47//!
48//! // Write features to database
49//! let mut writer = PostGisWriter::new(pool.clone(), "results")
50//!     .srid(4326)
51//!     .create_table(true);
52//!
53//! for feature in features {
54//!     writer.add_to_batch(feature);
55//! }
56//! writer.flush().await?;
57//! # Ok(())
58//! # }
59//! ```
60//!
61//! # SQL Injection Prevention
62//!
63//! All SQL generation is protected against SQL injection attacks through:
64//! - Parameterized queries
65//! - Identifier validation and quoting
66//! - Safe SQL builders
67//!
68//! # Performance
69//!
70//! - Connection pooling reduces connection overhead
71//! - Batch operations improve write performance
72//! - Streaming API supports large datasets
73//! - Spatial indexes are automatically used
74//!
75//! # Requirements
76//!
77//! - PostgreSQL 12 or later
78//! - PostGIS 3.0 or later
79
80#![warn(missing_docs)]
81#![warn(clippy::all)]
82// Pedantic disabled to reduce noise - default clippy::all is sufficient
83// #![warn(clippy::pedantic)]
84#![deny(clippy::unwrap_used)]
85#![allow(clippy::module_name_repetitions)]
86// Allow collapsible match for explicit SQL building patterns
87#![allow(clippy::collapsible_match)]
88#![allow(clippy::collapsible_if)]
89// Allow expect() for internal database state invariants
90#![allow(clippy::expect_used)]
91// Allow async fn in traits for database operations
92#![allow(async_fn_in_trait)]
93// Allow dead code for future features
94#![allow(dead_code)]
95// Allow unsafe blocks in transaction module for FFI
96#![allow(unsafe_code)]
97
98pub mod connection;
99pub mod error;
100pub mod query;
101pub mod reader;
102pub mod sql;
103pub mod transaction;
104pub mod types;
105pub mod wkb;
106pub mod writer;
107
108// Re-export commonly used items
109pub use connection::{ConnectionConfig, ConnectionPool, HealthCheckResult, PoolConfig, SslMode};
110pub use error::{PostGisError, Result};
111pub use query::{JoinType, SpatialJoin, SpatialQuery};
112pub use reader::PostGisReader;
113pub use sql::functions;
114pub use transaction::Transaction;
115pub use types::{FeatureBuilder, PostGisGeometry, srid};
116pub use wkb::{ByteOrder, WkbDecoder, WkbEncoder, WkbGeometryType};
117pub use writer::PostGisWriter;
118
119/// Crate version
120pub const VERSION: &str = env!("CARGO_PKG_VERSION");
121
122/// Crate name
123pub const NAME: &str = env!("CARGO_PKG_NAME");
124
125#[cfg(test)]
126mod tests {
127    use super::*;
128
129    #[test]
130    fn test_version() {
131        assert!(!VERSION.is_empty());
132        assert_eq!(NAME, "oxigdal-postgis");
133    }
134}