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> {
274 self.close_by_ref().await
275 }
276
277 pub async fn close_by_ref(&self) -> Result<(), DbErr> {
279 self.pool.close().await;
280 Ok(())
281 }
282}
283
284impl From<PgRow> for QueryResult {
285 fn from(row: PgRow) -> QueryResult {
286 QueryResult {
287 row: QueryResultRow::SqlxPostgres(row),
288 }
289 }
290}
291
292impl From<PgQueryResult> for ExecResult {
293 fn from(result: PgQueryResult) -> ExecResult {
294 ExecResult {
295 result: ExecResultHolder::SqlxPostgres(result),
296 }
297 }
298}
299
300pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, SqlxValues> {
301 let values = stmt
302 .values
303 .as_ref()
304 .map_or(Values(Vec::new()), |values| values.clone());
305 sqlx::query_with(&stmt.sql, SqlxValues(values))
306}
307
308pub(crate) async fn set_transaction_config(
309 conn: &mut PoolConnection<Postgres>,
310 isolation_level: Option<IsolationLevel>,
311 access_mode: Option<AccessMode>,
312) -> Result<(), DbErr> {
313 if let Some(isolation_level) = isolation_level {
314 let stmt = Statement {
315 sql: format!("SET TRANSACTION ISOLATION LEVEL {isolation_level}"),
316 values: None,
317 db_backend: DbBackend::Postgres,
318 };
319 let query = sqlx_query(&stmt);
320 conn.execute(query).await.map_err(sqlx_error_to_exec_err)?;
321 }
322 if let Some(access_mode) = access_mode {
323 let stmt = Statement {
324 sql: format!("SET TRANSACTION {access_mode}"),
325 values: None,
326 db_backend: DbBackend::Postgres,
327 };
328 let query = sqlx_query(&stmt);
329 conn.execute(query).await.map_err(sqlx_error_to_exec_err)?;
330 }
331 Ok(())
332}
333
334impl
335 From<(
336 PoolConnection<sqlx::Postgres>,
337 Statement,
338 Option<crate::metric::Callback>,
339 )> for crate::QueryStream
340{
341 fn from(
342 (conn, stmt, metric_callback): (
343 PoolConnection<sqlx::Postgres>,
344 Statement,
345 Option<crate::metric::Callback>,
346 ),
347 ) -> Self {
348 crate::QueryStream::build(
349 stmt,
350 crate::InnerConnection::Postgres(conn),
351 metric_callback,
352 )
353 }
354}
355
356impl crate::DatabaseTransaction {
357 pub(crate) async fn new_postgres(
358 inner: PoolConnection<sqlx::Postgres>,
359 metric_callback: Option<crate::metric::Callback>,
360 isolation_level: Option<IsolationLevel>,
361 access_mode: Option<AccessMode>,
362 ) -> Result<crate::DatabaseTransaction, DbErr> {
363 Self::begin(
364 Arc::new(Mutex::new(crate::InnerConnection::Postgres(inner))),
365 crate::DbBackend::Postgres,
366 metric_callback,
367 isolation_level,
368 access_mode,
369 )
370 .await
371 }
372}
373
374#[cfg(feature = "proxy")]
375pub(crate) fn from_sqlx_postgres_row_to_proxy_row(row: &sqlx::postgres::PgRow) -> crate::ProxyRow {
376 use sea_query::Value;
379 use sqlx::{Column, Row, TypeInfo};
380 crate::ProxyRow {
381 values: row
382 .columns()
383 .iter()
384 .map(|c| {
385 (
386 c.name().to_string(),
387 match c.type_info().name() {
388 "BOOL" => Value::Bool(Some(
389 row.try_get(c.ordinal()).expect("Failed to get boolean"),
390 )),
391 #[cfg(feature = "postgres-array")]
392 "BOOL[]" => Value::Array(
393 sea_query::ArrayType::Bool,
394 Some(Box::new(
395 row.try_get::<Vec<bool>, _>(c.ordinal())
396 .expect("Failed to get boolean array")
397 .iter()
398 .map(|val| Value::Bool(Some(*val)))
399 .collect(),
400 )),
401 ),
402
403 "\"CHAR\"" => Value::TinyInt(Some(
404 row.try_get(c.ordinal())
405 .expect("Failed to get small integer"),
406 )),
407 #[cfg(feature = "postgres-array")]
408 "\"CHAR\"[]" => Value::Array(
409 sea_query::ArrayType::TinyInt,
410 Some(Box::new(
411 row.try_get::<Vec<i8>, _>(c.ordinal())
412 .expect("Failed to get small integer array")
413 .iter()
414 .map(|val| Value::TinyInt(Some(*val)))
415 .collect(),
416 )),
417 ),
418
419 "SMALLINT" | "SMALLSERIAL" | "INT2" => Value::SmallInt(Some(
420 row.try_get(c.ordinal())
421 .expect("Failed to get small integer"),
422 )),
423 #[cfg(feature = "postgres-array")]
424 "SMALLINT[]" | "SMALLSERIAL[]" | "INT2[]" => Value::Array(
425 sea_query::ArrayType::SmallInt,
426 Some(Box::new(
427 row.try_get::<Vec<i16>, _>(c.ordinal())
428 .expect("Failed to get small integer array")
429 .iter()
430 .map(|val| Value::SmallInt(Some(*val)))
431 .collect(),
432 )),
433 ),
434
435 "INT" | "SERIAL" | "INT4" => Value::Int(Some(
436 row.try_get(c.ordinal()).expect("Failed to get integer"),
437 )),
438 #[cfg(feature = "postgres-array")]
439 "INT[]" | "SERIAL[]" | "INT4[]" => Value::Array(
440 sea_query::ArrayType::Int,
441 Some(Box::new(
442 row.try_get::<Vec<i32>, _>(c.ordinal())
443 .expect("Failed to get integer array")
444 .iter()
445 .map(|val| Value::Int(Some(*val)))
446 .collect(),
447 )),
448 ),
449
450 "BIGINT" | "BIGSERIAL" | "INT8" => Value::BigInt(Some(
451 row.try_get(c.ordinal()).expect("Failed to get big integer"),
452 )),
453 #[cfg(feature = "postgres-array")]
454 "BIGINT[]" | "BIGSERIAL[]" | "INT8[]" => Value::Array(
455 sea_query::ArrayType::BigInt,
456 Some(Box::new(
457 row.try_get::<Vec<i64>, _>(c.ordinal())
458 .expect("Failed to get big integer array")
459 .iter()
460 .map(|val| Value::BigInt(Some(*val)))
461 .collect(),
462 )),
463 ),
464
465 "FLOAT4" | "REAL" => Value::Float(Some(
466 row.try_get(c.ordinal()).expect("Failed to get float"),
467 )),
468 #[cfg(feature = "postgres-array")]
469 "FLOAT4[]" | "REAL[]" => Value::Array(
470 sea_query::ArrayType::Float,
471 Some(Box::new(
472 row.try_get::<Vec<f32>, _>(c.ordinal())
473 .expect("Failed to get float array")
474 .iter()
475 .map(|val| Value::Float(Some(*val)))
476 .collect(),
477 )),
478 ),
479
480 "FLOAT8" | "DOUBLE PRECISION" => Value::Double(Some(
481 row.try_get(c.ordinal()).expect("Failed to get double"),
482 )),
483 #[cfg(feature = "postgres-array")]
484 "FLOAT8[]" | "DOUBLE PRECISION[]" => Value::Array(
485 sea_query::ArrayType::Double,
486 Some(Box::new(
487 row.try_get::<Vec<f64>, _>(c.ordinal())
488 .expect("Failed to get double array")
489 .iter()
490 .map(|val| Value::Double(Some(*val)))
491 .collect(),
492 )),
493 ),
494
495 "VARCHAR" | "CHAR" | "TEXT" | "NAME" => Value::String(Some(Box::new(
496 row.try_get(c.ordinal()).expect("Failed to get string"),
497 ))),
498 #[cfg(feature = "postgres-array")]
499 "VARCHAR[]" | "CHAR[]" | "TEXT[]" | "NAME[]" => Value::Array(
500 sea_query::ArrayType::String,
501 Some(Box::new(
502 row.try_get::<Vec<String>, _>(c.ordinal())
503 .expect("Failed to get string array")
504 .iter()
505 .map(|val| Value::String(Some(Box::new(val.clone()))))
506 .collect(),
507 )),
508 ),
509
510 "BYTEA" => Value::Bytes(Some(Box::new(
511 row.try_get(c.ordinal()).expect("Failed to get bytes"),
512 ))),
513 #[cfg(feature = "postgres-array")]
514 "BYTEA[]" => Value::Array(
515 sea_query::ArrayType::Bytes,
516 Some(Box::new(
517 row.try_get::<Vec<Vec<u8>>, _>(c.ordinal())
518 .expect("Failed to get bytes array")
519 .iter()
520 .map(|val| Value::Bytes(Some(Box::new(val.clone()))))
521 .collect(),
522 )),
523 ),
524
525 #[cfg(feature = "with-bigdecimal")]
526 "NUMERIC" => Value::BigDecimal(Some(Box::new(
527 row.try_get(c.ordinal()).expect("Failed to get numeric"),
528 ))),
529 #[cfg(all(
530 feature = "with-rust_decimal",
531 not(feature = "with-bigdecimal")
532 ))]
533 "NUMERIC" => Value::Decimal(Some(Box::new(
534 row.try_get(c.ordinal()).expect("Failed to get numeric"),
535 ))),
536
537 #[cfg(all(feature = "with-bigdecimal", feature = "postgres-array"))]
538 "NUMERIC[]" => Value::Array(
539 sea_query::ArrayType::BigDecimal,
540 Some(Box::new(
541 row.try_get::<Vec<bigdecimal::BigDecimal>, _>(c.ordinal())
542 .expect("Failed to get numeric array")
543 .iter()
544 .map(|val| Value::BigDecimal(Some(Box::new(val.clone()))))
545 .collect(),
546 )),
547 ),
548 #[cfg(all(
549 feature = "with-rust_decimal",
550 not(feature = "with-bigdecimal"),
551 feature = "postgres-array"
552 ))]
553 "NUMERIC[]" => Value::Array(
554 sea_query::ArrayType::Decimal,
555 Some(Box::new(
556 row.try_get::<Vec<rust_decimal::Decimal>, _>(c.ordinal())
557 .expect("Failed to get numeric array")
558 .iter()
559 .map(|val| Value::Decimal(Some(Box::new(val.clone()))))
560 .collect(),
561 )),
562 ),
563
564 "OID" => Value::BigInt(Some(
565 row.try_get(c.ordinal()).expect("Failed to get oid"),
566 )),
567 #[cfg(feature = "postgres-array")]
568 "OID[]" => Value::Array(
569 sea_query::ArrayType::BigInt,
570 Some(Box::new(
571 row.try_get::<Vec<i64>, _>(c.ordinal())
572 .expect("Failed to get oid array")
573 .iter()
574 .map(|val| Value::BigInt(Some(*val)))
575 .collect(),
576 )),
577 ),
578
579 "JSON" | "JSONB" => Value::Json(Some(Box::new(
580 row.try_get(c.ordinal()).expect("Failed to get json"),
581 ))),
582 #[cfg(any(feature = "json-array", feature = "postgres-array"))]
583 "JSON[]" | "JSONB[]" => Value::Array(
584 sea_query::ArrayType::Json,
585 Some(Box::new(
586 row.try_get::<Vec<serde_json::Value>, _>(c.ordinal())
587 .expect("Failed to get json array")
588 .iter()
589 .map(|val| Value::Json(Some(Box::new(val.clone()))))
590 .collect(),
591 )),
592 ),
593
594 #[cfg(feature = "with-ipnetwork")]
595 "INET" | "CIDR" => Value::IpNetwork(Some(Box::new(
596 row.try_get(c.ordinal()).expect("Failed to get ip address"),
597 ))),
598 #[cfg(feature = "with-ipnetwork")]
599 "INET[]" | "CIDR[]" => Value::Array(
600 sea_query::ArrayType::IpNetwork,
601 Some(Box::new(
602 row.try_get::<Vec<ipnetwork::IpNetwork>, _>(c.ordinal())
603 .expect("Failed to get ip address array")
604 .iter()
605 .map(|val| Value::IpNetwork(Some(Box::new(val.clone()))))
606 .collect(),
607 )),
608 ),
609
610 #[cfg(feature = "with-mac_address")]
611 "MACADDR" | "MACADDR8" => Value::MacAddress(Some(Box::new(
612 row.try_get(c.ordinal()).expect("Failed to get mac address"),
613 ))),
614 #[cfg(all(feature = "with-mac_address", feature = "postgres-array"))]
615 "MACADDR[]" | "MACADDR8[]" => Value::Array(
616 sea_query::ArrayType::MacAddress,
617 Some(Box::new(
618 row.try_get::<Vec<mac_address::MacAddress>, _>(c.ordinal())
619 .expect("Failed to get mac address array")
620 .iter()
621 .map(|val| Value::MacAddress(Some(Box::new(val.clone()))))
622 .collect(),
623 )),
624 ),
625
626 #[cfg(feature = "with-chrono")]
627 "TIMESTAMP" => Value::ChronoDateTime(Some(Box::new(
628 row.try_get(c.ordinal()).expect("Failed to get timestamp"),
629 ))),
630 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
631 "TIMESTAMP" => Value::TimeDateTime(Some(Box::new(
632 row.try_get(c.ordinal()).expect("Failed to get timestamp"),
633 ))),
634
635 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
636 "TIMESTAMP[]" => Value::Array(
637 sea_query::ArrayType::ChronoDateTime,
638 Some(Box::new(
639 row.try_get::<Vec<chrono::NaiveDateTime>, _>(c.ordinal())
640 .expect("Failed to get timestamp array")
641 .iter()
642 .map(|val| Value::ChronoDateTime(Some(Box::new(val.clone()))))
643 .collect(),
644 )),
645 ),
646 #[cfg(all(
647 feature = "with-time",
648 not(feature = "with-chrono"),
649 feature = "postgres-array"
650 ))]
651 "TIMESTAMP[]" => Value::Array(
652 sea_query::ArrayType::TimeDateTime,
653 Some(Box::new(
654 row.try_get::<Vec<time::OffsetDateTime>, _>(c.ordinal())
655 .expect("Failed to get timestamp array")
656 .iter()
657 .map(|val| Value::TimeDateTime(Some(Box::new(val.clone()))))
658 .collect(),
659 )),
660 ),
661
662 #[cfg(feature = "with-chrono")]
663 "DATE" => Value::ChronoDate(Some(Box::new(
664 row.try_get(c.ordinal()).expect("Failed to get date"),
665 ))),
666 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
667 "DATE" => Value::TimeDate(Some(Box::new(
668 row.try_get(c.ordinal()).expect("Failed to get date"),
669 ))),
670
671 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
672 "DATE[]" => Value::Array(
673 sea_query::ArrayType::ChronoDate,
674 Some(Box::new(
675 row.try_get::<Vec<chrono::NaiveDate>, _>(c.ordinal())
676 .expect("Failed to get date array")
677 .iter()
678 .map(|val| Value::ChronoDate(Some(Box::new(val.clone()))))
679 .collect(),
680 )),
681 ),
682 #[cfg(all(
683 feature = "with-time",
684 not(feature = "with-chrono"),
685 feature = "postgres-array"
686 ))]
687 "DATE[]" => Value::Array(
688 sea_query::ArrayType::TimeDate,
689 Some(Box::new(
690 row.try_get::<Vec<time::Date>, _>(c.ordinal())
691 .expect("Failed to get date array")
692 .iter()
693 .map(|val| Value::TimeDate(Some(Box::new(val.clone()))))
694 .collect(),
695 )),
696 ),
697
698 #[cfg(feature = "with-chrono")]
699 "TIME" => Value::ChronoTime(Some(Box::new(
700 row.try_get(c.ordinal()).expect("Failed to get time"),
701 ))),
702 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
703 "TIME" => Value::TimeTime(Some(Box::new(
704 row.try_get(c.ordinal()).expect("Failed to get time"),
705 ))),
706
707 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
708 "TIME[]" => Value::Array(
709 sea_query::ArrayType::ChronoTime,
710 Some(Box::new(
711 row.try_get::<Vec<chrono::NaiveTime>, _>(c.ordinal())
712 .expect("Failed to get time array")
713 .iter()
714 .map(|val| Value::ChronoTime(Some(Box::new(val.clone()))))
715 .collect(),
716 )),
717 ),
718 #[cfg(all(
719 feature = "with-time",
720 not(feature = "with-chrono"),
721 feature = "postgres-array"
722 ))]
723 "TIME[]" => Value::Array(
724 sea_query::ArrayType::TimeTime,
725 Some(Box::new(
726 row.try_get::<Vec<time::Time>, _>(c.ordinal())
727 .expect("Failed to get time array")
728 .iter()
729 .map(|val| Value::TimeTime(Some(Box::new(val.clone()))))
730 .collect(),
731 )),
732 ),
733
734 #[cfg(feature = "with-chrono")]
735 "TIMESTAMPTZ" => Value::ChronoDateTimeUtc(Some(Box::new(
736 row.try_get(c.ordinal()).expect("Failed to get timestamptz"),
737 ))),
738 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
739 "TIMESTAMPTZ" => Value::TimeDateTime(Some(Box::new(
740 row.try_get(c.ordinal()).expect("Failed to get timestamptz"),
741 ))),
742
743 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
744 "TIMESTAMPTZ[]" => Value::Array(
745 sea_query::ArrayType::ChronoDateTimeUtc,
746 Some(Box::new(
747 row.try_get::<Vec<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())
748 .expect("Failed to get timestamptz array")
749 .iter()
750 .map(|val| {
751 Value::ChronoDateTimeUtc(Some(Box::new(val.clone())))
752 })
753 .collect(),
754 )),
755 ),
756 #[cfg(all(
757 feature = "with-time",
758 not(feature = "with-chrono"),
759 feature = "postgres-array"
760 ))]
761 "TIMESTAMPTZ[]" => Value::Array(
762 sea_query::ArrayType::TimeDateTime,
763 Some(Box::new(
764 row.try_get::<Vec<time::OffsetDateTime>, _>(c.ordinal())
765 .expect("Failed to get timestamptz array")
766 .iter()
767 .map(|val| Value::TimeDateTime(Some(Box::new(val.clone()))))
768 .collect(),
769 )),
770 ),
771
772 #[cfg(feature = "with-chrono")]
773 "TIMETZ" => Value::ChronoTime(Some(Box::new(
774 row.try_get(c.ordinal()).expect("Failed to get timetz"),
775 ))),
776 #[cfg(all(feature = "with-time", not(feature = "with-chrono")))]
777 "TIMETZ" => Value::TimeTime(Some(Box::new(
778 row.try_get(c.ordinal()).expect("Failed to get timetz"),
779 ))),
780
781 #[cfg(all(feature = "with-chrono", feature = "postgres-array"))]
782 "TIMETZ[]" => Value::Array(
783 sea_query::ArrayType::ChronoTime,
784 Some(Box::new(
785 row.try_get::<Vec<chrono::NaiveTime>, _>(c.ordinal())
786 .expect("Failed to get timetz array")
787 .iter()
788 .map(|val| Value::ChronoTime(Some(Box::new(val.clone()))))
789 .collect(),
790 )),
791 ),
792 #[cfg(all(
793 feature = "with-time",
794 not(feature = "with-chrono"),
795 feature = "postgres-array"
796 ))]
797 "TIMETZ[]" => Value::Array(
798 sea_query::ArrayType::TimeTime,
799 Some(Box::new(
800 row.try_get::<Vec<time::Time>, _>(c.ordinal())
801 .expect("Failed to get timetz array")
802 .iter()
803 .map(|val| Value::TimeTime(Some(Box::new(val.clone()))))
804 .collect(),
805 )),
806 ),
807
808 #[cfg(feature = "with-uuid")]
809 "UUID" => Value::Uuid(Some(Box::new(
810 row.try_get(c.ordinal()).expect("Failed to get uuid"),
811 ))),
812
813 #[cfg(all(feature = "with-uuid", feature = "postgres-array"))]
814 "UUID[]" => Value::Array(
815 sea_query::ArrayType::Uuid,
816 Some(Box::new(
817 row.try_get::<Vec<uuid::Uuid>, _>(c.ordinal())
818 .expect("Failed to get uuid array")
819 .iter()
820 .map(|val| Value::Uuid(Some(Box::new(val.clone()))))
821 .collect(),
822 )),
823 ),
824
825 _ => unreachable!("Unknown column type: {}", c.type_info().name()),
826 },
827 )
828 })
829 .collect(),
830 }
831}