Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8b7bfa1
Add support for property queries.
Buggaboo Oct 23, 2019
7829e33
Use obx_query_prop_distinct_case instead of obx_query_prop_distinct_s…
greenrobot-team Jun 23, 2020
860398e
Signatures: return T instead of Pointer<T> to not throw off code anal…
greenrobot-team Jun 23, 2020
2d0ff5d
property: Free pointers even if checkObx throws.
greenrobot-team Jun 23, 2020
1c5887e
property: add missing default switch cases, formatting.
greenrobot-team Jun 23, 2020
ae9008f
Resolve dart analysis warnings in added code.
greenrobot-team Jun 29, 2020
473ea5b
Format added code.
greenrobot-team Jun 29, 2020
dc00837
Write proper docs for Query.property(prop).
greenrobot-team Jun 29, 2020
23203b2
Fix find tests to not expect order.
greenrobot-team Jun 29, 2020
a8c88aa
Untangle and simplify find replace null tests.
greenrobot-team Jun 29, 2020
884dcfe
Add negative integer and float values to test.
greenrobot-team Jun 29, 2020
836b86d
Fix float average test.
greenrobot-team Jun 29, 2020
90be788
Use signed integer for OBX int array structs.
greenrobot-team Jun 29, 2020
8a28265
Float default value: do not cast from Double.
greenrobot-team Jun 29, 2020
23c5350
Improve README example, use Note entity.
greenrobot-team Jun 30, 2020
5174823
Make PropertyQuery abstract+generic, pull up find method.
greenrobot-team Jun 30, 2020
eafcc15
Add docs to property query flags, count method.
greenrobot-team Jun 30, 2020
5787d2b
formatting
vaind Jul 13, 2020
a9b3330
fix property query c-api signature mapping
vaind Jul 13, 2020
b1766d5
remove resurrected test/index.dart
vaind Jul 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,34 @@ final qt = box.query(Entity_.text.notNull())
.build();
```

### Property Queries

Instead of returning complete entities, with property queries only values or an aggregate of a property can be returned.
Build a regular query with conditions as seen above, then turn it into a property query, e.g.:

```dart
// final query ...

// Use distinct or caseSensitive to refine results.
final textQuery = query.stringProperty(Note_.text)
..distinct = true
..caseSensitive = true;
final texts = textQuery.find();
textQuery.close();

// Get aggregates, like min, max, avg, sum and count.
final createdQuery = query.integerProperty(Note_.created);
final min = createdQuery.min();
createdQuery.close();

// Set replaceNullWith to map null values.
final scoreQuery = query.doubleProperty(Note_.score);
final scores = scoreQuery.find(replaceNullWith: 0.0);
scoreQuery.close();

