You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Hugi Thordarson <hu...@karlmenn.is> on 2017/01/16 09:41:24 UTC

Column select API - fetch return types

Hi all,

I’ve been using the new column select API for the past week days and I’m loving it so far.

One thing that I find a little bothersome (and at times confusing) when using these APIs though is how return types change based on what you’re fetching, especially how the type will change between List<Object> to List<Object[]> based on if I’m fetching multiple columns or a single column (I see this was discussed a little on the list the other day). As an API consumer I think it would be much nicer if fetches consistently returned List<Object[]>.

If this isn’t possible, might a possible workaround be to make DataRow fetches always return DataRows? That would allow me to stick to a single API and have consistent results from fetches, regardless of whether I’m limiting myself to a set of columns. Example:

		List<DataRow> list = ObjectSelect.dataRowQuery( Entry.class )
				.where( Entry.RECEIPT.dot( Receipt.USER ).dot( User.NAME ).eq( "Hugi Þórðarson" ) )
				.columns( Entry.TEXT, Entry.PRICE )
				.select( someObjectContext() );

		for( DataRow entry : list ) {
			System.out.println( entry.get( "text" ) );
		}

Cheers,
- hugi

Re: Column select API - fetch return types

Posted by Nikita Timofeev <nt...@objectstyle.com>.
I think your confusion is from the bug that I'm trying to solve right
now: single argument in columns() method leads to erroneous result:
return type is declared like Object[] but actual result is single
Object.
This shouldn't happen as columns() method should always return
Object[] regardless argument count. Only way to have single Object in
result is explicitly call column() or corresponding factory method
ColumnSelect.query(EntityClass.class, singleProperty).

And I'm implementing fetchDataRow() support for the ColumnSelect too.

So I hope it will reduce inconsistency in new API.

On Mon, Jan 16, 2017 at 12:41 PM, Hugi Thordarson <hu...@karlmenn.is> wrote:
> Hi all,
>
> I’ve been using the new column select API for the past week days and I’m loving it so far.
>
> One thing that I find a little bothersome (and at times confusing) when using these APIs though is how return types change based on what you’re fetching, especially how the type will change between List<Object> to List<Object[]> based on if I’m fetching multiple columns or a single column (I see this was discussed a little on the list the other day). As an API consumer I think it would be much nicer if fetches consistently returned List<Object[]>.
>
> If this isn’t possible, might a possible workaround be to make DataRow fetches always return DataRows? That would allow me to stick to a single API and have consistent results from fetches, regardless of whether I’m limiting myself to a set of columns. Example:
>
>                 List<DataRow> list = ObjectSelect.dataRowQuery( Entry.class )
>                                 .where( Entry.RECEIPT.dot( Receipt.USER ).dot( User.NAME ).eq( "Hugi Þórðarson" ) )
>                                 .columns( Entry.TEXT, Entry.PRICE )
>                                 .select( someObjectContext() );
>
>                 for( DataRow entry : list ) {
>                         System.out.println( entry.get( "text" ) );
>                 }
>
> Cheers,
> - hugi


-- 
Best regards,
Nikita Timofeev

Re: Column select API - fetch return types

Posted by Aristedes Maniatis <ar...@maniatis.org>.
On 16/1/17 8:41pm, Hugi Thordarson wrote:
> One thing that I find a little bothersome (and at times confusing) when using these APIs though is how return types change based on what you\u2019re fetching, especially how the type will change between List<Object> to List<Object[]> based on if I\u2019m fetching multiple columns or a single column (I see this was discussed a little on the list the other day). As an API consumer I think it would be much nicer if fetches consistently returned List<Object[]>.


The problem is that the result type depends on too many different things:

* the execute function: select(), selectOne()
* the initial constructor: dataRowQuery(), query()
* something in the middle: columns(), column()
* maybe some shortcut execute function (if we want to add such a thing) like: max(), sum()

Would a different initial constructor make things clearer (as Nikita's idea)?

   columnQuery(<T>Artist.class) -> ColumnSelect<T>

or is it simply enough to always return List<Object[]> and never List<Object>. That way, we never worry about mixing columns() and column().


When we want shortcuts for count() and sum(), then we could add another constructor like this:

   sum(Artist.class, <T>property) -> AggregateSelect<T>
   max(Artist.class, <T>property) -> AggregateSelect<T>
   min(Artist.class, <T>property) -> AggregateSelect<T>
   count(Artist.class, <T>property) -> ScalarSelect<Integer>

Is that too much? I don't think we need more shortcuts than those. And these classes would not implement orderBy(), pageSize() or prefetch()

Ari






-- 
-------------------------->
Aristedes Maniatis
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A