Skip to content

Commit 9361a43

Browse files
committed
Create custom-pg feature
1 parent b5c0f74 commit 9361a43

File tree

8 files changed

+43
-12
lines changed

8 files changed

+43
-12
lines changed

butane/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ build = "build.rs"
1515
[features]
1616
async = ["butane_core/async", "butane_codegen/async"]
1717
async-adapter = ["butane_core/async-adapter"]
18+
custom-pg = ["butane_core/custom-pg"]
1819
deadpool = ["dep:deadpool", "async"]
1920
default = ["datetime", "json", "uuid"]
2021
fake = ["butane_core/fake"]

butane_core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ repository.workspace = true
1212
[features]
1313
async-adapter = ["async", "crossbeam-channel"]
1414
async = ["tokio"]
15+
custom-pg = ["pg"]
1516
datetime = ["chrono", "tokio-postgres?/with-chrono-0_4"]
1617
debug = ["log", "maybe-async-cfg/debug"]
1718
fake = ["dep:fake", "rand"]

butane_core/src/db/helper.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,16 @@ pub fn column_default(col: &AColumn) -> Result<SqlVal> {
240240
SqlType::Timestamp => {
241241
SqlVal::Timestamp(chrono::DateTime::from_timestamp(0, 0).unwrap().naive_utc())
242242
}
243+
#[cfg(feature = "custom-pg")]
243244
SqlType::Custom(_) => return Err(Error::NoCustomDefault),
244245
},
245-
TypeIdentifier::Name(_) => return Err(Error::NoCustomDefault),
246+
TypeIdentifier::Name(_) => {
247+
// TODO: fixme
248+
#[cfg(feature = "custom-pg")]
249+
return Err(Error::NoCustomDefault);
250+
#[cfg(not(feature = "custom-pg"))]
251+
return Err(Error::NotInitialized);
252+
}
246253
})
247254
}
248255

@@ -307,6 +314,7 @@ pub fn sql_literal_value(val: &SqlVal) -> Result<String> {
307314
Json(val) => Ok(format!("{val}")),
308315
#[cfg(feature = "datetime")]
309316
Timestamp(ndt) => Ok(ndt.format("'%Y-%m-%dT%H:%M:%S%.f'").to_string()),
317+
#[cfg(feature = "custom-pg")]
310318
Custom(val) => Err(Error::LiteralForCustomUnsupported(*(*val).clone())),
311319
}
312320
}

butane_core/src/db/pg.rs

+12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::borrow::Cow;
33
use std::fmt::{Debug, Write};
44

55
use async_trait::async_trait;
6+
#[cfg(feature = "custom-pg")]
67
use bytes::BufMut;
78
#[cfg(feature = "datetime")]
89
use chrono::NaiveDateTime;
@@ -12,6 +13,7 @@ use tokio_postgres::GenericClient;
1213

1314
use super::connmethods::VecRows;
1415
use super::helper;
16+
#[cfg(feature = "custom-pg")]
1517
use crate::custom::{SqlTypeCustom, SqlValRefCustom};
1618
use crate::db::{
1719
Backend, BackendConnectionAsync as BackendConnection, BackendRow,
@@ -449,10 +451,12 @@ impl postgres::types::ToSql for SqlValRef<'_> {
449451
#[cfg(feature = "datetime")]
450452
Timestamp(dt) => dt.to_sql_checked(requested_ty, out),
451453
Null => Ok(postgres::types::IsNull::Yes),
454+
#[cfg(feature = "custom-pg")]
452455
Custom(SqlValRefCustom::PgToSql { ty, tosql }) => {
453456
check_type_match(ty, requested_ty)?;
454457
tosql.to_sql_checked(requested_ty, out)
455458
}
459+
#[cfg(feature = "custom-pg")]
456460
Custom(SqlValRefCustom::PgBytes { ty, data }) => {
457461
check_type_match(ty, requested_ty)?;
458462
out.put(*data);
@@ -469,6 +473,7 @@ impl postgres::types::ToSql for SqlValRef<'_> {
469473
postgres::types::to_sql_checked!();
470474
}
471475

476+
#[cfg(feature = "custom-pg")]
472477
fn check_type_match(
473478
ty1: &postgres::types::Type,
474479
ty2: &postgres::types::Type,
@@ -505,10 +510,15 @@ impl<'a> postgres::types::FromSql<'a> for SqlValRef<'a> {
505510
)?)),
506511
#[cfg(feature = "datetime")]
507512
Type::TIMESTAMP => Ok(SqlValRef::Timestamp(NaiveDateTime::from_sql(ty, raw)?)),
513+
#[cfg(feature = "custom-pg")]
508514
_ => Ok(SqlValRef::Custom(SqlValRefCustom::PgBytes {
509515
ty: ty.clone(),
510516
data: raw,
511517
})),
518+
#[cfg(not(feature = "custom-pg"))]
519+
_ => Err(Box::new(crate::Error::Internal(format!(
520+
"postgres type {ty} not supported"
521+
)))),
512522
}
513523
}
514524

