[Pljava-dev] advice needed

From: thhal at mailblocks(dot)com (Thomas Hallgren)
To:
Subject: [Pljava-dev] advice needed
Date: 2005-02-16 22:29:04
Message-ID: thhal-0s2HvAi+OxicoAri/IE5Q6XehocNEMg@mailblocks.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pljava-dev

George,
I think we agree that it would be beneficial to add an alternative way
of doing things such as the getResult() you suggest. I'd like to clarify
a couple of things with the current design though.

>// client interface method
>public ResultSet getResult();
>
>The receiver presented in the assignRowValues is already a ResultSet consisting of a single row. If you are worried about type matching you can easily check for that by gathering the appropriate meta data (as you do with a normal ResultSet) or throw an exception if type constraints have been violated (see below).
>Why is it a problem to supplement it with a ResultSet object containing not one row, but the entire set and then iterate over it *internally*, using next?
>
>
Let's assume that you want to return a set that cannot be expressed as a
single query. Each row in your result contains data that you create from
one or more sources. The source might be a socket, a file, a query
combined with other sources, etc. Point is, you don't have a ResultSet
to return. Using the current approach you have no problem doing this.
You simply update the row that is passed to with data from your sources,
once for each row, and you're all set. The tailor made, single row
ResultSet object that is passed to this method of course reused for each
call.

You must look at this ResultSet object, not as a "set" per se, but as a
single Tuple. There's no way to position within this set or add a row.
The one and only row is always present and the set is always positioned
on this row. If there was a standard interface in java.sql representing
a single Tuple, that interface would have been used instead. But there
is no such interface.

So current approach:
~~~~~~~~~~~~
on first call:
1. create a single-row ResultSet object.
2. call assignRowValues.
3. process result (extract the tuple data from the ResultSet object).

on each subsequent call:
1. call assignRowValues using the same single-row ResultSet object.
2. process result (extract the tuple data from the ResultSet object).

Now, with your suggested approach you have two choices:
1. Build a SyntheticResultSet in memory and return it. A fair amount of
code and the result might consume an unacceptable amount of memory.
2. Create your own implementation of ResultSet where you are the
implementor of the next() method. This is a great deal of work. A lot
more then just implementing the assignRowValues method.

New approach:
~~~~~~~~~~~~
on first call:
1. call getResult()
2. call next() on the obtained ResultSet
3. process result (extract the tuple from the ResultSet object).

on each subsequent call:
1. call next()
2. process result (extract the tuple from the ResultSet object).

Same amount of work for both approaches. The first approach doesn't
suffer from any of the disadvantages that the second approach has so
there's a good motivation to keep it.

>That I think would be much easier for developers like myself to handle it - all I have to worry about then is to prepare the ResultSet in a way I want it without the need to get bogged down in implementing iteractions and mess about with row numbers and the like.
>
>
Yes. The use case you have, when a function actually executes a query
and want to return the result of that query is a good motivation to add
the new approach.

>Better still, you can define and 'fire' different events through the entire process to give developers more control of what is being done. If adopted I have a suggestion of (at least) three such events (I suspect these methods will be in addition to the once controlling the pool behaviour, like 'make', 'activate', 'passivate' and 'destroy'):
>
>public void initialise(); // fired before the getResult() interface method is actually called to give the client class a chance to initialise itself
>public void lastRowProcessed(); // fired after the last row of the ResultSet has been processed;
>public void processException(Exception e); // when pljava/processing exception has occured
>
>
I assume that 'activate' is the same as 'initialise' and 'passivate' is
the same as 'lastRowProcessed'? If so, I must say I like the original
names better. 'initialise' sounds like a constructor. 'activate' is a
well known term for patterns that use pooling, and if we use 'activate',
then 'passivate' comes natural.

'destroy' is fine but I don't think we need 'make' since that's the same
as the constructor and I'm opposed to a special processException method.
Let the implementor decide how and when he want to deal with exceptions.
It's easy enough to implement and several patterns are possible.

>Nah! When I have time (probably around Friday time by the looks of it) I'll post the code of our pool framework based on Jakarta's Generic Object Pool which has been used by us for the past 7 months - all that without a single glitch (I can hardly recall stopping the service or bringing down the servers more than 2-3 times since it was launched).
>The framework is very robuslt and as I pointed out earlier has dealt with a lot of pounding in the past.
>
>
Great. I look forward to reviewing it.

Regards,
Thomas Hallgren

In response to

Browse pljava-dev by date

  From Date Subject
Next Message George 2005-02-17 00:31:20 [Pljava-dev] advice needed
Previous Message WYSE Systems Limited Information 2005-02-16 21:09:55 [Pljava-dev] advice needed