Skip to content

Commit 08e8530

Browse files
authored
Merge pull request #16 from objectbox/dev-2.5
0.2 Release
2 parents ef45938 + 11361e1 commit 08e8530

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3221
-223
lines changed

.gitignore

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
.dart_tool/
2-
.packages
3-
build/
4-
pubspec.lock
5-
objectbox/
1+
**/.dart_tool/
2+
**/.packages
3+
**/build/
4+
**/pubspec.lock
65
misc/
7-
.idea/
6+
.idea/
7+
**/*.g.dart

CHANGELOG.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1+
0.2.0 (2019-09-11)
2+
------------------
3+
* UTF-8 support for Store and Box (thanks to [Buggaboo](https://github.com/Buggaboo) for [#14](https://github.com/objectbox/objectbox-dart/pull/14)!)
4+
* Bulk put and get functions (getMany, getAll, putMany)
5+
* Updated to objectbox-c 0.7
6+
* Basic Store options
7+
* Minimal unit tests
8+
* Removed reflection code, switched to model code generation instead
9+
* Minimal Flutter Desktop example for Dart 2.5.0
10+
111
0.1.0 (2019-09-03)
212
------------------
313
* Minimal Store setup
4-
* Minimal Box with put and get
14+
* Minimal Box with put and get

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ Getting started
3636
---------------
3737
To try out the demo code in this repository, follow these steps:
3838

39-
1. Install [objectbox-c](https://github.com/objectbox/objectbox-c) system-wide: `bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-c/master/download.sh)` (answer Y when it asks about installing to /usr/lib).
40-
2. Back in this repository, run `pub get` to download all Dart dependencies.
41-
3. Finally run `dart test/test.dart` to start the demo script.
42-
Note that, as fairly recent language features are used, the minimal required Dart version is 2.2.2.
39+
1. Install [objectbox-c](https://github.com/objectbox/objectbox-c) system-wide: `bash <(curl -s https://raw.githubusercontent.com/objectbox/objectbox-c/master/download.sh) 0.7` (answer Y when it asks about installing to /usr/lib).
40+
2. Back in this repository, run `pub get` in each of the following directories: `objectbox`, `objectbox_model_generator`, `objectbox_test`. If you just want to try out the tests, running it in `objectbox_test` is enough.
41+
3. Move into the `objectbox_test` directory and execute `pub run build_runner build`. This regenerates the ObjectBox model to make it usable in Dart (i.e. the file `test/test.g.dart`) and is necessary each time you add or change a class annotated with `@Entity(...)`.
42+
4. Finally run `pub run test test/test.dart` to run the unit tests.
4343

4444
Dart integration
4545
----------------
@@ -59,37 +59,37 @@ New (not yet persisted) objects typically have _Id_ value of `0` or `null`: call
5959

6060
*Note:* specifying the (meta model) IDs in annotations manually is a temporary quick solution.
6161
In a later version, you won't have to do this the and e.g. `@Property(id: 2, uid: 1002)` can be dropped completely.
62-
Technically, we need to setup [build time tools for Dart](https://github.com/objectbox/objectbox-dart/issues/3) for automatic management of the meta model IDs.
62+
As specified in step 3 of the _Getting started_ section, Dart's _build\_runner_ and _source\_gen_ are currently used and the generator will be extended to automatically manage the meta model IDs in the future.
6363

6464
```dart
6565
import "../lib/objectbox.dart";
66+
part "test.g.dart";
6667
6768
@Entity(id: 1, uid: 1)
6869
class Note {
69-
@Id(id: 1, uid: 1001, type: Type.Long)
70+
@Id(id: 1, uid: 1001) // automatically always 'int' in Dart code and 'Long' in ObjectBox
7071
int id;
7172
7273
@Property(id: 2, uid: 1002)
7374
String text;
7475
7576
Note(); // empty default constructor needed
7677
Note.construct(this.text);
77-
7878
toString() => "Note{id: $id, text: $text}";
7979
}
8080
```
8181

82-
In your main function, you can then create a _store_ which needs an array of your entity classes to be constructed.
82+
In your main function, you can then create a _store_ which needs an array of your entity classes and definitions to be constructed. If you have several entities, construct your store like `Store([[Entity1, Entity1_OBXDefs], [Entity2, Entity2_OBXDefs]])` etc.
8383
Finally, you need a _box_, representing the interface for objects of one specific entity type.
8484

8585
```dart
86-
var store = Store([Note]);
86+
var store = Store([[Note, Note_OBXDefs]]);
8787
var box = Box<Note>(store);
8888
89-
var note = Note("Hello");
90-
box.put(note);
89+
var note = Note.construct("Hello");
90+
note.id = box.put(note);
9191
print("new note got id ${note.id}");
92-
print("refetched note: ${box.getById(note.id)}");
92+
print("refetched note: ${box.get(note.id)}");
9393
9494
store.close();
9595
```
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
targets:
2+
$default:
3+
builders:
4+
objectbox_model_generator|objectbox:
5+
enabled: true
6+
7+
builders:
8+
objectbox:
9+
target: ":objectbox_model_generator"
10+
import: "package:objectbox_model_generator/builder.dart"
11+
builder_factories: ["objectboxModelFactory"]
12+
build_extensions: {".dart": [".objectbox_model.g.part"]}
13+
auto_apply: dependents
14+
build_to: cache
15+
applies_builders: ["source_gen|combining_builder"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import "package:build/build.dart";
2+
import "package:source_gen/source_gen.dart";
3+
import "package:objectbox_model_generator/src/generator.dart";
4+
5+
Builder objectboxModelFactory(BuilderOptions options) =>
6+
SharedPartBuilder([EntityGenerator()], "objectbox_model");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import "dart:async";
2+
import "package:analyzer/dart/element/element.dart";
3+
import "package:build/src/builder/build_step.dart";
4+
import "package:source_gen/source_gen.dart";
5+
6+
import "package:objectbox/objectbox.dart";
7+
import "package:objectbox/src/bindings/constants.dart";
8+
9+
class EntityGenerator extends GeneratorForAnnotation<Entity> {
10+
@override
11+
FutureOr<String> generateForAnnotatedElement(Element elementBare, ConstantReader annotation, BuildStep buildStep) {
12+
if(elementBare is! ClassElement)
13+
throw InvalidGenerationSourceError("in target ${elementBare.name}: annotated element isn't a class");
14+
15+
// get basic entity info
16+
var entity = Entity(id: annotation.read('id').intValue, uid: annotation.read('uid').intValue);
17+
var element = elementBare as ClassElement;
18+
var ret = """
19+
const _${element.name}_OBXModel = {
20+
"entity": {
21+
"name": "${element.name}",
22+
"id": ${entity.id},
23+
"uid": ${entity.uid}
24+
},
25+
"properties": [
26+
""";
27+
28+
// read all suitable annotated properties
29+
var props = [];
30+
String idPropertyName;
31+
for(var f in element.fields) {
32+
if(f.metadata == null || f.metadata.length != 1) // skip unannotated fields
33+
continue;
34+
var annotElmt = f.metadata[0].element as ConstructorElement;
35+
var annotType = annotElmt.returnType.toString();
36+
var annotVal = f.metadata[0].computeConstantValue();
37+
var fieldTypeObj = annotVal.getField("type");
38+
int fieldType = fieldTypeObj == null ? null : fieldTypeObj.toIntValue();
39+
40+
var prop = {
41+
"name": f.name,
42+
"id": annotVal.getField("id").toIntValue(),
43+
"uid": annotVal.getField("uid").toIntValue(),
44+
"flags": 0,
45+
};
46+
47+
if(annotType == "Id") {
48+
if(idPropertyName != null)
49+
throw InvalidGenerationSourceError("in target ${elementBare.name}: has more than one properties annotated with @Id");
50+
if(fieldType != null)
51+
throw InvalidGenerationSourceError("in target ${elementBare.name}: programming error: @Id property may not specify a type");
52+
if(f.type.toString() != "int")
53+
throw InvalidGenerationSourceError("in target ${elementBare.name}: field with @Id property has type '${f.type.toString()}', but it must be 'int'");
54+
55+
fieldType = OBXPropertyType.Long;
56+
prop["flags"] = OBXPropertyFlag.ID;
57+
idPropertyName = f.name;
58+
} else if(annotType == "Property") {
59+
// nothing special here
60+
} else {
61+
// skip unknown annotations
62+
continue;
63+
}
64+
65+
if(fieldType == null) {
66+
var fieldTypeStr = f.type.toString();
67+
if(fieldTypeStr == "int")
68+
fieldType = OBXPropertyType.Int;
69+
else if(fieldTypeStr == "String")
70+
fieldType = OBXPropertyType.String;
71+
else {
72+
print("warning: skipping field '${f.name}' in entity '${element.name}', as it has the unsupported type '$fieldTypeStr'");
73+
continue;
74+
}
75+
}
76+
77+
prop["type"] = fieldType;
78+
props.add(prop);
79+
ret += """
80+
{
81+
"name": "${prop['name']}",
82+
"id": ${prop['id']},
83+
"uid": ${prop['uid']},
84+
"type": ${prop['type']},
85+
"flags": ${prop['flags']},
86+
"flatbuffers_id": ${(prop['id'] as int) - 1},
87+
},
88+
""";
89+
}
90+
91+
// some checks on the entity's integrity
92+
if(idPropertyName == null)
93+
throw InvalidGenerationSourceError("in target ${elementBare.name}: has no properties annotated with @Id");
94+
95+
// main code for instance builders and readers
96+
ret += """
97+
],
98+
"idPropertyName": "${idPropertyName}",
99+
};
100+
101+
${element.name} _${element.name}_OBXBuilder(Map<String, dynamic> members) {
102+
${element.name} r = new ${element.name}();
103+
${props.map((p) => "r.${p['name']} = members[\"${p['name']}\"];").join()}
104+
return r;
105+
}
106+
107+
Map<String, dynamic> _${element.name}_OBXReader(${element.name} inst) {
108+
Map<String, dynamic> r = {};
109+
${props.map((p) => "r[\"${p['name']}\"] = inst.${p['name']};").join()}
110+
return r;
111+
}
112+
113+
const ${element.name}_OBXDefs = {
114+
"model": _${element.name}_OBXModel,
115+
"builder": _${element.name}_OBXBuilder,
116+
"reader": _${element.name}_OBXReader,
117+
};
118+
""";
119+
120+
return ret;
121+
}
122+
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: objectbox_model_generator
2+
version: 0.2.0
3+
description: >-
4+
A preprocessor for Dart source files containing ObjectBox entity definitions.
5+
environment:
6+
sdk: '>=2.5.0 <3.0.0'
7+
dependencies:
8+
build: '>=0.12.0 <2.0.0'
9+
source_gen: ^0.9.0
10+
objectbox:
11+
path: ../objectbox
12+
dev_dependencies:
13+
build_runner: '>=0.9.0 <0.11.0'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.atom/
2+
.dart_tool/
3+
.idea
4+
.vscode/
5+
.packages
6+
.pub/
7+
android/
8+
build/
9+
ios/
10+
packages
11+
.flutter-plugins
12+
# Since the current expectation is that clients are using Flutter head,
13+
# and Dart SDK changes unlock dependencies, pubspec.lock isn't useful.
14+
# Ignore it since it just creates noise. When there's a system in place
15+
# for versioning this project relative to Flutter, remove this.
16+
pubspec.lock
17+
objectbox
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: eaa9b47a4ac278a9439468911d2c361a472b114b
8+
channel: master
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# objectbox_demo_desktop
2+
3+
## Getting Started
4+
5+
In this early demo version, only desktop environments are supported. Mobile platform support, i.e. Android and iOS, will be added later. The current code is based on Google's [flutter-desktop-embedding](https://github.com/google/flutter-desktop-embedding) repository.
6+
7+
If you have never run Flutter on desktop before, execute the following commands (these are for Linux, adjust accordingly for your OS, see [here](https://github.com/flutter/flutter/wiki/Desktop-shells#tooling)):
8+
9+
flutter channel master
10+
flutter upgrade
11+
flutter config --enable-linux-desktop
12+
13+
When trying out this demo for the first time, you definitely need to run:
14+
15+
flutter packages get
16+
17+
And on first run and whenever you added or changed any classes annotated with ObjectBox's `@Entity(...)`, execute:
18+
19+
flutter pub run build_runner build
20+
flutter run

0 commit comments

Comments
 (0)