@@ -713,6 +723,7 @@ fn col_sqltype(col: &AColumn) -> Result<Cow<str>> {
713723
SqlType::Blob => Cow::Borrowed("BYTEA"),
714724
#[cfg(feature = "json")]
715725
SqlType::Json => Cow::Borrowed("JSONB"),
726+
#[cfg(feature = "custom-pg")]
716727
SqlType::Custom(c) => match c {
717728
SqlTypeCustom::Pg(ref ty) => Cow::Owned(ty.name().to_string()),
718729
},
@@ -905,6 +916,7 @@ fn pgtype_for_val(val: &SqlVal) -> postgres::types::Type {
905916
Some(SqlType::Json) => postgres::types::Type::JSON,
906917
#[cfg(feature = "datetime")]
907918
Some(SqlType::Timestamp) => postgres::types::Type::TIMESTAMP,
919+
#[cfg(feature = "custom-pg")]
908920
Some(SqlType::Custom(inner)) => match inner {
909921
#[cfg(feature = "pg")]
910922
SqlTypeCustom::Pg(ty, ..) => ty,

butane_core/src/db/sqlite.rs

-3
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,6 @@ fn sqlvalref_to_sqlite<'a>(valref: &SqlValRef<'a>) -> rusqlite::types::ToSqlOutp
518518
Owned(Value::Text(f.to_string()))
519519
}
520520
Null => Owned(Value::Null),
521-
Custom(_) => panic!("Custom types not supported in sqlite"),
522521
}
523522
}
524523

@@ -631,7 +630,6 @@ fn sql_valref_from_rusqlite<'a>(
631630
SQLITE_DT_FORMAT,
632631
)?),
633632
SqlType::Blob => SqlValRef::Blob(val.as_blob()?),
634-
SqlType::Custom(v) => return Err(Error::IncompatibleCustomT(v.clone(), BACKEND_NAME)),
635633
})
636634
}
637635

@@ -748,7 +746,6 @@ fn sqltype(ty: &SqlType) -> &'static str {
748746
SqlType::Json => "TEXT",
749747
#[cfg(feature = "datetime")]
750748
SqlType::Timestamp => "TEXT",
751-
SqlType::Custom(_) => panic!("Custom types not supported by sqlite backend"),
752749
}
753750
}
754751

butane_core/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
1010
use thiserror::Error as ThisError;
1111

1212
pub mod codegen;
13+
#[cfg(feature = "custom-pg")]
1314
pub mod custom;
1415
pub mod db;
1516
pub mod fkey;
@@ -25,6 +26,7 @@ mod autopk;
2526
mod util;
2627

