1 package SL::Clipboard::Base;
 
   5 use parent qw(Rose::Object);
 
   7 use Rose::Object::MakeMethods::Generic (
 
   8   'scalar --get_set_init' => [ qw(content timestamp) ],
 
  11 use Rose::DB::Object::Helpers ();
 
  13 sub init_timestamp { die "'timestamp' property not set"; }
 
  14 sub init_content   { die "'content' property not set";   }
 
  17   my ($self_or_class) = @_;
 
  18   return (split m/::/, ref($self_or_class) ? ref($self_or_class) : $self_or_class)[-1];
 
  22   my ($self, $object) = @_;
 
  24   return ref($object)->new(map { $_ => $object->$_ } $object->meta->primary_key)->load;
 
  28   my ($self, $object, %params) = @_;
 
  30   my $tree = Rose::DB::Object::Helpers::as_tree($object, %params);
 
  31   $self->_fix_tree($tree, $object);
 
  37   my $object = Rose::DB::Object::Helpers::new_from_tree("SL::DB::" . $self->type, $self->content);
 
  39   # Reset primary key columns and itime/mtime if the class supports it.
 
  40   foreach ($object->meta->primary_key, 'itime', 'mtime') {
 
  41     $object->$_(undef) if $object->can($_);
 
  44   # Let sub classes fix the objects further.
 
  45   $self->_fix_object($object);
 
  50   my ($self, $object) = @_;
 
  51   return $self->as_tree($self->reload_object($object), max_depth => 1);
 
  55   die "'describe' method not overwritten by derived class";
 
  59   my ($self, $object) = @_;
 
  60   # To be overwritten by child classes.
 
  64   my ($self, $tree, $object) = @_;
 
  66   # Delete primary key columns and itime/mtime if the class supports it.
 
  67   foreach ($object->meta->primary_key, 'itime', 'mtime') {
 
  68     delete $tree->{$_} if $object->can($_);
 
  72 sub _binary_column_names {
 
  73   my ($self, $class) = @_;
 
  74   return map  { $_->name }
 
  75          grep { ref($_) =~ m/Pg::Bytea$/i }
 
  76          @{ $class->meta->columns };
 
  88 SL::Clipboard::Base - Base class for clipboard specialization classes
 
  92 See the synopsis of L<SL::Clipboard>.
 
  96 This is a base class providing a lot of utility and
 
  97 defaults. Sub-classes must overwrite at least the function
 
  98 L</describe> but can overwrite others as well.
 
 100 Writing a specialized sub-class for a database type involves
 
 101 overwriting one or more functions. These are:
 
 107 Must be overwritten. Returns a human-readable description of the
 
 108 content. Should only be one line.
 
 112 Optional. Overwrite if sub-class needs to dump more/less than the
 
 113 implementation in this class dumps.
 
 115 =item * C<_fix_object>
 
 117 Optional. Overwrite if re-created Rose::DB::Object instances must be
 
 118 cleaned further before they're returned to the caller.
 
 122 Optional. Overwrite if the tree created during a copy operation of a
 
 123 Rose::DB::Object instance must be cleaned further before it's stored.
 
 127 You don't have to or should not overwrite the other functions:
 
 133 =item * C<reload_object>
 
 141 Don't forget to C<use> the specialized module here in Base!
 
 147 =item C<as_tree $object, %params>
 
 149 A convenience function calling L<Rose::DB::Object::Helpers/as_tree>
 
 150 with C<$object> and C<%params> as parameters. Returns a hash/array
 
 151 reference tree of the function.
 
 153 Don't overwrite this function in sub-classes. Overwrite L</dump>
 
 158 Returns a human-readable description of the content. This should only
 
 159 be a single line without any markup.
 
 161 Sub-classes must overwrite this function.
 
 163 =item C<dump $object>
 
 165 Dumps the object as a hash/array tree and returns it by calling
 
 166 L<Rose::DB::Object::Helpers/as_tree>. The default implementation
 
 167 reloads the object first by calling L</reload_object>. It also only
 
 168 dumps the object itself, not any of the relationships, by calling
 
 169 C<as_tree> with the parameter C<max_depth =E<gt> 1>.
 
 171 Overwrite this in a sub-class if you need to dump more or differently
 
 172 (see L<SL::Clipboard::RequirementSpecItem> for an example).
 
 174 =item C<reload_object $object>
 
 176 Reloads C<$object> from the database and returns a new instance. Can
 
 177 be useful for sanitizing the object given to L</dump> before
 
 178 converting into a tree. It is used by the default implementation of
 
 183 Converts the dumped representation back to a Rose::DB::Object
 
 184 instance. Several columns of the newly created object are cleared by
 
 185 C<to_object> itself: the primary key columns (if any) and the columns
 
 186 C<itime> and C<mtime> (if the object has such columns).
 
 188 This function should not be overwritten by sub-classes. Instead,
 
 189 functions can overwrite C<_fix_object> which can be used for sanitizing
 
 190 the newly created object before handing it back to the caller.
 
 194 Returns the actual clipped type (e.g. C<RequirementSpecItem>). This is
 
 195 derived from the actual class name of C<$self>.
 
 197 =item C<_binary_column_names $class>
 
 199 Returns an array of column names that have a binary type. Useful for
 
 200 sub-classes which need to encode binary content in Base64 during
 
 203 =item C<_fix_object $object>
 
 205 This function is called by L</to_object> before the object is passed
 
 206 back to the caller. It does not do anything in the default
 
 207 implementation, but sub-classes are free to overwrite it if they need
 
 208 to sanitize the object. See L<SL::Clipboard::RequirementSpecItem> for
 
 211 Its return value is ignored.
 
 213 =item C<_fix_tree $tree, $object>
 
 215 This function is called by L</as_tree> after dumping and before the
 
 216 object is stored during a copy operation. In the default
 
 217 implementation all primary key columns and the columns C<itime> and
 
 218 C<mtime> (if the object has such columns) are removed from the tree.
 
 219 Sub-classes are free to overwrite it if they need to sanitize the
 
 220 tree. See L<SL::Clipboard::RequirementSpecItem> for an example.
 
 222 C<$object> is just passed in for reference and should not be modified.
 
 224 Its return value is ignored.
 
 234 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>