diff --git a/butane_cli/src/main.rs b/butane_cli/src/main.rs index 65800c07..6c769156 100644 --- a/butane_cli/src/main.rs +++ b/butane_cli/src/main.rs @@ -115,7 +115,7 @@ fn main() { } } -#[derive(Serialize, Deserialize, Default)] +#[derive(Debug, Default, Deserialize, Serialize)] struct CliState { embedded: bool, } diff --git a/butane_core/src/codegen/dbobj.rs b/butane_core/src/codegen/dbobj.rs index b340ac18..bd60cf93 100644 --- a/butane_core/src/codegen/dbobj.rs +++ b/butane_core/src/codegen/dbobj.rs @@ -7,7 +7,7 @@ use quote::{quote, quote_spanned}; use syn::{spanned::Spanned, Field, ItemStruct}; // Configuration that can be specified with attributes to override default behavior -#[derive(Default)] +#[derive(Debug, Default)] pub struct Config { pub table_name: Option, } diff --git a/butane_core/src/codegen/mod.rs b/butane_core/src/codegen/mod.rs index 6d451357..44ac87d1 100644 --- a/butane_core/src/codegen/mod.rs +++ b/butane_core/src/codegen/mod.rs @@ -531,6 +531,7 @@ fn sqlval_from_lit(lit: Lit) -> std::result::Result { } } +#[derive(Debug)] struct CustomTypeInfo { name: String, ty: DeferredSqlType, diff --git a/butane_core/src/custom.rs b/butane_core/src/custom.rs index 8b9ca4c7..40c1ac60 100644 --- a/butane_core/src/custom.rs +++ b/butane_core/src/custom.rs @@ -9,14 +9,14 @@ use serde::{Deserialize, Serialize}; use std::fmt; /// For use with [SqlType::Custom](crate::SqlType) -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum SqlTypeCustom { #[cfg(feature = "pg")] Pg(#[serde(with = "pgtypeser")] postgres::types::Type), } /// For use with [SqlVal::Custom](crate::SqlVal) -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum SqlValCustom { #[cfg(feature = "pg")] Pg { @@ -151,7 +151,7 @@ mod pgtypeser { } //Serializable version of postgres::types::Type - #[derive(Serialize, Deserialize, Clone)] + #[derive(Clone, Debug, Deserialize, Serialize)] struct SerializablePgType { name: String, oid: u32, @@ -174,7 +174,7 @@ mod pgtypeser { } } - #[derive(Serialize, Deserialize, Clone)] + #[derive(Clone, Debug, Deserialize, Serialize)] enum SerializablePgKind { Simple, Enum(Vec), @@ -217,7 +217,7 @@ mod pgtypeser { } } - #[derive(Serialize, Deserialize, Clone)] + #[derive(Clone, Debug, Deserialize, Serialize)] struct SerializablePgField { name: String, ty: SerializablePgType, diff --git a/butane_core/src/db/connmethods.rs b/butane_core/src/db/connmethods.rs index 85078ec4..71cf74dc 100644 --- a/butane_core/src/db/connmethods.rs +++ b/butane_core/src/db/connmethods.rs @@ -57,6 +57,7 @@ pub trait ConnectionMethods { /// Represents a database column. Most users do not need to use this /// directly. +#[derive(Debug)] pub struct Column { name: &'static str, ty: SqlType, @@ -134,6 +135,7 @@ pub trait ConnectionMethodWrapper { fn wrapped_connection_methods(&self) -> Result<&Self::Wrapped>; } +#[derive(Debug)] pub(crate) struct VecRows { rows: Vec, idx: usize, diff --git a/butane_core/src/db/mod.rs b/butane_core/src/db/mod.rs index c6779899..8c45beb8 100644 --- a/butane_core/src/db/mod.rs +++ b/butane_core/src/db/mod.rs @@ -16,6 +16,7 @@ use crate::query::BoolExpr; use crate::{migrations::adb, Error, Result, SqlVal, SqlValRef}; use serde::{Deserialize, Serialize}; use std::borrow::Cow; +use std::fmt::Debug; use std::fs; use std::io::Write; use std::ops::{Deref, DerefMut}; @@ -42,7 +43,7 @@ pub use connmethods::{ }; /// Database connection. -pub trait BackendConnection: ConnectionMethods + Send + 'static { +pub trait BackendConnection: ConnectionMethods + Debug + Send + 'static { /// Begin a database transaction. The transaction object must be /// used in place of this connection until it is committed and aborted. fn transaction(&mut self) -> Result; @@ -56,6 +57,7 @@ pub trait BackendConnection: ConnectionMethods + Send + 'static { /// Database connection. May be a connection to any type of database /// as it is a boxed abstraction over a specific connection. +#[derive(Debug)] pub struct Connection { conn: Box, } @@ -88,7 +90,7 @@ connection_method_wrapper!(Connection); /// Connection specification. Contains the name of a database backend /// and the backend-specific connection string. See [connect][crate::db::connect] /// to make a [Connection][crate::db::Connection] from a `ConnectionSpec`. -#[derive(Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] pub struct ConnectionSpec { pub backend_name: String, pub conn_str: String, @@ -166,7 +168,7 @@ pub fn connect(spec: &ConnectionSpec) -> Result { .connect(&spec.conn_str) } -trait BackendTransaction<'c>: ConnectionMethods { +trait BackendTransaction<'c>: ConnectionMethods + Debug { /// Commit the transaction Unfortunately because we use this as a /// trait object, we can't consume self. It should be understood /// that no methods should be called after commit. This trait is @@ -184,6 +186,7 @@ trait BackendTransaction<'c>: ConnectionMethods { /// /// Begin a transaction using the `BackendConnection` /// [`transaction`][crate::db::BackendConnection::transaction] method. +#[derive(Debug)] pub struct Transaction<'c> { trans: Box + 'c>, } diff --git a/butane_core/src/db/pg.rs b/butane_core/src/db/pg.rs index 37ebad45..777c00eb 100644 --- a/butane_core/src/db/pg.rs +++ b/butane_core/src/db/pg.rs @@ -18,7 +18,7 @@ use std::fmt::Write; pub const BACKEND_NAME: &str = "pg"; /// Pg [Backend][crate::db::Backend] implementation. -#[derive(Default)] +#[derive(Debug, Default)] pub struct PgBackend {} impl PgBackend { pub fn new() -> PgBackend { @@ -53,11 +53,15 @@ impl Backend for PgBackend { /// Pg database connection. pub struct PgConnection { + #[cfg(feature = "debug")] + params: Box, conn: RefCell, } impl PgConnection { fn open(params: &str) -> Result { Ok(PgConnection { + #[cfg(feature = "debug")] + params: params.into(), conn: RefCell::new(Self::connect(params)?), }) } @@ -95,6 +99,16 @@ impl BackendConnection for PgConnection { self.conn.borrow().is_closed() } } +impl Debug for PgConnection { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut d = f.debug_struct("PgConnection"); + #[cfg(feature = "debug")] + d.field("params", &self.params); + // postgres::Client doesnt expose any internal state + d.field("conn", &!self.is_closed()); + d.finish() + } +} type DynToSqlPg<'a> = (dyn postgres::types::ToSql + Sync + 'a); @@ -316,6 +330,15 @@ impl<'c> PgTransaction<'c> { Error::Internal("transaction has already been consumed".to_string()) } } +impl<'c> Debug for PgTransaction<'c> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("PgTransaction") + // postgres::Transaction doesnt expose any internal state + .field("trans", &self.trans.is_some()) + .finish() + } +} + impl<'c> PgConnectionLike for PgTransaction<'c> { type Client = postgres::Transaction<'c>; fn cell(&self) -> Result<&RefCell> { @@ -706,6 +729,7 @@ fn pgtype_for_val(val: &SqlVal) -> postgres::types::Type { } } +#[derive(Debug)] struct PgPlaceholderSource { n: i8, } diff --git a/butane_core/src/db/r2.rs b/butane_core/src/db/r2.rs index b208aada..e76c9256 100644 --- a/butane_core/src/db/r2.rs +++ b/butane_core/src/db/r2.rs @@ -4,6 +4,7 @@ use crate::Result; pub use r2d2::ManageConnection; /// R2D2 support for Butane. Implements [`r2d2::ManageConnection`]. +#[derive(Debug)] pub struct ConnectionManager { spec: ConnectionSpec, } diff --git a/butane_core/src/db/sqlite.rs b/butane_core/src/db/sqlite.rs index b1fd8e5c..fb5b1203 100644 --- a/butane_core/src/db/sqlite.rs +++ b/butane_core/src/db/sqlite.rs @@ -22,7 +22,7 @@ const SQLITE_DT_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; pub const BACKEND_NAME: &str = "sqlite"; /// SQLite [Backend][crate::db::Backend] implementation. -#[derive(Default)] +#[derive(Debug, Default)] pub struct SQLiteBackend {} impl SQLiteBackend { pub fn new() -> SQLiteBackend { @@ -60,6 +60,7 @@ impl Backend for SQLiteBackend { } /// SQLite database connection. +#[derive(Debug)] pub struct SQLiteConnection { conn: rusqlite::Connection, } @@ -249,6 +250,7 @@ impl ConnectionMethods for rusqlite::Connection { } } +#[derive(Debug)] struct SqliteTransaction<'c> { trans: Option>, } @@ -329,6 +331,7 @@ fn sqlvalref_to_sqlite<'a>(valref: &SqlValRef<'a>) -> rusqlite::types::ToSqlOutp } #[pin_project] +// Debug can not be derived because rusqlite::Rows doesn't implement it. struct QueryAdapterInner<'a> { stmt: rusqlite::Statement<'a>, // will always be Some when the constructor has finished. We use an option only to get the @@ -363,6 +366,7 @@ impl<'a> QueryAdapterInner<'a> { } } +// Debug can not be derived because QueryAdapterInner above doesn't implement it. struct QueryAdapter<'a> { inner: Pin>>, } @@ -608,6 +612,7 @@ pub fn sql_insert_or_update(table: &str, columns: &[Column], w: &mut impl Write) write!(w, ")").unwrap(); } +#[derive(Debug)] struct SQLitePlaceholderSource {} impl SQLitePlaceholderSource { fn new() -> Self { diff --git a/butane_core/src/fkey.rs b/butane_core/src/fkey.rs index 86bc10ef..44fd4f5e 100644 --- a/butane_core/src/fkey.rs +++ b/butane_core/src/fkey.rs @@ -20,7 +20,6 @@ use std::fmt::{Debug, Formatter}; /// blog: ForeignKey, /// ... /// } -/// pub struct ForeignKey where T: DataObject, diff --git a/butane_core/src/lib.rs b/butane_core/src/lib.rs index 0e33bb39..10ae6d38 100644 --- a/butane_core/src/lib.rs +++ b/butane_core/src/lib.rs @@ -32,7 +32,7 @@ pub type Result = std::result::Result; /// in the database yet. Butane automatically creates the field /// `state: ObjectState` on `#[model]` structs. When initializing the /// state field, use `ObjectState::default()`. -#[derive(Clone, Default, Debug)] +#[derive(Clone, Debug, Default)] pub struct ObjectState { pub saved: bool, } @@ -202,7 +202,7 @@ impl From for Error { /// Enumeration of the types a database value may take. /// /// See also [`SqlVal`][crate::SqlVal]. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum SqlType { Bool, /// 4 bytes diff --git a/butane_core/src/many.rs b/butane_core/src/many.rs index e27cc7a9..aa84d89b 100644 --- a/butane_core/src/many.rs +++ b/butane_core/src/many.rs @@ -16,7 +16,7 @@ fn default_oc() -> OnceCell> { /// U::PKType. Table name is T_ManyToMany_foo where foo is the name of /// the Many field // -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct Many where T: DataObject, diff --git a/butane_core/src/migrations/adb.rs b/butane_core/src/migrations/adb.rs index 0209cd71..553d443e 100644 --- a/butane_core/src/migrations/adb.rs +++ b/butane_core/src/migrations/adb.rs @@ -11,7 +11,7 @@ use std::collections::{HashMap, HashSet}; /// [SqlType](crate::SqlType) and identifiers known only by name. The /// latter is used for custom types. `SqlType::Custom` cannot easily be used /// directly at compile time when the proc macro serializing type information runs. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum TypeIdentifier { Ty(SqlType), Name(String), @@ -23,7 +23,7 @@ impl From for TypeIdentifier { } /// Key used to help resolve `DeferredSqlType` -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub enum TypeKey { /// Represents a type which is the primary key for a table with the given name PK(String), @@ -60,6 +60,8 @@ impl<'de> Deserialize<'de> for TypeKey { deserializer.deserialize_string(TypeKeyVisitor) } } + +#[derive(Debug)] struct TypeKeyVisitor; impl<'de> Visitor<'de> for TypeKeyVisitor { type Value = TypeKey; @@ -138,7 +140,7 @@ impl TypeResolver { } /// Abstract representation of a database schema. -#[derive(Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct ADB { tables: HashMap, extra_types: HashMap, @@ -246,7 +248,7 @@ impl ADB { } /// Abstract representation of a database table schema. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct ATable { pub name: String, pub columns: Vec, @@ -280,7 +282,7 @@ impl ATable { } /// SqlType which may not yet be known. -#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] +#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub enum DeferredSqlType { Known(SqlType), // Kept for backwards deserialization compat, supplanted by KnownId KnownId(TypeIdentifier), @@ -311,7 +313,7 @@ impl From for DeferredSqlType { } /// Abstract representation of a database column schema. -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct AColumn { name: String, sqltype: DeferredSqlType, @@ -386,7 +388,7 @@ impl AColumn { } /// Individual operation use to apply a migration. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub enum Operation { //future improvement: support column renames AddTable(ATable), diff --git a/butane_core/src/migrations/fs.rs b/butane_core/src/migrations/fs.rs index 6dc849d9..705fa2eb 100644 --- a/butane_core/src/migrations/fs.rs +++ b/butane_core/src/migrations/fs.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; @@ -5,7 +6,7 @@ use std::path::{Path, PathBuf}; /// allow bypassing the real filesystem during testing, but /// implementations that do not call through to the real filesystem /// are supported in production. -pub trait Filesystem { +pub trait Filesystem: Debug { /// Ensure a directory exists, recursively creating missing components fn ensure_dir(&self, path: &Path) -> std::io::Result<()>; /// List all paths in a directory @@ -16,6 +17,7 @@ pub trait Filesystem { fn read(&self, path: &Path) -> std::io::Result>; } +#[derive(Debug)] pub struct OsFilesystem {} impl Filesystem for OsFilesystem { diff --git a/butane_core/src/migrations/fsmigrations.rs b/butane_core/src/migrations/fsmigrations.rs index c2d5e424..450ae994 100644 --- a/butane_core/src/migrations/fsmigrations.rs +++ b/butane_core/src/migrations/fsmigrations.rs @@ -15,7 +15,7 @@ use std::rc::Rc; type SqlTypeMap = BTreeMap; const TYPES_FILENAME: &str = "types.json"; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] struct MigrationInfo { /// The migration this one is based on, or None if this is the /// first migration in the chain @@ -31,7 +31,7 @@ impl MigrationInfo { } } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] struct MigrationsState { latest: Option, } @@ -42,6 +42,7 @@ impl MigrationsState { } /// A migration stored in the filesystem +#[derive(Debug)] pub struct FsMigration { fs: Rc, root: PathBuf, @@ -235,6 +236,7 @@ impl PartialEq for FsMigration { impl Eq for FsMigration {} /// A collection of migrations stored in the filesystem. +#[derive(Debug)] pub struct FsMigrations { fs: Rc, root: PathBuf, @@ -341,6 +343,7 @@ impl MigrationsMut for FsMigrations { } } +#[derive(Debug)] struct MigrationLock { file: File, } diff --git a/butane_core/src/migrations/memmigrations.rs b/butane_core/src/migrations/memmigrations.rs index e194ec3b..9f348beb 100644 --- a/butane_core/src/migrations/memmigrations.rs +++ b/butane_core/src/migrations/memmigrations.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use std::collections::HashMap; /// A migration stored in memory. -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct MemMigration { name: String, db: ADB, @@ -91,7 +91,7 @@ impl MigrationMut for MemMigration { } /// A collection of migrations stored in memory. -#[derive(Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize)] pub struct MemMigrations { migrations: HashMap, current: MemMigration, diff --git a/butane_core/src/migrations/migration.rs b/butane_core/src/migrations/migration.rs index b73b5d39..e00a525c 100644 --- a/butane_core/src/migrations/migration.rs +++ b/butane_core/src/migrations/migration.rs @@ -5,6 +5,7 @@ use crate::query::{BoolExpr, Expr}; use crate::{db, sqlval::ToSql, DataObject, DataResult, Error, Result}; use std::borrow::Cow; use std::cmp::PartialEq; +use std::fmt::Debug; /// Type representing a database migration. A migration describes how /// to bring the database from state A to state B. In general, the @@ -13,7 +14,7 @@ use std::cmp::PartialEq; /// /// A Migration cannot be constructed directly, only retrieved from /// [Migrations][crate::migrations::Migrations]. -pub trait Migration: PartialEq { +pub trait Migration: Debug + PartialEq { /// Retrieves the full abstract database state describing all tables fn db(&self) -> Result; diff --git a/butane_core/src/migrations/mod.rs b/butane_core/src/migrations/mod.rs index b4fba4cc..30758404 100644 --- a/butane_core/src/migrations/mod.rs +++ b/butane_core/src/migrations/mod.rs @@ -232,7 +232,7 @@ pub fn copy_migration(from: &impl Migration, to: &mut impl MigrationMut) -> Resu Ok(()) } -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] struct ButaneMigration { name: String, } diff --git a/butane_core/src/query/fieldexpr.rs b/butane_core/src/query/fieldexpr.rs index 91ed621e..f90ff518 100644 --- a/butane_core/src/query/fieldexpr.rs +++ b/butane_core/src/query/fieldexpr.rs @@ -37,6 +37,7 @@ impl DataOrd for Option where T: PartialOrd + FieldType {} impl DataOrd for T where T: PartialOrd + FieldType {} /// Used to implement the `query!` and `filter!` macros. +#[derive(Debug)] pub struct FieldExpr where T: Into, @@ -94,6 +95,7 @@ impl FieldExpr> { } } +#[derive(Debug)] pub struct ManyFieldExpr where O: DataObject, // owner diff --git a/butane_core/src/query/mod.rs b/butane_core/src/query/mod.rs index d6e88599..6a38b568 100644 --- a/butane_core/src/query/mod.rs +++ b/butane_core/src/query/mod.rs @@ -15,7 +15,7 @@ pub use fieldexpr::{DataOrd, FieldExpr, ManyFieldExpr}; type TblName = Cow<'static, str>; /// Abstract representation of a database expression. -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Expr { /// A column, referenced by name. Column(&'static str), @@ -28,7 +28,7 @@ pub enum Expr { } /// Abstract representation of a boolean expression. -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum BoolExpr { True, Eq(&'static str, Expr), @@ -65,20 +65,20 @@ pub enum BoolExpr { } /// Represents the direction of a sort. -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum OrderDirection { Ascending, Descending, } /// Represents a sorting term (ORDER BY in SQL). -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Order { pub direction: OrderDirection, pub column: &'static str, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub enum Join { /// Inner join `join_table` where `col1` is equal to /// `col2` @@ -89,7 +89,7 @@ pub enum Join { }, } -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Column { table: Option, name: &'static str, @@ -113,7 +113,7 @@ impl Column { } /// Representation of a database query. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Query { table: TblName, filter: Option, diff --git a/butane_core/src/sqlval.rs b/butane_core/src/sqlval.rs index 98e778bd..b8ea3128 100644 --- a/butane_core/src/sqlval.rs +++ b/butane_core/src/sqlval.rs @@ -62,7 +62,7 @@ impl SqlValRef<'_> { /// /// [`FromSql`]: crate::FromSql /// [`ToSql`]: crate::ToSql -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub enum SqlVal { Null, Bool(bool),