10.2A Encapsulating a ProDataSet

Posted by weihe on 05-May-2009 08:07

Hi,

has anyone got a code example of a encapsulated ProDataSet using OOP techniques?

An idea how to realize it would help, too.

The OERA model describes to pass the dataset throuth the objects and layers. I think that's not the best solution designing an architecture, is it?

Thanks

André

All Replies

Posted by Peter Judge on 05-May-2009 08:22

 

has anyone got a code example of a encapsulated ProDataSet?

An idea how to realize it would help, too

AutoEdge is an example of this. The installer can be found at http://communities.progress.com/pcom/docs/DOC-57428

It uses ProDataSets and OERA.

 

The OERA model describes to pass the dataset throuth the objects and layers. I think that's not the best solution designing an architecture, is it?

There've been some discussions on this on Principles & Reference Architecture Forum ( http://communities.progress.com/pcom/community/psdn/openedge/principles ). There have also been discussions on the role of the PDS in an OO-based architecture; I'm not sure which forum that's on (may be the one above, or the OOABL one).

-- peter

Posted by Admin on 05-May-2009 08:25

Hi,

has anyone got a code example of a encapsulated ProDataSet?

I'm pretty sure Dr. Thomas will guide you to his samples, once it's time for him to get up...

The OERA model describes to pass the dataset throuth the objects and layers. I think that's not the best solution designing an architecture, is it?

YES and NO. From an encapsulation point of view, that's true.

But as of 10.2A there are at least two things that prevent working (fully) encapsulated with Datasets inside classes:

1. No native object serialization.

You need to build your own XML serialization and deserialization routines. I've discussed that during an Exchange talk (2007 I guess). Works o.k., you'd probably want to build a generator for that since it's not possible to automate the process in 10.2A (no reflection API).

2. DataBinding in GUI for .NET or Browsers in the classic GUI require access to queries or tables.

No way to get around this restriction...

So in other languages (like C#) both problems do not exist. Serialization is absolutely easy and you can databind a grid to any collection or lists of objects. So here - where the language supports the modell effectively I share your view, that encapsulating temp-tables or datasets is the way to go.

The ABL is not build for that! So I prefer to work effectively and give the UI acccess to the ProDataset or a query.

Mike

Posted by Thomas Mercer-Hursh on 05-May-2009 11:58

AutoEdge is *not* an example of what is being requested since it *passes* ProDataSets between objects instead of encapsulating them in an object.

Posted by Thomas Mercer-Hursh on 05-May-2009 12:04

Unfortunately, I don't have any published examples to point to ... been busy on other things.  Wish I did.  If Exchange ever happens and I do the talk I have proposed, I will have to come up with some, but that hasn't happened yet.

Native serialization is nice, but I would never let the lack of it keep me from using it since doing the serialization oneself is hardly difficult and I have found that I often want something a bit different than what the native serialization will provide anyway.

There is nothing to say that a method of a class encapsulating a PDS can't return a PDS for use elsewhere.  Whether or not it looks like the underlying PDS, whether it includes selection, whether it is complete, whether it has denormalized the underlying relations for use in a browser, etc. is invisible to the object consuming the method.

Posted by GregHiggins on 06-May-2009 06:39

What is it that prevents you from visualizing the dataset as an object in its own right?

Posted by Admin on 06-May-2009 10:05

There is nothing to say that a method of a class encapsulating a PDS can't return a PDS for use elsewhere.  Whether or not it looks like the underlying PDS, whether it includes selection, whether it is complete, whether it has denormalized the underlying relations for use in a browser, etc. is invisible to the object consuming the method.

Are you talking about creating a copy (maybe denomalized) of the data that would already be at the client to bind it using a bindingSource? And synchronization back when the UI changes the data?

Do you have a working sample of that? I'd like to see how well that performs and how easy that can be managed :-) Basically it's adding another layer to the application architecture.

Posted by Thomas Mercer-Hursh on 06-May-2009 11:18

Not necessarily a layer.  Think in terms of the encapsulated PDS being a server side object and a technology neutral interface to a client using an XML representation of some or all of the PDS data.  If the client is ABL, then it is free to construct a PDS from that XML to use in the interface, but if the client is something else, it will do something else with the same source.

Samples will come with the proposed talk.

Posted by Admin on 06-May-2009 15:41

I understand.

But what's the life time of that encapsulated PDS? Given an ABL client talking to a state-less or state-free AppServer, the data inside (and possibly the encapsulted PDS itself) may only live for the duration of a single AppServer call. In most cases the data belongs to a single user only.

So you read data from the database inside the PSD encapsulating object and then creating a second PDS as the result set that will be send to the client?

I'm not convinced by that tactic. How can you optimize the fill process of the prodataset? From my experience you need to limit the data read to the data really required for read operations for what the clients needs right now (partial fill / horizontal and vertical, i.e. Batching and defining the buffers to be read).

Don't get me wrong, I'd like to be able to have objects (like your encapsulted PDS) on the AppServer bound to a single client session, not an agent as well. But as long as that's not available, I try to build the best architecture around what's possible right now.

Nachricht geändert durch Mike Fechner

Posted by Thomas Mercer-Hursh on 06-May-2009 16:47

Given an ABL client talking to a state-less or state-free AppServer, the data inside (and possibly the encapsulted PDS itself) may only live for the duration of a single AppServer call. In most cases the data belongs to a single user only.

Let me start by taking exception to your "given".  In an OERA world, I don't think we should be designing to depend on an ABL client.  The server side components should be agnostic about the techology used for the UI.  In particular, it is all too easy when thinking about an ABL client up front ... even if we end up using an ABL client in the end ... is that we:

1) get tempted to use ABL-specific features to connect the client and server and thus lock us out of other clients; and

