1 package SL::DB::Object;
6 use List::MoreUtils qw(any);
9 use SL::DB::Helper::Attr;
10 use SL::DB::Helper::Metadata;
11 use SL::DB::Helper::Manager;
12 use SL::DB::Object::Hooks;
14 use base qw(Rose::DB::Object);
18 my $self = $class->SUPER::new();
20 $self->_assign_attributes(@_) if $self;
26 my $class_or_self = shift;
27 my $class = ref($class_or_self) || $class_or_self;
28 my $type = $class =~ m/::Auth/ ? 'LXOFFICE_AUTH' : 'LXOFFICE';
30 return SL::DB::create(undef, $type);
34 return 'SL::DB::Helper::Metadata';
37 sub _get_manager_class {
38 my $class_or_self = shift;
39 my $class = ref($class_or_self) || $class_or_self;
41 return $class->meta->convention_manager->auto_manager_class_name($class);
44 my %text_column_types = (text => 1, char => 1, varchar => 1);
46 sub assign_attributes {
50 my $pk = ref($self)->meta->primary_key;
51 delete @attributes{$pk->column_names} if $pk;
53 return $self->_assign_attributes(%attributes);
56 sub _assign_attributes {
60 my %types = map { $_->name => $_->type } ref($self)->meta->columns;
62 while (my ($attribute, $value) = each %attributes) {
63 my $type = lc($types{$attribute} || 'text');
64 $value = $type eq 'boolean' ? ($value ? 't' : 'f')
65 : $text_column_types{$type} ? $value
66 : defined($value) && ($value eq '') ? undef
68 $self->$attribute($value);
74 sub update_attributes {
77 $self->assign_attributes(@_)->save;
85 return $self->$sub(@_);
93 $check = $check->($self) if ref($check) eq 'CODE';
95 return $check ? $self->$sub(@_) : $self;
98 # These three functions cannot sit in SL::DB::Object::Hooks because
99 # mixins don't deal well with super classes (SUPER is the current
100 # package's super class, not $self's).
102 my ($self, @args) = @_;
104 SL::DB::Object::Hooks::run_hooks($self, 'before_load');
105 my $result = $self->SUPER::load(@args);
106 SL::DB::Object::Hooks::run_hooks($self, 'after_load', $result);
112 my ($self, @args) = @_;
114 SL::DB::Object::Hooks::run_hooks($self, 'before_save');
115 my $result = $self->SUPER::save(@args);
116 SL::DB::Object::Hooks::run_hooks($self, 'after_save', $result);
119 return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
123 my ($self, @args) = @_;
125 SL::DB::Object::Hooks::run_hooks($self, 'before_delete');
126 my $result = $self->SUPER::delete(@args);
127 SL::DB::Object::Hooks::run_hooks($self, 'after_delete', $result);
130 return $self->db->in_transaction ? $worker->() : $self->db->do_transaction($worker);
141 SL::DB::Object: Base class for all of our model classes
145 This is the base class from which all other model classes are
146 derived. It contains functionality and settings required for all model
149 Several functions (e.g. C<make_manager_class>, C<init_db>) in this
150 class are used for setting up the classes / base classes used for all
151 model instances. They overwrite the functions from
158 =item assign_attributes %attributes
160 =item _assign_attributes %attributes
162 Assigns all elements from C<%attributes> to the columns by calling
163 their setter functions. The difference between the two functions is
164 that C<assign_attributes> protects primary key columns while
165 C<_assign_attributes> doesn't.
167 Both functions handle values that are empty strings by replacing them
168 with C<undef> for non-text columns. This allows the calling functions
169 to use data from HTML forms as the input for C<assign_attributes>
170 without having to remove empty strings themselves (think of
171 e.g. select boxes with an empty option which should be turned into
172 C<NULL> in the database).
174 =item update_attributes %attributes
176 Assigns the attributes from C<%attributes> by calling the
177 C<assign_attributes> function and saves the object afterwards. Returns
180 =item _get_manager_class
182 Returns the manager package for the object or class that it is called
183 on. Can be used from methods in this package for getting the actual
186 =item C<call_sub $name, @args>
188 Calls the sub C<$name> on C<$self> with the arguments C<@args> and
189 returns its result. This is meant for situations in which the sub's
190 name is a composite, e.g.
192 my $chart_id = $buchungsgruppe->call_sub(($is_sales ? "income" : "expense") . "_accno_id_${taxzone_id}");
194 =item C<call_sub_if $name, $check, @args>
196 Calls the sub C<$name> on C<$self> with the arguments C<@args> if
197 C<$check> is trueish. If C<$check> is a code reference then it will be
198 called with C<$self> as the only argument and its result determines
199 whether or not C<$name> is called.
201 Returns the sub's result if the check is positive and C<$self>
208 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>