Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - support for dart26 #57

Merged
merged 11 commits into from
Nov 14, 2019
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Proceed based on whether you're developing a Flutter app or a standalone dart pr
* macOS: if dart later complains that it cannot find the `libobjectbox.dylib` you probably have to unsign the
`dart` binary (source: [dart issue](https://github.com/dart-lang/sdk/issues/38314#issuecomment-534102841)):
```shell script
sudo xcode --remove-signature $(which dart)
sudo codesign --remove-signature $(which dart)
```
* Windows: use "Git Bash" or similar to execute the following command
```shell script
Expand Down Expand Up @@ -111,17 +111,17 @@ queryNullText.close(); // We have to manually close queries and query builders.
```

More complex queries can be constructed using `and/or` operators.
Also there is basic operator overloading support for `equal`, `greater`, `less`, `and` and `or`,
respectively `==`, `>`, `<`, `&`, `|`.
Also there is basic operator overloading support for `greater`, `less`, `and` and `or`,
respectively `>`, `<`, `&`, `|`.

```dart
// final box ...

box.query(value.greaterThan(10).or(date.IsNull())).build();
box.query(value.greaterThan(10).or(date.isNull())).build();

// equivalent to

final overloaded = (value > 10) | date.IsNull();
final overloaded = (value > 10) | date.isNull();
box.query(overloaded as Condition).build(); // the cast is necessary due to the type analyzer
```

Expand All @@ -137,7 +137,7 @@ final q = box.query(Entity_.number > 0)
// ...

final qt = box.query(Entity_.text.notNull())
.order(Entity_.text, flags: OBXOrderFlag.DESCENDING | OBXOrderFlag.CASE_SENSITIVE)
.order(Entity_.text, flags: Order.descending | Order.caseSensitive)
.build();
```

Expand Down
4 changes: 2 additions & 2 deletions lib/src/bindings/bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class _ObjectBoxBindings {
obx_int8_array_free,
obx_double_array_free,
obx_float_array_free;
obx_free_t<OBX_bytes_array> obx_bytes_array_free;
obx_free_t<OBX_id_array> obx_id_array_free;
obx_free_dart_t<OBX_bytes_array> obx_bytes_array_free;
obx_free_dart_t<OBX_id_array> obx_id_array_free;

// error info
int Function() obx_last_error_code;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/bindings/flatbuffers.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "dart:ffi";
import "dart:typed_data" show Uint8List;
import "package:flat_buffers/flat_buffers.dart" as fb;
import "package:ffi/ffi.dart" show allocate, free;

import "constants.dart";
import "structs.dart";
Expand Down Expand Up @@ -136,7 +137,7 @@ class OBXFlatbuffersManager<T> {

// expects pointer to OBX_bytes_array and manually resolves its contents (see objectbox.h)
List<T> unmarshalArray(final Pointer<OBX_bytes_array> bytesArray, {bool allowMissing = false}) {
final OBX_bytes_array array = bytesArray.load();
final OBX_bytes_array array = bytesArray.ref;
var fn = (OBX_bytes b) => unmarshal(b.data);
if (allowMissing) {
fn = (OBX_bytes b) => b.isEmpty ? null : unmarshal(b.data);
Expand Down
1 change: 1 addition & 0 deletions lib/src/bindings/signatures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'structs.dart';
typedef obx_version_native_t = Void Function(Pointer<Int32> major, Pointer<Int32> minor, Pointer<Int32> patch);
typedef obx_version_string_native_t = Pointer<Uint8> Function();
typedef obx_free_t<T extends NativeType> = Void Function(Pointer<T> ptr);
typedef obx_free_dart_t<T extends NativeType> = void Function(Pointer<T> ptr);
typedef obx_free_struct_native_t = Void Function(Pointer<Uint64> structPtr);

// error info
Expand Down
64 changes: 33 additions & 31 deletions lib/src/bindings/structs.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:ffi';
import "dart:typed_data" show Uint8List, Uint64List;

import "package:ffi/ffi.dart" show allocate, free;

import '../common.dart';

// Note: IntPtr seems to be the the correct representation for size_t: "Represents a native pointer-sized integer in C."
Expand All @@ -10,34 +12,34 @@ import '../common.dart';
/// obx_id* ids;
/// size_t count;
/// };
class OBX_id_array extends Struct<OBX_id_array> {
class OBX_id_array extends Struct {
Pointer<Uint64> _itemsPtr;

@IntPtr() // size_t
int length;

/// Get a copy of the list
List<int> items() => Uint64List.view(_itemsPtr.asExternalTypedData(count: length).buffer).toList();
List<int> items() => _itemsPtr.asTypedList(length);

/// Execute the given function, managing the resources consistently
static R executeWith<R>(List<int> items, R Function(Pointer<OBX_id_array>) fn) {
// allocate a temporary structure
final ptr = Pointer<OBX_id_array>.allocate();
final ptr = allocate<OBX_id_array>();

// fill it with data
OBX_id_array array = ptr.load();
OBX_id_array array = ptr.ref;
array.length = items.length;
array._itemsPtr = Pointer<Uint64>.allocate(count: array.length);
array._itemsPtr = allocate<Uint64>(count: array.length);
for (int i = 0; i < items.length; ++i) {
array._itemsPtr.elementAt(i).store(items[i]);
array._itemsPtr.elementAt(i).value = items[i];
}

// call the function with the structure and free afterwards
try {
return fn(ptr);
} finally {
array._itemsPtr.free();
ptr.free();
free(array._itemsPtr);
free(ptr);
}
}
}
Expand All @@ -47,7 +49,7 @@ class OBX_id_array extends Struct<OBX_id_array> {
/// const void* data;
/// size_t size;
/// };
class OBX_bytes extends Struct<OBX_bytes> {
class OBX_bytes extends Struct {
Pointer<Uint8> _dataPtr;

@IntPtr() // size_t
Expand All @@ -56,7 +58,7 @@ class OBX_bytes extends Struct<OBX_bytes> {
/// Get access to the data (no-copy)
Uint8List get data => isEmpty
? throw ObjectBoxException("can't access data of empty OBX_bytes")
: Uint8List.view(_dataPtr.asExternalTypedData(count: length).buffer);
: _dataPtr.asTypedList(length);

bool get isEmpty => length == 0 || _dataPtr.address == 0;

Expand All @@ -65,8 +67,8 @@ class OBX_bytes extends Struct<OBX_bytes> {
/// Returns a pointer to OBX_bytes with copy of the passed data.
/// Warning: this creates an two unmanaged pointers which must be freed manually: OBX_bytes.freeManaged(result).
static Pointer<OBX_bytes> managedCopyOf(Uint8List data) {
final ptr = Pointer<OBX_bytes>.allocate();
final OBX_bytes bytes = ptr.load();
final ptr = allocate<OBX_bytes>();
final OBX_bytes bytes = ptr.ref;

const align = true; // ObjectBox requires data to be aligned to the length of 4
bytes.length = align ? ((data.length + 3.0) ~/ 4.0) * 4 : data.length;
Expand All @@ -79,19 +81,19 @@ class OBX_bytes extends Struct<OBX_bytes> {
// }

// create a copy of the data
bytes._dataPtr = Pointer<Uint8>.allocate(count: bytes.length);
bytes._dataPtr = allocate<Uint8>(count: bytes.length);
for (int i = 0; i < data.length; ++i) {
bytes._dataPtr.elementAt(i).store(data[i]);
bytes._dataPtr.elementAt(i).value = data[i];
}

return ptr;
}

/// Free a dart-created OBX_bytes pointer.
static void freeManaged(Pointer<OBX_bytes> ptr) {
final OBX_bytes bytes = ptr.load();
bytes._dataPtr.free();
ptr.free();
final OBX_bytes bytes = ptr.ref;
free(bytes._dataPtr);
free(ptr);
}
}

Expand All @@ -100,7 +102,7 @@ class OBX_bytes extends Struct<OBX_bytes> {
/// OBX_bytes* bytes;
/// size_t count;
/// };
class OBX_bytes_array extends Struct<OBX_bytes_array> {
class OBX_bytes_array extends Struct {
Pointer<OBX_bytes> _items;

@IntPtr() // size_t
Expand All @@ -110,7 +112,7 @@ class OBX_bytes_array extends Struct<OBX_bytes_array> {
List<OBX_bytes> items() {
final result = List<OBX_bytes>();
for (int i = 0; i < length; i++) {
result.add(_items.elementAt(i).load());
result.add(_items.elementAt(i).ref);
}
return result;
}
Expand All @@ -119,42 +121,42 @@ class OBX_bytes_array extends Struct<OBX_bytes_array> {
/// It's supposed to be used by PutMany()
// /// Create a dart-managed OBX_bytes_array.
// static Pointer<OBX_bytes_array> createManaged(int count) {
// final ptr = Pointer<OBX_bytes_array>.allocate();
// final OBX_bytes_array array = ptr.load();
// final ptr = allocate<OBX_bytes_array>();
// final OBX_bytes_array array = ptr.ref;
// array.length = count;
// array._items = Pointer<OBX_bytes>.allocate(count: count);
// array._items = allocate<OBX_bytes>(count: count);
// return ptr;
// }
//
// /// Replace the data at the given index with the passed pointer.
// void setAndFree(int i, Pointer<OBX_bytes> src) {
// assert(i >= 0 && i < length);
//
// final OBX_bytes srcBytes = src.load();
// final OBX_bytes tarBytes = _items.elementAt(i).load();
// final OBX_bytes srcBytes = src.ref;
// final OBX_bytes tarBytes = _items.elementAt(i).ref;
//
// assert(!srcBytes.isEmpty);
// assert(tarBytes.isEmpty);
//
// tarBytes._dataPtr = srcBytes._dataPtr;
// tarBytes.length = srcBytes.length;
//
// srcBytes._dataPtr.store(nullptr.address);
// srcBytes._dataPtr.value = nullptr.address;
// srcBytes.length = 0;
// src.free();
// free(src);
// }
//
// /// Free a dart-created OBX_bytes pointer.
// static void freeManaged(Pointer<OBX_bytes_array> ptr, bool freeIncludedBytes) {
// final OBX_bytes_array array = ptr.load();
// final OBX_bytes_array array = ptr.ref;
// if (freeIncludedBytes) {
// for (int i = 0; i < array.length; i++) {
// // Calling OBX_bytes.freeManaged() would cause double free
// final OBX_bytes bytes = array._items.elementAt(i).load();
// bytes._dataPtr.free();
// final OBX_bytes bytes = array._items.elementAt(i).ref;
// free(bytes._dataPtr);
// }
// }
// array._items.free();
// ptr.free();
// free(array._items);
// free(ptr);
// }
}
Loading