Skip to content

Commit

Permalink
C 0.19: enable query conditions for integer and floating point vectors.
Browse files Browse the repository at this point in the history
Add tests for the supported conditions, drop placeholder tests.
  • Loading branch information
greenrobot-team committed Sep 5, 2023
1 parent 54d421f commit 9fcce55
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 68 deletions.
24 changes: 24 additions & 0 deletions objectbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
## latest

* **Query support for integer and floating point lists**: For integer lists (excluding byte lists)
greater, less and equal are supported on elements of the vector (e.g. "has element greater").

For floating point lists greater and less queries are supported on elements of the vector
(e.g. "has element greater").

A simple example is a shape entity that stores a palette of RGB colors:
```dart
@Entity()
class Shape {
@Id()
int id = 0;
// An array of RGB color values that are used by this shape.
Int32List? palette;
}
// Find all shapes that use red in their palette
final query = store.box<Shape>()
.query(Shape_.palette.equals(0xFF0000))
.build();
query.findIds();
query.close();
```
* Update: [objectbox-c 0.19.0](https://github.com/objectbox/objectbox-c/releases/tag/v0.19.0).
Notably now requires glibc 2.28 or higher (and GLIBCXX_3.4.25); e.g. at least **Debian Buster 10
(2019) or Ubuntu 20.04**.
Expand Down
91 changes: 43 additions & 48 deletions objectbox/lib/src/native/query/query.dart
Original file line number Diff line number Diff line change
Expand Up @@ -181,34 +181,31 @@ class QueryIntegerProperty<EntityT> extends QueryProperty<EntityT, int> {
}

/// For integer vectors (excluding [QueryByteVectorProperty]) greater, less and
/// equal will be supported on elements of the vector (e.g. "has element greater")
/// in the future.
/// equal are supported on elements of the vector (e.g. "has element greater").
class QueryIntegerVectorProperty<EntityT> extends QueryProperty<EntityT, int> {
QueryIntegerVectorProperty(ModelProperty model) : super(model);

// Note: The C library currently does not support queries for integer vector properties.

// Condition<EntityT> _op(_ConditionOp cop, int p1, int p2, String? alias) =>
// _IntegerCondition<EntityT, int>(cop, this, p1, p2, alias);
//
// Condition<EntityT> equals(int p, {String? alias}) =>
// _op(_ConditionOp.eq, p, 0, alias);
//
// Condition<EntityT> greaterThan(int p, {String? alias}) =>
// _op(_ConditionOp.gt, p, 0, alias);
//
// Condition<EntityT> greaterOrEqual(int p, {String? alias}) =>
// _op(_ConditionOp.greaterOrEq, p, 0, alias);
//
// Condition<EntityT> lessThan(int p, {String? alias}) =>
// _op(_ConditionOp.lt, p, 0, alias);
//
// Condition<EntityT> lessOrEqual(int p, {String? alias}) =>
// _op(_ConditionOp.lessOrEq, p, 0, alias);
//
// Condition<EntityT> operator <(int p) => lessThan(p);
//
// Condition<EntityT> operator >(int p) => greaterThan(p);
Condition<EntityT> _op(_ConditionOp cop, int p1, int p2, String? alias) =>
_IntegerCondition<EntityT, int>(cop, this, p1, p2, alias);

Condition<EntityT> equals(int p, {String? alias}) =>
_op(_ConditionOp.eq, p, 0, alias);

Condition<EntityT> greaterThan(int p, {String? alias}) =>
_op(_ConditionOp.gt, p, 0, alias);

Condition<EntityT> greaterOrEqual(int p, {String? alias}) =>
_op(_ConditionOp.greaterOrEq, p, 0, alias);

Condition<EntityT> lessThan(int p, {String? alias}) =>
_op(_ConditionOp.lt, p, 0, alias);

Condition<EntityT> lessOrEqual(int p, {String? alias}) =>
_op(_ConditionOp.lessOrEq, p, 0, alias);

Condition<EntityT> operator <(int p) => lessThan(p);

Condition<EntityT> operator >(int p) => greaterThan(p);
}

class QueryDoubleProperty<EntityT> extends QueryProperty<EntityT, double> {
Expand Down Expand Up @@ -245,33 +242,31 @@ class QueryDoubleProperty<EntityT> extends QueryProperty<EntityT, double> {
Condition<EntityT> operator >(double p) => greaterThan(p);
}

/// For double vectors greater and less queries will be supported on elements of
/// the vector (e.g. "has element greater") in the future.
/// For double vectors greater and less queries are supported on elements of
/// the vector (e.g. "has element greater").
class QueryDoubleVectorProperty<EntityT>
extends QueryProperty<EntityT, double> {
QueryDoubleVectorProperty(ModelProperty model) : super(model);

// Note: The C library currently does not support queries for floating point vector properties.

// Condition<EntityT> _op(
// _ConditionOp op, double p1, double? p2, String? alias) =>
// _DoubleCondition<EntityT>(op, this, p1, p2, alias);
//
// Condition<EntityT> greaterThan(double p, {String? alias}) =>
// _op(_ConditionOp.gt, p, 0, alias);
//
// Condition<EntityT> greaterOrEqual(double p, {String? alias}) =>
// _op(_ConditionOp.greaterOrEq, p, null, alias);
//
// Condition<EntityT> lessThan(double p, {String? alias}) =>
// _op(_ConditionOp.lt, p, null, alias);
//
// Condition<EntityT> lessOrEqual(double p, {String? alias}) =>
// _op(_ConditionOp.lessOrEq, p, null, alias);
//
// Condition<EntityT> operator <(double p) => lessThan(p);
//
// Condition<EntityT> operator >(double p) => greaterThan(p);
Condition<EntityT> _op(
_ConditionOp op, double p1, double? p2, String? alias) =>
_DoubleCondition<EntityT>(op, this, p1, p2, alias);

Condition<EntityT> greaterThan(double p, {String? alias}) =>
_op(_ConditionOp.gt, p, 0, alias);

Condition<EntityT> greaterOrEqual(double p, {String? alias}) =>
_op(_ConditionOp.greaterOrEq, p, null, alias);

Condition<EntityT> lessThan(double p, {String? alias}) =>
_op(_ConditionOp.lt, p, null, alias);

Condition<EntityT> lessOrEqual(double p, {String? alias}) =>
_op(_ConditionOp.lessOrEq, p, null, alias);

Condition<EntityT> operator <(double p) => lessThan(p);

Condition<EntityT> operator >(double p) => greaterThan(p);
}

class QueryBooleanProperty<EntityT> extends QueryProperty<EntityT, bool> {
Expand Down
116 changes: 96 additions & 20 deletions objectbox_test/test/query_scalar_vector_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,62 @@ void main() {
TestEntityScalarVectors_.tLongList
];

for (int i = 0; i < properties.length; i++) {
var property = properties[i];
final paramsLarger = [
1010, // short
100010, // int
10000000010 // long
];

// Note: regular conditions currently not supported by C library.
final params5 = [
1004, // short
100004, // int
10000000004 // long
];

final queryNull = box.query(property.isNull()).build();
expect(queryNull.findIds(), []);
queryNull.close();
final params10 = [
1009, // short
100009, // int
10000000009 // long
];

final queryNotNull = box.query(property.notNull()).build();
expect(queryNotNull.findIds(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
queryNotNull.close();
for (int i = 0; i < properties.length; i++) {
final property = properties[i];
final pLarger = paramsLarger[i];
final p5 = params5[i];
final p10 = params10[i];

// "greater" which behaves like "has element greater"
final qGreater = box.query(property.greaterThan(pLarger)).build();
expect(qGreater.findIds(), []);
qGreater.param(property).value = p5;
expect(qGreater.findIds(), [6, 7, 8, 9, 10]);
qGreater.close();

// "greater or equal", only check equal
final qGreaterOrEq = box.query(property.greaterOrEqual(p10)).build();
expect(qGreaterOrEq.findIds(), [10]);
qGreaterOrEq.close();

// "less" which behaves like "has element less".
final qLess = box.query(property.lessThan(-pLarger)).build();
expect(qLess.findIds(), []);
qLess.param(property).value = -p5;
expect(qLess.findIds(), [6, 7, 8, 9, 10]);
qLess.close();

// "less or equal", only check equal
final qLessOrEq = box.query(property.lessOrEqual(-p10)).build();
expect(qLessOrEq.findIds(), [10]);
qLessOrEq.close();

// "equal" which behaves like "contains element".
final qEq = box.query(property.equals(-1)).build();
expect(qEq.findIds(), []);
qEq.param(property).value = p5;
expect(qEq.findIds(), [5]);
qEq.close();

// Note: "not equal" for scalar arrays does not do anything useful.
}
});

Expand All @@ -45,23 +89,55 @@ void main() {
var testEntities = TestEntityScalarVectors.createTen();
box.putMany(testEntities);

final paramsLarger = [
21.0, // float
2000.0001, // double
];

final params5 = [
20.4, // float
2000.00004, // double
];

final params10 = [
20.9, // float
2000.00009, // double
];

final properties = [
TestEntityScalarVectors_.tFloatList,
TestEntityScalarVectors_.tDoubleList
];

for (int i = 0; i < properties.length; i++) {
var property = properties[i];

// Note: regular conditions currently not supported by C library.

final queryNull = box.query(property.isNull()).build();
expect(queryNull.findIds(), []);
queryNull.close();

final queryNotNull = box.query(property.notNull()).build();
expect(queryNotNull.findIds(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
queryNotNull.close();
final property = properties[i];
final pLarger = paramsLarger[i];
final p5 = params5[i];
final p10 = params10[i];

// "greater" which behaves like "has element greater"
final qGreater = box.query(property.greaterThan(pLarger)).build();
expect(qGreater.findIds(), []);
qGreater.param(property).value = p5;
expect(qGreater.findIds(), [6, 7, 8, 9, 10]);
qGreater.close();

// "greater or equal", only check equal
final qGreaterOrEq = box.query(property.greaterOrEqual(p10)).build();
expect(qGreaterOrEq.findIds(), [10]);
qGreaterOrEq.close();

// "less" which behaves like "has element less".
final qLess = box.query(property.lessThan(-pLarger)).build();
expect(qLess.findIds(), []);
qLess.param(property).value = -p5;
expect(qLess.findIds(), [6, 7, 8, 9, 10]);
qLess.close();

// "less or equal", only check equal
final qLessOrEq = box.query(property.lessOrEqual(-p10)).build();
expect(qLessOrEq.findIds(), [10]);
qLessOrEq.close();
}
});
}

0 comments on commit 9fcce55

Please sign in to comment.