#!/usr/bin/perl -w # =pod =head1 SqlHtmlRpt.pm Uses an HTML template file containing embedded SQL statements and optional CGI parameters to run and format a report. Supports nested queries, so you can do breaks and rollups. It works with mod_perl and Perl versions 5.5.3 and later. It has been used extensively with I, but should work with any SQL database supporting the DBI:: interface. =head2 Copyright =over 4 =item Author Fred Morris =item version 2.8 =item Creation Date 07-Jul-2002 =item Modification History FWM 12-Jun-2005 parse(); Check for whitespace after the comment opener in comment mode. FWM 11-Jun-2005 format(), subclassable methods; No functional changes. Refactored format() and created subclassable methods, for easier.. subclassing. properties; The template is now stored as a property. FWM 17-Aug-2003 format() $cgi and $dbi became non-optional with 2.0. Shame on me... FWM 12-May-2003 query() If a field is undefined, set it to an empty string. This gets rid of unitialized value errors in the logs. FWM 08-Mar-2003 ... Implement nested/iterative queries. format() opt (a hashref containing additional substitutions) as an optional parameter was removed. This is easy for the caller to do for themselves, and they get more control that way anyway. =item Copyright Copyright (c) 2002-2005 by Fred Morris, 6739 3rd NW Seattle WA USA 98117 e-mail: m3047 (funny sign) inwa-dot-net telephone 206.297.6344 Licensed under the same terms as Perl itself, with no warranty or claims of fitness for any particular use. =item Acknowledgements Thanks to early adopter Daniel Stillwaggon for the valuable feedback. =back =head2 Properties The following properties may exist for the object: =over 4 =item cgi This is an instance of CGI, and is supplied in the call to new(). =item dbh This is a DBI:: database handle, and is supplied in the called to new(). =item formatter A reference to a procedure which will be called for each field in the result set, prior to substituting it into the template. =item errstr This is an error string containing a description of the last error. If there is no error it tests false (usually undef). =item next A reference to the next SqlHtmlRpt object at this level =item subq A reference to the first SqlHtmlRpt object which is a subquery attached to this object. =item presql The portion parsed which lies before the SQL statement. =item sql The SQL statement. =item postsql The portion parsed which lies after the SQL statement but before the list definition. =item list The list definition. =item tail Everything after the list definition. =item template At the outer level, the template is available as a property within format(). =back =head2 Subclassable Methods The methods here are called by format(). They have been structured to make it easy to subclass and extend I. All routines are expected to return undef on success or an error message on failure unless otherwise noted. =head3 fmt_init( init ) Called prior to CGI parameter processing. The I flag is provided for extensions. This method does nothing here. =head3 fmt_param( field_hash, init ) Processes CGI parameters into I to be used as substitutions. I indicates that the report is being called in initialization mode and that valid parameters cannot be expected. Extensions may want to do something special with this. One global check is performed, which is that a bare quotation mark is disallowed since this breaks most C tags in HTML forms. The following parameters are supported. If an error is found they should return undef and store a description in the I property. =head4 fmt_param_n( param_value ) Handles numeric parameters. =head4 fmt_param_s( param_value ) Handles string parameters. Basically nothing to do here, escaping is performed later during the actual substitutions. =head4 fmt_param_p( param_value ) Handles unchecked, raw parameters. B for substitution into SQL statements unless you do some additional checking yourself before calling SqlHtmlRpt. =head3 fmt_report( template, field_hash ) Prepares a report from I