source: LATMOS-Accounts/lib/LATMOS/Accounts/Bases/Sql/objects.pm @ 155

Last change on this file since 155 was 155, checked in by nanardon, 15 years ago
  • remove factorized code
  • Property svn:keywords set to Id Rev
File size: 8.9 KB
Line 
1package LATMOS::Accounts::Bases::Sql::objects;
2
3use 5.010000;
4use strict;
5use warnings;
6
7use base qw(LATMOS::Accounts::Bases::Objects);
8
9our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
10
11=head1 NAME
12
13LATMOS::Ad - Perl extension for blah blah blah
14
15=head1 SYNOPSIS
16
17  use LATMOS::Accounts::Bases;
18  my $base = LATMOS::Accounts::Bases->new('unix');
19  ...
20
21=head1 DESCRIPTION
22
23Account base access over standard unix file format.
24
25=head1 FUNCTIONS
26
27=cut
28
29=head2 new(%options)
30
31Create a new LATMOS::Ad object for windows AD $domain.
32
33domain / server: either the Ad domain or directly the server
34
35ldap_args is an optionnal list of arguments to pass to L<Net::LDAP>.
36
37=cut
38
39sub list {
40    my ($class, $base) = @_;
41
42    my $sth = $base->db->prepare_cached(
43        sprintf(
44            q{select %s as k from %s order by %s},
45            $base->db->quote_identifier($class->key_field),
46            $base->db->quote_identifier($class->object_table),
47            $base->db->quote_identifier($class->key_field),
48        )
49    );
50    $sth->execute;
51    my @keys;
52    while(my $res = $sth->fetchrow_hashref) {
53        push(@keys, $res->{k});
54    }
55    @keys
56}
57
58sub list_from_rev {
59    my ($class, $base, $rev) = @_;
60    my $sth = $base->db->prepare_cached(
61        sprintf(
62            q{select %s as k from %s where rev > ? order by %s},
63            $base->db->quote_identifier($class->key_field),
64            $base->db->quote_identifier($class->object_table),
65            $base->db->quote_identifier($class->key_field),
66        )
67    );
68    $sth->execute($rev);
69    my @keys;
70    while(my $res = $sth->fetchrow_hashref) {
71        push(@keys, $res->{k});
72    }
73    @keys
74}
75
76sub has_extended_attributes { 0 }
77
78sub _inline_fields {
79    my ($self, $for, $base) = @_;
80    $self->_initial_fields($for, $base)
81}
82
83sub _initial_fields {
84    my ($self, $for, $base) = @_;
85    $base ||= $self->base;
86    my $sth = $base->db->prepare_cached(
87        q{SELECT column_name FROM information_schema.columns
88          WHERE table_name = ?}
89    );
90    $sth->execute($self->object_table);
91    my @res;
92    while (my $res = $sth->fetchrow_hashref) {
93        if ($for =~ 'w') {
94            next if($res->{column_name} =~ /^(rev|date|create|ikey)$/);
95            next if($res->{column_name} eq $self->key_field);
96        }
97        push(@res, $res->{column_name});
98    }
99    my %fields = map { $_ => $_ } @res;
100    \%fields
101}
102
103sub _canonical_fields {
104    my ($class, $base, $for) = @_;
105    $for ||= 'rw';
106    my @attr;
107    if ($class->has_extended_attributes) {
108        my $sth = $base->db->prepare_cached(
109            sprintf(
110                q{select canonical from %s order by canonical},
111                $base->db->quote_identifier($class->object_table . '_attributes_list'),
112            )
113        );
114        $sth->execute;
115        while (my $res = $sth->fetchrow_hashref) {
116            push(@attr, $res->{canonical});
117        }
118    }
119    @attr, keys %{ $class->_inline_fields($for, $base) || {} }
120}
121
122sub _get_field_name_db {
123    my ($class, $c_field, $base) = @_;
124    $class->has_extended_attributes or return;
125    $class->object_table or return;
126    my $sth = $base->db->prepare_cached(
127        sprintf(
128            q{select ikey from %s where canonical = ?},
129            $base->db->quote_identifier($class->object_table . '_attributes_list'),
130        )
131    );
132    $sth->execute($c_field);
133   
134    my $res = $sth->fetchrow_hashref;
135    $sth->finish;
136    $res->{ikey}
137}
138
139sub _get_field_name {
140    my ($class, $c_field, $base, $for) = @_;
141    $c_field or return;
142    $for ||= 'rw';
143    my $inline = $class->_inline_fields($for, $base) || {};
144    return $inline->{$c_field}
145        ? $inline->{$c_field}
146        : $class->_get_field_name_db($c_field, $base);
147}
148
149sub new {
150    my ($class, $base, $id) = @_;
151    my $sth = $base->db->prepare_cached(
152        sprintf(q{select 1 from %s where %s = ?},
153            $base->db->quote_identifier($class->object_table),
154            $base->db->quote_identifier($class->key_field),
155        ),
156    );
157    my $count = $sth->execute($id);
158    $sth->finish;
159    $count == 1 or return;
160    bless({ _id => $id, _base => $base }, $class);
161}
162
163sub _create {
164    my ($class, $base, $id, %data) = @_;
165
166    # splitting inline from extended
167    my $inl = $class->_initial_fields('w', $base) || {};
168    my %inline = map { $inl->{$_} => 1 }  keys %{ $inl || {}};
169    my (%first, %second);
170    foreach (keys %data) {
171        if ($inline{$_}) {
172            $first{$_} = $data{$_};
173        } else {
174            $second{$_} = $data{$_};
175        }
176    }
177    $first{$class->key_field} = $id;
178
179    my $sth = $base->db->prepare(
180        sprintf(
181            q{insert into %s (%s) values (%s)},
182            $base->db->quote_identifier($class->object_table),
183            join(', ', map { $base->db->quote_identifier($_) } sort keys %first),
184            join(',', qw(?) x scalar(keys %first)),
185        )
186    );
187    $sth->execute(map { $first{$_} } sort keys %first) or return;
188
189    $class->new($base, $id)->set_fields(%second);
190
191    1;
192}
193
194sub _delete {
195    my ($class, $base, $id) = @_;
196
197    my $sthd = $base->db->prepare_cached(
198        sprintf(
199            q{delete from %s where %s = ?},
200            $base->db->quote_identifier($class->object_table),
201            $base->db->quote_identifier($class->key_field),
202        )
203    );
204    $sthd->execute($id);
205}
206
207sub db {
208    return $_[0]->base->db;
209}
210
211sub quote_object_table {
212    my ($self) = @_;
213    my $table = $self->object_table or return;
214    $self->db->quote_identifier($table);
215}
216sub quote_key_field { 
217    my ($self) = @_;
218    my $key_field = $self->key_field or return;
219    $self->db->quote_identifier($key_field);
220}
221
222sub get_field {
223    my ($self, $field) = @_;
224    my $inl = $self->_inline_fields('r') || {};
225    my %inline = map { $inl->{$_} => 1 }  keys %{ $inl || {}};
226    if ($inline{lc($field)}) {
227    my $sth = $self->db->prepare_cached(
228        sprintf(
229            q{select %s from %s where %s = ?},
230            $self->db->quote_identifier(lc($field)),
231            $self->quote_object_table,
232            $self->quote_key_field,
233        )
234    );
235    $sth->execute($self->id);
236    my $res = $sth->fetchrow_hashref;
237    $sth->finish;
238    return $res->{$field};
239    } elsif ($self->has_extended_attributes) { # else, then we mandatory have extend attr
240        my $sth = $self->db->prepare_cached(
241            sprintf(
242                q{select value from %s where id = ? and attr = ?},
243                $self->db->quote_identifier($self->object_table. '_attributes'),
244            )
245        );
246        $sth->execute($self->id, $field);
247        my $res = $sth->fetchrow_hashref;
248        $sth->finish;
249        return $res->{value};
250    }
251}
252
253sub set_fields {
254    my ($self, %data) = @_;
255    my @fields;
256    my @vals;
257    my %ext;
258    my $inl = $self->_inline_fields('w') || {};
259    my %inline = map { $inl->{$_} => 1 }  keys %{ $inl || {}};
260    foreach my $field (keys %data) {
261        my $oldval = $self->get_field($field);
262        next if (($data{$field} || '') eq ($oldval || ''));
263        if ($inline{$field}) {
264        # TODO check fields exists !
265        push(@fields, sprintf("%s = ?", $self->db->quote_identifier($field)));
266        push(@vals, $data{$field});
267        } else {
268            $ext{$field} = $data{$field};
269        }
270    }
271    if (@fields) {
272        my $sth = $self->db->prepare_cached(
273            sprintf(
274                q{update %s set %s where %s = ?},
275                $self->quote_object_table,
276                join(', ', @fields),
277                $self->quote_key_field,
278            )
279        );
280        $sth->execute(@vals, $self->id);
281    }
282   
283    if ($self->has_extended_attributes) {
284        my $sthd = $self->db->prepare_cached(
285            sprintf(
286                q{delete from %s where id = ? and attr = ?},
287                $self->db->quote_identifier($self->object_table. '_attributes'),
288            ),
289        );
290        my $sthx = $self->db->prepare_cached(
291            sprintf(
292                q{insert into %s (id, attr, value) values (?,?,?)},
293                $self->db->quote_identifier($self->object_table. '_attributes'),
294            )
295        );
296        my $sthu = $self->db->prepare_cached(
297            sprintf(
298                q{update %s set value = ? where id = ? and attr = ?},
299                $self->db->quote_identifier($self->object_table. '_attributes'),
300            )
301        );
302
303        foreach (keys %ext) {
304            if ($ext{$_}) {
305                $sthu->execute($ext{$_}, $self->id, $_) != 0 ||
306                $sthx->execute($self->id, $_, $ext{$_}) or return;
307            } else {
308                $sthd->execute($self->id, $_) or return;
309            }
310        }
311    }
312
313    1;
314}
315
3161;
317
318__END__
319
320=head1 SEE ALSO
321
322=head1 AUTHOR
323
324Olivier Thauvin, E<lt>olivier.thauvin@latmos.ipsl.frE<gt>
325
326=head1 COPYRIGHT AND LICENSE
327
328Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS
329
330This library is free software; you can redistribute it and/or modify
331it under the same terms as Perl itself, either Perl version 5.10.0 or,
332at your option, any later version of Perl 5 you may have available.
333
334
335=cut
Note: See TracBrowser for help on using the repository browser.