2728
pub use autopk::AutoPk;
29+
#[cfg(feature = "custom-pg")]
2830
use custom::SqlTypeCustom;
2931
use db::{BackendRow, Column, ConnectionMethods};
3032
pub use query::Query;
@@ -266,14 +268,18 @@ pub enum Error {
266268
CannotResolveType(String),
267269
#[error("Auto fields are only supported for integer fields. {0} cannot be auto.")]
268270
InvalidAuto(String),
271+
#[cfg(feature = "custom-pg")]
269272
#[error("No implicit default available for custom sql types.")]
270273
NoCustomDefault,
271274
#[error("No enum variant named '{0}'")]
272275
UnknownEnumVariant(String),
276+
#[cfg(feature = "custom-pg")]
273277
#[error("Backend {1} is not compatible with custom SqlVal {0:?}")]
274278
IncompatibleCustom(custom::SqlValCustom, &'static str),
279+
#[cfg(feature = "custom-pg")]
275280
#[error("Backend {1} is not compatible with custom SqlType {0:?}")]
276281
IncompatibleCustomT(custom::SqlTypeCustom, &'static str),
282+
#[cfg(feature = "custom-pg")]
277283
#[error("Literal values for custom types are currently unsupported.")]
278284
LiteralForCustomUnsupported(custom::SqlValCustom),
279285
#[error("This DataObject doesn't support determining whether it has been saved.")]
@@ -369,6 +375,7 @@ pub enum SqlType {
369375
#[cfg(feature = "json")]
370376
/// JSON
371377
Json,
378+
#[cfg(feature = "custom-pg")]
372379
/// Custom SQL type
373380
Custom(SqlTypeCustom),
374381
}
@@ -386,6 +393,7 @@ impl std::fmt::Display for SqlType {
386393
Blob => "blob",
387394
#[cfg(feature = "json")]
388395
Json => "json",
396+
#[cfg(feature = "custom-pg")]
389397
Custom(_) => "custom",
390398
}
391399
.fmt(f)

butane_core/src/sqlval.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use std::fmt;
1111
use chrono::{naive::NaiveDateTime, DateTime};
1212
use serde::{Deserialize, Serialize};
1313

14-
#[cfg(feature = "pg")]
14+
#[cfg(feature = "custom-pg")]
1515
use crate::custom::SqlTypeCustom;
16+
#[cfg(feature = "custom-pg")]
1617
use crate::custom::{SqlValCustom, SqlValRefCustom};
1718
use crate::{DataObject, Error::CannotConvertSqlVal, Result, SqlType};
1819

@@ -29,6 +30,7 @@ pub enum SqlValRef<'a> {
2930
Json(serde_json::Value),
3031
#[cfg(feature = "datetime")]
3132
Timestamp(NaiveDateTime), // NaiveDateTime is Copy
33+
#[cfg(feature = "custom-pg")]
3234
Custom(SqlValRefCustom<'a>),
3335
}
3436
impl SqlValRef<'_> {
@@ -46,7 +48,7 @@ impl SqlValRef<'_> {
4648
SqlValRef::Blob(_) => Some(SqlType::Blob),
4749
#[cfg(feature = "json")]
4850
SqlValRef::Json(_) => Some(SqlType::Json),
49-
#[cfg(feature = "pg")]
51+
#[cfg(feature = "custom-pg")]
5052
SqlValRef::Custom(c) => match c {
5153
SqlValRefCustom::PgToSql { ty, .. } => {
5254
Some(SqlType::Custom(SqlTypeCustom::Pg(ty.clone())))
@@ -55,8 +57,6 @@ impl SqlValRef<'_> {
5557
Some(SqlType::Custom(SqlTypeCustom::Pg(ty.clone())))
5658
}
5759
},
58-
#[cfg(not(feature = "pg"))]
59-
SqlValRef::Custom(_) => None,
6060
}
6161
}
6262
}
@@ -80,6 +80,7 @@ pub enum SqlVal {
8080
Json(serde_json::Value),
8181
#[cfg(feature = "datetime")]
8282
Timestamp(NaiveDateTime),
83+
#[cfg(feature = "custom-pg")]
8384
Custom(Box<SqlValCustom>),
8485
}
8586
impl SqlVal {
@@ -165,11 +166,11 @@ impl SqlVal {
165166
SqlVal::Blob(_) => Some(SqlType::Blob),
166167
#[cfg(feature = "json")]
167168
SqlVal::Json(_) => Some(SqlType::Json),
168-
#[cfg(feature = "pg")]
169+
#[cfg(feature = "custom-pg")]
169170
SqlVal::Custom(c) => match c.as_ref() {
170171
SqlValCustom::Pg { ty, .. } => Some(SqlType::Custom(SqlTypeCustom::Pg(ty.clone()))),
171172
},
172-
#[cfg(not(feature = "pg"))]
173+
#[cfg(feature = "custom-pg")]
173174
SqlVal::Custom(_) => None,
174175
}
175176
}
@@ -189,6 +190,7 @@ impl fmt::Display for SqlVal {
189190
Json(val) => f.write_str(val.as_str().unwrap()),
190191
#[cfg(feature = "datetime")]
191192
Timestamp(val) => val.format("%+").fmt(f),
193+
#[cfg(feature = "custom-pg")]
192194
Custom(val) => val.fmt(f),
193195
}
194196
}
@@ -255,6 +257,7 @@ impl From<SqlValRef<'_>> for SqlVal {
255257
Json(v) => SqlVal::Json(v),
256258
#[cfg(feature = "datetime")]
257259
Timestamp(v) => SqlVal::Timestamp(v),
260+
#[cfg(feature = "custom-pg")]
258261
Custom(v) => SqlVal::Custom(Box::new(v.into())),
259262
}
260263
}
@@ -275,6 +278,7 @@ impl<'a> From<&'a SqlVal> for SqlValRef<'a> {
275278
Json(v) => SqlValRef::Json(v.to_owned()),
276279
#[cfg(feature = "datetime")]
277280
Timestamp(v) => SqlValRef::Timestamp(*v),
281+
#[cfg(feature = "custom-pg")]
278282
Custom(v) => SqlValRef::Custom(v.as_valref()),
279283
}
280284
}

examples/custom_pg/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ pg = ["butane/pg"]
1717

1818

1919
[dependencies]
20-
butane = {workspace = true, features = ["async", "pg"]}
21-
butane_core = {workspace = true, features = ["async", "pg"]}
20+
butane = {workspace = true, features = ["async", "custom-pg"] }
21+
butane_core = {workspace = true, features = ["async", "custom-pg"]}
2222
butane_test_helper = { workspace = true, default-features = false, features = ["pg"] }
2323
butane_test_macros.workspace = true
2424
cfg-if = { workspace = true }

0 commit comments

Comments
 (0)