NAME

AxKit::App::TABOO::Data - Base class of abstracted Data objects for TABOO

DESCRIPTION

You would rarely if ever use this class directly. Instead, you would call a subclass of this class, depending on what kind of data you are operating on. This class does, however, define some very useful methods that its subclasses can use unaltered.

It is to be noted that I have not, neither in this class nor in the subclasses, created methods to access or set every field. Instead, I rely mainly on methods that will manipulate internal data based on the for example objects that are passed as arguments. For example, the write_xml-method (below), will create XML based on all the available data in the object. This is usually all you want anyway.

In some subclasses, you will have some degree of control of what is loaded into the object data structure in the first place, by sending the names of the fields of the storage medium (e.g. database in the present implementation).

Similarly, if data is sent from a web application, the present implementation makes it possible to pass an Apache::Request object to a Data object, and it is up to a method of the Data object to take what it wants from the Apache::Request object, and intelligently store it.

Some methods to access data will be implemented on an ad hoc basis, notably timestamp()-methods, that will be important in determining the validity of cached data.

Sometimes you might want to retrieve more than one object from the data store, and do stuff on these objects as a whole. Furthermore, the load methods used to retrieve multiple objects may be optimized. For this, TABOO also has Plural classes.

Methods

new()

The constructor of this class. Rarely used.

load(what => fields, limit => {key => value, [...]})

Will load and populate the data structure of an object with the data from a data store. It uses named parameters, the first what is used to determine which fields to retrieve. It is a string consisting of a commaseparated list of fields, as specified in the data store. If not given, all fields will be fetched. The limit argument is to be used to determine which records to retrieve, and must be used to identify a record uniquely. It is itself a reference to a hash, containing data store field values as keys and values are corresponding values to retrieve. These will be combined by logical AND.

If there is no data that corresponds to the given arguments, this method will return undef.

_load(what => fields, limit => {key => value, [...]})

As the underscore implies this is for internal use only! It is intended to do the hard work for this class and its subclasses. It returns a hashref of the data from the datastore.

See the documentation for the load method for the details on the parameters.

write_xml($doc, $parent)

Takes arguments $doc, which must be an XML::LibXML::Document object, and $parent, a reference to the parent node. The method will append the object it is handed it with the data contained in the data structure of the class in XML. This method is the jewel of this class, it should be sufficiently generic to rarely require subclassing. References to subclasses will be followed, and write_xml will call the write_xml of that object. Arrays will be represented with multiple instances of the same element. Fields that have undefined values will not be included. It will also parse fields indicated by elementneedsparse(), see below. Currently, we get HTML from TinyMCE, which we let XML::LibXML parse.

populate(\%args)

This method takes as argument a reference to a hash and will populate the data object by adding any data from a key having the same name as is used in the data storage. Fields that are not specified by the data object or that has uppercase letters are ignored.

It may be used to insert data from a request by first noting that in a HTTP request, the Request object is available as $r, so you may create the hash to hand to this method by

my %args = $r->args;

Note that this only the case for HTTP GET, in the case of POST, you may have to construct the hash by e.g.

my %args = map { $_ => join('', $cgi->param($_)) } $cgi->param;
apache_request_changed(\%args)

Like the above method, this method takes as argument a reference to the args hash of a Apache::Request object. Instead of populating the Data object, it will compare the \%args with the contents of the object and return an array of fields that differs between the two. Fields that are not specified by the data object, that has uppercase letters or has no value, are ignored.

save([$olddbkey])

This is a generic save method, that will write a new record to the data store, or update an old one. It may have to be subclassed for certain classes. It takes an optional argument $olddbkey, which is the primary key of an existing record in the data store. You may supply this in the case if you want to update the record with a new key. In that case, you'd better be sure it actually exists, because the method will trust you do.

It is not yet a very rigorous implementation: It may well fail badly if it is given something with a reference to other Data objects, which is the case if you have a full story with all comments. Or it may cope. Only time will tell! Expect to see funny warnings in your logs if you try.

exist(%limitargs)

This method can be used to check if a record allready exists. The argument is the hash you would give to limit in the load method.

stored()

Checks if a record with the present object's identifier is allready present in the datastore. Returns 1 if this is so.

onfile

Method to set a flag to indicate that the record is in the data store.

dbconnectargs(@args)

This method will set or retrieve the arguments that are passed to DBI's connect method. Since this needs to be done for every object, you may also pass these arguments to the new constructor of each subclass. However, it is recommended that you use environment variables instead.

elementneedsparse($string)

User-supplied formatting may not be valid XHTML, and so needs to be validated and parsed. This method takes a string consisting of a comma-separated list of fields that needs parsing as argument, or will return such a list if it is not given.

xmlelement($string)

This method is intended for internal use, but if you can use it without shooting somebody in the foot (including yourself), fine by me... It sets the root element that will enclose an object's data to $string, or return it if not given.

xmlns($string)

Like xmlelement(), this method is intended for internal use. It sets the namespace URI of the XML representation of an object to $string, or return it if not given.

xmlprefix($string)

Alse like xmlelement(), this method is intended for internal use. It sets the namespace prefix of the XML representation of an object to $string, to allow using QNames, or return it if not given.

STORED DATA

The data is stored in named fields, currently in a database, but there is nothing stopping you from subclassing the Data classes and storing it somewhere else. TABOO should work well, but if you want to make it less painful for yourself, you should use the same names or provide some kind of mapping between your names and the names in these Data classes. Note that any similarity between these names and the internal names of this class is purely coincidential (eh, not really).

Consult the documentation for each individual Data class for the names of the stored data.

BUGS/TODO

There is the issue with the handling of references to other objects in the save() method. I think it may actually cope in most cases, but it definately could use some more attention.

FORMALITIES

See AxKit::App::TABOO.