gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnue] report IDL


From: Christopher Browne
Subject: Re: [Gnue] report IDL
Date: Wed, 20 Sep 2000 21:20:05 -0500

On 20 Sep 2000 08:51:51 -0100, the world broke into rejoicing as
Rodrigo Moya <address@hidden>  said:
> Hi!
> 
> Well, here's is the first proposal for the report IDL. Please add your
> comments, additions, etc.
> 
> module GDA {
> 
>       struct Param {
>                   string name;
>      any value;
>       };
>       typedef sequence<Param> ParamList;
>       
> enum Converter {
>      CONVERTER_TO_PDF,
>      CONVERTER_TO_PS,
>      ...
> };
> 
>       interface Report {
>                   string run (in ParamList params); // returns the XML
>               output, in case clients want to play
>      any convert (in Converter format); // returns the contents of the
> file?
> 
>      /* here, add functions for accessing report's internal format */
>       };
>       typedef sequence<Report> ReportList;
>       
>       interface ReportEngine {
>                   ReportList getAvailableReports ();
>                   Report openReport (in string rep_name);
>      Report addReport (in string rep_name, in string xml_report);
>      void removeReport (in string rep_name);
>       };
> 
> };

> The idea I have is that the report engine has all the reports stored in
> a location known only to him, and clients access them through the
> report's name, although they can add new reports to the system (through
> addReport).

One problem:  This scheme does not appear to have a way of adding
references to _programs_ that generate reports; it only seems to provide
(in openReport()) the ability to add a specific _instance_ of a report.

My other objection is to the use of a single output string as the output
from a report.  That is _arguably_ reasonable if what is being passed
back is to simply be a mapping to a Unix filter.  I'd expect to surely
do a _little_ more than that.

The approach has several problems, that imply several alternatives:
a) It utterly destroys _all_ structuring of a report.  There are
   two reasonable alternatives:

   1) to treat the report as a sequence of lines, thus:

   typedef string ReportLine;
   typedef sequence<ReportLine> ReportLines;
   ReportLines run (in ParamList params);

   This has the interesting merit that lines don't need to be
   delimited, and so there's no "DOS mode" or "Unix mode."

   2) to treat the report as a tree of XML elements, perhaps
   thus:
   struct Attribute {
     string Name;
     string Value;
   };
   typedef sequence<Attribute> AttributeList;
   struct Element {
     string Name;
     AttributeList Attributes;
     VE Contents;
   };
   typedef sequence<Element> ElementList;

   enum ContentType {
      AnElement, 
      PCDATA
   };
   union VE switch (ContentType) {
     case AnElement:
        ElementList EList;
     case PCDATA:
        string Contents;
   }

   And basically this means that the report passes back an Element,
   which can recursively contain elements, PCDATA, and attributes.
   (This may not _perfectly_ represent XML, but should be pretty close;
   feel free to FIX IT rather than merely poking holes at it...)

   By passing around a tree, programs can walk the tree rather than
   having to keep parsing it each time they run into it.

These two bits of IDL suggest either somewhat or a _LOT_ more structured
data being passed around.  It seems a bit silly to me to destroy what
structure gets built up just because it passes through an IDL layer.

Then there's the bigger problem.

b) What if the report is pretty big?  All of the options thus far examined
will produce HUGE requests for HUGE reports.  I'm not sure that it's 
wise to assume that an ORB will necessarily cope perfectly well with
a 15MB request.

The two approaches I suggested in a) (lines versus structures) provide
for differently complex results in this regard.

If what is passed around is a set of lines, it's not an outrageous
idea to have:

   typedef string ReportLine;
   typedef sequence<ReportLine,2500> ReportLines;
   ReportLines run (in ParamList params, in start);

   where if it pulls back 2500 lines, you call again with value
   2500 to get the chunk starting at line 2500, then at 5000 to get
   another 2500 lines, and so forth.  (Perhaps there should be a
   reference to some sort of "report instance" object here too;
   I will happily elide material we may not be ready to hit on...)

There are OMG defined interfaces that do this very thing, where 
you can indicate that limited chunks should be pulled, and the
requests also pass back a continuation that can be submitted to
get the "next chunk."

Life gets more complex if we're using the "tree" form of this; 
it is far less obvious in that case how the tree should get "walked"
to provide things in a useful order to the consumer.  I would tend
to think it valuable to return "a bunch of elements" at one shot;
how to select that "bunch" isn't obvious.  The _easy_ answer is probably
to go breadth-first, where you request an element, and thus get it,
its attributes, and then a list of object references to its
children probably including the childrens' names.

And it could well be a good move to have a function that can pass in
an ordered sequence of element references and pull back a corresponding
list of elements, one for each requested, with some sort of "limit"
value so that only so many of the "grandkids" get returned in total.

Thus, passing in:
  [ ref1, ref2, ref3, ref4, ref5 ], 6, 0
This indicates we're trying to get up to 6 elements, starting with
ref1, element 0, and looking, in order, at the sequence of elements
ref1, ref2, ... ref5.

We get back:
 [ ref1's atts, ref1's PCDATA ]
 [ ref2's atts, ref2's children, namely [ref7, ref8, ref9] ]
 [ ref3's atts, ref3's children, namely [ref10, ref11] ]
 [ ref4's atts, the first one of ref4's children, namely [ref12] ]

Note that we didn't get all of ref4's kids, and got NOTHING of ref5,
because there were already 6 element references returned.

The next call might continue by passing in:
[ ref4, ref5 ] , 6, 1
which means that we are looking for the "kids" of ref4 + ref5, up
to 6 elements, and we're starting not at 0, but at 1, because we
already found part of the kids of "ref4."

If the explanation seems rough, um, sorry; it _does_ get ugly pretty
quick, and I _did_ say that pulling in pieces of trees was not
particularly trivial...

At any rate, if you want to cope well with both:
a) Potentially big results, and
b) Structured data,
this is the sort of thing to consider.
--
address@hidden - <http://www.ntlug.org/~cbbrowne/corba.html>
"Never make any mistaeks." (Anonymous, in a mail discussion about to a
kernel bug report.)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]