#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
use ormer::generate_create_table_sql;
mod _test_common;
define_test_user!(TestUser, "create_table_users_1");
define_test_complete_types!(TestCompleteTypes, "create_table_complete_types_1");
#[derive(Debug, ormer::Model)]
#[table = "create_table_datetime_pk_1"]
struct TestDateTimePrimaryKey {
#[primary]
update_time: chrono::NaiveDateTime,
message: String,
}
#[cfg(test)]
mod create_table_tests {
use super::*;
async fn test_turso_create_table_sql_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestUser>(config.0)?;
#[allow(unreachable_patterns)]
match config.0 {
#[cfg(not(any(feature = "sqlite", feature = "postgresql", feature = "mysql")))]
ormer::DbType::None => panic!("No database backend available"),
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(sql.contains("id INTEGER PRIMARY KEY"));
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT")); }
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT")); }
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id INT PRIMARY KEY AUTO_INCREMENT")); assert!(sql.contains("name VARCHAR(255) NOT NULL"));
assert!(sql.contains("age INT NOT NULL"));
assert!(sql.contains("email VARCHAR(255)")); }
#[allow(unreachable_patterns)]
_ => {}
}
let db_type_name = match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => "Sqlite",
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => "PostgreSQL",
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => "MySQL",
#[allow(unreachable_patterns)]
_ => "Unknown",
};
println!("{} SQL: {}", db_type_name, sql);
Ok(())
}
async fn test_postgresql_create_table_sql_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestUser>(config.0)?;
match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT"));
println!("Sqlite SQL: {}", sql);
}
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT"));
println!("PostgreSQL SQL: {}", sql);
}
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id INT PRIMARY KEY"));
assert!(sql.contains("name VARCHAR(255) NOT NULL"));
assert!(sql.contains("age INT NOT NULL"));
assert!(sql.contains("email VARCHAR(255)"));
println!("MySQL SQL: {}", sql);
}
#[allow(unreachable_patterns)]
_ => {}
}
Ok(())
}
async fn test_mysql_create_table_sql_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestUser>(config.0)?;
match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT"));
println!("Sqlite SQL: {}", sql);
}
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("name TEXT NOT NULL"));
assert!(sql.contains("age INTEGER NOT NULL"));
assert!(sql.contains("email TEXT"));
println!("PostgreSQL SQL: {}", sql);
}
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id INT PRIMARY KEY"));
assert!(sql.contains("name VARCHAR(255) NOT NULL"));
assert!(sql.contains("age INT NOT NULL"));
assert!(sql.contains("email VARCHAR(255)"));
println!("MySQL SQL: {}", sql);
}
#[allow(unreachable_patterns)]
_ => {}
}
Ok(())
}
async fn test_different_databases_produce_different_sql_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; #[cfg(all(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
{
let turso_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::Sqlite)?;
let pg_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::PostgreSQL)?;
let mysql_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::MySQL)?;
assert_ne!(
turso_sql, pg_sql,
"Sqlite and PostgreSQL SQL should be different"
);
assert_ne!(
turso_sql, mysql_sql,
"Sqlite and MySQL SQL should be different"
);
assert_ne!(
pg_sql, mysql_sql,
"PostgreSQL and MySQL SQL should be different"
);
}
#[cfg(all(feature = "sqlite", feature = "postgresql", not(feature = "mysql")))]
{
let turso_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::Sqlite)?;
let pg_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::PostgreSQL)?;
assert_ne!(turso_sql, pg_sql);
}
#[cfg(all(feature = "sqlite", feature = "mysql", not(feature = "postgresql")))]
{
let turso_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::Sqlite)?;
let mysql_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::MySQL)?;
assert_ne!(turso_sql, mysql_sql);
}
#[cfg(all(feature = "postgresql", feature = "mysql", not(feature = "sqlite")))]
{
let pg_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::PostgreSQL)?;
let mysql_sql = generate_create_table_sql::<TestCompleteTypes>(ormer::DbType::MySQL)?;
assert_ne!(pg_sql, mysql_sql);
}
Ok(())
}
async fn test_postgresql_complete_types_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestCompleteTypes>(config.0)?;
match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT"));
assert!(sql.contains("optional_int INTEGER"));
assert!(sql.contains("bool_val INTEGER NOT NULL"));
assert!(sql.contains("optional_bool INTEGER"));
println!("Sqlite Complete Types SQL: {}", sql);
}
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT"));
assert!(sql.contains("optional_int INTEGER"));
assert!(sql.contains("bool_val BOOLEAN NOT NULL"));
assert!(sql.contains("optional_bool BOOLEAN"));
println!("PostgreSQL Complete Types SQL: {}", sql);
}
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(sql.contains("text_val VARCHAR(255) NOT NULL"));
assert!(sql.contains("optional_text VARCHAR(255)"));
assert!(sql.contains("optional_int INT"));
assert!(sql.contains("bool_val TINYINT(1) NOT NULL"));
assert!(sql.contains("optional_bool TINYINT(1)"));
println!("MySQL Complete Types SQL: {}", sql);
}
#[allow(unreachable_patterns)]
_ => {}
}
Ok(())
}
async fn test_mysql_complete_types_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestCompleteTypes>(config.0)?;
match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(
sql.contains("id SERIAL PRIMARY KEY") || sql.contains("id INTEGER PRIMARY KEY")
);
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT"));
assert!(sql.contains("optional_int INTEGER"));
assert!(sql.contains("bool_val INTEGER NOT NULL"));
assert!(sql.contains("optional_bool INTEGER"));
println!("Sqlite Complete Types SQL: {}", sql);
}
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT"));
assert!(sql.contains("optional_int INTEGER"));
assert!(sql.contains("bool_val BOOLEAN NOT NULL"));
assert!(sql.contains("optional_bool BOOLEAN"));
println!("PostgreSQL Complete Types SQL: {}", sql);
}
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(sql.contains("text_val VARCHAR(255) NOT NULL"));
assert!(sql.contains("optional_text VARCHAR(255)"));
assert!(sql.contains("optional_int INT"));
assert!(sql.contains("bool_val TINYINT(1) NOT NULL"));
assert!(sql.contains("optional_bool TINYINT(1)"));
println!("MySQL Complete Types SQL: {}", sql);
}
#[allow(unreachable_patterns)]
_ => {}
}
Ok(())
}
async fn test_turso_complete_types_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let _ = config; let sql = generate_create_table_sql::<TestCompleteTypes>(config.0)?;
match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => {
assert!(sql.contains("id INTEGER PRIMARY KEY"));
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT")); assert!(sql.contains("optional_int INTEGER")); assert!(sql.contains("bool_val INTEGER NOT NULL"));
assert!(sql.contains("optional_bool INTEGER")); }
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(sql.contains("text_val TEXT NOT NULL"));
assert!(sql.contains("optional_text TEXT"));
assert!(sql.contains("optional_int INTEGER"));
assert!(sql.contains("bool_val BOOLEAN NOT NULL"));
assert!(sql.contains("optional_bool BOOLEAN"));
}
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => {
assert!(sql.contains("id BIGINT PRIMARY KEY"));
assert!(!sql.contains("AUTO_INCREMENT")); assert!(sql.contains("text_val VARCHAR(255) NOT NULL"));
assert!(sql.contains("optional_text VARCHAR(255)"));
assert!(sql.contains("optional_int INT"));
assert!(sql.contains("bool_val TINYINT(1) NOT NULL"));
assert!(sql.contains("optional_bool TINYINT(1)"));
}
#[allow(unreachable_patterns)]
_ => {}
}
let db_type_name = match config.0 {
#[cfg(feature = "sqlite")]
ormer::DbType::Sqlite => "Sqlite",
#[cfg(feature = "postgresql")]
ormer::DbType::PostgreSQL => "PostgreSQL",
#[cfg(feature = "mysql")]
ormer::DbType::MySQL => "MySQL",
#[allow(unreachable_patterns)]
_ => "Unknown",
};
println!("{} Complete Types SQL: {}", db_type_name, sql);
Ok(())
}
#[cfg(feature = "postgresql")]
#[test]
fn test_postgresql_datetime_primary_key_sql() {
let sql =
generate_create_table_sql::<TestDateTimePrimaryKey>(ormer::DbType::PostgreSQL).unwrap();
assert!(sql.contains("update_time TIMESTAMP PRIMARY KEY"));
assert!(!sql.contains("update_time INTEGER PRIMARY KEY"));
}
test_on_all_dbs_result!(test_turso_create_table_sql_impl);
test_on_all_dbs_result!(test_postgresql_create_table_sql_impl);
test_on_all_dbs_result!(test_mysql_create_table_sql_impl);
test_on_all_dbs_result!(test_different_databases_produce_different_sql_impl);
test_on_all_dbs_result!(test_postgresql_complete_types_impl);
test_on_all_dbs_result!(test_mysql_complete_types_impl);
test_on_all_dbs_result!(test_turso_complete_types_impl);
}