1use futures_util::lock::Mutex;
2use log::LevelFilter;
3use sea_query::Values;
4use std::{fmt::Write, future::Future, pin::Pin, sync::Arc};
5
6use sqlx::{
7 Connection, Executor, PgPool, Postgres,
8 pool::PoolConnection,
9 postgres::{PgConnectOptions, PgQueryResult, PgRow},
10};
11
12use sea_query_sqlx::SqlxValues;
13use tracing::instrument;
14
15use crate::{
16 AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,
17 DbBackend, IsolationLevel, QueryStream, Statement, TransactionError, debug_print, error::*,
18 executor::*,
19};
20
21use super::sqlx_common::*;
22
23#[derive(Debug)]
25pub struct SqlxPostgresConnector;
26
27#[derive(Clone)]
29pub struct SqlxPostgresPoolConnection {
30 pub(crate) pool: PgPool,
31 metric_callback: Option<crate::metric::Callback>,
32}
33
34impl std::fmt::Debug for SqlxPostgresPoolConnection {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 write!(f, "SqlxPostgresPoolConnection {{ pool: {:?} }}", self.pool)
37 }
38}
39
40impl From<PgPool> for SqlxPostgresPoolConnection {
41 fn from(pool: PgPool) -> Self {
42 SqlxPostgresPoolConnection {
43 pool,
44 metric_callback: None,
45 }
46 }
47}
48
49impl From<PgPool> for DatabaseConnection {
50 fn from(pool: PgPool) -> Self {
51 DatabaseConnectionType::SqlxPostgresPoolConnection(pool.into()).into()
52 }
53}
54
55impl SqlxPostgresConnector {
56 pub fn accepts(string: &str) -> bool {
58 string.starts_with("postgres://") && string.parse::<PgConnectOptions>().is_ok()
59 }
60
61 #[instrument(level = "trace")]
63 pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {
64 let mut opt = options
65 .url
66 .parse::<PgConnectOptions>()
67 .map_err(sqlx_error_to_conn_err)?;
68 use sqlx::ConnectOptions;
69 if !options.sqlx_logging {
70 opt = opt.disable_statement_logging();
71 } else {
72 opt = opt.log_statements(options.sqlx_logging_level);
73 if options.sqlx_slow_statements_logging_level != LevelFilter::Off {
74 opt = opt.log_slow_statements(
75 options.sqlx_slow_statements_logging_level,
76 options.sqlx_slow_statements_logging_threshold,
77 );
78 }
79 }
80 let set_search_path_sql = options.schema_search_path.as_ref().map(|schema| {
81 let mut string = "SET search_path = ".to_owned();
82 if schema.starts_with('"') {
83 write!(&mut string, "{schema}").expect("Infallible");
84 } else {
85 for (i, schema) in schema.split(',').enumerate() {
86 if i > 0 {
87 write!(&mut string, ",").expect("Infallible");
88 }
89 if schema.starts_with('"') {
90 write!(&mut string, "{schema}").expect("Infallible");
91 } else {
92 write!(&mut string, "\"{schema}\"").expect("Infallible");
93 }
94 }
95 }
96 string
97 });
98 let lazy = options.connect_lazy;
99 let mut pool_options = options.sqlx_pool_options();
100 if let Some(sql) = set_search_path_sql {
101 pool_options = pool_options.after_connect(move |conn, _| {
102 let sql = sql.clone();
103 Box::pin(async move {
104 sqlx::Executor::execute(conn, sql.as_str())
105 .await
106 .map(|_| ())
107 })
108 });
109 }
110 let pool = if lazy {
111 pool_options.connect_lazy_with(opt)
112 } else {
113 pool_options
114 .connect_with(opt)
115 .await
116 .map_err(sqlx_error_to_conn_err)?
117 };
118 Ok(
119 DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {
120 pool,
121 metric_callback: None,
122 })
123 .into(),
124 )
125 }
126}
127
128impl SqlxPostgresConnector {
129 pub fn from_sqlx_postgres_pool(pool: PgPool) -> DatabaseConnection {
131 DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {
132 pool,
133 metric_callback: None,
134 })
135 .into()
136 }
137}
138
139impl SqlxPostgresPoolConnection {
140 #[instrument(level = "trace")]
142 pub async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {
143 debug_print!("{}", stmt);
144
145 let query = sqlx_query(&stmt);
146 let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
147 crate::metric::metric!(self.metric_callback, &stmt, {
148 match query.execute(&mut *conn).await {
149 Ok(res) => Ok(res.into()),
150 Err(err) => Err(sqlx_error_to_exec_err(err)),
151 }
152 })
153 }
154
155 #[instrument(level = "trace")]
157 pub async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {
158 debug_print!("{}", sql);
159
160 let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
161 match conn.execute(sql).await {
162 Ok(res) => Ok(res.into()),
163 Err(err) => Err(sqlx_error_to_exec_err(err)),
164 }
165 }
166
167 #[instrument(level = "trace")]
169 pub async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {
170 debug_print!("{}", stmt);
171
172 let query = sqlx_query(&stmt);
173 let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
174 crate::metric::metric!(self.metric_callback, &stmt, {
175 match query.fetch_one(&mut *conn).await {
176 Ok(row) => Ok(Some(row.into())),
177 Err(err) => match err {
178 sqlx::Error::RowNotFound => Ok(None),
179 _ => Err(sqlx_error_to_query_err(err)),
180 },
181 }
182 })
183 }
184
185 #[instrument(level = "trace")]
187 pub async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {
188 debug_print!("{}", stmt);
189
190 let query = sqlx_query(&stmt);
191 let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
192 crate::metric::metric!(self.metric_callback, &stmt, {
193 match query.fetch_all(&mut *conn).await {
194 Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),
195 Err(err) => Err(sqlx_error_to_query_err(err)),
196 }
197 })
198 }
199
200 #[instrument(level = "trace")]
202 pub async fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {
203 debug_print!("{}", stmt);
204
205 let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
206 Ok(QueryStream::from((
207 conn,
208 stmt,
209 self.metric_callback.clone(),
210 )))
211 }
212
213 #[instrument(level = "trace")]
215 pub async fn begin(
216 &self,
217 isolation_level: Option<IsolationLevel>,
218 access_mode: Option<AccessMode>,
219 ) -> Result<DatabaseTransaction, DbErr> {
220 let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
221 DatabaseTransaction::new_postgres(
222 conn,
223 self.metric_callback.clone(),
224 isolation_level,
225 access_mode,
226 )
227 .await
228 }
229
230 #[instrument(level = "trace", skip(callback))]
232 pub async fn transaction<F, T, E>(
233 &self,
234 callback: F,
235 isolation_level: Option<IsolationLevel>,
236 access_mode: Option<AccessMode>,
237 ) -> Result<T, TransactionError<E>>
238 where
239 F: for<'b> FnOnce(
240 &'b DatabaseTransaction,
241 ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>
242 + Send,
243 T: Send,
244 E: std::fmt::Display + std::fmt::Debug + Send,
245 {
246 let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
247 let transaction = DatabaseTransaction::new_postgres(
248 conn,
249 self.metric_callback.clone(),
250 isolation_level,
251 access_mode,
252 )
253 .await
254 .map_err(|e| TransactionError::Connection(e))?;
255 transaction.run(callback).await
256 }
257
258 pub(crate) fn set_metric_callback<F>(&mut self, callback: F)
259 where
260 F: Fn(&crate::metric::Info<'_>) + Send + Sync + 'static,
261 {
262 self.metric_callback = Some(Arc::new(callback));
263 }
264
265 pub async fn ping(&self) -> Result<(), DbErr> {
267 let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;
268 match conn.ping().await {
269 Ok(_) => Ok(()),
270 Err(err) => Err(sqlx_error_to_conn_err(err)),
271 }
272 }
273
274 pub async fn close(self) -> Result<(), DbErr> {
277 self.close_by_ref().await
278 }
279
280 pub async fn close_by_ref(&self) -> Result<(), DbErr> {
282 self.pool.close().await;
283 Ok(())
284 }
285}
286
287impl From<PgRow> for QueryResult {
288 fn from(row: PgRow) -> QueryResult {
289 QueryResult {
290 row: QueryResultRow::SqlxPostgres(row),
291 }
292 }
293}
294
295impl From<PgQueryResult> for ExecResult {
296 fn from(result: PgQueryResult) -> ExecResult {
297 ExecResult {
298 result: ExecResultHolder::SqlxPostgres(result),
299 }
300 }
301}
302
303pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, SqlxValues> {
304 let values = stmt
305 .values
306 .as_ref()
307 .map_or(Values(Vec::new()), |values| values.clone());
308 sqlx::query_with(&stmt.sql, SqlxValues(values))
309}
310
311pub(crate) async fn set_transaction_config(
312 conn: &mut PoolConnection<Postgres>,
313 isolation_level: Option<IsolationLevel>,
314 access_mode: Option<AccessMode>,
315) -> Result<(), DbErr> {
316 if let Some(isolation_level) = isolation_level {
317 let stmt = Statement {
318 sql: format!("SET TRANSACTION ISOLATION LEVEL {isolation_level}"),
319 values: None,
320 db_backend: DbBackend::Postgres,
321 };
322 let query = sqlx_query(&stmt);
323 conn.execute(query).await.map_err(sqlx_error_to_exec_err)?;
324 }
325 if let Some(access_mode) = access_mode {
326 let stmt = Statement {
327 sql: format!("SET TRANSACTION {access_mode}"),
328 values: None,
329 db_backend: DbBackend::Postgres,
330 };
331 let query = sqlx_query(&stmt);
332 conn.execute(query).await.map_err(sqlx_error_to_exec_err)?;
333 }
334 Ok(())
335}
336
337impl
338 From<(
339 PoolConnection<sqlx::Postgres>,
340 Statement,
341 Option<crate::metric::Callback>,
342 )> for crate::QueryStream
343{
344 fn from(
345 (conn, stmt, metric_callback): (
346 PoolConnection<sqlx::Postgres>,
347 Statement,
348 Option<crate::metric::Callback>,
349 ),
350 ) -> Self {
351 crate::QueryStream::build(
352 stmt,
353 crate::InnerConnection::Postgres(conn),
354 metric_callback,
355 )
356 }
357}
358
359impl crate::DatabaseTransaction {
360 pub(crate) async fn new_postgres(
361 inner: PoolConnection<sqlx::Postgres>,
362 metric_callback: Option<crate::metric::Callback>,
363 isolation_level: Option<IsolationLevel>,
364 access_mode: Option<AccessMode>,
365 ) -> Result<crate::DatabaseTransaction, DbErr> {
366 Self::begin(
367 Arc::new(Mutex::new(crate::InnerConnection::Postgres(inner))),
368 crate::DbBackend::Postgres,
369 metric_callback,
370 isolation_level,
371 access_mode,
372 )
373 .await
374 }
375}
376
377#[cfg(feature = "proxy")]
378pub(crate) fn from_sqlx_postgres_row_to_proxy_row(row: &sqlx::postgres::PgRow) -> crate::ProxyRow {
379 use sea_query::Value;
382 use sqlx::{Column, Row, TypeInfo};
383 crate::ProxyRow {
384 values: row
385 .columns()
386 .iter()
387 .map(|c| {
388 (
389 c.name().to_string(),
390 match c.type_info().name() {
391 "BOOL" => Value::Bool(Some(
392 row.try_get(c.ordinal()).expect("Failed to get boolean"),
393 )),
394 #[cfg(feature = "postgres-array")]
395 "BOOL[]" => Value::Array(
396 sea_query::ArrayType::Bool,
397 Some(Box::new(
398 row.try_get::<Vec<bool>, _>(c.ordinal())
399 .expect("Failed to get boolean array")
400 .iter()
401 .map(|val| Value::Bool(Some(*val)))
402 .collect(),
403 )),
404 ),
405
406 "\"CHAR\"" => Value::TinyInt(Some(
407 row.try_get(c.ordinal())
408 .expect("Failed to get small integer"),
409 )),
410 #[cfg(feature = "postgres-array")]
411 "\"CHAR\"[]" => Value::Array(
412 sea_query::ArrayType::TinyInt,
413 Some(Box::new(
414 row.try_get::<Vec<i8>, _>(c.ordinal())
415 .expect("Failed to get small integer array")
416 .iter()
417 .map(|val| Value::TinyInt(Some(*val)))
418 .collect(),
419 )),
420 ),
421
422 "SMALLINT" | "SMALLSERIAL" | "INT2" => Value::SmallInt(Some(
423 row.try_get(c.ordinal())
424 .expect("Failed to get small integer"),
425 )),
426 #[cfg(feature = "postgres-array")]
427 "SMALLINT[]" | "SMALLSERIAL[]" | "INT2[]" => Value::Array(
428 sea_query::ArrayType::SmallInt,
429 Some(Box::new(
430 row.try_get::<Vec<i16>, _>(c.ordinal())
431 .expect("Failed to get small integer array")
432 .iter()
433 .map(|val| Value::SmallInt(Some(*val)))
434 .collect(),
435 )),
436 ),
437
438 "INT" | "SERIAL" | "INT4" => Value::Int(Some(
439 row.try_get(c.ordinal()).expect("Failed to get integer"),
440 )),
441 #[cfg(feature = "postgres-array")]
442 "INT[]" | "SERIAL[]" | "INT4[]" => Value::Array(
443 sea_query::ArrayType::Int,
444 Some(Box::new(
445 row.try_get::<Vec<i32>, _>(c.ordinal())
446 .expect("Failed to get integer array")
447 .iter()
448 .map(|val| Value::Int(Some(*val)))
449 .collect(),
450 )),
451 ),
452
453 "BIGINT" | "BIGSERIAL" | "INT8" => Value::BigInt(Some(
454 row.try_get(c.ordinal()).expect("Failed to get big integer"),
455 )),
456 #[cfg(feature = "postgres-array")]
457 "BIGINT[]" | "BIGSERIAL[]" | "INT8[]" => Value::Array(
458 sea_query::ArrayType::BigInt,
459 Some(Box::new(
460 row.try_get::<Vec<i64>, _>(c.ordinal())
461 .expect("Failed to get big integer array")
462 .iter()
463 .map(|val| Value::BigInt(Some(*val)))
464 .collect(),
465 )),
466 ),
467
468 "FLOAT4" | "REAL" => Value::Float(Some(
469 row.try_get(c.ordinal()).expect("Failed to get float"),
470 )),
471 #[cfg(feature = "postgres-array")]
472 "FLOAT4[]" | "REAL[]" => Value::Array(
473 sea_query::ArrayType::Float,
474 Some(Box::new(
475 row.try_get::<Vec<f32>, _>(c.ordinal())
476 .expect("Failed to get float array")
477 .iter()
478 .map(|val| Value::Float(Some(*val)))
479 .collect(),
480 )),
481 ),
482
483 "FLOAT8" | "DOUBLE PRECISION" => Value::Double(Some(
484 row.try_get(c.ordinal()).expect("Failed to get double"),
485 )),
486 #[cfg(feature = "postgres-array")]
487 "FLOAT8[]" | "DOUBLE PRECISION[]" => Value::Array(
488 sea_query::ArrayType::Double,
489 Some(Box::new(
490 row.try_get::<Vec<f64>, _>(c.ordinal())
491 .expect("Failed to get double array")
492 .iter()
493 .map(|val| Value::Double(Some(*val)))
494 .collect(),
495 )),
496 ),
497
498 "VARCHAR" | "CHAR" | "TEXT" | "NAME" => Value::String(Some(Box::new(
499 row.try_get(c.ordinal()).expect("Failed to get string"),
500 ))),
501 #[cfg(feature = "postgres-array")]
502 "VARCHAR[]" | "CHAR[]" | "TEXT[]" | "NAME[]" => Value::Array(
503 sea_query::ArrayType::String,
504 Some(Box::new(
505 row.try_get::<Vec<String>, _>(c.ordinal())
506 .expect("Failed to get string array")
507 .iter()
508 .map(|val| Value::String(Some(Box::new(val.clone()))))
509 .collect(),
510 )),
511 ),
512
513 "BYTEA" => Value::Bytes(Some(Box::new(
514 row.try_get(c.ordinal()).expect("Failed to get bytes"),
515 ))),
516 #[cfg(feature = "postgres-array")]
517 "BYTEA[]" => Value::Array(
518 sea_query::ArrayType::Bytes,
519 Some(Box::new(
520 row.try_get::<Vec<Vec<u8>>, _>(c.ordinal())
521 .expect("Failed to get bytes array")
522 .iter()
523 .map(|val| Value::Bytes(Some(Box::new(val.clone()))))
524 .collect(),
525 )),
526 ),
527
528 #[cfg(feature = "with-bigdecimal")]
529 "NUMERIC" => Value::BigDecimal(Some(Box::new(
530 row.try_get(c.ordinal()).expect("Failed to get numeric"),
531 ))),
532 #[cfg(all(
533 feature = "with-rust_decimal",
534 not(feature = "with-bigdecimal")
535 ))]
536 "NUMERIC" => Value::Decimal(Some(Box::new(
537 row.try_get(c.ordinal()).expect("Failed to get numeric"),
538 ))),
539
540 #[cfg(all(feature = "with-bigdecimal", feature = "postgres-array"))]
541 "NUMERIC[]" => Value::Array(
542 sea_query::ArrayType::BigDecimal,
543 Some(Box::new(
544 row.try_get::<Vec<bigdecimal::BigDecimal>, _>(c.ordinal())
545 .expect("Failed to get numeric array")
546 .iter()
547 .map(|val| Value::BigDecimal(Some(Box::new(val.clone()))))
548 .collect(),
549 )),
550 ),
551 #[cfg(all(
552 feature = "with-rust_decimal",
553 not(feature = "with-bigdecimal"),
554 feature = "postgres-array"
555 ))]
556 "NUMERIC[]" => Value::Array(
557 sea_query::ArrayType::Decimal,
558 Some(Box::new(
559 row.try_get::<Vec<rust_decimal::Decimal>, _>(c.ordinal())
560 .expect("Failed to get numeric array")
561 .iter()
562 .map(|val| Value::Decimal(Some(Box::new(val.clone()))))
563 .collect(),
564 )),
565 ),
566
567 "OID" => Value::BigInt(Some(
568 row.try_get(c.ordinal()).expect("Failed to get oid"),
569 )),
570 #[cfg(feature = "postgres-array")]
571 "OID[]" => Value::Array(
572 sea_query::ArrayType::BigInt,
573 Some(Box::new(
574 row.try_get::<Vec<i64>, _>(c.ordinal())
575 .expect("Failed to get oid array")
576 .iter()
577 .map(|val| Value::BigInt(Some(*val)))
578 .collect(),
579 )),
580 ),
581
582 "JSON" | "JSONB" => Value::Json(Some(Box::new(
583 row.try_get(c.ordinal()).expect("Failed to get json"),
584 ))),
585 #[cfg(any(feature = "json-array", feature = "postgres-array"))]
586 "JSON[]" | "JSONB[]" => Value::Array(
587 sea_query::ArrayType::Json,
588 Some(Box::new(
589 row.try_get::<Vec<serde_json::Value>, _>(c.ordinal())
590 .expect("Failed to get json array")
591 .iter()
592 .map(|val| Value::Json(Some(Box::new(val.clone()))))
593 .collect(),
594 )),
595 ),
596
597 #[cfg(feature = "with-ipnetwork")]
598 "INET" | "CIDR" => Value::IpNetwork(Some(Box::new(
599 row.try_get(c.ordinal()).expect("Failed to get ip address"),
600 ))),
601 #[cfg(feature = "with-ipnetwork")]
602 "INET[]" | "CIDR[]" => Value::Array(
603 sea_query::ArrayType::IpNetwork,
604 Some(Box::new(
605 row.try_get::<Vec<ipnetwork::IpNetwork>, _>(c.ordinal())
606 .expect("Failed to get ip address array")
607 .iter()
608 .map(|val| Value::IpNetwork(Some(Box::new(*val))))
609 .collect(),
610 )),
611 ),
612
613 #[cfg(feature = "with-mac_address")]
614 "MACADDR" | "MACADDR8" => Value::MacAddress(Some(Box::new(
615 row.try_get(c.ordinal()).expect("Failed to get mac address"),
616 ))),
617 #[cfg(all(feature = "with-mac_address", feature = "postgres-array"))]
618 "MACADDR[]" | "MACADDR8[]" => Value::Array(
619 sea_query::ArrayType::MacAddress,
620 Some(Box::new(
621 row.try_get::<Vec<mac_address::MacAddress>, _>(c.ordinal())
622 .expect("Failed to get mac address array")
623 .iter()
624 .map(|val| Value::MacAddress(Some(Box::new(val.clone()))))
625 .collect(),
626 )),
627 ),
628
629 #[cfg(feature = "with-chrono")]
630 "TIMESTAMP" => Value::ChronoDateTime(Some(Box::new(
631 row.try_get(c.ordinal()).expect("Failed to get timestamp"),
632 ))),
633 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
634 "TIMESTAMP" => Value::TimeDateTime(Some(Box::new(
635 row.try_get(c.ordinal()).expect("Failed to get timestamp"),
636 ))),
637
638 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
639 "TIMESTAMP[]" => Value::Array(
640 sea_query::ArrayType::ChronoDateTime,
641 Some(Box::new(
642 row.try_get::<Vec<chrono::NaiveDateTime>, _>(c.ordinal())
643 .expect("Failed to get timestamp array")
644 .iter()
645 .map(|val| Value::ChronoDateTime(Some(Box::new(*val))))
646 .collect(),
647 )),
648 ),
649 #[cfg(all(
650 feature = "with-time",
651 not(feature = "with-chrono"),
652 feature = "postgres-array"
653 ))]
654 "TIMESTAMP[]" => Value::Array(
655 sea_query::ArrayType::TimeDateTime,
656 Some(Box::new(
657 row.try_get::<Vec<time::OffsetDateTime>, _>(c.ordinal())
658 .expect("Failed to get timestamp array")
659 .iter()
660 .map(|val| Value::TimeDateTime(Some(Box::new(val.clone()))))
661 .collect(),
662 )),
663 ),
664
665 #[cfg(feature = "with-chrono")]
666 "DATE" => Value::ChronoDate(Some(Box::new(
667 row.try_get(c.ordinal()).expect("Failed to get date"),
668 ))),
669 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
670 "DATE" => Value::TimeDate(Some(Box::new(
671 row.try_get(c.ordinal()).expect("Failed to get date"),
672 ))),
673
674 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
675 "DATE[]" => Value::Array(
676 sea_query::ArrayType::ChronoDate,
677 Some(Box::new(
678 row.try_get::<Vec<chrono::NaiveDate>, _>(c.ordinal())
679 .expect("Failed to get date array")
680 .iter()
681 .map(|val| Value::ChronoDate(Some(Box::new(*val))))
682 .collect(),
683 )),
684 ),
685 #[cfg(all(
686 feature = "with-time",
687 not(feature = "with-chrono"),
688 feature = "postgres-array"
689 ))]
690 "DATE[]" => Value::Array(
691 sea_query::ArrayType::TimeDate,
692 Some(Box::new(
693 row.try_get::<Vec<time::Date>, _>(c.ordinal())
694 .expect("Failed to get date array")
695 .iter()
696 .map(|val| Value::TimeDate(Some(Box::new(val.clone()))))
697 .collect(),
698 )),
699 ),
700
701 #[cfg(feature = "with-chrono")]
702 "TIME" => Value::ChronoTime(Some(Box::new(
703 row.try_get(c.ordinal()).expect("Failed to get time"),
704 ))),
705 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
706 "TIME" => Value::TimeTime(Some(Box::new(
707 row.try_get(c.ordinal()).expect("Failed to get time"),
708 ))),
709
710 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
711 "TIME[]" => Value::Array(
712 sea_query::ArrayType::ChronoTime,
713 Some(Box::new(
714 row.try_get::<Vec<chrono::NaiveTime>, _>(c.ordinal())
715 .expect("Failed to get time array")
716 .iter()
717 .map(|val| Value::ChronoTime(Some(Box::new(*val))))
718 .collect(),
719 )),
720 ),
721 #[cfg(all(
722 feature = "with-time",
723 not(feature = "with-chrono"),
724 feature = "postgres-array"
725 ))]
726 "TIME[]" => Value::Array(
727 sea_query::ArrayType::TimeTime,
728 Some(Box::new(
729 row.try_get::<Vec<time::Time>, _>(c.ordinal())
730 .expect("Failed to get time array")
731 .iter()
732 .map(|val| Value::TimeTime(Some(Box::new(val.clone()))))
733 .collect(),
734 )),
735 ),
736
737 #[cfg(feature = "with-chrono")]
738 "TIMESTAMPTZ" => Value::ChronoDateTimeUtc(Some(Box::new(
739 row.try_get(c.ordinal()).expect("Failed to get timestamptz"),
740 ))),
741 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
742 "TIMESTAMPTZ" => Value::TimeDateTime(Some(Box::new(
743 row.try_get(c.ordinal()).expect("Failed to get timestamptz"),
744 ))),
745
746 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
747 "TIMESTAMPTZ[]" => Value::Array(
748 sea_query::ArrayType::ChronoDateTimeUtc,
749 Some(Box::new(
750 row.try_get::<Vec<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())
751 .expect("Failed to get timestamptz array")
752 .iter()
753 .map(|val| Value::ChronoDateTimeUtc(Some(Box::new(*val))))
754 .collect(),
755 )),
756 ),
757 #[cfg(all(
758 feature = "with-time",
759 not(feature = "with-chrono"),
760 feature = "postgres-array"
761 ))]
762 "TIMESTAMPTZ[]" => Value::Array(
763 sea_query::ArrayType::TimeDateTime,
764 Some(Box::new(
765 row.try_get::<Vec<time::OffsetDateTime>, _>(c.ordinal())
766 .expect("Failed to get timestamptz array")
767 .iter()
768 .map(|val| Value::TimeDateTime(Some(Box::new(val.clone()))))
769 .collect(),
770 )),
771 ),
772
773 #[cfg(feature = "with-chrono")]
774 "TIMETZ" => Value::ChronoTime(Some(Box::new(
775 row.try_get(c.ordinal()).expect("Failed to get timetz"),
776 ))),
777 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
778 "TIMETZ" => Value::TimeTime(Some(Box::new(
779 row.try_get(c.ordinal()).expect("Failed to get timetz"),
780 ))),
781
782 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
783 "TIMETZ[]" => Value::Array(
784 sea_query::ArrayType::ChronoTime,
785 Some(Box::new(
786 row.try_get::<Vec<chrono::NaiveTime>, _>(c.ordinal())
787 .expect("Failed to get timetz array")
788 .iter()
789 .map(|val| Value::ChronoTime(Some(Box::new(*val))))
790 .collect(),
791 )),
792 ),
793 #[cfg(all(
794 feature = "with-time",
795 not(feature = "with-chrono"),
796 feature = "postgres-array"
797 ))]
798 "TIMETZ[]" => Value::Array(
799 sea_query::ArrayType::TimeTime,
800 Some(Box::new(
801 row.try_get::<Vec<time::Time>, _>(c.ordinal())
802 .expect("Failed to get timetz array")
803 .iter()
804 .map(|val| Value::TimeTime(Some(Box::new(val.clone()))))
805 .collect(),
806 )),
807 ),
808
809 #[cfg(feature = "with-uuid")]
810 "UUID" => Value::Uuid(Some(Box::new(
811 row.try_get(c.ordinal()).expect("Failed to get uuid"),
812 ))),
813
814 #[cfg(all(feature = "with-uuid", feature = "postgres-array"))]
815 "UUID[]" => Value::Array(
816 sea_query::ArrayType::Uuid,
817 Some(Box::new(
818 row.try_get::<Vec<uuid::Uuid>, _>(c.ordinal())
819 .expect("Failed to get uuid array")
820 .iter()
821 .map(|val| Value::Uuid(Some(Box::new(*val))))
822 .collect(),
823 )),
824 ),
825
826 _ => unreachable!("Unknown column type: {}", c.type_info().name()),
827 },
828 )
829 })
830 .collect(),
831 }
832}