On Tue, Apr 7, 2015 at 8:29 PM Aristedes Maniatis <a...@maniatis.org> wrote:
> On 7/04/2015 9:13pm, Savva Kolbachev wrote: > > Hi All! It's a pleasure for me to introduce to you some new features in > > Select API. I'd be thrilled if you could have a look and give us your > > feedback. > > Nice work. > > > > > This method selects a single object regardless of how many objects are > > matched by query. This makes 'selectFirst' different from ‘selectOne’, > > which would throw exception in this situation. ‘selectFirst’ is useful > e.g. > > when the query is ordered and we only want to see the first object (e.g. > > "most recent news article"): > > It seems like quite a bit of clutter to have: > > query.limit(1).select(context) > query.selectOne(context) > query.selectFirst(context) > query.requireOne(context) (Michael's suggestion) > > That's a lot of function calls that people are going to get mixed up, with > only a bunch of different exceptions separating them. How about we reduce > that to two: > > query.selectFirst(context) -> no exceptions even if there are zero or >1 > records > query.selectOne(context) -> exception if there are zero or >1 records > > That would require that internally, the second function needs to generate > LIMIT 2 in the SQL, in order to catch that second exception. So perhaps > that has a small performance penalty. > You have to have a fluent way to set a fetch limit to any number, so you have to have: query.limit(1).select(context) Besides that, it's handy to have a method whose signature indicates it returns a single object, hence: query.selectOne(context) Personally, I see no use for having this throw exceptions. You have to prevent > 1 objects using the database. And for the non-existent case you have null in Java 6/7 and Optional in Java 8. So until we get Java 8, just use null. If it does throw any exception, it would need to be a checked exception. And doing that brings in so much boilerplate that it's not even worth using. > > > // Add ordering > > > > query.addOrdering(new Ordering(Article.PUBLISHED.getName())); > > Can we have a shorter syntax for this as well (for a typical use case): > > query.addOrdering(Article.PUBLISHED); > There already is: query.addOrdering(Article.PUBLISHED.asc()); > > > > > // Select most recent news article > > > > Article article = query.selectFirst(context); > > > > Selecting the first object via "Select.selectFirst(ObjectContext)" is > more > > comprehensible than selecting via "ObjectContext.selectFirst(Select)", > > because implementations of "Select" usually set fetch size limit to one. > > > > 3. I’ve added ResultBatchIterator which allows iterating through results > by > > micro-batches. For example: > > > Although it looks really cool, I worry that this is taking us too far away > from Cayenne's true purpose. Personally I'm -1 on all the iterator methods. > There are plenty of libraries that already do all that, and probably better > than us (more choices, flexibility, users, testing). > > http://docs.guava-libraries.googlecode.com/git/javadoc/ > com/google/common/collect/Lists.html#partition%28java.util.List,%20int%29 > > https://commons.apache.org/proper/commons-collections/ > javadocs/api-3.2.1/index.html?org/apache/commons/ > collections/IteratorUtils.html > > > Am I missing the point here of why these should be in an ORM? Personally > if we are going to add more convenience functions I'd rather see > query.count(), query.sum(Article.PRICE), etc aggregate functions. > These exist to provide iteration WITHOUT fetching all the objects in the memory at once. For very large result sets this is very important, even required. > > > Cheers > Ari > > > > > -- > --------------------------> > Aristedes Maniatis > GPG fingerprint CBFB 84B4 738D 4E87 5E5C 5EFA EF6A 7D2E 3E49 102A >