use tmsoft_dbase::dbfutils::dbf;
use std::collections::HashMap;
use anyhow::Result;
use tempfile::NamedTempFile;
use std::time::Instant;
#[test]
fn test_find_records() -> Result<()> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let mut query = std::collections::HashMap::new();
query.insert("KSBH".to_string(), "103523210040149".to_string());
let records = dbf::find_records(path, &query)?;
println!("符合条件的记录:{:?}", records.len());
for record in records {
for (name, value) in record {
println!("{} -> {}", name, value);
}
}
Ok(())
}
#[test]
fn test_update_records() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let mut query = std::collections::HashMap::new();
query.insert("KSBH".to_string(), "103523210040010".to_string());
let mut updates = std::collections::HashMap::new();
updates.insert("BYXX1".to_string(), "6666".to_string());
updates.insert("RENSHU".to_string(), "6666".to_string());
let updated_count = dbf::update_records(path, query.clone(), updates)?;
println!("更新的记录数: {}", updated_count);
let updated_records = dbf::find_records(path, &query)?;
println!("更新后的记录数: {}", updated_records.len());
for record in updated_records {
for (name, value) in record {
println!("{} -> {}", name, value);
}
}
Ok(())
}
#[test]
fn test_add_record() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let mut new_record = std::collections::HashMap::new();
new_record.insert("KSBH".to_string(), "103523210040149".to_string());
new_record.insert("BYXX1".to_string(), "99999".to_string());
new_record.insert("RENSHU".to_string(), "99999".to_string());
dbf::add_record(path, new_record.clone())?;
let mut query = std::collections::HashMap::new();
query.insert("KSBH".to_string(), "103523210040149".to_string());
let records = dbf::find_records(path, &query)?;
assert_eq!(records.len(), 1, "未找到新增的记录");
for record in records {
for (name, value) in &new_record {
assert_eq!(record.get(name), Some(value), "字段 {} 的值不匹配", name);
}
}
Ok(())
}
#[test]
fn test_delete_records() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let mut query = std::collections::HashMap::new();
query.insert("KSBH".to_string(), "103523210040149".to_string());
let deleted_count = dbf::delete_records(path, &query)?;
println!("删除的记录数: {}", deleted_count);
let remaining_records = dbf::find_records(path, &query)?;
assert_eq!(remaining_records.len(), 0, "记录未被成功删除");
Ok(())
}
#[test]
fn test_get_record_count() -> Result<(), Box<dyn std::error::Error>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let record_count = dbf::get_record_count(path)?;
println!("DBF 文件的记录数: {}", record_count);
assert!(record_count > 0, "记录数应大于零");
Ok(())
}
#[test]
fn test_get_record_count_query() -> Result<(), Box<dyn std::error::Error>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let mut query = HashMap::new();
query.insert("KSBH".to_string(), "103523210020404".to_string());
let record_count = dbf::get_filtered_record_count(path,&query)?;
println!("DBF 文件的记录数: {}", record_count);
assert!(record_count == 1, "记录数应大于零");
Ok(())
}
#[test]
fn test_read_dbf_paged() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let page_size = 10;
let page_number = 1;
let paged_records = dbf::read_dbf_paged(path, page_size, page_number)?;
println!("DBF 文件的分页记录 (第 {} 页, 每页 {} 条记录):", page_number, page_size);
for record in paged_records {
for (name, value) in record {
println!("{} -> {}", name, value);
}
}
Ok(())
}
fn create_test_query() -> HashMap<String, String> {
let mut query = HashMap::new();
query.insert("KSBH".to_string(), "103523210020404".to_string());
query
}
#[test]
fn test_pagination() {
let query = create_test_query();
let result = dbf::read_dbf_paged_query("/Users/zhoujiandong/Downloads/sbk.dbf", &query, 1, 2).unwrap();
assert_eq!(result.len(), 1);
}
#[test]
fn test_empty_page() {
let query = create_test_query();
let result = dbf::read_dbf_paged_query("/Users/zhoujiandong/Downloads/sbk.dbf", &query, 3, 2).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_full_match() {
let mut query = HashMap::new();
query.insert("KSBH".to_string(), "103523210020404".to_string());
let result = dbf::read_dbf_paged_query("/Users/zhoujiandong/Downloads/sbk.dbf", &query, 1, 10).unwrap();
assert_eq!(result.len(), 1);
}
#[test]
fn test_no_match() {
let mut query = HashMap::new();
query.insert("KSBH".to_string(), "X".to_string());
let result = dbf::read_dbf_paged_query("/Users/zhoujiandong/Downloads/sbk.dbf", &query, 1, 10).unwrap();
assert!(result.is_empty());
}
#[test]
fn test_read_dbf_concurrent() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let records = dbf::read_dbf_concurrent(path)?;
println!("DBF 文件的记录:");
for record in records {
for (name, value) in record {
println!("{} -> {}", name, value);
}
}
Ok(())
}
#[test]
fn test_get_dbf_fields() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let path = "/Users/zhoujiandong/Downloads/sbk.dbf";
let fields = dbf::get_dbf_fields(path)?;
println!("DBF 文件的字段信息:");
for field in fields {
println!("字段名: {}, 类型: {}, 长度: {}, 小数位数: {}", field.name, field.field_type, field.length, field.decimal);
}
Ok(())
}
#[test]
fn test_add_fields_to_dbf() {
let test_file = "/Users/zhoujiandong/Downloads/sbk.dbf";
let new_fields = vec![
dbf::FieldDescriptor { name: "RENSHU".into(), field_type: 'C', length: 10, decimal: 0 }
];
dbf::add_fields_to_dbf(test_file, new_fields).unwrap();
}
#[test]
fn test_modify_fields_in_dbf() {
let modify_fields = vec![dbf::FieldDescriptor { name: "RENSHU".to_string(), field_type: 'C', length: 12, decimal: 0 }];
if let Err(e) = dbf::modify_fields_in_dbf("/Users/zhoujiandong/Downloads/sbk.dbf", modify_fields) {
eprintln!("Error modifying fields: {}", e);
}
}
#[test]
fn test_delete_fields_from_dbf() {
let delete_field_names = vec!["RENSHU".to_string()];
if let Err(e) = dbf::delete_fields_from_dbf("/Users/zhoujiandong/Downloads/sbk.dbf", delete_field_names) {
eprintln!("Error deleting fields: {}", e);
}
}
fn create_sample_dbf() -> NamedTempFile {
let mut file = NamedTempFile::new().unwrap();
let fields = vec![
dbf::FieldDescriptor {
name: "ID".to_string(),
field_type: 'N',
length: 5,
decimal: 0,
},
dbf::FieldDescriptor {
name: "NAME".to_string(),
field_type: 'C',
length: 20,
decimal: 0,
},
];
let records = vec![
[("ID", "1"), ("NAME", "Alice")]
.iter()
.map(|(k, v)| ((*k).to_string(), (*v).to_string()))
.collect::<HashMap<_, _>>(),
[("ID", "2"), ("NAME", "Bob")]
.iter()
.map(|(k, v)| ((*k).to_string(), (*v).to_string()))
.collect(),
];
println!("records:{:?}",file.path().to_str().unwrap());
dbf::write_dbf(file.path().to_str().unwrap(), &records, &fields).unwrap();
file
}
#[test]
fn test_read_write() {
let file = create_sample_dbf();
let dbf = dbf::DbfFile::open(file.path().to_str().unwrap()).unwrap();
assert_eq!(dbf.record_count(), 2);
assert_eq!(dbf.get_fields().len(), 2);
let records = dbf.read_records().unwrap();
assert_eq!(records.len(), 2);
assert_eq!(records[0]["ID"], "1");
assert_eq!(records[1]["NAME"], "Bob");
}
#[test]
fn test_query() {
let dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let query = [("KSBH".to_string(), "103523210020555".to_string())]
.iter().cloned().collect();
let results = dbf.find_records(&query).unwrap();
println!("results:{:?}",results);
}
#[test]
fn test_concurrent_perf() {
let dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let start = Instant::now();
let _records = dbf.read_records().unwrap();
println!("Read {} records in {:?}", dbf.record_count(), start.elapsed());
}
#[test]
fn test_large_file() {
let mut file = NamedTempFile::new().unwrap();
let mut fields = Vec::new();
let mut records = Vec::new();
for i in 0..100 {
fields.push(dbf::FieldDescriptor {
name: format!("FIELD{}", i),
field_type: 'C',
length: 10,
decimal: 0,
});
}
for i in 0..10_000 {
let mut record = HashMap::new();
for j in 0..100 {
record.insert(format!("FIELD{}", j), format!("Value{}-{}", j, i));
}
records.push(record);
}
dbf::write_dbf(file.path().to_str().unwrap(), &records, &fields).unwrap();
let dbf = dbf::DbfFile::open(file.path().to_str().unwrap()).unwrap();
assert_eq!(dbf.record_count(), 10_000);
let start = Instant::now();
let page = dbf.read_paged(2, 100).unwrap();
assert_eq!(page.len(), 100);
println!("Paged read in {:?}", start.elapsed());
}
#[test]
fn test_update_records_dbffile() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let query = [("KSBH".to_string(), "103523210020555".to_string())]
.iter().cloned().collect();
let updates = [("XM".to_string(), "Alice2".to_string())]
.iter().cloned().collect();
let count = dbf.update_records(
"/Users/zhoujiandong/Downloads/sbk.dbf",
query,
updates
).unwrap();
assert_eq!(count, 1);
let records = dbf.read_records().unwrap();
assert_eq!(records[0]["XM"], "Alice2");
}
#[test]
fn test_insert_records_dbffile() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let query = [("KSBH".to_string(), "103523210020555".to_string()),("BYXX1".to_string(), "99999".to_string()),("BMDDM".to_string(), "3309".to_string()),("BMH".to_string(), "3309".to_string())]
.iter().cloned().collect();
dbf.add_record(
"/Users/zhoujiandong/Downloads/sbk.dbf",
query
).unwrap();
}
#[test]
fn test_delete_records_success() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let mut query = HashMap::new();
query.insert("KSBH".to_string(), "103523210020555".to_string());
let result = dbf.delete_records("/Users/zhoujiandong/Downloads/sbk.dbf", &query);
assert_eq!(result.unwrap(), 2);
}
#[test]
fn test_get_all_fields_dbffile() {
let dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let fields = dbf.get_fields();
println!("DBF 文件的字段信息:");
for field in fields {
println!("字段名: {}, 类型: {}, 长度: {}, 小数位数: {}", field.name, field.field_type, field.length, field.decimal);
}
}
#[test]
fn test_add_fields_dbffile() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let new_fields = vec![
dbf::FieldDescriptor { name: "RENSHU".into(), field_type: 'C', length: 10, decimal: 0 }
];
dbf.add_fields(
"/Users/zhoujiandong/Downloads/sbk.dbf",
new_fields
).unwrap();
}
#[test]
fn test_modify_fields_dbffile() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let modified_fields = vec![
dbf::FieldDescriptor { name: "RENSHU".to_string(), field_type: 'C', length: 15,decimal:0 },
];
let result = dbf.modify_fields("/Users/zhoujiandong/Downloads/sbk.dbf", &modified_fields);
}
#[test]
fn test_delete_fields_dbffile() {
let mut dbf = dbf::DbfFile::open("/Users/zhoujiandong/Downloads/sbk.dbf").unwrap();
let field_names= vec![("RENSHU".to_string())] ;
let result = dbf.delete_fields("/Users/zhoujiandong/Downloads/sbk.dbf", &field_names);
}