Skip to content

Commit cf18e0f

Browse files
authored
Merge pull request #101 from objectbox/dev
v0.6.3 release
2 parents 8eddac9 + 43bad49 commit cf18e0f

File tree

15 files changed

+102
-45
lines changed

15 files changed

+102
-45
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
0.6.3 (2020-05-07)
2+
------------------
3+
* Update FlatBuffers to 1.12.0
4+
* Provide error hinting when DB can't be created (e.g. when an app docs directory isn't passed properly on Flutter).
5+
16
0.6.2 (2020-03-09)
27
------------------
38
* Support large object arrays on 32-bit platforms/emulators.

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ Installation
1616
Add the following dependencies to your `pubspec.yaml`:
1717
```yaml
1818
dependencies:
19-
objectbox: ^0.6.2
19+
objectbox: ^0.6.3
2020

2121
dev_dependencies:
2222
build_runner: ^1.0.0
23-
objectbox_generator: ^0.6.2
23+
objectbox_generator: ^0.6.3
2424
```
2525
2626
Proceed based on whether you're developing a Flutter app or a standalone dart program:

example/README.md

+38-11
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,45 @@ Finally, you will create a `Box<Note>` which gives you a typed interface for sto
3737
import 'objectbox.g.dart'; // this file will be generated by ObjectBox after running `pub run build_runner build`
3838
3939
void main() {
40-
var store = Store(getObjectBoxModel()); // Note: getObjectBoxModel() is generated for you in objectbox.g.dart
41-
var box = Box<Note>(store);
42-
43-
var note = Note(text: "Hello");
44-
note.id = box.put(note);
45-
print("new note got id ${note.id}");
46-
print("refetched note: ${box.get(note.id)}");
47-
48-
store.close();
40+
var store = Store(getObjectBoxModel()); // Note: getObjectBoxModel() is generated for you in objectbox.g.dart
41+
var box = Box<Note>(store);
42+
43+
var note = Note(text: "Hello");
44+
note.id = box.put(note);
45+
print("new note got id ${note.id}");
46+
print("refetched note: ${box.get(note.id)}");
47+
48+
store.close();
4949
}
5050
```
5151

52-
See also
52+
Flutter
5353
--------
54-
* sample [Flutter android app](flutter/objectbox_demo) - requires Flutter 1.12
54+
* See a [Flutter example app](flutter/objectbox_demo) - requires Flutter 1.12
55+
56+
As opposed to a plain Dart app which runs directly on your PC, there are more restrictions where your Flutter app can
57+
write data. Therefore, you should give ObjectBox a full path to a per-app documents directory, where to store the data
58+
even when a user closes your app.
59+
60+
If you didn't specify this path to ObjectBox, it would try to use a default "objectbox" directory where the app is
61+
currently running, but it doesn't have permissions to write there: `failed to create store: 10199 Dir does not exist: objectbox (30)`.
62+
63+
To configure ObjectBox properly, you can use `getApplicationDocumentsDirectory()` from the `path_provider` package.
64+
See [Flutter: read & write files](https://flutter.dev/docs/cookbook/persistence/reading-writing-files) for more info.
65+
Have a look how it's done in the Flutter example app:
66+
```dart
67+
import 'package:path_provider/path_provider.dart';
68+
69+
class _MyHomePageState extends State<MyHomePage> {
70+
Store _store;
71+
72+
@override
73+
void initState() {
74+
super.initState();
75+
76+
getApplicationDocumentsDirectory().then((dir) {
77+
_store = Store(getObjectBoxModel(), directory: dir.path + "/objectbox");
78+
});
79+
}
80+
}
81+
```

example/flutter/objectbox_demo/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ dependencies:
1111
cupertino_icons: ^0.1.2
1212
path_provider: any
1313
intl: any
14-
objectbox: ^0.6.2
14+
objectbox: ^0.6.3
1515

1616
dev_dependencies:
1717
flutter_test:
1818
sdk: flutter
1919
build_runner: ^1.0.0
20-
objectbox_generator: ^0.6.2
20+
objectbox_generator: ^0.6.3
2121

2222
flutter:
2323
uses-material-design: true

example/flutter/objectbox_demo_desktop/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ dependencies:
1111
flutter:
1212
sdk: flutter
1313
cupertino_icons: ^0.1.0
14-
objectbox: ^0.6.2
14+
objectbox: ^0.6.3
1515

1616
dev_dependencies:
1717
flutter_test:
1818
sdk: flutter
1919
build_runner: ^1.0.0
20-
objectbox_generator: ^0.6.2
20+
objectbox_generator: ^0.6.3
2121

2222
flutter:
2323
uses-material-design: true

generator/pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: objectbox_generator
2-
version: 0.6.2
2+
version: 0.6.3
33
repository: https://github.com/objectbox/objectbox-dart
44
homepage: https://objectbox.io
55
description: ObjectBox binding code generator - finds annotated entities and adds them to the ObjectBox DB model.
@@ -8,7 +8,7 @@ environment:
88
sdk: ">=2.5.0 <3.0.0"
99

1010
dependencies:
11-
objectbox: 0.6.2
11+
objectbox: 0.6.3
1212
build: ^1.0.0
1313
source_gen: ^0.9.0
1414
analyzer: ">=0.35.0 <0.100.0"

lib/src/bindings/helpers.dart

+7-8
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,26 @@ import "bindings.dart";
55
import "constants.dart";
66
import "../common.dart";
77

8-
checkObx(errorCode) {
9-
if (errorCode != OBXError.OBX_SUCCESS) throw ObjectBoxException(lastObxErrorString(errorCode));
8+
checkObx(int code) {
9+
if (code != OBXError.OBX_SUCCESS) throw latestNativeError(codeIfMissing: code);
1010
}
1111

12-
Pointer<T> checkObxPtr<T extends NativeType>(Pointer<T> ptr, String msg) {
12+
Pointer<T> checkObxPtr<T extends NativeType>(Pointer<T> ptr, String dartMsg) {
1313
if (ptr == null || ptr.address == 0) {
14-
final info = lastObxErrorString();
15-
throw ObjectBoxException(info.isEmpty ? msg : "$msg: $info");
14+
throw latestNativeError(dartMsg: dartMsg);
1615
}
1716
return ptr;
1817
}
1918

20-
String lastObxErrorString([int err = 0]) {
19+
ObjectBoxException latestNativeError({String dartMsg, int codeIfMissing}) {
2120
int code = bindings.obx_last_error_code();
2221
String text = cString(bindings.obx_last_error_message());
2322

2423
if (code == 0 && text.isEmpty) {
25-
return (err != 0) ? "code $err" : "unknown native error";
24+
return ObjectBoxException(dartMsg: dartMsg, nativeCode: codeIfMissing, nativeMsg: 'unknown native error');
2625
}
2726

28-
return code == 0 ? text : "$code $text";
27+
return ObjectBoxException(dartMsg: dartMsg, nativeCode: code, nativeMsg: text);
2928
}
3029

3130
String cString(Pointer<Utf8> charPtr) {

lib/src/bindings/structs.dart

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class OBX_bytes extends Struct {
5757
int length;
5858

5959
/// Get access to the data (no-copy)
60-
Uint8List get data =>
61-
isEmpty ? throw ObjectBoxException("can't access data of empty OBX_bytes") : _dataPtr.asTypedList(length);
60+
Uint8List get data => isEmpty
61+
? throw ObjectBoxException(dartMsg: "can't access data of empty OBX_bytes")
62+
: _dataPtr.asTypedList(length);
6263

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

lib/src/box.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class Box<T> {
5959
int id = propVals[_modelEntity.idProperty.name];
6060
if (id == null || id == 0) {
6161
id = bindings.obx_box_id_for_put(_cBox, 0);
62-
if (id == 0) throw ObjectBoxException(lastObxErrorString());
62+
if (id == 0) throw latestNativeError();
6363
propVals[_modelEntity.idProperty.name] = id;
6464
}
6565

lib/src/common.dart

+16-8
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,20 @@ Version versionLib() {
2828
}
2929

3030
class ObjectBoxException implements Exception {
31-
final String message;
32-
final String msg;
33-
34-
ObjectBoxException(msg)
35-
: message = "ObjectBoxException: " + msg,
36-
msg = msg;
37-
38-
String toString() => message;
31+
final String dartMsg;
32+
final int nativeCode;
33+
final String nativeMsg;
34+
35+
ObjectBoxException({String dartMsg, int nativeCode, String nativeMsg})
36+
: dartMsg = dartMsg,
37+
nativeCode = nativeCode,
38+
nativeMsg = nativeMsg;
39+
40+
@override
41+
String toString() {
42+
var result = 'ObjectBoxException: ';
43+
if (dartMsg != null) result += dartMsg + ': ';
44+
if (nativeCode != 0) result += '$nativeCode ';
45+
return result + nativeMsg;
46+
}
3947
}

lib/src/model.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Model {
3333
int code = bindings.obx_model_error_code(_cModel);
3434
String text = cString(bindings.obx_model_error_message(_cModel));
3535

36-
throw ObjectBoxException("$code $text");
36+
throw ObjectBoxException(nativeCode: code, nativeMsg: text);
3737
}
3838

3939
void addEntity(ModelEntity entity) {

lib/src/query/builder.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class QueryBuilder<T> {
1313
void _throwExceptionIfNecessary() {
1414
if (bindings.obx_qb_error_code(_cBuilder) != OBXError.OBX_SUCCESS) {
1515
final msg = cString(bindings.obx_qb_error_message(_cBuilder));
16-
throw ObjectBoxException("$msg");
16+
throw ObjectBoxException(nativeMsg: msg);
1717
}
1818
}
1919

lib/src/store.dart

+18-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import "bindings/bindings.dart";
44
import "bindings/helpers.dart";
55
import "modelinfo/index.dart";
66
import "model.dart";
7+
import "common.dart";
78

89
enum TxMode {
910
Read,
@@ -40,7 +41,23 @@ class Store {
4041
rethrow;
4142
}
4243
_cStore = bindings.obx_store_open(opt);
43-
checkObxPtr(_cStore, "failed to create store");
44+
45+
try {
46+
checkObxPtr(_cStore, "failed to create store");
47+
} on ObjectBoxException catch (e) {
48+
// Recognize common problems when trying to open/create a database
49+
// 10199 = OBX_ERROR_STORAGE_GENERAL
50+
if (e.nativeCode == 10199 && e.nativeMsg != null && e.nativeMsg.contains('Dir does not exist')) {
51+
// 13 = permissions denied, 30 = read-only filesystem
52+
if (e.nativeMsg.endsWith(' (13)') || e.nativeMsg.endsWith(' (30)')) {
53+
final msg = e.nativeMsg +
54+
" - this usually indicates a problem with permissions; if you're using Flutter you may need to use " +
55+
"getApplicationDocumentsDirectory() from the path_provider package, see example/README.md";
56+
throw ObjectBoxException(dartMsg: e.dartMsg, nativeCode: e.nativeCode, nativeMsg: msg);
57+
}
58+
}
59+
rethrow;
60+
}
4461
}
4562

4663
/// Closes this store.

pubspec.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: objectbox
2-
version: 0.6.2
2+
version: 0.6.3
33
repository: https://github.com/objectbox/objectbox-dart
44
homepage: https://objectbox.io
55
description: ObjectBox is a super-fast NoSQL ACID compliant object database.
@@ -9,7 +9,7 @@ environment:
99

1010
dependencies:
1111
# take care updating flatbuffers - keep aligned with other bindings
12-
flat_buffers: 1.11.0
12+
flat_buffers: 1.12.0
1313
ffi: ^0.1.3
1414

1515
dev_dependencies:

test/basics_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ void main() {
1111
// sanity check - the result is a null pointer
1212
expect(cStore, isA<ffi.Pointer>().having((ptr) => ptr.address, "address", equals(0)));
1313

14-
final error = lastObxErrorString();
15-
expect(error, matches('Argument .+ must not be null'));
14+
final error = latestNativeError();
15+
expect(error.nativeMsg, matches('Argument .+ must not be null'));
1616
});
1717
}

0 commit comments

Comments
 (0)