2) are way too easily tempted to put business logic in the client that really should be in the server per modern design.

Second, lets consider what we are talking about.  If it is a single record, e.g., one being fetched for edit, then I wouldn't use a PDS at all.  I would use properties.  So, the fact that it is a PDS implies that we have a set of data and, in fact, if it is a PDS and not just a TT, it implies that there are multiple "tables" involved. I.e., we have something moderately complex.  So, we need to think a bit about what kind of work it took to create this object and what we are likely to do with it.

Some uses are essentially read-only, so it is appropriate for us to discard the object after the data is passed to the client.

In other cases, there is an expection of edit.  If it is inexpensive to recreate the object when changed data is submitted, then that makes things easy.  As you say, with a state-free AppServer, we can't currently do anything else *unless* we pass the PDS *itself* to the client, in which case we have programmed ourselves into a corner.  There are cases where the PDS was relatively "expensive" to create, but I would suggest that in the bulk of those cases the changes are only over a fraction of the total data, so it is still efficient to deal with the changes we get back.  The "gotcha" is when the changes are sweeping and the PDS expensive.  That is certainly a place where we would like to be able to cache the object in some kind of pool for use by any agent.

So you read data from the database inside the PSD encapsulating object and then creating a second PDS as the result set that will be send to the client?

Probably not.  Probably I send XML to the client since I want to be technology agnostic.

Note too that the data sent to the client is not necessarily all of the data in the object., nor is it necessarily in the same form.  E.g., if I pull an order or set of orders and I have multiple lines and item data etc., etc., what I send to the client is likely to be de-normalized such as item descriptions folded into the order lines.

From my experience you need to limit the data read to the data really required for read operations for what the clients needs right now (partial fill / horizontal and vertical, i.e. Batching and defining the buffers to be read).

Those are certainly real issues and they are ones which a server side cache would help to solve, but I don't see that you solve them particularly well by flinging the entire PDS back and forth to the client.  Perhaps you "solve" them with a fat client talking directly to the database or even a fat client which has all kinds of the business logic layer in it and is using the AppServer as an intermediary to direct access to the database, but I don't see those as being modern designs.  They certainly are designs that lock one into ABL UI.

