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