diff options
| author | Jan Tuomi <jan@jantuomi.fi> | 2025-02-03 18:58:49 +0200 |
|---|---|---|
| committer | Jan Tuomi <jan@jantuomi.fi> | 2025-02-03 18:58:49 +0200 |
| commit | f60b372db09f4ed091a55d44ac5013926f4cf64b (patch) | |
| tree | 14791c3f1c24f94564123bfb0cccb7a7ca684eaa /log_db/tests/integration.rs | |
| parent | 35687a08b48337c9989d59fa033580766c6e0947 (diff) | |
Support adding nullable fields
Diffstat (limited to 'log_db/tests/integration.rs')
| -rw-r--r-- | log_db/tests/integration.rs | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/log_db/tests/integration.rs b/log_db/tests/integration.rs index 31d2831..5376850 100644 --- a/log_db/tests/integration.rs +++ b/log_db/tests/integration.rs @@ -714,3 +714,152 @@ fn test_rollback_transaction() { assert_eq!(johns.len(), 0); } + +#[derive(Eq, PartialEq, Clone, Debug)] +enum FieldWithNewNullableField { + Id, + Name, + Data, + MaybeStr, +} + +struct InstWithNewNullableField { + pub id: i64, + pub name: Option<String>, + pub data: Vec<u8>, + pub maybe_str: Option<String>, +} + +impl Recordable for InstWithNewNullableField { + type Field = FieldWithNewNullableField; + + fn schema() -> Vec<(Self::Field, Type)> { + vec![ + (FieldWithNewNullableField::Id, Type::int()), + (FieldWithNewNullableField::Name, Type::string().nullable()), + (FieldWithNewNullableField::Data, Type::bytes()), + ( + FieldWithNewNullableField::MaybeStr, + Type::string().nullable(), + ), + ] + } + + fn primary_key() -> Self::Field { + FieldWithNewNullableField::Id + } + + fn secondary_keys() -> Vec<Self::Field> { + vec![FieldWithNewNullableField::Name] + } + + fn into_record(self) -> Vec<Value> { + vec![ + Value::Int(self.id), + match self.name { + Some(name) => Value::String(name), + None => Value::Null, + }, + Value::Bytes(self.data), + match self.maybe_str { + Some(maybe_str) => Value::String(maybe_str), + None => Value::Null, + }, + ] + } + + fn from_record(record: Vec<Value>) -> Self { + let mut it = record.into_iter(); + + InstWithNewNullableField { + id: match it.next().unwrap() { + Value::Int(id) => id, + other => panic!("Invalid value type: {:?}", other), + }, + name: match it.next().unwrap() { + Value::String(name) => Some(name), + Value::Null => None, + other => panic!("Invalid value type: {:?}", other), + }, + data: match it.next().unwrap() { + Value::Bytes(data) => data, + other => panic!("Invalid value type: {:?}", other), + }, + maybe_str: match it.next() { + Some(Value::String(maybe_str)) => Some(maybe_str), + Some(Value::Null) => None, + None => None, + other => panic!("Invalid value type: {:?}", other), + }, + } + } +} + +#[test] +fn test_add_nullable_field() { + let data_dir = tmp_dir(); + + // Insert a record with 3 fields + { + let mut db = DB::<Inst>::configure() + .data_dir(&data_dir) + .initialize() + .expect("Failed to initialize DB instance"); + + db.upsert(Inst { + id: 0, + name: Some("John".to_string()), + data: vec![3, 4, 5], + }) + .unwrap(); + } + + // Insert a record with 4 fields (last is nullable) + let mut db = DB::<InstWithNewNullableField>::configure() + .data_dir(&data_dir) + .initialize() + .expect("Failed to initialize DB instance"); + + db.upsert(InstWithNewNullableField { + id: 1, + name: Some("John".to_string()), + data: vec![3, 4, 5], + maybe_str: None, + }) + .unwrap(); + + let johns = db + .find_by( + &FieldWithNewNullableField::Name, + &Value::String("John".to_string()), + ) + .unwrap(); + + assert_eq!(johns.len(), 2); +} + +#[test] +fn test_add_non_nullable_field() { + let data_dir = tmp_dir(); + + // Insert a record with just one field + { + let mut db = DB::<InstSingleId>::configure() + .data_dir(&data_dir) + .initialize() + .expect("Failed to initialize DB instance"); + + db.upsert(InstSingleId { id: 0 }).unwrap(); + } + + // Configure the DB with three fields, one of which is non-nullable + // This should fail + match DB::<Inst>::configure().data_dir(&data_dir).initialize() { + Ok(_) => panic!("Expected initialization to fail"), + Err(DBError::ValidationError(e)) => { + // Expected + error!("Expected: {:?}", e); + } + Err(e) => panic!("Unexpected error: {:?}", e), + } +} |
