1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
//! # Query Building and Execution
//!
//! This module provides the core query building infrastructure for constructing complex
//! database queries using a fluent, chainable API. It implements the PostgREST query
//! specification for seamless integration with Supabase.
//!
//! ## 🏗️ Architecture
//!
//! The query system is built around several key components:
//! - **[`QueryBuilder`]**: Fluent API for chaining operations
//! - **[`Query`]**: Internal query state and parameter management
//! - **[`Filter`]**: Individual filter conditions with type-safe operators
//! - **[`Sort`]**: Sorting specifications with direction control
//!
//! ## 🎯 Design Philosophy
//!
//! - **Fluent Interface**: Method chaining for intuitive query construction
//! - **Type Safety**: Compile-time guarantees for query validity
//! - **Performance**: Efficient query string generation and HTTP request batching
//! - **Flexibility**: Support for complex filtering and sorting combinations
//!
//! ## 🔍 Query Components
//!
//! ### Filter Operations
//! | Operator | PostgREST | Description | Example |
//! |----------|-----------|-------------|---------|
//! | `Equals` | `eq` | Exact match | `age.eq=25` |
//! | `NotEquals` | `neq` | Not equal | `status.neq=inactive` |
//! | `GreaterThan` | `gt` | Greater than | `score.gt=100` |
//! | `LessThan` | `lt` | Less than | `price.lt=50` |
//! | `GreaterThanOrEquals` | `gte` | Greater or equal | `created_at.gte=2024-01-01` |
//! | `LessThanOrEquals` | `lte` | Less or equal | `updated_at.lte=2024-12-31` |
//!
//! ### Sort Operations
//! | Order | PostgREST | Description |
//! |-------|-----------|-------------|
//! | `Ascending` | `asc` | Smallest to largest |
//! | `Descending` | `desc` | Largest to smallest |
//!
//! ## 📖 Usage Examples
//!
//! ### Basic Query Construction
//!
//! ```rust,no_run
//! use supabase_rs::query::{Filter, Operator, Query, Sort, SortOrder};
//!
//! # fn example() -> Result<(), String> {
//! // Build a query manually (low-level API)
//! let mut query = Query::new();
//!
//! // Add a filter: age > 18
//! let age_filter = Filter {
//! column: "age".to_string(),
//! operator: Operator::GreaterThan,
//! value: "18".to_string(),
//! };
//! query.add_filter(age_filter);
//!
//! // Add sorting: name ascending
//! let name_sort = Sort {
//! column: "name".to_string(),
//! order: SortOrder::Ascending,
//! };
//! query.add_sort(name_sort);
//!
//! // Build the query string
//! let query_string = query.build();
//! println!("Generated query: {}", query_string);
//! # Ok(())
//! # }
//! ```
//!
//! ### Fluent API Usage (Recommended)
//!
//! ```rust,no_run
//! use supabase_rs::SupabaseClient;
//! use serde_json::Value;
//!
//! # async fn example() -> Result<(), String> {
//! # let client = SupabaseClient::new("url".to_string(), "key".to_string()).unwrap();
//! // Use the fluent QueryBuilder API (high-level, recommended)
//! let results: Vec<Value> = client
//! .select("users") // Start query
//! .gte("age", "18") // Add filter
//! .eq("verified", "true") // Add another filter
//! .order("created_at", false) // Sort by created_at desc
//! .limit(50) // Limit results
//! .execute() // Execute query
//! .await?;
//! # Ok(())
//! # }
//! ```
// local imports
use crateSupabaseClient;
// Re-export join types for structured nested selects
pub use crate;
/// Comparison operators for query filters.
///
/// These operators map directly to PostgREST's filter operators and provide
/// type-safe query construction with compile-time validation.
///
/// # PostgREST Mapping
/// Each variant corresponds to a specific PostgREST operator:
/// - `Equals` → `eq` - Exact equality match
/// - `NotEquals` → `neq` - Inequality match
/// - `GreaterThan` → `gt` - Numeric/date comparison
/// - `LessThan` → `lt` - Numeric/date comparison
/// - `GreaterThanOrEquals` → `gte` - Inclusive range start
/// - `LessThanOrEquals` → `lte` - Inclusive range end
///
/// # Examples
///
/// ```rust
/// use supabase_rs::query::{Filter, Operator};
///
/// // Age exactly 25
/// let exact_age = Filter {
/// column: "age".to_string(),
/// operator: Operator::Equals,
/// value: "25".to_string(),
/// };
///
/// // Price range: $10 to $100
/// let min_price = Filter {
/// column: "price".to_string(),
/// operator: Operator::GreaterThanOrEquals,
/// value: "10.00".to_string(),
/// };
/// ```
/// Sort order specification for query results.
///
/// Determines the direction of sorting for query results. Maps directly to
/// PostgREST's ordering syntax for consistent behavior.
///
/// # Examples
///
/// ```rust
/// use supabase_rs::query::{Sort, SortOrder};
///
/// // Sort by creation date, newest first
/// let recent_first = Sort {
/// column: "created_at".to_string(),
/// order: SortOrder::Descending,
/// };
///
/// // Sort by name alphabetically
/// let alphabetical = Sort {
/// column: "name".to_string(),
/// order: SortOrder::Ascending,
/// };
/// ```
/// A filter condition for database queries.
///
/// Represents a single filter criterion that can be applied to a query.
/// Combines a column name, comparison operator, and target value into a
/// PostgREST-compatible filter expression.
///
/// # Examples
///
/// ```rust
/// use supabase_rs::query::{Filter, Operator};
///
/// // Filter for active users
/// let active_filter = Filter {
/// column: "status".to_string(),
/// operator: Operator::Equals,
/// value: "active".to_string(),
/// };
///
/// // Filter for adults (age >= 18)
/// let adult_filter = Filter {
/// column: "age".to_string(),
/// operator: Operator::GreaterThanOrEquals,
/// value: "18".to_string(),
/// };
/// ```
/// Sorting specification for query results.
///
/// Defines how query results should be ordered by specifying a column name
/// and sort direction. Multiple sorts can be applied to create complex ordering.
///
/// # Examples
///
/// ```rust
/// use supabase_rs::query::{Sort, SortOrder};
///
/// // Sort by creation date, newest first
/// let by_date = Sort {
/// column: "created_at".to_string(),
/// order: SortOrder::Descending,
/// };
///
/// // Sort by name alphabetically
/// let by_name = Sort {
/// column: "name".to_string(),
/// order: SortOrder::Ascending,
/// };
/// ```
/// Internal query state container.
///
/// Manages the complete state of a database query including parameters, filters,
/// sorting criteria, and pagination settings. This struct is typically managed
/// internally by [`QueryBuilder`] and not used directly by end users.
///
/// # Query Components
///
/// - **Parameters**: Key-value pairs for basic query parameters (select, limit, etc.)
/// - **Filters**: Structured filter conditions with type-safe operators
/// - **Sorts**: Sorting specifications with column and direction
/// - **Range**: Optional pagination range for efficient data retrieval
///
/// # Examples
///
/// ```rust
/// use supabase_rs::query::{Query, Filter, Operator, Sort, SortOrder};
///
/// let mut query = Query::new();
///
/// // Add parameters
/// query.add_param("select", "id,name,email");
/// query.add_param("limit", "50");
///
/// // Add filters
/// query.add_filter(Filter {
/// column: "age".to_string(),
/// operator: Operator::GreaterThanOrEquals,
/// value: "18".to_string(),
/// });
///
/// // Add sorting
/// query.add_sort(Sort {
/// column: "name".to_string(),
/// order: SortOrder::Ascending,
/// });
///
/// // Set pagination range
/// query.set_range(0, 49); // First 50 records
///
/// let query_string = query.build();
/// ```
/// Fluent query builder for constructing and executing database queries.
///
/// `QueryBuilder` provides a chainable API for building complex queries against Supabase tables.
/// It encapsulates query state and provides type-safe methods for filtering, sorting, and pagination.
///
/// # Design Pattern
///
/// The builder uses the fluent interface pattern, allowing operations to be chained together:
/// ```text
/// client.select("table").eq("column", "value").limit(10).execute()
/// ```
///
/// # Performance Characteristics
///
/// - **Lazy Evaluation**: Query is built but not executed until `.execute()` is called
/// - **Efficient Serialization**: Parameters are collected and serialized once
/// - **Connection Reuse**: Leverages the underlying client's connection pool
/// - **Memory Efficient**: Minimal allocations during query construction
///
/// # Examples
///
/// ## Basic Usage
/// ```rust,no_run
/// use supabase_rs::SupabaseClient;
/// use serde_json::Value;
///
/// # async fn example() -> Result<(), String> {
/// # let client = SupabaseClient::new("url".to_string(), "key".to_string()).unwrap();
/// let users: Vec<Value> = client
/// .select("users")
/// .eq("active", "true")
/// .order("created_at", false)
/// .limit(25)
/// .execute()
/// .await?;
/// # Ok(())
/// # }
/// ```
///
/// ## Complex Queries
/// ```rust,no_run
/// # use supabase_rs::SupabaseClient;
/// # use serde_json::Value;
/// # async fn example() -> Result<(), String> {
/// # let client = SupabaseClient::new("url".to_string(), "key".to_string()).unwrap();
/// let products: Vec<Value> = client
/// .from("products")
/// .columns(vec!["id", "name", "price"])
/// .gte("price", "10.00")
/// .lte("price", "100.00")
/// .in_("category", &["electronics", "books"])
/// .text_search("description", "wireless")
/// .order("price", true)
/// .range(0, 19)
/// .execute()
/// .await?;
/// # Ok(())
/// # }
/// ```