pile of reporting updates
authormiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 9 Oct 2006 00:53:17 +0000 (00:53 +0000)
committermiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 9 Oct 2006 00:53:17 +0000 (00:53 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@6408 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/fm_IDL.xml
Open-ILS/examples/reporter-sql-builder-test.pl
Open-ILS/src/perlmods/OpenILS/Reporter/SQLBuilder.pm
Open-ILS/src/reporter/clark-kent.pl
Open-ILS/src/sql/Pg/reporter-schema.sql

index 0286c97..9f98580 100644 (file)
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                </links>
        </class>
-       <class id="aun" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note">
+       <class id="aun" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note" reporter:label="User Note">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.usr_note_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="create_date" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="creator" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="pub" oils_obj:array_position="6" oils_persist:virtual="false" reporter:datatype="bool"/>
-                       <field name="title" oils_obj:array_position="7" oils_persist:virtual="false" />
-                       <field name="usr" oils_obj:array_position="8" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Creation Date/Time" name="create_date" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Creating Staff" name="creator" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Note ID" name="id" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Is OPAC Visible?" name="pub" oils_obj:array_position="6" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Note Title" name="title" oils_obj:array_position="7" oils_persist:virtual="false" />
+                       <field reporter:label="User" name="usr" oils_obj:array_position="8" oils_persist:virtual="false" />
+                       <field reporter:label="Note Content" name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
                </fields>
                <links>
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                        <link field="field" reltype="has_a" key="id" map="" class="cmf"/>
                </links>
        </class>
-       <class id="aihu" controller="open-ils.cstore" oils_obj:fieldmapper="action::in_house_use" oils_persist:tablename="action.in_house_use">
+       <class id="aihu" controller="open-ils.cstore" oils_obj:fieldmapper="action::in_house_use" oils_persist:tablename="action.in_house_use" reporter:core="true" reporter:label="In House Use">
                <fields oils_persist:primary="id" oils_persist:sequence="action.in_house_use_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="item" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="org_unit" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="staff" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="use_time" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Use ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Item" name="item" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Using Library" name="org_unit" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="Recording Staff" name="staff" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Use Date/Time" name="use_time" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="timestamp"/>
                </fields>
                <links>
                        <link field="item" reltype="has_a" key="id" map="" class="acp"/>
                        <link field="org_unit" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="ancihu" controller="open-ils.cstore" oils_obj:fieldmapper="action::non_cat_in_house_use" oils_persist:tablename="action.non_cat_in_house_use">
+       <class id="ancihu" controller="open-ils.cstore" oils_obj:fieldmapper="action::non_cat_in_house_use" oils_persist:tablename="action.non_cat_in_house_use" reporter:core="true" reporter:label="Non-cataloged In House Use">
                <fields oils_persist:primary="id" oils_persist:sequence="action.non_cat_in_house_use_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="item_type" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="org_unit" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="staff" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="use_time" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Use ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Item Type" name="item_type" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Using Library" name="org_unit" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="Recording Staff" name="staff" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Use Date/Time" name="use_time" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="timestamp"/>
                </fields>
                <links>
                        <link field="item_type" reltype="has_a" key="id" map="" class="cnct"/>
                        <link field="location" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="bre" controller="open-ils.cstore" oils_obj:fieldmapper="biblio::record_entry" oils_persist:tablename="biblio.record_entry">
+       <class id="bre" controller="open-ils.cstore" oils_obj:fieldmapper="biblio::record_entry" oils_persist:tablename="biblio.record_entry" reporter:core="true" reporter:label="Bibliographic Record">
                <fields oils_persist:primary="id" oils_persist:sequence="biblio.record_entry_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <link field="org_unit" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="acpn" controller="open-ils.cstore" oils_obj:fieldmapper="asset::copy_note" oils_persist:tablename="asset.copy_note">
+       <class id="acpn" controller="open-ils.cstore" oils_obj:fieldmapper="asset::copy_note" oils_persist:tablename="asset.copy_note" reporter:label="Copy Note">
                <fields oils_persist:primary="id" oils_persist:sequence="asset.copy_note_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="create_date" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="creator" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="owning_copy" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="pub" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="bool"/>
-                       <field name="title" oils_obj:array_position="8" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Note Creation Date/Time" name="create_date" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Note Creator" name="creator" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Node ID" name="id" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Copy" name="owning_copy" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Is OPAC Visible?" name="pub" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Note Title" name="title" oils_obj:array_position="8" oils_persist:virtual="false" />
+                       <field reporter:label="Note Content" name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
                </fields>
                <links>
                        <link field="owning_copy" reltype="has_a" key="id" map="" class="acp"/>
                        <link field="creator" reltype="has_a" key="id" map="" class="au"/>
                </links>
        </class>
-       <class id="mfr" controller="open-ils.cstore" oils_obj:fieldmapper="metabib::full_rec" oils_persist:tablename="metabib.full_rec">
+       <class id="mfr" controller="open-ils.cstore" oils_obj:fieldmapper="metabib::full_rec" oils_persist:tablename="metabib.full_rec" reporter:label="Flattened MARC Fields">
                <fields oils_persist:primary="id" oils_persist:sequence="metabib.full_rec_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="ind1" oils_obj:array_position="4" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="ind2" oils_obj:array_position="5" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="record" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="subfield" oils_obj:array_position="7" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="tag" oils_obj:array_position="8" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Field ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Indicator 1" name="ind1" oils_obj:array_position="4" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Indicator 2" name="ind2" oils_obj:array_position="5" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Bib Record Entry" name="record" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Subfield" name="subfield" oils_obj:array_position="7" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Tag" name="tag" oils_obj:array_position="8" oils_persist:virtual="false" />
+                       <field reporter:label="Normalized Value" name="value" oils_obj:array_position="9" oils_persist:virtual="false" />
                </fields>
                <links>
                        <link field="record" reltype="has_a" key="id" map="" class="bre"/>
                        <link field="xact" reltype="has_a" key="id" map="" class="mbt"/>
                </links>
        </class>
-       <class id="mrd" controller="open-ils.cstore" oils_obj:fieldmapper="metabib::record_descriptor" oils_persist:tablename="metabib.rec_descriptor">
+       <class id="mrd" controller="open-ils.cstore" oils_obj:fieldmapper="metabib::record_descriptor" oils_persist:tablename="metabib.rec_descriptor" reporter:label="Basic Record Descriptor">
                <fields oils_persist:primary="id" oils_persist:sequence="metabib.rec_descriptor_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="audience" oils_obj:array_position="3" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="bib_level" oils_obj:array_position="4" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="cat_form" oils_obj:array_position="5" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="char_encoding" oils_obj:array_position="6" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="control_type" oils_obj:array_position="7" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="enc_level" oils_obj:array_position="8" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="id" oils_obj:array_position="9" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="item_form" oils_obj:array_position="10" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="item_lang" oils_obj:array_position="11" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="item_type" oils_obj:array_position="12" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="lit_form" oils_obj:array_position="13" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="pub_status" oils_obj:array_position="14" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="record" oils_obj:array_position="15" oils_persist:virtual="false" />
-                       <field name="type_mat" oils_obj:array_position="16" oils_persist:virtual="false" oils_persist:primitive="string" />
-                       <field name="vr_format" oils_obj:array_position="17" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Audn" name="audience" oils_obj:array_position="3" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="BLvl" name="bib_level" oils_obj:array_position="4" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Cat Form" name="cat_form" oils_obj:array_position="5" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Character Encoding" name="char_encoding" oils_obj:array_position="6" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Ctrl" name="control_type" oils_obj:array_position="7" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="ELvl" name="enc_level" oils_obj:array_position="8" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Descriptor ID" name="id" oils_obj:array_position="9" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Form" name="item_form" oils_obj:array_position="10" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Lang" name="item_lang" oils_obj:array_position="11" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Type" name="item_type" oils_obj:array_position="12" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="LitF" name="lit_form" oils_obj:array_position="13" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Pub Status" name="pub_status" oils_obj:array_position="14" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Bib Record Entry" name="record" oils_obj:array_position="15" oils_persist:virtual="false" />
+                       <field reporter:label="TMat" name="type_mat" oils_obj:array_position="16" oils_persist:virtual="false" oils_persist:primitive="string" />
+                       <field reporter:label="Video Recording Format" name="vr_format" oils_obj:array_position="17" oils_persist:virtual="false" oils_persist:primitive="string" />
                </fields>
                <links>
                        <link field="record" reltype="has_a" key="id" map="" class="bre"/>
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                </links>
        </class>
-       <class id="aua" controller="open-ils.cstore" oils_obj:fieldmapper="actor::user_address" oils_persist:tablename="actor.usr_address">
+       <class id="aua" controller="open-ils.cstore" oils_obj:fieldmapper="actor::user_address" oils_persist:tablename="actor.usr_address" reporter:label="User Address">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.usr_address_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="address_type" oils_obj:array_position="3" oils_persist:virtual="false" />
-                       <field name="city" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="country" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="county" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="post_code" oils_obj:array_position="8" oils_persist:virtual="false" />
-                       <field name="state" oils_obj:array_position="9" oils_persist:virtual="false" />
-                       <field name="street1" oils_obj:array_position="10" oils_persist:virtual="false" />
-                       <field name="street2" oils_obj:array_position="11" oils_persist:virtual="false" />
-                       <field name="usr" oils_obj:array_position="12" oils_persist:virtual="false" />
-                       <field name="valid" oils_obj:array_position="13" oils_persist:virtual="false" reporter:datatype="bool"/>
-                       <field name="within_city_limits" oils_obj:array_position="14" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Type" name="address_type" oils_obj:array_position="3" oils_persist:virtual="false" />
+                       <field reporter:label="City" name="city" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Country" name="country" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="County" name="county" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Address ID" name="id" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Postal Code" name="post_code" oils_obj:array_position="8" oils_persist:virtual="false" />
+                       <field reporter:label="State" name="state" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Street (1)" name="street1" oils_obj:array_position="10" oils_persist:virtual="false" />
+                       <field reporter:label="Street (2)" name="street2" oils_obj:array_position="11" oils_persist:virtual="false" />
+                       <field reporter:label="User" name="usr" oils_obj:array_position="12" oils_persist:virtual="false" />
+                       <field reporter:label="Valid Address?" name="valid" oils_obj:array_position="13" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Within City Limits?" name="within_city_limits" oils_obj:array_position="14" oils_persist:virtual="false" reporter:datatype="bool"/>
                </fields>
                <links>
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                        <field reporter:label="Check Out Date/Time" name="xact_start" oils_obj:array_position="26" oils_persist:virtual="false" reporter:datatype="timestamp" />
                        <field reporter:label="Transaction Billings" name="billings" oils_obj:array_position="27" oils_persist:virtual="true" />
                        <field reporter:label="Transaction Payments" name="payments" oils_obj:array_position="28" oils_persist:virtual="true" />
-                       <field name="billable_transaction" oils_obj:array_position="29" oils_persist:virtual="true" />
+                       <field reporter:label="Base Transaction" name="billable_transaction" oils_obj:array_position="29" oils_persist:virtual="true" />
                </fields>
                <links>
                        <link field="billable_transaction" reltype="might_have" key="id" map="" class="mbt"/>
                        <link field="target_copy" reltype="has_a" key="id" map="" class="acp"/>
                </links>
        </class>
-       <class id="ahn" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_notification" oils_persist:tablename="action.hold_notification">
+       <class id="ahn" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_notification" oils_persist:tablename="action.hold_notification" reporter:label="Hold Notification">
                <fields oils_persist:primary="id" oils_persist:sequence="action.hold_notification_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="hold" oils_obj:array_position="3" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="method" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="note" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="notify_staff" oils_obj:array_position="7" oils_persist:virtual="false" />
-                       <field name="notify_time" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Hold" name="hold" oils_obj:array_position="3" oils_persist:virtual="false" />
+                       <field reporter:label="Notification ID" name="id" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Notification Method" name="method" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="Notification Note" name="note" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Notifying Staff" name="notify_staff" oils_obj:array_position="7" oils_persist:virtual="false" />
+                       <field reporter:label="Notification Date/Time" name="notify_time" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="timestamp"/>
                </fields>
                <links>
                        <link field="hold" reltype="has_a" key="id" map="" class="ahr"/>
                        <link field="org_unit" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="ahr" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_request" oils_persist:tablename="action.hold_request">
+       <class id="ahr" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_request" oils_persist:tablename="action.hold_request" reporter:core="true" reporter:label="Hold Request">
                <fields oils_persist:primary="id" oils_persist:sequence="action.hold_request_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
                        <field name="status" oils_obj:array_position="3" oils_persist:virtual="true" />
                        <field name="transit" oils_obj:array_position="4" oils_persist:virtual="true" />
-                       <field name="capture_time" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="current_copy" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="email_notify" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="bool"/>
-                       <field name="expire_time" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="fulfillment_lib" oils_obj:array_position="9" oils_persist:virtual="false" />
-                       <field name="fulfillment_staff" oils_obj:array_position="10" oils_persist:virtual="false" />
-                       <field name="fulfillment_time" oils_obj:array_position="11" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="hold_type" oils_obj:array_position="12" oils_persist:virtual="false" />
-                       <field name="holdable_formats" oils_obj:array_position="13" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="14" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="phone_notify" oils_obj:array_position="15" oils_persist:virtual="false" />
-                       <field name="pickup_lib" oils_obj:array_position="16" oils_persist:virtual="false" />
-                       <field name="prev_check_time" oils_obj:array_position="17" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Capture Date/Time" name="capture_time" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Currently Targeted Copy" name="current_copy" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Notify by Email?" name="email_notify" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Hold Expire Date/Time" name="expire_time" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Fulfilling Library" name="fulfillment_lib" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Fulfilling Staff" name="fulfillment_staff" oils_obj:array_position="10" oils_persist:virtual="false" />
+                       <field reporter:label="Fulfillment Date/Time" name="fulfillment_time" oils_obj:array_position="11" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Hold Type" name="hold_type" oils_obj:array_position="12" oils_persist:virtual="false" />
+                       <field reporter:label="Holdable Formats (for M-type hold)" name="holdable_formats" oils_obj:array_position="13" oils_persist:virtual="false" />
+                       <field reporter:label="Hold ID" name="id" oils_obj:array_position="14" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Notifications Phone Number" name="phone_notify" oils_obj:array_position="15" oils_persist:virtual="false" />
+                       <field reporter:label="Pickup Library" name="pickup_lib" oils_obj:array_position="16" oils_persist:virtual="false" />
+                       <field reporter:label="Last Targeting Date/Time" name="prev_check_time" oils_obj:array_position="17" oils_persist:virtual="false" reporter:datatype="timestamp"/>
                        <field name="request_lib" oils_obj:array_position="18" oils_persist:virtual="false" />
-                       <field name="request_time" oils_obj:array_position="19" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="requestor" oils_obj:array_position="20" oils_persist:virtual="false" />
-                       <field name="selection_depth" oils_obj:array_position="21" oils_persist:virtual="false" />
-                       <field name="selection_ou" oils_obj:array_position="22" oils_persist:virtual="false" />
+                       <field reporter:label="Request Date/Time" name="request_time" oils_obj:array_position="19" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Requesting User" name="requestor" oils_obj:array_position="20" oils_persist:virtual="false" />
+                       <field reporter:label="Item Selection Depth" name="selection_depth" oils_obj:array_position="21" oils_persist:virtual="false" />
+                       <field reporter:label="Selection Locus" name="selection_ou" oils_obj:array_position="22" oils_persist:virtual="false" />
                        <field name="target" oils_obj:array_position="23" oils_persist:virtual="false" />
                        <field name="usr" oils_obj:array_position="24" oils_persist:virtual="false" />
-                       <field name="cancel_time" oils_obj:array_position="25" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Hold Cancel Date/Time" name="cancel_time" oils_obj:array_position="25" oils_persist:virtual="false" reporter:datatype="timestamp"/>
                        <field name="notify_time" oils_obj:array_position="26" oils_persist:virtual="true" reporter:datatype="timestamp"/>
                        <field name="notify_count" oils_obj:array_position="27" oils_persist:virtual="true" reporter:datatype="int" />
                        <field name="notifications" oils_obj:array_position="28" oils_persist:virtual="true" />
                        <link field="selection_ou" reltype="has_a" key="id" map="" class="aou"/>
                        <link field="requestor" reltype="has_a" key="id" map="" class="au"/>
                        <link field="current_copy" reltype="has_a" key="id" map="" class="acp"/>
-                       <link field="usr" reltype="has_a" key="id" map="" class="au"/>
-                       <link field="request_lib" reltype="has_a" key="id" map="" class="aou"/>
-                       <link field="transits" reltype="has_many" key="hold" map="" class="ahtc"/>
-                       <link field="notifications" reltype="has_many" key="hold" map="" class="ahn"/>
-                       <link field="eligible_copies" reltype="has_many" key="hold" map="target_copy" class="ahcm"/>
+                       <link reporter:label="Hold User" field="usr" reltype="has_a" key="id" map="" class="au"/>
+                       <link reporter:label="Requesting Library" field="request_lib" reltype="has_a" key="id" map="" class="aou"/>
+                       <link reporter:label="Transit" field="transit" reltype="might_have" key="hold" map="" class="ahtc"/>
+                       <link reporter:label="Notifications" field="notifications" reltype="has_many" key="hold" map="" class="ahn"/>
+                       <link reporter:label="Eligible Copies" field="eligible_copies" reltype="has_many" key="hold" map="target_copy" class="ahcm"/>
                </links>
        </class>
        <class id="aou" controller="open-ils.cstore" oils_obj:fieldmapper="actor::org_unit" oils_persist:tablename="actor.org_unit" reporter:label="Organizational Unit">
                        <link field="billings" reltype="has_many" key="xact" map="" class="mb"/>
                </links>
        </class>
-       <class id="actsce" controller="open-ils.cstore" oils_obj:fieldmapper="actor::stat_cat_entry" oils_persist:tablename="actor.stat_cat_entry">
+       <class id="actsce" controller="open-ils.cstore" oils_obj:fieldmapper="actor::stat_cat_entry" oils_persist:tablename="actor.stat_cat_entry" reporter:label="User Stat Cat Entry">
                <fields oils_persist:primary="id" oils_persist:sequence="actor.stat_cat_entry_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="owner" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="stat_cat" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Entry ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Entry Owner" name="owner" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Stat Cat" name="stat_cat" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="Entry Value" name="value" oils_obj:array_position="6" oils_persist:virtual="false" />
                </fields>
                <links>
                        <link field="stat_cat" reltype="has_a" key="id" map="" class="actsc"/>
                        <link field="usr" reltype="has_a" key="id" map="" class="au"/>
                </links>
        </class>
-       <class id="clfm" controller="open-ils.cstore" oils_obj:fieldmapper="config::lit_form_map" oils_persist:tablename="config.lit_form_map">
+       <class id="clfm" controller="open-ils.cstore" oils_obj:fieldmapper="config::lit_form_map" oils_persist:tablename="config.lit_form_map" reporter:label="Literary Form">
                <fields oils_persist:primary="code" oils_persist:sequence="">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="code" oils_obj:array_position="3" oils_persist:virtual="false" />
-                       <field name="description" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="LitF Code" name="code" oils_obj:array_position="3" oils_persist:virtual="false" />
+                       <field reporter:label="LitF Description" name="description" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="LitF Name" name="value" oils_obj:array_position="5" oils_persist:virtual="false" />
                </fields>
                <links/>
        </class>
                        <link field="bucket" reltype="has_a" key="id" map="" class="cbreb"/>
                </links>
        </class>
-       <class id="asce" controller="open-ils.cstore" oils_obj:fieldmapper="asset::stat_cat_entry" oils_persist:tablename="asset.stat_cat_entry">
+       <class id="asce" controller="open-ils.cstore" oils_obj:fieldmapper="asset::stat_cat_entry" oils_persist:tablename="asset.stat_cat_entry" reporter:label="Item Stat Cat Entry">
                <fields oils_persist:primary="id" oils_persist:sequence="asset.stat_cat_entry_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="owner" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="stat_cat" oils_obj:array_position="5" oils_persist:virtual="false" />
-                       <field name="value" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Entry ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Entry Owner" name="owner" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Stat Cat" name="stat_cat" oils_obj:array_position="5" oils_persist:virtual="false" />
+                       <field reporter:label="Value" name="value" oils_obj:array_position="6" oils_persist:virtual="false" />
                </fields>
                <links>
                        <link field="stat_cat" reltype="has_a" key="id" map="" class="asc"/>
                        <link field="owner" reltype="has_a" key="id" map="" class="aou"/>
                </links>
        </class>
-       <class id="ahtc" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_transit_copy" oils_persist:tablename="action.hold_transit_copy">
+       <class id="ahtc" controller="open-ils.cstore" oils_obj:fieldmapper="action::hold_transit_copy" oils_persist:tablename="action.hold_transit_copy" reporter:core="true" reporter:label="Hold Transit">
                <fields oils_persist:primary="id" oils_persist:sequence="action.transit_copy_id_seq">
                        <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
                        <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
                        <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
-                       <field name="copy_status" oils_obj:array_position="3" oils_persist:virtual="false" />
-                       <field name="dest" oils_obj:array_position="4" oils_persist:virtual="false" />
-                       <field name="dest_recv_time" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="hold" oils_obj:array_position="6" oils_persist:virtual="false" />
-                       <field name="id" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="int" />
-                       <field name="persistant_transfer" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="bool"/>
-                       <field name="prev_hop" oils_obj:array_position="9" oils_persist:virtual="false" />
-                       <field name="source" oils_obj:array_position="10" oils_persist:virtual="false" />
-                       <field name="source_send_time" oils_obj:array_position="11" oils_persist:virtual="false" reporter:datatype="timestamp"/>
-                       <field name="target_copy" oils_obj:array_position="12" oils_persist:virtual="false" />
-                       <field name="transit_copy" oils_obj:array_position="13" oils_persist:virtual="true" />
+                       <field reporter:label="Copy Status at Transit" name="copy_status" oils_obj:array_position="3" oils_persist:virtual="false" />
+                       <field reporter:label="Destination Library" name="dest" oils_obj:array_position="4" oils_persist:virtual="false" />
+                       <field reporter:label="Receive Date/Time" name="dest_recv_time" oils_obj:array_position="5" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Hold requiring Transit" name="hold" oils_obj:array_position="6" oils_persist:virtual="false" />
+                       <field reporter:label="Transit ID" name="id" oils_obj:array_position="7" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Is Persistent?" name="persistant_transfer" oils_obj:array_position="8" oils_persist:virtual="false" reporter:datatype="bool"/>
+                       <field reporter:label="Previous Stop" name="prev_hop" oils_obj:array_position="9" oils_persist:virtual="false" />
+                       <field reporter:label="Sending Library" name="source" oils_obj:array_position="10" oils_persist:virtual="false" />
+                       <field reporter:label="Send Date/Time" name="source_send_time" oils_obj:array_position="11" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="Transited Copy" name="target_copy" oils_obj:array_position="12" oils_persist:virtual="false" />
+                       <field reporter:label="Base Transit" name="transit_copy" oils_obj:array_position="13" oils_persist:virtual="true" />
                </fields>
                <links>
                        <link field="transit_copy" reltype="might_have" key="id" map="" class="atc"/>
                        <link field="biblio_record" reltype="might_have" key="id" map="" class="bre"/>
                </links>
        </class>
+       <class id="rud" controller="open-ils.reporter-store open-ils.cstore" oils_obj:fieldmapper="reporter::user_demographic" oils_persist:tablename="reporter.demographic">
+               <fields oils_persist:primary="id">
+                       <field name="isnew" oils_obj:array_position="0" oils_persist:virtual="true" />
+                       <field name="ischanged" oils_obj:array_position="1" oils_persist:virtual="true" />
+                       <field name="isdeleted" oils_obj:array_position="2" oils_persist:virtual="true" />
+                       <field reporter:label="User ID" name="id" oils_obj:array_position="3" oils_persist:virtual="false" reporter:datatype="int" />
+                       <field reporter:label="Date of Birth" name="dob" oils_obj:array_position="4" oils_persist:virtual="false" reporter:datatype="timestamp"/>
+                       <field reporter:label="General Demographic Division" name="general_division" oils_obj:array_position="5" oils_persist:virtual="false" />
+               </fields>
+               <links>
+                       <link field="id" reltype="might_have" key="id" map="" class="au"/>
+               </links>
+       </class>
 </IDL>
index 8672673..10c1359 100755 (executable)
@@ -18,8 +18,8 @@ my $report = {
                        column  => 'barcode',
                        alias   => 'User Barcode',
                },
-               {       relation=> 'circ',
-                       column  => { transform => count => colname => 'id' },
+               {       relation=> 'circ-id-mb',
+                       column  => { transform => sum => colname => 'amount' },
                        alias   => '::PARAM3',
                },
        ],
@@ -30,11 +30,13 @@ my $report = {
                        checkin_staff => {
                                table   => 'actor.usr',
                                alias   => 'circ-circ_staff-au',
+                               type    => 'inner',
                                key     => 'id',
                                join    => {
                                        card => {
                                                table   => 'actor.card',
                                                alias   => 'circ-circ_staff-au-card-ac',
+                                               type    => 'inner',
                                                key     => 'id',
                                        },
                                },
@@ -42,11 +44,13 @@ my $report = {
                        checkin_lib => {
                                table   => 'actor.org_unit',
                                alias   => 'circ-checkin_lib-aou',
+                               type    => 'inner',
                                key     => 'id',
                        },
                        'id-billings' => {
                                table   => 'money.billing',
                                alias   => 'circ-id-mb',
+                               type    => 'left',
                                key     => 'xact',
                        },
                },
@@ -65,17 +69,8 @@ my $report = {
                        condition       => { '=' => '::PARAM7' },
                },
        ],
-       having => [
-               {       relation        => 'circ',
-                       column          => { transform => count => colname => 'id' },
-                       condition       => { 'between' => '::PARAM5' },
-               },
-       ],
+       having => [],
        order_by => [
-               {       relation=> 'circ',
-                       column  => { transform => count => colname => 'id' },
-                       direction => 'descending',
-               },
                {       relation=> 'circ-checkin_lib-aou',
                        column  => { colname => 'shortname', transform => 'Bare' },
                },
@@ -96,7 +91,7 @@ my $params = {
        PARAM1 => [ 18, 19, 20, 21, 22, 23 ],
        #PARAM2 => ['2006-07','2006-08','2006-09'],
        PARAM2 => [{transform => 'relative_month', params => [-2]},{transform => 'relative_month', params => [-3]}],
-       PARAM3 => 'Circ Count',
+       PARAM3 => 'Billed Amount',
        PARAM4 => 'Checkin Date',
        PARAM5 => [{ transform => 'Bare', params => [10] },{ transform => 'Bare', params => [100] }],
        PARAM6 => [ 1, 4 ],
@@ -112,3 +107,8 @@ $rs->relative_time('2006-10-01T00:00:00-4');
 print "Column Labels: " . join(', ', $rs->column_label_list) . "\n";
 print $rs->toSQL;
 
+print "\n\n";
+
+print "SQL group by list: ".join(',',$rs->group_by_list)."\n";
+print "Perl group by list: ".join(',',$rs->group_by_list(0))."\n";
+
index c2bfb96..d00f214 100644 (file)
@@ -26,6 +26,12 @@ sub set_builder {
        return $self;
 }
 
+sub find_relation {
+       my $self = shift;
+       my $rel = shift;
+       return $self->builder->{_rels}->{$rel};
+}
+
 sub builder {
        my $self = shift;
        return $self->{_builder};
@@ -94,37 +100,37 @@ sub is_subquery {
 
 sub pivot_data {
        my $self = shift;
-       return $self->{_pivot_data};
+       return $self->builder->{_pivot_data};
 }
 
 sub pivot_label {
        my $self = shift;
-       return $self->{_pivot_label};
+       return $self->builder->{_pivot_label};
 }
 
 sub pivot_default {
        my $self = shift;
-       return $self->{_pivot_label};
+       return $self->builder->{_pivot_default};
 }
 
 sub set_pivot_default {
        my $self = shift;
        my $p = shift;
-       $self->{_pivot_default} = $p if (defined $p);
+       $self->builder->{_pivot_default} = $p if (defined $p);
        return $self;
 }
 
 sub set_pivot_data {
        my $self = shift;
        my $p = shift;
-       $self->{_pivot_data} = $p if (defined $p);
+       $self->builder->{_pivot_data} = $p if (defined $p);
        return $self;
 }
 
 sub set_pivot_label {
        my $self = shift;
        my $p = shift;
-       $self->{_pivot_label} = $p if (defined $p);
+       $self->builder->{_pivot_label} = $p if (defined $p);
        return $self;
 }
 
@@ -153,7 +159,7 @@ sub set_from {
        my $self = shift;
        my $f = shift;
 
-       $self->{_from} = OpenILS::Reporter::SQLBuilder::Relation->parse( $f );
+       $self->{_from} = OpenILS::Reporter::SQLBuilder::Relation->parse( $f, $self );
 
        return $self;
 }
@@ -213,9 +219,14 @@ sub group_by_list {
        my $base = shift;
        $base = 1 unless (defined $base);
 
+       my $seen_label = 0;
        my $gcount = $base;
        my @group_by;
        for my $c ( @{ $self->{_select} } ) {
+               if ($base == 0 && !$seen_label  && defined($self->pivot_label) && $gcount == $self->pivot_label - 1) {
+                       $seen_label++;
+                       next;
+               }
                push @group_by, $gcount if (!$c->is_aggregate);
                $gcount++;
        }
@@ -897,7 +908,16 @@ sub toSQL {
        my $self = shift;
 
        return $self->{_sql} if ($self->{_sql});
-       my $sql = $self->SUPER::toSQL;
+
+       my $sql;
+
+       my $rel = $self->find_relation($self->{_relation});
+       warn $self->builder;
+       if ($rel && $rel->is_join && $rel->join_type ne 'inner') {
+               $sql = "($sql IS NULL OR ";
+       }
+
+       $sql .= $self->SUPER::toSQL;
 
        my ($op) = keys %{ $self->{_condition} };
        my $val = _flesh_conditions( $self->resolve_param( $self->{_condition}->{$op} ), $self->builder );
@@ -927,6 +947,10 @@ sub toSQL {
                $sql .= " $op " . $val->toSQL;
        }
 
+       if ($rel && $rel->is_join && $rel->join_type ne 'inner') {
+               $sql .= ")";
+       }
+
        return $self->{_sql} = $sql;
 }
 
@@ -944,15 +968,19 @@ sub parse {
        $self = $self->SUPER::new if (!ref($self));
 
        my $rel_data = shift;
+       my $b = shift;
+       $self->set_builder($b);
 
        $self->{_table} = $rel_data->{table};
        $self->{_alias} = $rel_data->{alias} || $self->name;
        $self->{_join} = [];
        $self->{_columns} = [];
 
+       $self->builder->{_rels}{$self->{_alias}} = $self;
+
        if ($rel_data->{join}) {
                $self->add_join(
-                       $_ => OpenILS::Reporter::SQLBuilder::Relation->parse( $rel_data->{join}->{$_} ) => $rel_data->{join}->{$_}->{key}
+                       $_ => OpenILS::Reporter::SQLBuilder::Relation->parse( $rel_data->{join}->{$_}, $b ) => $rel_data->{join}->{$_}->{key} => $rel_data->{join}->{$_}->{type}
                ) for ( keys %{ $rel_data->{join} } );
        }
 
@@ -977,11 +1005,12 @@ sub add_join {
        my $col = shift;
        my $frel = shift;
        my $fkey = shift;
+       my $type = lc(shift()) || 'inner';
 
-       if (ref($col) eq 'OpenILS::Reporter::SQLBuilder::Join') {
+       if (UNIVERSAL::isa($col,'OpenILS::Reporter::SQLBuilder::Join')) {
                push @{ $self->{_join} }, $col;
        } else {
-               push @{ $self->{_join} }, OpenILS::Reporter::SQLBuilder::Join->build( $self => $col, $frel => $fkey );
+               push @{ $self->{_join} }, OpenILS::Reporter::SQLBuilder::Join->build( $self => $col, $frel => $fkey, $type );
        }
 
        return $self;
@@ -994,6 +1023,13 @@ sub is_join {
        return $self->{_is_join};
 }
 
+sub join_type {
+       my $self = shift;
+       my $j = shift;
+       $self->{_join_type} = $j if ($j);
+       return $self->{_join_type};
+}
+
 sub toSQL {
        my $self = shift;
        return $self->{_sql} if ($self->{_sql});
@@ -1014,8 +1050,8 @@ package OpenILS::Reporter::SQLBuilder::Join;
 use base qw/OpenILS::Reporter::SQLBuilder/;
 
 sub build {
-       my $self = shift;
-       $self = $self->SUPER::new if (!ref($self));
+       my $class = shift;
+       my $self = $class->SUPER::new if (!ref($class));
 
        $self->{_left_rel} = shift;
        ($self->{_left_col}) = split(/-/,shift());
@@ -1023,21 +1059,85 @@ sub build {
        $self->{_right_rel} = shift;
        $self->{_right_col} = shift;
 
+       $self->{_join_type} = shift;
+
        $self->{_right_rel}->is_join(1);
+       $self->{_right_rel}->join_type($self->{_join_type});
+
+       bless $self => "OpenILS::Reporter::SQLBuilder::Join::$self->{_join_type}";
 
        return $self;
 }
 
 sub toSQL {
        my $self = shift;
-       return $self->{_sql} if ($self->{_sql});
 
-       my $sql = "\n\tJOIN " . $self->{_right_rel}->toSQL .
+       my $sql = "JOIN " . $self->{_right_rel}->toSQL .
                ' ON ("' . $self->{_left_rel}->{_alias} . '"."' . $self->{_left_col} .
                '" = "' . $self->{_right_rel}->{_alias} . '"."' . $self->{_right_col} . '")';
 
        $sql .= $_->toSQL for (@{ $self->{_right_rel}->{_join} });
 
+       return $sql;
+}
+
+#-------------------------------------------------------------------------------------------------
+package OpenILS::Reporter::SQLBuilder::Join::left;
+use base qw/OpenILS::Reporter::SQLBuilder::Join/;
+
+sub toSQL {
+       my $self = shift;
+       #return $self->{_sql} if ($self->{_sql});
+
+       my $sql = "\n\tLEFT OUTER ". $self->SUPER::toSQL;
+
+       #$sql .= $_->toSQL for (@{ $self->{_right_rel}->{_join} });
+
+       return $self->{_sql} = $sql;
+}
+
+#-------------------------------------------------------------------------------------------------
+package OpenILS::Reporter::SQLBuilder::Join::right;
+use base qw/OpenILS::Reporter::SQLBuilder::Join/;
+
+sub toSQL {
+       my $self = shift;
+       #return $self->{_sql} if ($self->{_sql});
+
+       my $sql = "\n\tRIGHT OUTER ". $self->SUPER::toSQL;
+
+       #$sql .= $_->toSQL for (@{ $self->{_right_rel}->{_join} });
+
+       return $self->{_sql} = $sql;
+}
+
+#-------------------------------------------------------------------------------------------------
+package OpenILS::Reporter::SQLBuilder::Join::inner;
+use base qw/OpenILS::Reporter::SQLBuilder::Join/;
+
+sub toSQL {
+       my $self = shift;
+       #return $self->{_sql} if ($self->{_sql});
+
+       my $sql = "\n\tINNER ". $self->SUPER::toSQL;
+
+       #$sql .= $_->toSQL for (@{ $self->{_right_rel}->{_join} });
+
+       return $self->{_sql} = $sql;
+}
+
+#-------------------------------------------------------------------------------------------------
+package OpenILS::Reporter::SQLBuilder::Join::cross;
+use base qw/OpenILS::Reporter::SQLBuilder::Join/;
+
+sub toSQL {
+       my $self = shift;
+       #return $self->{_sql} if ($self->{_sql});
+
+       my $sql = "\n\tFULL OUTER ". $self->SUPER::toSQL;
+
+       #$sql .= $_->toSQL for (@{ $self->{_right_rel}->{_join} });
+
        return $self->{_sql} = $sql;
 }
 
index 82c8bb7..0624b23 100755 (executable)
@@ -173,6 +173,9 @@ for my $r ( @reports ) {
 
                        $r->{column_labels} = $newdata->{columns};
                        $r->{data} = $newdata->{data};
+                       $r->{group_by_list} = $newdata->{group_by_list};
+               } else {
+                       $r->{group_by_list} = [$r->{resultset}->group_by_list(0)];
                }
 
                my $s2 = $r->{report}->{template}->{id};
@@ -470,7 +473,7 @@ sub draw_pie {
 
        my $data = $r->{data};
 
-       my @groups = $r->{resultset}->group_by_list(0);
+       my @groups = @{ $r->{group_by_list} };
        
        my @values = (0 .. (scalar(@{$r->{column_labels}}) - 1));
        delete @values[@groups];
@@ -556,7 +559,7 @@ sub draw_bars {
 
        #my $logo = $doc->findvalue('/reporter/setup/files/chart_logo');
 
-       my @groups = $r->{resultset}->group_by_list(0);
+       my @groups = @{ $r->{group_by_list} };
 
        
        my @values = (0 .. (scalar(@{$r->{column_labels}}) - 1));
@@ -670,7 +673,7 @@ sub draw_lines {
 
        #my $logo = $doc->findvalue('/reporter/setup/files/chart_logo');
 
-       my @groups = $r->{resultset}->group_by_list(0);
+       my @groups = @{ $r->{group_by_list} };
        
        my @values = (0 .. (scalar(@{$r->{column_labels}}) - 1));
        splice(@values,$_,1) for (reverse @groups);
@@ -784,6 +787,8 @@ sub pivot_data {
        my @keep_cols = (0 .. @$cols - 1);
        splice(@keep_cols, $_ - 1, 1) for (reverse sort ($pivot_label, $pivot_data));
 
+       my @gb = ( 0 .. @keep_cols - 1);
+
        #first, find the unique list of pivot values
        my %tmp;
        for my $row (@$data) {
@@ -822,7 +827,7 @@ sub pivot_data {
 
        push @keep_labels, @new_cols;
 
-       return { columns => \@keep_labels, data => [ values %new_data ] };
+       return { columns => \@keep_labels, data => [ values %new_data ], group_by_list => \@gb };
 }
 
 
index 4046bff..46ea188 100644 (file)
@@ -132,6 +132,17 @@ SELECT     r.id,
   WHERE        r.deleted IS FALSE
   GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12,13,14;
 
+CREATE OR REPLACE VIEW reporter.demographic AS
+SELECT u.id,
+       u.dob,
+       CASE
+               WHEN u.dob IS NULL
+                       THEN 'Adult'
+               WHEN AGE(u.dob) > '18 years'::INTERVAL
+                       THEN 'Adult'
+               ELSE 'Juvenile'
+       END AS general_division
+  FROM actor.usr u;
 
 COMMIT;