|
@@ -1,4 +1,5 @@
|
|
|
use cdk_common::database::Error;
|
|
use cdk_common::database::Error;
|
|
|
|
|
+use cdk_sql_common::run_db_operation;
|
|
|
use cdk_sql_common::stmt::{Column, Statement};
|
|
use cdk_sql_common::stmt::{Column, Statement};
|
|
|
use futures_util::{pin_mut, TryStreamExt};
|
|
use futures_util::{pin_mut, TryStreamExt};
|
|
|
use tokio_postgres::error::SqlState;
|
|
use tokio_postgres::error::SqlState;
|
|
@@ -9,7 +10,8 @@ use crate::value::PgValue;
|
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
|
fn to_pgsql_error(err: PgError) -> Error {
|
|
fn to_pgsql_error(err: PgError) -> Error {
|
|
|
if let Some(err) = err.as_db_error() {
|
|
if let Some(err) = err.as_db_error() {
|
|
|
- if *err.code() == SqlState::INTEGRITY_CONSTRAINT_VIOLATION {
|
|
|
|
|
|
|
+ let code = err.code().to_owned();
|
|
|
|
|
+ if code == SqlState::INTEGRITY_CONSTRAINT_VIOLATION || code == SqlState::UNIQUE_VIOLATION {
|
|
|
return Error::Duplicate;
|
|
return Error::Duplicate;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -21,7 +23,12 @@ fn to_pgsql_error(err: PgError) -> Error {
|
|
|
pub async fn pg_batch(conn: &Client, statement: Statement) -> Result<(), Error> {
|
|
pub async fn pg_batch(conn: &Client, statement: Statement) -> Result<(), Error> {
|
|
|
let (sql, _placeholder_values) = statement.to_sql()?;
|
|
let (sql, _placeholder_values) = statement.to_sql()?;
|
|
|
|
|
|
|
|
- conn.batch_execute(&sql).await.map_err(to_pgsql_error)
|
|
|
|
|
|
|
+ run_db_operation(
|
|
|
|
|
+ &sql,
|
|
|
|
|
+ async { conn.batch_execute(&sql).await },
|
|
|
|
|
+ to_pgsql_error,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
@@ -29,16 +36,22 @@ pub async fn pg_execute(conn: &Client, statement: Statement) -> Result<usize, Er
|
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
|
|
|
|
|
|
- conn.execute_raw(
|
|
|
|
|
- &prepared_statement,
|
|
|
|
|
- placeholder_values
|
|
|
|
|
- .iter()
|
|
|
|
|
- .map(|x| x.into())
|
|
|
|
|
- .collect::<Vec<PgValue>>(),
|
|
|
|
|
|
|
+ run_db_operation(
|
|
|
|
|
+ &sql,
|
|
|
|
|
+ async {
|
|
|
|
|
+ conn.execute_raw(
|
|
|
|
|
+ &prepared_statement,
|
|
|
|
|
+ placeholder_values
|
|
|
|
|
+ .iter()
|
|
|
|
|
+ .map(|x| x.into())
|
|
|
|
|
+ .collect::<Vec<PgValue>>(),
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
|
|
+ .map(|x| x as usize)
|
|
|
|
|
+ },
|
|
|
|
|
+ to_pgsql_error,
|
|
|
)
|
|
)
|
|
|
.await
|
|
.await
|
|
|
- .map_err(to_pgsql_error)
|
|
|
|
|
- .map(|x| x as usize)
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
@@ -49,30 +62,34 @@ pub async fn pg_fetch_one(
|
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
|
|
|
|
|
|
- let stream = conn
|
|
|
|
|
- .query_raw(
|
|
|
|
|
- &prepared_statement,
|
|
|
|
|
- placeholder_values
|
|
|
|
|
- .iter()
|
|
|
|
|
- .map(|x| x.into())
|
|
|
|
|
- .collect::<Vec<PgValue>>(),
|
|
|
|
|
- )
|
|
|
|
|
- .await
|
|
|
|
|
- .map_err(to_pgsql_error)?;
|
|
|
|
|
-
|
|
|
|
|
- pin_mut!(stream);
|
|
|
|
|
-
|
|
|
|
|
- stream
|
|
|
|
|
- .try_next()
|
|
|
|
|
- .await
|
|
|
|
|
- .map_err(to_pgsql_error)?
|
|
|
|
|
- .map(|row| {
|
|
|
|
|
- (0..row.len())
|
|
|
|
|
- .map(|i| row.try_get::<_, PgValue>(i).map(|value| value.into()))
|
|
|
|
|
- .collect::<Result<Vec<_>, _>>()
|
|
|
|
|
- })
|
|
|
|
|
- .transpose()
|
|
|
|
|
- .map_err(to_pgsql_error)
|
|
|
|
|
|
|
+ run_db_operation(
|
|
|
|
|
+ &sql,
|
|
|
|
|
+ async {
|
|
|
|
|
+ let stream = conn
|
|
|
|
|
+ .query_raw(
|
|
|
|
|
+ &prepared_statement,
|
|
|
|
|
+ placeholder_values
|
|
|
|
|
+ .iter()
|
|
|
|
|
+ .map(|x| x.into())
|
|
|
|
|
+ .collect::<Vec<PgValue>>(),
|
|
|
|
|
+ )
|
|
|
|
|
+ .await?;
|
|
|
|
|
+
|
|
|
|
|
+ pin_mut!(stream);
|
|
|
|
|
+
|
|
|
|
|
+ stream
|
|
|
|
|
+ .try_next()
|
|
|
|
|
+ .await?
|
|
|
|
|
+ .map(|row| {
|
|
|
|
|
+ (0..row.len())
|
|
|
|
|
+ .map(|i| row.try_get::<_, PgValue>(i).map(|value| value.into()))
|
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
|
+ })
|
|
|
|
|
+ .transpose()
|
|
|
|
|
+ },
|
|
|
|
|
+ to_pgsql_error,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
@@ -80,30 +97,35 @@ pub async fn pg_fetch_all(conn: &Client, statement: Statement) -> Result<Vec<Vec
|
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
|
|
|
|
|
|
- let stream = conn
|
|
|
|
|
- .query_raw(
|
|
|
|
|
- &prepared_statement,
|
|
|
|
|
- placeholder_values
|
|
|
|
|
- .iter()
|
|
|
|
|
- .map(|x| x.into())
|
|
|
|
|
- .collect::<Vec<PgValue>>(),
|
|
|
|
|
- )
|
|
|
|
|
- .await
|
|
|
|
|
- .map_err(to_pgsql_error)?;
|
|
|
|
|
-
|
|
|
|
|
- pin_mut!(stream);
|
|
|
|
|
-
|
|
|
|
|
- let mut rows = vec![];
|
|
|
|
|
- while let Some(row) = stream.try_next().await.map_err(to_pgsql_error)? {
|
|
|
|
|
- rows.push(
|
|
|
|
|
- (0..row.len())
|
|
|
|
|
- .map(|i| row.try_get::<_, PgValue>(i).map(|value| value.into()))
|
|
|
|
|
- .collect::<Result<Vec<_>, _>>()
|
|
|
|
|
- .map_err(to_pgsql_error)?,
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- Ok(rows)
|
|
|
|
|
|
|
+ run_db_operation(
|
|
|
|
|
+ &sql,
|
|
|
|
|
+ async {
|
|
|
|
|
+ let stream = conn
|
|
|
|
|
+ .query_raw(
|
|
|
|
|
+ &prepared_statement,
|
|
|
|
|
+ placeholder_values
|
|
|
|
|
+ .iter()
|
|
|
|
|
+ .map(|x| x.into())
|
|
|
|
|
+ .collect::<Vec<PgValue>>(),
|
|
|
|
|
+ )
|
|
|
|
|
+ .await?;
|
|
|
|
|
+
|
|
|
|
|
+ pin_mut!(stream);
|
|
|
|
|
+
|
|
|
|
|
+ let mut rows = vec![];
|
|
|
|
|
+ while let Some(row) = stream.try_next().await? {
|
|
|
|
|
+ rows.push(
|
|
|
|
|
+ (0..row.len())
|
|
|
|
|
+ .map(|i| row.try_get::<_, PgValue>(i).map(|value| value.into()))
|
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()?,
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Ok(rows)
|
|
|
|
|
+ },
|
|
|
|
|
+ to_pgsql_error,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
#[inline(always)]
|
|
@@ -111,24 +133,28 @@ pub async fn gn_pluck(conn: &Client, statement: Statement) -> Result<Option<Colu
|
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
let (sql, placeholder_values) = statement.to_sql()?;
|
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
let prepared_statement = conn.prepare(&sql).await.map_err(to_pgsql_error)?;
|
|
|
|
|
|
|
|
- let stream = conn
|
|
|
|
|
- .query_raw(
|
|
|
|
|
- &prepared_statement,
|
|
|
|
|
- placeholder_values
|
|
|
|
|
- .iter()
|
|
|
|
|
- .map(|x| x.into())
|
|
|
|
|
- .collect::<Vec<PgValue>>(),
|
|
|
|
|
- )
|
|
|
|
|
- .await
|
|
|
|
|
- .map_err(to_pgsql_error)?;
|
|
|
|
|
-
|
|
|
|
|
- pin_mut!(stream);
|
|
|
|
|
-
|
|
|
|
|
- stream
|
|
|
|
|
- .try_next()
|
|
|
|
|
- .await
|
|
|
|
|
- .map_err(to_pgsql_error)?
|
|
|
|
|
- .map(|row| row.try_get::<_, PgValue>(0).map(|value| value.into()))
|
|
|
|
|
- .transpose()
|
|
|
|
|
- .map_err(to_pgsql_error)
|
|
|
|
|
|
|
+ run_db_operation(
|
|
|
|
|
+ &sql,
|
|
|
|
|
+ async {
|
|
|
|
|
+ let stream = conn
|
|
|
|
|
+ .query_raw(
|
|
|
|
|
+ &prepared_statement,
|
|
|
|
|
+ placeholder_values
|
|
|
|
|
+ .iter()
|
|
|
|
|
+ .map(|x| x.into())
|
|
|
|
|
+ .collect::<Vec<PgValue>>(),
|
|
|
|
|
+ )
|
|
|
|
|
+ .await?;
|
|
|
|
|
+
|
|
|
|
|
+ pin_mut!(stream);
|
|
|
|
|
+
|
|
|
|
|
+ stream
|
|
|
|
|
+ .try_next()
|
|
|
|
|
+ .await?
|
|
|
|
|
+ .map(|row| row.try_get::<_, PgValue>(0).map(|value| value.into()))
|
|
|
|
|
+ .transpose()
|
|
|
|
|
+ },
|
|
|
|
|
+ to_pgsql_error,
|
|
|
|
|
+ )
|
|
|
|
|
+ .await
|
|
|
}
|
|
}
|