query.close();
```

Help wanted
-----------
ObjectBox for Dart is still in an early stage with limited feature set (compared to other languages).
Expand Down
1 change: 0 additions & 1 deletion generator/lib/src/entity_resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class EntityResolver extends Builder {
// read all suitable annotated properties
bool hasIdProperty = false;
for (var f in element.fields) {

if (_transientChecker.hasAnnotationOfExact(f)) {
log.info(" skipping property ${f.name} (annotated with @Transient)");
continue;
Expand Down
82 changes: 68 additions & 14 deletions lib/src/bindings/bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ class _ObjectBoxBindings {
obx_free_dart_t<OBX_bytes_array> obx_bytes_array_free;
obx_free_dart_t<OBX_id_array> obx_id_array_free;

// obx_free_dart_t<OBX__array> obx_string_array_free;
// obx_free_dart_t<OBX__array> obx_int64_array_free;
// obx_free_dart_t<OBX__array> obx_int32_array_free;
// obx_free_dart_t<OBX__array> obx_int16_array_free;
// obx_free_dart_t<OBX__array> obx_int8_array_free;
// obx_free_dart_t<OBX__array> obx_double_array_free;
// obx_free_dart_t<OBX__array> obx_float_array_free;
obx_free_dart_t<OBX_string_array> obx_string_array_free;
obx_free_dart_t<OBX_int64_array> obx_int64_array_free;
obx_free_dart_t<OBX_int32_array> obx_int32_array_free;
obx_free_dart_t<OBX_int16_array> obx_int16_array_free;
obx_free_dart_t<OBX_int8_array> obx_int8_array_free;
obx_free_dart_t<OBX_double_array> obx_double_array_free;
obx_free_dart_t<OBX_float_array> obx_float_array_free;

// error info
int Function() obx_last_error_code;
Expand Down Expand Up @@ -133,6 +133,27 @@ class _ObjectBoxBindings {

obx_query_visit_dart_t obx_query_visit;

// query property
obx_query_prop_t<int> obx_query_prop;
obx_query_prop_close_t<int> obx_query_prop_close;

obx_query_prop_distinct_t<int, int> obx_query_prop_distinct;
obx_query_prop_distinct2_t<int, int> obx_query_prop_distinct_case;

obx_query_prop_op_t<int, Uint64> obx_query_prop_count;

obx_query_prop_op_t<int, Double> obx_query_prop_avg, obx_query_prop_min, obx_query_prop_max, obx_query_prop_sum;

obx_query_prop_op_t<int, Int64> obx_query_prop_min_int, obx_query_prop_max_int, obx_query_prop_sum_int;

obx_query_prop_find_native_t<Pointer<OBX_string_array>, Int8> obx_query_prop_string_find;
obx_query_prop_find_native_t<Pointer<OBX_int64_array>, Int64> obx_query_prop_int64_find;
obx_query_prop_find_native_t<Pointer<OBX_int32_array>, Int32> obx_query_prop_int32_find;
obx_query_prop_find_native_t<Pointer<OBX_int16_array>, Int16> obx_query_prop_int16_find;
obx_query_prop_find_native_t<Pointer<OBX_int8_array>, Int8> obx_query_prop_int8_find;
obx_query_prop_find_native_t<Pointer<OBX_double_array>, Double> obx_query_prop_double_find;
obx_query_prop_find_native_t<Pointer<OBX_float_array>, Float> obx_query_prop_float_find;

// Utilities
obx_bytes_array_t<int> obx_bytes_array;
obx_bytes_array_set_t<int, int> obx_bytes_array_set;
Expand Down Expand Up @@ -170,13 +191,13 @@ class _ObjectBoxBindings {
obx_supports_bytes_array = _fn<obx_supports_bytes_array_native_t>("obx_supports_bytes_array").asFunction();
obx_bytes_array_free = _fn<obx_free_native_t<Pointer<OBX_bytes_array>>>("obx_bytes_array_free").asFunction();
obx_id_array_free = _fn<obx_free_native_t<Pointer<OBX_id_array>>>("obx_id_array_free").asFunction();
// obx_string_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_string_array_free").asFunction();
// obx_int64_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_int64_array_free").asFunction();
// obx_int32_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_int32_array_free").asFunction();
// obx_int16_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_int16_array_free").asFunction();
// obx_int8_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_int8_array_free").asFunction();
// obx_double_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_double_array_free").asFunction();
// obx_float_array_free = _fn<obx_free_native_t<Pointer<>>>("obx_float_array_free").asFunction();
obx_string_array_free = _fn<obx_free_native_t<Pointer<OBX_string_array>>>('obx_string_array_free').asFunction();
obx_int64_array_free = _fn<obx_free_native_t<Pointer<OBX_int64_array>>>('obx_int64_array_free').asFunction();
obx_int32_array_free = _fn<obx_free_native_t<Pointer<OBX_int32_array>>>('obx_int32_array_free').asFunction();
obx_int16_array_free = _fn<obx_free_native_t<Pointer<OBX_int16_array>>>('obx_int16_array_free').asFunction();
obx_int8_array_free = _fn<obx_free_native_t<Pointer<OBX_int8_array>>>('obx_int8_array_free').asFunction();
obx_double_array_free = _fn<obx_free_native_t<Pointer<OBX_double_array>>>('obx_double_array_free').asFunction();
obx_float_array_free = _fn<obx_free_native_t<Pointer<OBX_float_array>>>('obx_float_array_free').asFunction();

// error info
obx_last_error_code = _fn<obx_last_error_code_native_t>("obx_last_error_code").asFunction();
Expand Down Expand Up @@ -299,6 +320,39 @@ class _ObjectBoxBindings {

obx_query_visit = _fn<obx_query_visit_native_t>("obx_query_visit").asFunction();

// query property
obx_query_prop = _fn<obx_query_prop_t<Uint32>>('obx_query_prop').asFunction();
obx_query_prop_close = _fn<obx_query_prop_close_t<Int32>>('obx_query_prop_close').asFunction();

obx_query_prop_distinct = _fn<obx_query_prop_distinct_t<Int32, Int8>>('obx_query_prop_distinct').asFunction();
obx_query_prop_distinct_case =
_fn<obx_query_prop_distinct2_t<Int32, Int8>>('obx_query_prop_distinct_case').asFunction();

obx_query_prop_count = _fn<obx_query_prop_op_t<Int32, Uint64>>('obx_query_prop_count').asFunction();
obx_query_prop_avg = _fn<obx_query_prop_op_t<Int32, Double>>('obx_query_prop_avg').asFunction();
obx_query_prop_min = _fn<obx_query_prop_op_t<Int32, Double>>('obx_query_prop_min').asFunction();
obx_query_prop_max = _fn<obx_query_prop_op_t<Int32, Double>>('obx_query_prop_max').asFunction();
obx_query_prop_sum = _fn<obx_query_prop_op_t<Int32, Double>>('obx_query_prop_sum').asFunction();

obx_query_prop_min_int = _fn<obx_query_prop_op_t<Int32, Int64>>('obx_query_prop_min_int').asFunction();
obx_query_prop_max_int = _fn<obx_query_prop_op_t<Int32, Int64>>('obx_query_prop_max_int').asFunction();
obx_query_prop_sum_int = _fn<obx_query_prop_op_t<Int32, Int64>>('obx_query_prop_sum_int').asFunction();

obx_query_prop_string_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_string_array>, Int8>>('obx_query_prop_string_find').asFunction();
obx_query_prop_int64_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_int64_array>, Int64>>('obx_query_prop_int64_find').asFunction();
obx_query_prop_int32_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_int32_array>, Int32>>('obx_query_prop_int32_find').asFunction();
obx_query_prop_int16_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_int16_array>, Int16>>('obx_query_prop_int16_find').asFunction();
obx_query_prop_int8_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_int8_array>, Int8>>('obx_query_prop_int8_find').asFunction();
obx_query_prop_double_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_double_array>, Double>>('obx_query_prop_double_find').asFunction();
obx_query_prop_float_find =
_fn<obx_query_prop_find_native_t<Pointer<OBX_float_array>, Float>>('obx_query_prop_float_find').asFunction();

// Utilities
obx_bytes_array = _fn<obx_bytes_array_t<IntPtr>>("obx_bytes_array").asFunction();
obx_bytes_array_set = _fn<obx_bytes_array_set_t<Int32, IntPtr>>("obx_bytes_array_set").asFunction();
Expand Down
13 changes: 13 additions & 0 deletions lib/src/bindings/signatures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ typedef obx_query_visit_native_t = Int32 Function(Pointer<Void> query,
typedef obx_query_visit_dart_t = int Function(Pointer<Void> query,
Pointer<NativeFunction<obx_data_visitor_native_t>> visitor, Pointer<Void> user_data, int offset, int limit);

// query property

typedef obx_query_prop_t<T> = Pointer<Void> Function(Pointer<Void> query, T propertyId); // Uint32 -> int
typedef obx_query_prop_close_t<T> = T Function(Pointer<Void> query); // obx_err -> Int32 -> int
// note: can not use return type Pointer<T> as it throws off code analysis.
typedef obx_query_prop_find_native_t<T, V extends NativeType> = T Function(
Pointer<Void> query, Pointer<V> value_if_null);
typedef obx_query_prop_distinct_t<T, V> = T Function(
Pointer<Void> query, V distinct); // T = (Int32, int), V = (Int8, int)
typedef obx_query_prop_distinct2_t<T, V> = T Function(Pointer<Void> query, V distinct, V caseSensitive);
typedef obx_query_prop_op_t<T, V extends NativeType> = T Function(
Pointer<Void> query, Pointer<V> outValue, Pointer<Int64> outCount);

// Utilities

typedef obx_bytes_array_t<SizeT> = Pointer<OBX_bytes_array> Function(SizeT count);
Expand Down
71 changes: 70 additions & 1 deletion lib/src/bindings/structs.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:ffi';
import "dart:typed_data" show Uint8List;
import "package:ffi/ffi.dart" show allocate, free;
import "package:ffi/ffi.dart" show allocate, free, Utf8;
import '../common.dart';

// Disable some linter rules for this file
Expand Down Expand Up @@ -118,3 +118,72 @@ class OBX_bytes_array extends Struct {
return result;
}
}

class OBX_int8_array extends Struct {
Pointer<Int8> _itemsPtr;

@IntPtr() // size_t
int count;

List<int> items() => _itemsPtr.asTypedList(count).toList();
}

class OBX_int16_array extends Struct {
Pointer<Int16> _itemsPtr;

@IntPtr() // size_t
int count;

List<int> items() => _itemsPtr.asTypedList(count).toList();
}

class OBX_int32_array extends Struct {
Pointer<Int32> _itemsPtr;

@IntPtr() // size_t
int count;

List<int> items() => _itemsPtr.asTypedList(count).toList();
}

class OBX_int64_array extends Struct {
Pointer<Int64> _itemsPtr;

@IntPtr() // size_t
int count;

List<int> items() => _itemsPtr.asTypedList(count).toList();
}

class OBX_string_array extends Struct {
Pointer<Pointer<Uint8>> _itemsPtr;

@IntPtr() // size_t
int count;

List<String> items() {
final list = <String>[];
for (var i = 0; i < count; i++) {
list.add(Utf8.fromUtf8(_itemsPtr.elementAt(i).value.cast<Utf8>()));
}
return list;
}
}

class OBX_float_array extends Struct {
Pointer<Float> _itemsPtr;

@IntPtr() // size_t
int count;

List<double> items() => _itemsPtr.asTypedList(count).toList();
}

class OBX_double_array extends Struct {
Pointer<Double> _itemsPtr;

@IntPtr() // size_t
int count;

List<double> items() => _itemsPtr.asTypedList(count).toList();
}
Loading