From 17645a3e406af64b577d99927957dac70fc64ddc Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 19 Aug 2024 23:01:58 +0200 Subject: [PATCH 1/5] feat: implement `Self::with_init_sql` for relational databases --- Cargo.toml | 4 ++-- src/lib.rs | 27 +++++++++++++++++++++++++ src/mariadb/mod.rs | 40 +++++++++++++++++++++++++++++++++--- src/mysql/mod.rs | 41 +++++++++++++++++++++++++++++++++++-- src/postgres/mod.rs | 49 +++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 152 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f8db643..6c11585 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ kwok = [] [dependencies] # TODO: update parse-display after MSRV>=1.80.0 bump of `testcontainer-rs` and `testcontainers-modules` parse-display = { version = "0.9.1", optional = true, default-features = false, features = [] } -testcontainers = { version = "0.22.0" } +testcontainers = { version = "0.23.0" } [dev-dependencies] @@ -92,7 +92,7 @@ serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" surrealdb = { version = "1.2.0" } tar = "0.4.40" -testcontainers = { version = "0.22.0", features = ["blocking"] } +testcontainers = { version = "0.23.0", features = ["blocking"] } # To use Tiberius on macOS, rustls is needed instead of native-tls # https://github.com/prisma/tiberius/tree/v0.12.2#encryption-tlsssl tiberius = { version = "0.12.2", default-features = false, features = [ diff --git a/src/lib.rs b/src/lib.rs index e1242ce..ebd28bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,3 +145,30 @@ pub mod zookeeper; /// Re-exported version of `testcontainers` to avoid version conflicts pub use testcontainers; + +#[cfg(any(feature = "postgres", feature = "mariadb", feature = "mysql"))] +#[cfg_attr( + docsrs, + doc(cfg(any(feature = "postgres", feature = "mariadb", feature = "mysql"))) +)] +/// Trait to alight interface for users across different modules. +pub trait InitSql { + /// Registers sql to be executed automatically when the container starts. + /// + /// # Example + /// + /// ``` + /// # use testcontainers_modules::postgres::Postgres; + /// # use testcontainers_modules::InitSql; + /// let postgres_image = + /// Postgres::default().with_init_sql("CREATE EXTENSION IF NOT EXISTS hstore;"); + /// ``` + /// + /// ```rust,ignore + /// # use testcontainers_modules::postgres::Postgres; + /// # use testcontainers_modules::rdbms::InitSql; + /// let postgres_image = Postgres::default() + /// .with_init_sql(include_str!("path_to_init.sql")); + /// ``` + fn with_init_sql(self, init_sql: impl ToString) -> Self; +} diff --git a/src/mariadb/mod.rs b/src/mariadb/mod.rs index 7f7e64b..455b499 100644 --- a/src/mariadb/mod.rs +++ b/src/mariadb/mod.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use testcontainers::{core::WaitFor, Image}; +use testcontainers::{core::WaitFor, CopyToContainer, Image}; const NAME: &str = "mariadb"; const TAG: &str = "11.3"; @@ -27,7 +27,7 @@ const TAG: &str = "11.3"; /// [`MariaDB docker image`]: https://hub.docker.com/_/mariadb #[derive(Debug, Default, Clone)] pub struct Mariadb { - _priv: (), + init_sqls: Vec, } impl Image for Mariadb { @@ -54,8 +54,21 @@ impl Image for Mariadb { ("MARIADB_ALLOW_EMPTY_ROOT_PASSWORD", "1"), ] } + fn copy_to_sources(&self) -> impl IntoIterator { + &self.init_sqls + } +} +impl crate::InitSql for Mariadb { + fn with_init_sql(mut self, init_sql: impl ToString) -> Self { + let init_vec = init_sql.to_string().into_bytes(); + let target = format!( + "/docker-entrypoint-initdb.d/init_{i}.sql", + i = self.init_sqls.len() + ); + self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self + } } - #[cfg(test)] mod tests { use mysql::prelude::Queryable; @@ -66,6 +79,27 @@ mod tests { testcontainers::{runners::SyncRunner, ImageExt}, }; + #[test] + fn mariadb_with_init_sql() -> Result<(), Box> { + use crate::InitSql; + let node = MariadbImage::default() + .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .start()?; + + let connection_string = &format!( + "mysql://root@{}:{}/test", + node.get_host()?, + node.get_host_port_ipv4(3306.tcp())? + ); + let mut conn = mysql::Conn::new(mysql::Opts::from_url(connection_string).unwrap()).unwrap(); + + let rows = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); + assert_eq!(rows.len(), 0); + + let rows = conn.query("SELECT bar FROM foo").unwrap(); + assert_eq!(rows.len(), 1); + Ok(()) + } #[test] fn mariadb_one_plus_one() -> Result<(), Box> { let mariadb_image = MariadbImage::default(); diff --git a/src/mysql/mod.rs b/src/mysql/mod.rs index 7a996a7..e6e06ef 100644 --- a/src/mysql/mod.rs +++ b/src/mysql/mod.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use testcontainers::{core::WaitFor, Image}; +use testcontainers::{core::WaitFor, CopyToContainer, Image}; const NAME: &str = "mysql"; const TAG: &str = "8.1"; @@ -27,7 +27,7 @@ const TAG: &str = "8.1"; /// [`MySQL docker image`]: https://hub.docker.com/_/mysql #[derive(Debug, Default, Clone)] pub struct Mysql { - _priv: (), + init_sqls: Vec, } impl Image for Mysql { @@ -54,17 +54,54 @@ impl Image for Mysql { ("MYSQL_ALLOW_EMPTY_PASSWORD", "yes"), ] } + fn copy_to_sources(&self) -> impl IntoIterator { + &self.init_sqls + } +} +impl crate::InitSql for Mysql { + fn with_init_sql(mut self, init_sql: impl ToString) -> Self { + let init_vec = init_sql.to_string().into_bytes(); + let target = format!( + "/docker-entrypoint-initdb.d/init_{i}.sql", + i = self.init_sqls.len() + ); + self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self + } } #[cfg(test)] mod tests { use mysql::prelude::Queryable; + use testcontainers::core::IntoContainerPort; use crate::{ mysql::Mysql as MysqlImage, testcontainers::{runners::SyncRunner, ImageExt}, }; + #[test] + fn mysql_with_init_sql() -> Result<(), Box> { + use crate::InitSql; + let node = crate::mysql::Mysql::default() + .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .start()?; + + let connection_string = &format!( + "mysql://root@{}:{}/test", + node.get_host()?, + node.get_host_port_ipv4(3306.tcp())? + ); + let mut conn = mysql::Conn::new(mysql::Opts::from_url(connection_string).unwrap()).unwrap(); + + let rows = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); + assert_eq!(rows.len(), 0); + + let rows = conn.query("SELECT bar FROM foo").unwrap(); + assert_eq!(rows.len(), 1); + Ok(()) + } + #[test] fn mysql_one_plus_one() -> Result<(), Box> { let mysql_image = MysqlImage::default(); diff --git a/src/postgres/mod.rs b/src/postgres/mod.rs index eaec04e..3642cd1 100644 --- a/src/postgres/mod.rs +++ b/src/postgres/mod.rs @@ -1,6 +1,9 @@ use std::{borrow::Cow, collections::HashMap}; -use testcontainers::{core::WaitFor, Image}; +use testcontainers::{ + core::{Mount, WaitFor}, + CopyToContainer, Image, +}; const NAME: &str = "postgres"; const TAG: &str = "11-alpine"; @@ -30,6 +33,7 @@ const TAG: &str = "11-alpine"; #[derive(Debug, Clone)] pub struct Postgres { env_vars: HashMap, + init_sqls: Vec, } impl Postgres { @@ -62,6 +66,17 @@ impl Postgres { self } } +impl crate::InitSql for Postgres { + fn with_init_sql(mut self, init_sql: impl ToString) -> Self { + let init_vec = init_sql.to_string().into_bytes(); + let target = format!( + "/docker-entrypoint-initdb.d/init_{i}.sql", + i = self.init_sqls.len() + ); + self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self + } +} impl Default for Postgres { fn default() -> Self { @@ -70,7 +85,10 @@ impl Default for Postgres { env_vars.insert("POSTGRES_USER".to_owned(), "postgres".to_owned()); env_vars.insert("POSTGRES_PASSWORD".to_owned(), "postgres".to_owned()); - Self { env_vars } + Self { + env_vars, + init_sqls: Vec::new(), + } } } @@ -95,6 +113,9 @@ impl Image for Postgres { ) -> impl IntoIterator>, impl Into>)> { &self.env_vars } + fn copy_to_sources(&self) -> impl IntoIterator { + &self.init_sqls + } } #[cfg(test)] @@ -144,4 +165,28 @@ mod tests { assert!(first_column.contains("13")); Ok(()) } + + #[test] + fn postgres_with_init_sql() -> Result<(), Box> { + use crate::InitSql; + let node = Postgres::default() + .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .start()?; + + let connection_string = &format!( + "postgres://postgres:postgres@{}:{}/postgres", + node.get_host()?, + node.get_host_port_ipv4(5432)? + ); + let mut conn = postgres::Client::connect(connection_string, postgres::NoTls).unwrap(); + + let rows = conn + .query("INSERT INTO foo(bar) VALUES ($1)", &[&"blub"]) + .unwrap(); + assert_eq!(rows.len(), 0); + + let rows = conn.query("SELECT bar FROM foo", &[]).unwrap(); + assert_eq!(rows.len(), 1); + Ok(()) + } } From 506c5292e2e3d0a259ad414638bfb862b9e4f51d Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Wed, 25 Sep 2024 23:19:23 +0800 Subject: [PATCH 2/5] allign the implementation with #217 --- src/lib.rs | 14 ++++++++++---- src/mariadb/mod.rs | 24 ++++++++++++++---------- src/mysql/mod.rs | 24 ++++++++++++++---------- src/postgres/mod.rs | 25 +++++++++++++------------ 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ebd28bc..4aa1242 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -158,17 +158,23 @@ pub trait InitSql { /// # Example /// /// ``` + /// # #[cfg(feature = "postgres")] + /// # { /// # use testcontainers_modules::postgres::Postgres; /// # use testcontainers_modules::InitSql; - /// let postgres_image = - /// Postgres::default().with_init_sql("CREATE EXTENSION IF NOT EXISTS hstore;"); + /// let postgres_image = Postgres::default().with_init_sql( + /// "CREATE EXTENSION IF NOT EXISTS hstore;" + /// .to_string() + /// .into_bytes(), + /// ); + /// # } /// ``` /// /// ```rust,ignore /// # use testcontainers_modules::postgres::Postgres; /// # use testcontainers_modules::rdbms::InitSql; /// let postgres_image = Postgres::default() - /// .with_init_sql(include_str!("path_to_init.sql")); + /// .with_init_sql(include_str!("path_to_init.sql").to_string().into_bytes()); /// ``` - fn with_init_sql(self, init_sql: impl ToString) -> Self; + fn with_init_sql(self, init_sql: impl Into) -> Self; } diff --git a/src/mariadb/mod.rs b/src/mariadb/mod.rs index 455b499..90edbe4 100644 --- a/src/mariadb/mod.rs +++ b/src/mariadb/mod.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use testcontainers::{core::WaitFor, CopyToContainer, Image}; +use testcontainers::{core::WaitFor, CopyDataSource, CopyToContainer, Image}; const NAME: &str = "mariadb"; const TAG: &str = "11.3"; @@ -27,7 +27,7 @@ const TAG: &str = "11.3"; /// [`MariaDB docker image`]: https://hub.docker.com/_/mariadb #[derive(Debug, Default, Clone)] pub struct Mariadb { - init_sqls: Vec, + copy_to_sources: Vec, } impl Image for Mariadb { @@ -55,17 +55,17 @@ impl Image for Mariadb { ] } fn copy_to_sources(&self) -> impl IntoIterator { - &self.init_sqls + &self.copy_to_sources } } impl crate::InitSql for Mariadb { - fn with_init_sql(mut self, init_sql: impl ToString) -> Self { - let init_vec = init_sql.to_string().into_bytes(); + fn with_init_sql(mut self, init_sql: impl Into) -> Self { let target = format!( "/docker-entrypoint-initdb.d/init_{i}.sql", - i = self.init_sqls.len() + i = self.copy_to_sources.len() ); - self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self.copy_to_sources + .push(CopyToContainer::new(init_sql.into(), target)); self } } @@ -83,7 +83,11 @@ mod tests { fn mariadb_with_init_sql() -> Result<(), Box> { use crate::InitSql; let node = MariadbImage::default() - .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .with_init_sql( + "CREATE TABLE foo (bar varchar(255));" + .to_string() + .into_bytes(), + ) .start()?; let connection_string = &format!( @@ -93,10 +97,10 @@ mod tests { ); let mut conn = mysql::Conn::new(mysql::Opts::from_url(connection_string).unwrap()).unwrap(); - let rows = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); + let rows: Vec = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); assert_eq!(rows.len(), 0); - let rows = conn.query("SELECT bar FROM foo").unwrap(); + let rows: Vec = conn.query("SELECT bar FROM foo").unwrap(); assert_eq!(rows.len(), 1); Ok(()) } diff --git a/src/mysql/mod.rs b/src/mysql/mod.rs index e6e06ef..b1d767a 100644 --- a/src/mysql/mod.rs +++ b/src/mysql/mod.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use testcontainers::{core::WaitFor, CopyToContainer, Image}; +use testcontainers::{core::WaitFor, CopyDataSource, CopyToContainer, Image}; const NAME: &str = "mysql"; const TAG: &str = "8.1"; @@ -27,7 +27,7 @@ const TAG: &str = "8.1"; /// [`MySQL docker image`]: https://hub.docker.com/_/mysql #[derive(Debug, Default, Clone)] pub struct Mysql { - init_sqls: Vec, + copy_to_sources: Vec, } impl Image for Mysql { @@ -55,17 +55,17 @@ impl Image for Mysql { ] } fn copy_to_sources(&self) -> impl IntoIterator { - &self.init_sqls + &self.copy_to_sources } } impl crate::InitSql for Mysql { - fn with_init_sql(mut self, init_sql: impl ToString) -> Self { - let init_vec = init_sql.to_string().into_bytes(); + fn with_init_sql(mut self, init_sql: impl Into) -> Self { let target = format!( "/docker-entrypoint-initdb.d/init_{i}.sql", - i = self.init_sqls.len() + i = self.copy_to_sources.len() ); - self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self.copy_to_sources + .push(CopyToContainer::new(init_sql.into(), target)); self } } @@ -84,7 +84,11 @@ mod tests { fn mysql_with_init_sql() -> Result<(), Box> { use crate::InitSql; let node = crate::mysql::Mysql::default() - .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .with_init_sql( + "CREATE TABLE foo (bar varchar(255));" + .to_string() + .into_bytes(), + ) .start()?; let connection_string = &format!( @@ -94,10 +98,10 @@ mod tests { ); let mut conn = mysql::Conn::new(mysql::Opts::from_url(connection_string).unwrap()).unwrap(); - let rows = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); + let rows: Vec = conn.query("INSERT INTO foo(bar) VALUES ('blub')").unwrap(); assert_eq!(rows.len(), 0); - let rows = conn.query("SELECT bar FROM foo").unwrap(); + let rows: Vec = conn.query("SELECT bar FROM foo").unwrap(); assert_eq!(rows.len(), 1); Ok(()) } diff --git a/src/postgres/mod.rs b/src/postgres/mod.rs index 3642cd1..58ba3d7 100644 --- a/src/postgres/mod.rs +++ b/src/postgres/mod.rs @@ -1,9 +1,6 @@ use std::{borrow::Cow, collections::HashMap}; -use testcontainers::{ - core::{Mount, WaitFor}, - CopyToContainer, Image, -}; +use testcontainers::{core::WaitFor, CopyDataSource, CopyToContainer, Image}; const NAME: &str = "postgres"; const TAG: &str = "11-alpine"; @@ -33,7 +30,7 @@ const TAG: &str = "11-alpine"; #[derive(Debug, Clone)] pub struct Postgres { env_vars: HashMap, - init_sqls: Vec, + copy_to_sources: Vec, } impl Postgres { @@ -67,13 +64,13 @@ impl Postgres { } } impl crate::InitSql for Postgres { - fn with_init_sql(mut self, init_sql: impl ToString) -> Self { - let init_vec = init_sql.to_string().into_bytes(); + fn with_init_sql(mut self, init_sql: impl Into) -> Self { let target = format!( "/docker-entrypoint-initdb.d/init_{i}.sql", - i = self.init_sqls.len() + i = self.copy_to_sources.len() ); - self.init_sqls.push(CopyToContainer::new(init_vec, target)); + self.copy_to_sources + .push(CopyToContainer::new(init_sql.into(), target)); self } } @@ -87,7 +84,7 @@ impl Default for Postgres { Self { env_vars, - init_sqls: Vec::new(), + copy_to_sources: Vec::new(), } } } @@ -114,7 +111,7 @@ impl Image for Postgres { &self.env_vars } fn copy_to_sources(&self) -> impl IntoIterator { - &self.init_sqls + &self.copy_to_sources } } @@ -170,7 +167,11 @@ mod tests { fn postgres_with_init_sql() -> Result<(), Box> { use crate::InitSql; let node = Postgres::default() - .with_init_sql("CREATE TABLE foo (bar varchar(255));") + .with_init_sql( + "CREATE TABLE foo (bar varchar(255));" + .to_string() + .into_bytes(), + ) .start()?; let connection_string = &format!( From 27c1e541416468672d2a430c17a1b6fe40cb88a5 Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Thu, 26 Sep 2024 01:29:42 +0800 Subject: [PATCH 3/5] remove the trait to unify implmentations --- src/lib.rs | 33 --------------------------------- src/mariadb/mod.rs | 43 +++++++++++++++++++++++++++++++------------ src/mysql/mod.rs | 41 +++++++++++++++++++++++++++++------------ src/postgres/mod.rs | 25 ++++++++++++++++++++----- 4 files changed, 80 insertions(+), 62 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4aa1242..e1242ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,36 +145,3 @@ pub mod zookeeper; /// Re-exported version of `testcontainers` to avoid version conflicts pub use testcontainers; - -#[cfg(any(feature = "postgres", feature = "mariadb", feature = "mysql"))] -#[cfg_attr( - docsrs, - doc(cfg(any(feature = "postgres", feature = "mariadb", feature = "mysql"))) -)] -/// Trait to alight interface for users across different modules. -pub trait InitSql { - /// Registers sql to be executed automatically when the container starts. - /// - /// # Example - /// - /// ``` - /// # #[cfg(feature = "postgres")] - /// # { - /// # use testcontainers_modules::postgres::Postgres; - /// # use testcontainers_modules::InitSql; - /// let postgres_image = Postgres::default().with_init_sql( - /// "CREATE EXTENSION IF NOT EXISTS hstore;" - /// .to_string() - /// .into_bytes(), - /// ); - /// # } - /// ``` - /// - /// ```rust,ignore - /// # use testcontainers_modules::postgres::Postgres; - /// # use testcontainers_modules::rdbms::InitSql; - /// let postgres_image = Postgres::default() - /// .with_init_sql(include_str!("path_to_init.sql").to_string().into_bytes()); - /// ``` - fn with_init_sql(self, init_sql: impl Into) -> Self; -} diff --git a/src/mariadb/mod.rs b/src/mariadb/mod.rs index 90edbe4..90c6532 100644 --- a/src/mariadb/mod.rs +++ b/src/mariadb/mod.rs @@ -30,6 +30,36 @@ pub struct Mariadb { copy_to_sources: Vec, } +impl Mariadb { + /// Registers sql to be executed automatically when the container starts. + /// + /// # Example + /// + /// ``` + /// # use testcontainers_modules::mariadb::Mariadb; + /// let mariadb_image = Mariadb::default().with_init_sql( + /// "CREATE EXTENSION IF NOT EXISTS hstore;" + /// .to_string() + /// .into_bytes(), + /// ); + /// ``` + /// + /// ```rust,ignore + /// # use testcontainers_modules::mariadb::Mariadb; + /// let mariadb_image = Mariadb::default() + /// .with_init_sql(include_str!("path_to_init.sql").to_string().into_bytes()); + /// ``` + pub fn with_init_sql(mut self, init_sql: impl Into) -> Self { + let target = format!( + "/docker-entrypoint-initdb.d/init_{i}.sql", + i = self.copy_to_sources.len() + ); + self.copy_to_sources + .push(CopyToContainer::new(init_sql.into(), target)); + self + } +} + impl Image for Mariadb { fn name(&self) -> &str { NAME @@ -58,17 +88,7 @@ impl Image for Mariadb { &self.copy_to_sources } } -impl crate::InitSql for Mariadb { - fn with_init_sql(mut self, init_sql: impl Into) -> Self { - let target = format!( - "/docker-entrypoint-initdb.d/init_{i}.sql", - i = self.copy_to_sources.len() - ); - self.copy_to_sources - .push(CopyToContainer::new(init_sql.into(), target)); - self - } -} + #[cfg(test)] mod tests { use mysql::prelude::Queryable; @@ -81,7 +101,6 @@ mod tests { #[test] fn mariadb_with_init_sql() -> Result<(), Box> { - use crate::InitSql; let node = MariadbImage::default() .with_init_sql( "CREATE TABLE foo (bar varchar(255));" diff --git a/src/mysql/mod.rs b/src/mysql/mod.rs index b1d767a..7013859 100644 --- a/src/mysql/mod.rs +++ b/src/mysql/mod.rs @@ -29,6 +29,35 @@ const TAG: &str = "8.1"; pub struct Mysql { copy_to_sources: Vec, } +impl Mysql { + /// Registers sql to be executed automatically when the container starts. + /// + /// # Example + /// + /// ``` + /// # use testcontainers_modules::mysql::Mysql; + /// let mysql_image = Mysql::default().with_init_sql( + /// "CREATE TABLE foo (bar varchar(255));" + /// .to_string() + /// .into_bytes(), + /// ); + /// ``` + /// + /// ```rust,ignore + /// # use testcontainers_modules::mysql::Mysql; + /// let mysql_image = Mysql::default() + /// .with_init_sql(include_str!("path_to_init.sql").to_string().into_bytes()); + /// ``` + pub fn with_init_sql(mut self, init_sql: impl Into) -> Self { + let target = format!( + "/docker-entrypoint-initdb.d/init_{i}.sql", + i = self.copy_to_sources.len() + ); + self.copy_to_sources + .push(CopyToContainer::new(init_sql.into(), target)); + self + } +} impl Image for Mysql { fn name(&self) -> &str { @@ -58,17 +87,6 @@ impl Image for Mysql { &self.copy_to_sources } } -impl crate::InitSql for Mysql { - fn with_init_sql(mut self, init_sql: impl Into) -> Self { - let target = format!( - "/docker-entrypoint-initdb.d/init_{i}.sql", - i = self.copy_to_sources.len() - ); - self.copy_to_sources - .push(CopyToContainer::new(init_sql.into(), target)); - self - } -} #[cfg(test)] mod tests { @@ -82,7 +100,6 @@ mod tests { #[test] fn mysql_with_init_sql() -> Result<(), Box> { - use crate::InitSql; let node = crate::mysql::Mysql::default() .with_init_sql( "CREATE TABLE foo (bar varchar(255));" diff --git a/src/postgres/mod.rs b/src/postgres/mod.rs index 58ba3d7..116d2c7 100644 --- a/src/postgres/mod.rs +++ b/src/postgres/mod.rs @@ -62,9 +62,26 @@ impl Postgres { .insert("POSTGRES_PASSWORD".to_owned(), password.to_owned()); self } -} -impl crate::InitSql for Postgres { - fn with_init_sql(mut self, init_sql: impl Into) -> Self { + + /// Registers sql to be executed automatically when the container starts. + /// + /// # Example + /// + /// ``` + /// # use testcontainers_modules::postgres::Postgres; + /// let postgres_image = Postgres::default().with_init_sql( + /// "CREATE EXTENSION IF NOT EXISTS hstore;" + /// .to_string() + /// .into_bytes(), + /// ); + /// ``` + /// + /// ```rust,ignore + /// # use testcontainers_modules::postgres::Postgres; + /// let postgres_image = Postgres::default() + /// .with_init_sql(include_str!("path_to_init.sql").to_string().into_bytes()); + /// ``` + pub fn with_init_sql(mut self, init_sql: impl Into) -> Self { let target = format!( "/docker-entrypoint-initdb.d/init_{i}.sql", i = self.copy_to_sources.len() @@ -74,7 +91,6 @@ impl crate::InitSql for Postgres { self } } - impl Default for Postgres { fn default() -> Self { let mut env_vars = HashMap::new(); @@ -165,7 +181,6 @@ mod tests { #[test] fn postgres_with_init_sql() -> Result<(), Box> { - use crate::InitSql; let node = Postgres::default() .with_init_sql( "CREATE TABLE foo (bar varchar(255));" From 84b70390b231959d57ac36f5e914bae028bbd1da Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Thu, 26 Sep 2024 01:42:44 +0800 Subject: [PATCH 4/5] fixed loading a postgres exstension without postgres --- src/mariadb/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mariadb/mod.rs b/src/mariadb/mod.rs index 90c6532..ce0b738 100644 --- a/src/mariadb/mod.rs +++ b/src/mariadb/mod.rs @@ -38,7 +38,7 @@ impl Mariadb { /// ``` /// # use testcontainers_modules::mariadb::Mariadb; /// let mariadb_image = Mariadb::default().with_init_sql( - /// "CREATE EXTENSION IF NOT EXISTS hstore;" + /// "CREATE TABLE foo (bar varchar(255));" /// .to_string() /// .into_bytes(), /// ); From 7f0a3f9e9e70409dde2254467f4113505611bcdd Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Thu, 26 Sep 2024 16:32:03 +0200 Subject: [PATCH 5/5] made sure that the additive appended aspect of `with_init_sql` is clear --- src/mariadb/mod.rs | 1 + src/mysql/mod.rs | 1 + src/postgres/mod.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/src/mariadb/mod.rs b/src/mariadb/mod.rs index ce0b738..3e086db 100644 --- a/src/mariadb/mod.rs +++ b/src/mariadb/mod.rs @@ -32,6 +32,7 @@ pub struct Mariadb { impl Mariadb { /// Registers sql to be executed automatically when the container starts. + /// Can be called multiple times to add (not override) scripts. /// /// # Example /// diff --git a/src/mysql/mod.rs b/src/mysql/mod.rs index 7013859..6e9ee24 100644 --- a/src/mysql/mod.rs +++ b/src/mysql/mod.rs @@ -31,6 +31,7 @@ pub struct Mysql { } impl Mysql { /// Registers sql to be executed automatically when the container starts. + /// Can be called multiple times to add (not override) scripts. /// /// # Example /// diff --git a/src/postgres/mod.rs b/src/postgres/mod.rs index 116d2c7..b9b590c 100644 --- a/src/postgres/mod.rs +++ b/src/postgres/mod.rs @@ -64,6 +64,7 @@ impl Postgres { } /// Registers sql to be executed automatically when the container starts. + /// Can be called multiple times to add (not override) scripts. /// /// # Example ///