.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "MQdb::MappedQuery 3pm" .TH MQdb::MappedQuery 3pm "2022-12-13" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" MQdb::MappedQuery \- DESCRIPTION of Object .SH "SYNOPSIS" .IX Header "SYNOPSIS" An Object_relational_mapping (\s-1ORM\s0) design pattern based on mapping named_column results from any query into attributes of an object. As long as the column_names are parsable into attributes, any query is ok. This is an evolution of several ideas I have either used or created over the last 15 years of coding. This is a variation on the ActiveRecord design pattern but it trades more flexibility, power and control for slightly less automation. It still provides a development speed/ease advange over many \s-1ORM\s0 patterns. .SH "DESCRIPTION" .IX Header "DESCRIPTION" MappedQuery is an abstract superclass that is a variation on the ActiveRecord design pattern. Instead of actively mapping a table into an object, this will actively map the result of a query into an object. The query is standardized for a subclass of this object, and the columns returned by the query define the attributes of the object. This gives much more flexibility than the standard implementation of ActiveRecord. Since this design pattern is based around mapping a query (from potentially a multiple table join) to a single class object, this pattern is called MappedQuery. .PP In this particular implementation of this design pattern (mainly due to some limitations in perl) several aspects must be hand coded as part of the implementation of a subclass. Subclasses must handcode \&\- all accessor methods \&\- override the mapRow method \&\- APIs for all explicit fetch methods (by using the superclass fetch_single and fetch_multiple) \&\- the store methods are coded by general \s-1DBI\s0 code (no framework assistance) .PP Individual MQdb::Database handle objects are assigned at an instance level for each object. This is different from some ActiveRecord implementations which place database handles into a global context or at the Class level. By placing it with each instance, this allows creation of instances of the same class pulled from two different databases, but with similar schemas. This is very useful when building certain types of data analysis systems. .PP The only restriction is that the database handle must be able run the queries that the object requires for it to work. .PP Future implementations could do more automatic code generation but this version already speeds development time by 2x\-3x without imposing any limitations and retains all the flexibility of handcoding with \s-1DBI.\s0 .SH "CONTACT" .IX Header "CONTACT" Jessica Severin .SH "LICENSE" .IX Header "LICENSE" .Vb 10 \& * Software License Agreement (BSD License) \& * MappedQueryDB [MQdb] toolkit \& * copyright (c) 2006\-2009 Jessica Severin \& * All rights reserved. \& * Redistribution and use in source and binary forms, with or without \& * modification, are permitted provided that the following conditions are met: \& * * Redistributions of source code must retain the above copyright \& * notice, this list of conditions and the following disclaimer. \& * * Redistributions in binary form must reproduce the above copyright \& * notice, this list of conditions and the following disclaimer in the \& * documentation and/or other materials provided with the distribution. \& * * Neither the name of Jessica Severin nor the \& * names of its contributors may be used to endorse or promote products \& * derived from this software without specific prior written permission. \& * \& * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS \*(Aq\*(AqAS IS\*(Aq\*(Aq AND ANY \& * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \& * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \& * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY \& * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \& * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \& * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND \& * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \& * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \& * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .Ve .SH "APPENDIX" .IX Header "APPENDIX" The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _ .SS "mapRow" .IX Subsection "mapRow" .Vb 10 \& Description: This method must be overridden by subclasses to do the mapping of columns \& from the query response into attributes of the object. This is part of the \& internal factory machinery. The instance of the class is created before this method is \& called and the default init() method has already been called. The purpose of this \& method is to initialize the rest of the state of the instance based on the $row_hash \& Arg (1) : $row_hash perl hash \& Arg (2) : optional $dbc DBI connection (not generally used by most sublcasses) \& Returntype : $self \& Exceptions : none \& Caller : only called by internal factory methods \& Example : \& sub mapRow { \& my $self = shift; \& my $rowHash = shift; \& \& $self\->primary_id($rowHash\->{\*(Aqsymbol_id\*(Aq}); \& $self\->type($rowHash\->{\*(Aqsym_type\*(Aq}); \& $self\->symbol($rowHash\->{\*(Aqsym_value\*(Aq}); \& return $self; \& } .Ve .SS "store" .IX Subsection "store" .Vb 6 \& Description: This method is just an empty template as part of the API definition. \& How it is defined, and how parameters are handled are completely up to each \& subclass. Each subclass should override and implement. \& Returntype : $self \& Exceptions : none \& Caller : general loader scripts .Ve .SS "fetch_single" .IX Subsection "fetch_single" .Vb 10 \& Description: General purpose template method for fetching a single instance \& of this class(subclass) using the mapRow method to convert \& a row of data into an object. \& Arg (1) : $database (MQdb::Database) \& Arg (2) : $sql (string of SQL statement with place holders) \& Arg (3...) : optional parameters to map to the placehodlers within the SQL \& Returntype : instance of this Class (subclass) \& Exceptions : none \& Caller : subclasses (not public methods) \& Example : \& sub fetch_by_id { \& my $class = shift; \& my $db = shift; \& my $id = shift; \& my $sql = "SELECT * FROM symbol WHERE symbol_id=?"; \& return $class\->fetch_single($db, $sql, $id); \& } .Ve .SS "fetch_multiple" .IX Subsection "fetch_multiple" .Vb 10 \& Description: General purpose template method for fetching an array of instance \& of this class(subclass) using the mapRow method to convert \& a row of data into an object. \& Arg (1) : $database (MQdb::Database) \& Arg (2) : $sql (string of SQL statement with place holders) \& Arg (3...) : optional parameters to map to the placehodlers within the SQL \& Returntype : array of all instances of this Class (subclass) which match the query \& Exceptions : none \& Caller : subclasses (not public methods) \& Example : \& sub fetch_all_by_value { \& my $class = shift; \& my $db = shift; \& my $name = shift; \& my $sql = "SELECT * FROM symbol WHERE sym_value=?"; \& return $class\->fetch_multiple($db, $sql, $name); \& } .Ve .SS "stream_multiple" .IX Subsection "stream_multiple" .Vb 10 \& Description: General purpose template method for fetching multiple instance \& of this class(subclass) using the mapRow method to convert \& a row of data into an object. Instead of instantiating all \& instance at once and returning as array, this method returns \& a DBStream instance which then creates each instance from an \& open handle on each $stream\->next_in_stream() call. \& Arg (1) : $database (MQdb::Database) \& Arg (2) : $sql (string of SQL statement with place holders) \& Arg (3...) : optional parameters to map to the placehodlers within the SQL \& Returntype : DBStream object \& Exceptions : none \& Caller : subclasses use this internally when creating new API stream_by....() methods \& Example : \& sub stream_by_value { \& my $class = shift; \& my $db = shift; \& my $name = shift; \& my $sql = "SELECT * FROM symbol WHERE sym_value=?"; \& return $class\->stream_multiple($db, $sql, $name); \& } .Ve .SS "fetch_col_value" .IX Subsection "fetch_col_value" .Vb 9 \& Description: General purpose function to allow fetching of a single column from a single row. \& Arg (1) : $sql (string of SQL statement with place holders) \& Arg (2...) : optional parameters to map to the placehodlers within the SQL \& Example : $value = $self\->fetch_col_value($db, \& "select symbol_id from symbol where sym_type=? and sym_value=?", \& $type,$value); \& Returntype : scalar value \& Exceptions : none \& Caller : within subclasses to easy development .Ve .SS "fetch_col_array" .IX Subsection "fetch_col_array" .Vb 7 \& Description: General purpose function to allow fetching of a single column from many rows into a simple array. \& Arg (1) : $sql (string of SQL statement with place holders) \& Arg (2...) : optional parameters to map to the placehodlers within the SQL \& Example : $array_ref = $self\->fetch_col_array($db, "select some_column from my_table where source_id=?", $id); \& Returntype : array reference of scalar values \& Exceptions : none \& Caller : within subclasses to easy development .Ve .SS "next_sequence_id" .IX Subsection "next_sequence_id" .Vb 4 \& Description: Convenience method for working with SEQUENCES in ORACLE databases. \& Arg (1) : $sequenceName \& Returntype : scalar of the nextval in the sequence \& Exceptions : none .Ve