Comments (20)
Thanks, the stream and futures look nice; there are async stuff on the objectbox-c project, that can be implemented to support async queries. The syntax is somewhat constrained by how objects/methods are defined in the objectbox-c project.
There should be a new ticket for syntax-sugar related wish-list. Since objectbox is not a SQL DB, I don't feel that we have to stick to that syntactic tradition, e.g. select(cond)..groupBy(prop)..orderBy(prop)
etc..
I can imagine something like this:
// box = Box<S> bla
final builder = box.query(S_.text == 'meh');
final firstFuture = builder.firstFuture(); // Future<S>
final listFuture = builder.future(); // Future<List<S>>
final generator = builder.generator(); // Iterator<S> Function();
final stream = builder.stream(); // Stream<List<S>>
// Stream<S> singleStream = builder.streamSingle(); // is probably achievable thru a StreamTransform.
try {
await print(firstFuture.toString());
await for(list in listFuture) {
print (list.map((s) => s.toString()).toList().join(", "));
}
print (generator()); // yields s0
print (generator()); // yields s1 after s0
print (generator()); // yields s2 after s1
await print(stream.first);
stream.listen((list) => print (list.map((s) => s.toString()).toList().join(", ")));
} catch (err) {
print('Caught error: $err');
}
We don't really have groupBy
support yet. Although this can be implemented from dart.
from objectbox-dart.
I started by wrapping the C functions, I'll share a branch soon.
With regard to designing the interface, I'm thinking of passing a closure to the Store#query method, to produce a QueryBuilder object like swift.
I think another way to do it idiomatically in dart is by declaring this query
method as a factory
that takes a closure that takes instances of Condition
in the body. Also one can leverage the ..
cascade operator, so there's no need to declare those types as part of a builder pattern. And boolean operator overloading for any / join (i.e. respectively ||
, &&
).
At some point in the future, we'll can leverage extension
(a la Objc: category
, swift: extension
), to bolt on the properties to create conditions. Right now, I'm generating the EntityType
properties, in a separate EntityType_
class (like java).
@Entity class Person { @Id... }
final store = Store([...]);
final box = Box<Person>(store);
final query = box.query(() {
Person_.age.isNotNull()
..greaterThan(18); // equivalent to: && Person_.age > 18
}).build();
var p = query.findFirst();
Something like this.
from objectbox-dart.
Factory method taking Condition
is what Go does (not closure, directly a list of conditions). That's probably similar to what you had in mind, isn't it? Maybe it would make the code/usage simpler without the closure?
box.Query(Person_.age.greaterThan(18), Person_.name.startsWith("John"))
from objectbox-dart.
A few things to keep in mind:
- consider building queries an expensive operation, the idea is they should be built once and reusable (just changing parameter values)
- there are links (over relation fields) - swift and go take slightly different approaches, with Go creating a condition and passing it to the query and swift chaining the link on the query object (therefore requiring an explicit
build()
call which Go doesn't need)
In any case, having a look at the query-builder implementation in go/swift may help you clear some things up. https://github.com/objectbox/objectbox-go/blob/master/objectbox/querybuilder.go
from objectbox-dart.
- java - https://docs.objectbox.io/queries
- go - https://golang.objectbox.io/queries
- swift - https://swift.objectbox.io/queries
from objectbox-dart.
We can't use varargs or reuse method names, that's why I initially thought of passing a closure.
For example:
QueryBuilder Query(Condition... c)
Nor this will work:
QueryBuilder Query(Condition c1) { ... }
QueryBuilder Query(Condition c1, ..., Condition cn) { ... }
We can do optional positional arguments though of constant size n, but I doubt that's gonna be pretty.
from objectbox-dart.
Oh, no variadic functions in dart? What about taking a list then? Still less cumbersome than a closure
from objectbox-dart.
And there's a "solution" for variadic functions as well actually: http://yuasakusa.github.io/dart/2014/01/23/dart-variadic.html
It would be interesting to see the performance hit when compared to passing a list
from objectbox-dart.
Actually, looking back at your original comment @Buggaboo, I quite like the idea of operator overloading. However, is it really necessary for Query to take a closure? What about taking a Condition
interface, i.e. something produced by Person_.age.greaterThan(18)
or by an operator overload (a combination of two conditions) - Person_.age.greaterThan(18) && Person_.name.startsWith("A")
from objectbox-dart.
I have something working, it might leak or explode on your machine. I'm not ready to merge yet, but count
already works.
This design allows for very complex Condition
trees using and
/ or
.
It would be nice if the user wouldn't need to manually close
a query.
Also I'm not very sure of the type mapping I have right now:
{
"dart" : "objectbox-c"
"int" : "Int64", // this could be Int32 instead, or even a c-byte (aka Uint8), dart<2.0 used to be arbitrary precision
"bool" : "Uint8",
}
I added a box.queryAll
and box.queryAny
function, e.g.:
final text = TestEntity_.text;
final anyGroup = <QueryCondition>[text.equal("meh"), text.equal("bleh")];
final queryAny = box.queryAny(anyGroup).build();
// equivalent to
box.query(text == "meh" | text == "bleh").build();
// equivalent to
box.query(text.equal("meh").or(text.equal("bleh"))).build();
from objectbox-dart.
I've taken first a look at the code and it looks good 👍 I especially like the operator overloads.
There are a few things that could be updated with the changes introduced by #25 - I hope it gets merged soon. It's merged into dev
now.
Also, as you mentioned, it seems like #11 is a prerequisite of queries supporting all types. However, it doesn't mean we can't finish the rest first and maybe even merge it in.
Do you mind creating a PR? It's fine if the code is unfinished but at least some parts could be clarified already.
from objectbox-dart.
I'll do a PR after I implement findFirst / find / findIds
. I quickly implemented findFirst
and find
by (ab)using Box<T>.getMany
.
I plan to expose new OBXFlatbuffersManager<T>
in a certain Box<T>
to the queries, to reuse for unmarshalling the buffer from find
. Instead of passing the whole box like I do right now.
I haven't started on orderBy
yet.
from objectbox-dart.
I plan to expose
new OBXFlatbuffersManager<T>
in a certainBox<T>
to the queries, to reuse for unmarshalling the buffer fromfind
. Instead of passing the whole box like I do right now.
Yes, makes sense for queries to have access to their entity's box. Similar is done in Go.
I haven't started on
orderBy
yet.
Order, offset, limit, params, etc. are not necessary for the first step. Let's limit the scope of this issue to "Basic query support" so the PR would be more manageable if you don't mind.
from objectbox-dart.
Hi,
I'm not sure if this is still a matter of discussion however I wanted to share a couple of Dart projects with built-in ORMs.
I guess that a major part of the objective here is having an API similar to the other languages SDKs but maybe some inspiration can be drawn from these:
- https://moor.simonbinder.eu/docs/getting-started/writing_queries/
- https://aqueduct.io/docs/db/executing_queries/ not Flutter compatible, it uses reflection.
Edit:
Maybe the aqueduct one is a little out of scope as it isn't compatible with Flutter.
from objectbox-dart.
Would be really nice, about aggregators I guess it's fine.
For what is worth I really dig the idea of using operator overloading to logically join the Conditions.
from objectbox-dart.
I'm not sure if this is still a matter of discussion however I wanted to share a couple of Dart projects with built-in ORMs.
I guess that a major part of the objective here is having an API similar to the other languages SDKs but maybe some inspiration can be drawn from these:
Thanks, it's pretty similar to what we do in other languages as well but when there's a specific functionality that needs to be done differently, it's always nice to have a fairly "standardized" interface - that's where it makes much sense to look at other solutions - if it makes sense to provide familiar experience to developers.
from objectbox-dart.
We don't really have groupBy support yet. Although this can be implemented from dart.
FYI, aggregators are (to some extent) supported by objectbox-c = Property-Query OBX_query_prop
- that would end up as a new issue I guess, certainly not in scope of this one.
Since objectbox is not a SQL DB, I don't feel that we have to stick to that syntactic tradition, e.g. select(cond)..groupBy(prop)..orderBy(prop) etc..
Certainly - while there are similarities, ObjectBox doesn't even want to look/work like SQL.
from objectbox-dart.
Thank you @Buggaboo for tackling this. It ended up to be quite a big PR 👍
from objectbox-dart.
Well, we did it together more or less. Now we have proper ffi Structs etc., and other fancy stuff. I learned a lot.
from objectbox-dart.
Awesome! 👍
from objectbox-dart.
Related Issues (20)
- Loaded ObjectBox core dynamic library has unsupported version 0.18.1, expected ^0.19.0 HOT 17
- Does it support arm64 arch (Raspberrypi)? HOT 1
- @Transient does not work with freezed HOT 4
- how to control the count for each category HOT 2
- ObjectBox 0.18.1 problem archlinux desktop programming HOT 2
- Wrong artifact created during build when adding flutter_libs HOT 1
- Allowing a different Constructor as the one used by ObjectBox HOT 3
- [Flutter] Async methods working significantly slower than the Sync methods. HOT 6
- Generated code contains multiple linting issues HOT 4
- Any plan to port this project to chrome/web ? HOT 1
- namespace not specified. HOT 2
- Data Visualization Tool HOT 2
- Reordering list HOT 5
- Missing tests examples for Flutter/Dart HOT 4
- macbook m2 virtual machine packaging windows linux cannot download the libs of the corresponding platform
- notOneOf() is missing in Dart API HOT 1
- generator error with retrofit HOT 1
- Dsym files not present in Release mode of ObjectBox Dart HOT 9
- this app add unauthorized charges to your mobile bill by registering for recurring charges HOT 4
- ObjectBox Admin with Docker not working in Windows HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from objectbox-dart.