use sqltool::{DataTransfer, StructureMigration, create_connection, DatabaseType, FieldMapping};
#[tokio::test]
async fn test_sqlite_to_sqlite_transfer() {
let source_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
let target_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
source_conn.execute(
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)"
).await.unwrap();
source_conn.execute(
"INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')"
).await.unwrap();
source_conn.execute(
"INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com')"
).await.unwrap();
target_conn.execute(
"CREATE TABLE users_copy (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)"
).await.unwrap();
let transfer = DataTransfer::new(source_conn, target_conn);
let mappings = vec![
FieldMapping {
source_table: "users".to_string(),
source_field: "id".to_string(),
target_table: "users_copy".to_string(),
target_field: "id".to_string(),
},
FieldMapping {
source_table: "users".to_string(),
source_field: "name".to_string(),
target_table: "users_copy".to_string(),
target_field: "name".to_string(),
},
FieldMapping {
source_table: "users".to_string(),
source_field: "email".to_string(),
target_table: "users_copy".to_string(),
target_field: "email".to_string(),
},
];
let result = transfer.transfer(mappings).await;
assert!(result.is_ok(), "Transfer failed: {:?}", result.err());
println!("✓ SQLite 到 SQLite 数据转移测试通过");
}
#[tokio::test]
#[ignore] async fn test_sqlite_structure_migration() {
let source_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
let target_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
source_conn.execute(
"CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL,
description TEXT,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
)"
).await.unwrap();
source_conn.execute(
"INSERT INTO products (name, price, description) VALUES ('Product 1', 99.99, 'Description 1')"
).await.unwrap();
source_conn.execute(
"INSERT INTO products (name, price, description) VALUES ('Product 2', 149.99, 'Description 2')"
).await.unwrap();
let migration = StructureMigration::new(source_conn, target_conn);
let result = migration.migrate_structure("products", "products_copy").await;
assert!(result.is_ok(), "Migration failed: {:?}", result.err());
println!("✓ SQLite 结构迁移测试通过");
}
#[tokio::test]
async fn test_field_mapping_generation() {
let source_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
let target_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
source_conn.execute(
"CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
total_amount DECIMAL(10, 2),
status TEXT
)"
).await.unwrap();
target_conn.execute(
"CREATE TABLE orders_copy (
id INTEGER PRIMARY KEY,
customer_id INTEGER,
amount DECIMAL(10, 2),
order_status TEXT
)"
).await.unwrap();
let transfer = DataTransfer::new(source_conn, target_conn);
let mappings = transfer.generate_auto_mappings("orders", "orders_copy").await.unwrap();
println!("生成的字段映射: {:?}", mappings.len());
assert!(!mappings.is_empty(), "Should generate some mappings");
println!("✓ 字段映射生成测试通过");
}
#[tokio::test]
async fn test_related_tables_transfer() {
let source_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
let target_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
source_conn.execute(
"CREATE TABLE categories (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)"
).await.unwrap();
source_conn.execute(
"CREATE TABLE products (
id INTEGER PRIMARY KEY,
category_id INTEGER,
name TEXT NOT NULL,
price DECIMAL(10, 2),
FOREIGN KEY (category_id) REFERENCES categories(id)
)"
).await.unwrap();
source_conn.execute("INSERT INTO categories (name) VALUES ('Electronics')").await.unwrap();
source_conn.execute("INSERT INTO categories (name) VALUES ('Books')").await.unwrap();
source_conn.execute("INSERT INTO products (category_id, name, price) VALUES (1, 'Laptop', 999.99)").await.unwrap();
source_conn.execute("INSERT INTO products (category_id, name, price) VALUES (1, 'Phone', 599.99)").await.unwrap();
source_conn.execute("INSERT INTO products (category_id, name, price) VALUES (2, 'Book', 19.99)").await.unwrap();
target_conn.execute(
"CREATE TABLE categories_copy (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)"
).await.unwrap();
target_conn.execute(
"CREATE TABLE products_copy (
id INTEGER PRIMARY KEY,
category_id INTEGER,
name TEXT NOT NULL,
price DECIMAL(10, 2),
FOREIGN KEY (category_id) REFERENCES categories_copy(id)
)"
).await.unwrap();
let categories_transfer = DataTransfer::new(
create_connection(DatabaseType::SQLite, "sqlite://:memory:").await.unwrap(),
create_connection(DatabaseType::SQLite, "sqlite://:memory:").await.unwrap(),
);
println!("✓ 多表关联数据转移测试通过");
}
#[tokio::test]
async fn test_data_type_conversion() {
let source_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
let target_conn = create_connection(
DatabaseType::SQLite,
"sqlite://:memory:"
).await.unwrap();
source_conn.execute(
"CREATE TABLE mixed_types (
id INTEGER PRIMARY KEY,
int_field INTEGER,
text_field TEXT,
real_field REAL,
blob_field BLOB
)"
).await.unwrap();
source_conn.execute(
"INSERT INTO mixed_types (int_field, text_field, real_field) VALUES (42, 'hello', 3.14)"
).await.unwrap();
target_conn.execute(
"CREATE TABLE mixed_types_copy (
id INTEGER PRIMARY KEY,
int_field INTEGER,
text_field TEXT,
real_field REAL,
blob_field BLOB
)"
).await.unwrap();
let transfer = DataTransfer::new(source_conn, target_conn);
let mappings = vec![
FieldMapping {
source_table: "mixed_types".to_string(),
source_field: "id".to_string(),
target_table: "mixed_types_copy".to_string(),
target_field: "id".to_string(),
},
FieldMapping {
source_table: "mixed_types".to_string(),
source_field: "int_field".to_string(),
target_table: "mixed_types_copy".to_string(),
target_field: "int_field".to_string(),
},
FieldMapping {
source_table: "mixed_types".to_string(),
source_field: "text_field".to_string(),
target_table: "mixed_types_copy".to_string(),
target_field: "text_field".to_string(),
},
FieldMapping {
source_table: "mixed_types".to_string(),
source_field: "real_field".to_string(),
target_table: "mixed_types_copy".to_string(),
target_field: "real_field".to_string(),
},
];
let result = transfer.transfer(mappings).await;
assert!(result.is_ok(), "Transfer failed: {:?}", result.err());
println!("✓ 数据类型转换测试通过");
}