Für Auth*-Models eigene Datenbankverbindung nutzen
[kivitendo-erp.git] / SL / DB / Object.pm
1 package SL::DB::Object;
2
3 use strict;
4
5 use Readonly;
6 use Rose::DB::Object;
7 use List::MoreUtils qw(any);
8
9 use SL::DB;
10 use SL::DB::Helpers::Attr;
11 use SL::DB::Helpers::Metadata;
12 use SL::DB::Helpers::Manager;
13
14 use base qw(Rose::DB::Object);
15
16 sub new {
17   my $class = shift;
18   my $self  = $class->SUPER::new();
19
20   $self->_assign_attributes(@_) if $self;
21
22   return $self;
23 }
24
25 sub init_db {
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';
29
30   return SL::DB::create(undef, $type);
31 }
32
33 sub meta_class {
34   return 'SL::DB::Helpers::Metadata';
35 }
36
37 sub _get_manager_class {
38   my $class_or_self = shift;
39   my $class         = ref($class_or_self) || $class_or_self;
40
41   return $class->meta->convention_manager->auto_manager_class_name($class);
42 }
43
44 Readonly my %text_column_types => (text => 1, char => 1, varchar => 1);
45
46 sub assign_attributes {
47   my $self       = shift;
48   my %attributes = @_;
49
50   my $pk         = ref($self)->meta->primary_key;
51   delete @attributes{$pk->column_names} if $pk;
52
53   return $self->_assign_attributes(%attributes);
54 }
55
56 sub _assign_attributes {
57   my $self       = shift;
58   my %attributes = @_;
59
60   my %types      = map { $_->name => $_->type } ref($self)->meta->columns;
61
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              :                             ($value || undef);
67     $self->$attribute($value);
68   }
69
70   return $self;
71 }
72
73 sub update_attributes {
74   my $self = shift;
75
76   $self->assign_attributes(@_)->save;
77
78   return $self;
79 }
80
81 1;
82
83 __END__
84
85 =pod
86
87 =head1 NAME
88
89 SL::DB::Object: Base class for all of our model classes
90
91 =head1 DESCRIPTION
92
93 This is the base class from which all other model classes are
94 derived. It contains functionality and settings required for all model
95 classes.
96
97 Several functions (e.g. C<make_manager_class>, C<init_db>) in this
98 class are used for setting up the classes / base classes used for all
99 model instances. They overwrite the functions from
100 L<Rose::DB::Object>.
101
102 =head1 FUNCTIONS
103
104 =over 4
105
106 =item assign_attributes %attributes
107
108 =item _assign_attributes %attributes
109
110 Assigns all elements from C<%attributes> to the columns by calling
111 their setter functions. The difference between the two functions is
112 that C<assign_attributes> protects primary key columns while
113 C<_assign_attributes> doesn't.
114
115 Both functions handle values that are empty strings by replacing them
116 with C<undef> for non-text columns. This allows the calling functions
117 to use data from HTML forms as the input for C<assign_attributes>
118 without having to remove empty strings themselves (think of
119 e.g. select boxes with an empty option which should be turned into
120 C<NULL> in the database).
121
122 =item update_attributes %attributes
123
124 Assigns the attributes from C<%attributes> by calling the
125 C<assign_attributes> function and saves the object afterwards. Returns
126 the object itself.
127
128 =item _get_manager_class
129
130 Returns the manager package for the object or class that it is called
131 on. Can be used from methods in this package for getting the actual
132 object's manager.
133
134 =back
135
136 =head1 AUTHOR
137
138 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
139
140 =cut