Skip to main content

fraiseql_cli/schema/
advanced_types.rs

1//! Advanced type operators and SQL templates for Week 5.
2//!
3//! This module documents the implementation of advanced type operators
4//! that require specialized SQL generation or external libraries.
5//!
6//! # Geospatial Types (PostGIS)
7//!
8//! Geospatial operators require PostGIS extensions on PostgreSQL, or
9//! equivalent spatial functions on other databases.
10//!
11//! ## Coordinates Type
12//!
13//! Represents a single point with latitude and longitude.
14//!
15//! **Format**: JSON `{lat: float, lng: float}`
16//!
17//! **Operators**:
18//! - `distanceWithin`: Distance from point within radius (km)
19//! - `withinBoundingBox`: Point within rectangular bounding box
20//! - `withinPolygon`: Point within polygon (future enhancement)
21//!
22//! **Database Support**:
23//! - PostgreSQL: Native PostGIS support (ST_DWithin, ST_GeomFromText)
24//! - MySQL: Built-in spatial functions (ST_Distance_Sphere)
25//! - SQLite: Haversine formula approximation (no spatial library)
26//! - SQL Server: Native geography type (ST_Distance)
27//!
28//! **Example Query**:
29//! ```graphql
30//! query {
31//!   restaurants(
32//!     where: {
33//!       location: {
34//!         distanceWithin: {
35//!           latitude: 40.7128
36//!           longitude: -74.0060
37//!           radiusKm: 5
38//!         }
39//!       }
40//!     }
41//!   ) {
42//!     name
43//!   }
44//! }
45//! ```
46//!
47//! # Phone Number Type
48//!
49//! Phone number operators provide E.164 format validation and
50//! country code extraction.
51//!
52//! **Format**: E.164 string (e.g., "+14155552671")
53//!
54//! **Operators**:
55//! - `countryCodeEq`: Country code matches
56//! - `countryCodeIn`: Country code in list
57//! - `isValid`: Valid E.164 format (+[1-9]{1,3}[0-9]{1,14})
58//! - `typeEq`: Type classification (US, UK, OTHER)
59//!
60//! **Database Support**:
61//! - PostgreSQL: Regex matching with '^\\+[1-9]' pattern
62//! - MySQL: REGEXP operator with escaping
63//! - SQLite: GLOB patterns for basic matching
64//! - SQL Server: LIKE patterns for matching
65//!
66//! **Notes**:
67//! - Full phone validation (including carrier type) requires phonenumber-rs
68//! - Current implementation provides basic E.164 validation
69//! - Country code extraction assumes standard E.164 format
70//!
71//! **Example Query**:
72//! ```graphql
73//! query {
74//!   users(
75//!     where: {
76//!       phone: {
77//!         countryCodeEq: "+1"
78//!       }
79//!     }
80//!   ) {
81//!     phone
82//!   }
83//! }
84//! ```
85//!
86//! # Date Range Type
87//!
88//! Date range operators provide range analysis and overlap detection.
89//!
90//! **Format**: JSON with ISO 8601 dates
91//! ```json
92//! {
93//!   "start": "2024-01-01T00:00:00Z",
94//!   "end": "2024-12-31T23:59:59Z"
95//! }
96//! ```
97//!
98//! **Operators**:
99//! - `durationGte`: Total duration >= min days
100//! - `startsAfter`: Range starts after date
101//! - `endsBefore`: Range ends before date
102//! - `overlaps`: Overlaps with another date range
103//!
104//! **Database Support**:
105//! - PostgreSQL: Native timestamp and INTERVAL types
106//! - MySQL: DATEDIFF and date functions
107//! - SQLite: julianday for date arithmetic
108//! - SQL Server: DATEDIFF and datetime functions
109//!
110//! **Example Query**:
111//! ```graphql
112//! query {
113//!   projects(
114//!     where: {
115//!       timeline: {
116//!         durationGte: 90
117//!         overlaps: {
118//!           start: "2024-06-01T00:00:00Z"
119//!           end: "2024-08-31T23:59:59Z"
120//!         }
121//!       }
122//!     }
123//!   ) {
124//!     name
125//!     timeline {
126//!       start
127//!       end
128//!     }
129//!   }
130//! }
131//! ```
132//!
133//! # Duration Type
134//!
135//! Duration operators convert ISO 8601 durations to seconds/minutes
136//! for range queries.
137//!
138//! **Format**: ISO 8601 duration string
139//! - "P1Y2M3DT4H5M6S" (1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds)
140//! - "PT1H" (1 hour)
141//! - "PT30M" (30 minutes)
142//! - "PT45S" (45 seconds)
143//!
144//! **Operators**:
145//! - `totalSecondsEq`: Duration equals (in seconds)
146//! - `totalMinutesGte`: Duration >= min (in minutes)
147//!
148//! **Database Support**:
149//! - PostgreSQL: CAST to INTERVAL, then EXTRACT(EPOCH ...)
150//! - MySQL: Parse PT notation and cast to numeric
151//! - SQLite: Parse PT notation and cast to numeric
152//! - SQL Server: SUBSTRING to parse and cast
153//!
154//! **Example Query**:
155//! ```graphql
156//! query {
157//!   tasks(
158//!     where: {
159//!       estimatedTime: {
160//!         totalMinutesGte: 480
161//!       }
162//!     }
163//!   ) {
164//!     name
165//!     estimatedTime
166//!   }
167//! }
168//! ```
169//!
170//! # Implementation Status
171//!
172//! | Type | Operator | PostgreSQL | MySQL | SQLite | SQL Server | Status |
173//! |------|----------|-----------|-------|--------|------------|--------|
174//! | Coordinates | distanceWithin | ✅ PostGIS | ✅ | ⚠️ Approx | ✅ | Implemented |
175//! | Coordinates | withinBoundingBox | ✅ | ✅ | ✅ | ✅ | Implemented |
176//! | Phone | countryCodeEq | ✅ | ✅ | ✅ | ✅ | Implemented |
177//! | Phone | isValid | ✅ Regex | ✅ | ⚠️ Basic | ⚠️ Basic | Implemented |
178//! | DateRange | durationGte | ✅ | ✅ | ✅ | ✅ | Implemented |
179//! | DateRange | overlaps | ✅ | ✅ | ✅ | ✅ | Implemented |
180//! | Duration | totalSecondsEq | ✅ | ✅ | ✅ | ✅ | Implemented |
181//! | Duration | totalMinutesGte | ✅ | ✅ | ✅ | ✅ | Implemented |
182//!
183//! # Performance Considerations
184//!
185//! ## Geospatial Queries
186//! - PostGIS indexes (GIST/BRIN) required for performance
187//! - ST_DWithin uses index-aware distance calculation
188//! - Bounding box queries are generally fast (simple range checks)
189//!
190//! ## Date Range Queries
191//! - Indexes on start/end timestamp fields recommended
192//! - OVERLAP operations efficient with proper indexes
193//! - Use separate indexed columns for start/end instead of JSON
194//!
195//! ## Duration Parsing
196//! - ISO 8601 parsing done in SQL (no application overhead)
197//! - Regex validation in application layer (before SQL)
198//!
199//! # Limitations and Future Work
200//!
201//! ## Current Limitations
202//! - Phone validation limited to E.164 format (not carrier type)
203//! - SQLite geospatial using Haversine approximation (not exact)
204//! - No polygon containment without spatial extension
205//! - ISO 8601 duration parsing requires standard format
206//!
207//! ## Future Enhancements
208//! - Full phone number validation via phonenumber-rs library
209//! - PostGIS polygon operators (CoordinatesWithinPolygon)
210//! - Advanced date range operations (gaps, unions)
211//! - Time zone aware date operations
212//! - Route distance calculation (requires routing library)
213
214/// Marker type for documentation. This module documents advanced type
215/// operators but doesn't export any functions (implementation is in sql_templates.rs).
216// Reason: This is a documentation marker type that exists to organize module-level docs
217#[allow(dead_code)]
218pub struct AdvancedTypesDocumentation;
219
220#[cfg(test)]
221mod tests {
222    use super::*;
223
224    #[test]
225    fn test_documentation_exists() {
226        // This test ensures the documentation module compiles
227        let _ = AdvancedTypesDocumentation;
228    }
229}