Don't get me wrong, I'd like to be able to have objects (like your encapsulted PDS) on the AppServer bound to a single client session, not an agent as well. But as long as that's not available, I try to build the best architecture around what's possible right now.

Me too, but for me that best architecture starts with being technology agnostic about the client so solutions that involve ABL lock-in are just not in the running.  I do think there are some strategies we can use now to make these things work better and I think we need to argue for a persistence mechanism.

p.s., interesting that having your UI in German means that the "message changed by" text comes up in German.  Sensible I suppose, but interesting.

Posted by GregHiggins on 06-May-2009 17:02

> That is certainly a place where we would like to be able to cache the object in some kind of pool for use by any agent.

This is possible today, but I still can't figure out whether you're talking about a generic object holding many different types of data or a specific object, e.g., I'm customer 57 ( specific ) vs  I'm a customer object (generic).

If you're talking about a generic object, how is it effectively different from an appServer devoted to (for example) generic customer objects only?.

If it's specific, how do you go about identifying that object to whomever wants to speak to it? 

Posted by Thomas Mercer-Hursh on 06-May-2009 17:30

I'm not sure that I quite understand the question.  I am talking about a facility by which one could instantiate an object, do things with it, and then park it in some kind of holding area with a tag that allowed one to find it again and bring in back into the then current session without the overhead of having to instantiate it and populate it.  E.g., for a large, batched query.

For a single customer, there is no PDS, only properties, and the expense of recreating it is probably so low that it isn't worth the overhead of parking it on the chance that some edits might come back.  I suspect this is also true of some fairly significant objects because the data which populated them originally is in all probablility still in the -B buffer.

I am aware that one can preserve state in a database, but I'm not convinced as a general case that serializing an object, storing it in the DB, finding it again, and deserializing it will be all that more efficient than simply recreating it when needed unless some significant state is involved and I suspect that most of those are better handled by recording the relevant aspects of state than the entire object.

Posted by GregHiggins on 06-May-2009 17:59

tamhas wrote:

I am aware that one can preserve state in a database, but I'm not convinced as a general case that serializing an object, storing it in the DB, finding it again, and deserializing it will be all that more efficient than simply recreating it when needed unless some significant state is involved and I suspect that most of those are better handled by recording the relevant aspects of state than the entire object.

I wasn't thinking of a database, I was thinking of an ABL session using Sonic. It has persistence, is capable of communicating with diverse systems regardless of how it is started, may be run in the foreground if .Net capabilities are desired, is capable of either direct connection to a database or connection via AppServer, can do data mashups, etc.

Posted by Thomas Mercer-Hursh on 06-May-2009 18:37

And how does that help when an object is instantiated in any one of many AppServer sessions?  And, how does it help one keep sessions state free so that they can be reused.  If you keep a session going with some object, then it is no longer state free.

I am with on the idea of tiering the task and the AppServer being mostly a facade for services that are tiered up behind it, but to preserve state, something somewhere has to not be state-free.

Perhaps we should start a new thread on this topic since it doesn't really address the OP's question and the indention is getting unpleasant.

Posted by GregHiggins on 06-May-2009 18:52

tamhas wrote:

And how does that help when an object is instantiated in any one of many AppServer sessions? 

I don't recall using the phrase "instantiated in any one of many AppServer sessions". Obviously that has to go.

Posted by Thomas Mercer-Hursh on 06-May-2009 19:04

Well, as I said, perhaps a new thread if you are proposing an entirely different architecture.  The issues Mike and I were discussing do assume AppServer used in some form of its normal fashion.  I am with you on thinking we can do better than that, but vague on your ideas of the specifics of what that looks like.

And, whether AppServer agent or Sonic service, there is still the goal of remaining state free.  If we had multi-threading, then we could have stateful threads and a statefree main process, but that's something else we don't have.

Posted by Thomas Mercer-Hursh on 20-May-2009 17:54

I have started a new thread dealing with some of the topics here in the OERA Principles forum here http://communities.progress.com/pcom/thread/17178

This thread is closed