Releases: plabayo/venndb
0.5.0
New Features:
- [
#15
]: support multi dimensional filter options to be filtered in group
Example:
use venndb::{Any, VennDB};
#[derive(Debug, VennDB)]
pub struct Value {
#[venndb(filter)]
pub foo: String,
pub bar: u32,
}
let db = ValueDB::from_iter([
Value {
foo: "a".to_owned(),
bar: 8,
},
Value {
foo: "b".to_owned(),
bar: 12,
},
Value {
foo: "c".to_owned(),
bar: 16,
},
].into_Iter()).unwrap();
let mut query = db.query();
query.foo(MyString("a".to_owned()));
query.foo(MyString("c".to_owned()));
let values: Vec<_> = query.execute().unwrap().iter().collect();
assert_eq!(values.len(), 2);
assert_eq!(values[0].bar, 8);
assert_eq!(values[0].bar, 16);
0.4.0
Breaking Changes:
- [
#7
]: correct the behaviour of any filter map query values:- When using an any value as a query filter map value it will now only match rows
which have an any value registered for the row; - Prior to this release it was matching on all rows, as if the filter wasn't defined.
This seemed correct when deciding on it, but on hindsight is is incorrect behaviour.
- When using an any value as a query filter map value it will now only match rows
New Features:
- [
#8
]: support custom validations of rows prior to appending them
Example:
#[derive(Debug, VennDB)]
#[venndb(name = "MyDB", validator = my_validator_fn)]
pub struct Value {
pub foo: String,
pub bar: u32,
}
fn my_validator_fn(value: &Value) -> bool {
!value.foo.is_empty() && value.bar > 0
}
let mut db = MyDB::default();
assert!(db.append(Value {
foo: "".to_owned(),
bar: 42,
}).is_err()); // fails because foo == empty
0.3.0
Breaking changes:
- [
#6
] query filter maps now accept arguments asimpl Into<T>
instead ofT
,
this can be a breaking change for users that were inserting them asvalue.into()
,
as the compiler will for these cases now give a compile time error due to the now introduced ambiguity;- Migration is as easy as removing the manual
.into()
(like) calls that you previously had to add yourself;
- Migration is as easy as removing the manual
Bug Fixes from 0.2.1:
- [
#5
] any filters now also allow rows to match on unknown filter map variants.- e.g. if you have a
MyType
filter map and have not a single row that has"foo"
as value,
then all rows that that have a value for whichassert!(Any::is_any(value: MyType))
will still work. - prior to this bug fix these values could not be matched on, and the
any
rows would only hit
if there were also rows that had that value explicitly defined.
- e.g. if you have a
0.2.1
A backwards compatible patch for v0.2.0
to support rows that allow any value for a specific column.
Non-Breaking changes:
- support
#[venndb(any)]
filters;- these are possible only for
T
filter maps, whereT: ::venndb::Any
; bool
filters cannot beany
asbool
doesn't implement the::venndb::Any
trait;- rows that are
any
will match regardless of the query filter used for that property;
- these are possible only for
Example usage:
use venndb::{Any, VennDB};
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum Department {
Any,
Hr,
Engineering,
}
impl Any for Department {
fn is_any(&self) -> bool {
self == Department::Any
}
}
#[derive(Debug, VennDB)]
pub struct Employee {
name: String,
#[venndb(filter, any)]
department: Department,
}
let db = EmployeeDB::from_iter([
Employee { name: "Jack".to_owned(), department: Department::Any },
Employee { name: "Derby".to_owned(), department: Department::Hr },
]);
let mut query = db.query();
// will match Jack and Derby, as Jack is marked as Any, meaning it can work for w/e value
let hr_employees: Vec<_> = query.department(Department::Hr).execute().unwrap().iter().collect();
assert_eq!(hr_employees.len(), 2);
In case you combine it with the filter map property being optional (department: Option<Department>
),
then it will still work the same, where rows with None
are seen as nothing at all and just ignored.
This has no affect on the correct functioning of Any
.
0.2.0
Breaking Changes:
- Support Option in a special way:
- for filters it means that both positive and negative bits will be set to false if the value is
None
; - for filter maps this means that the filter is not even registered;
- keys cannot be optional;
- While technically this is a breaking change it is not expected to actually break someone,
as keys always had to be unique already and two timesNone
will result in same hash... so it is unlikely
that there was anOption<T>
already used by someone;
- While technically this is a breaking change it is not expected to actually break someone,
- this is potentially breaking as some implementations from
0.1*
might have already usedOption
in a different way;
- for filters it means that both positive and negative bits will be set to false if the value is
While this changes behaviour of filters
and filter maps
it is unlikely that someone was already using
Option<T>
for these types before, as their ergonomics have been a bit weird prior to this version.
Even more so for filter maps
it could have resulted in panics.
Updated Example from 0.1:
use venndb::VennDB
#[derive(Debug, VennDB)]
pub struct Employee {
#[venndb(key)]
id: u32,
name: String,
is_manager: Option<bool>,
is_admin: bool,
#[venndb(skip)]
foo: bool,
#[venndb(filter)]
department: Department,
#[venndb(filter)]
country: Option<String>,
}
fn main() {
let db = EmployeeDB::from_iter(/* .. */);
let mut query = db.query();
let employee = query
.is_admin(true)
.is_manager(false) // rows which have `None` for this property will NOT match this filter
.department(Department::Engineering)
.execute()
.expect("to have found at least one")
.any();
println!("non-manager admin engineer: {:?}", employee);
// as we didn't specify a `country` filter, even rows without a country specified will
// match here if they match the defined (query) filters)
}
Non-Breaking Changes:
- improve documentation;
0.1.1
v0.1.0
Implement the first version of this library, venndb
.
Released as venndb
(0.1.0) and venndb-macros
(0.1.0).
API Example:
use venndb::VennDB
#[derive(Debug, VennDB)]
pub struct Employee {
#[venndb(key)]
id: u32,
name: String,
is_manager: bool,
is_admin: bool,
#[venndb(skip)]
foo: bool,
#[venndb(filter)]
department: Department,
}
fn main() {
let db = EmployeeDB::from_iter(/* .. */);
let mut query = db.query();
let employee = query
.is_admin(true)
.is_manager(false)
.department(Department::Engineering)
.execute()
.expect("to have found at least one")
.any();
println!("non-manager admin engineer: {:?}", employee);
}
This API, using nothing more then a derive
macro allows to:
- store rows of data in a generated
database
; - query the database using the defined
filter
fields; - get references to rows directly by a
key
;
The crate comes with examples and a detailed README.
Please share with us if you have any feedback about this first version,
how you are using it, what you would like different, etc.