source: LATMOS-Accounts/lib/LATMOS/Accounts/Bases.pm @ 103

Last change on this file since 103 was 103, checked in by nanardon, 15 years ago
  • rename list_canonicals_fields to list_canonical_fields
  • Property svn:keywords set to Id Rev
File size: 6.8 KB
Line 
1package LATMOS::Accounts::Bases;
2
3use 5.010000;
4use strict;
5use warnings;
6use LATMOS::Accounts::Bases::Objects;
7
8our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0];
9
10=head1 NAME
11
12LATMOS::Accounts::Bases - Base class for account data bases
13
14=head1 SYNOPSIS
15
16  use LATMOS::Accounts::Bases;
17  my $base = LATMOS::Accounts::Bases->new('type', %options);
18  ...
19
20=head1 DESCRIPTION
21
22This module provide basic functions for various account base
23
24=head1 FUNTIONS
25
26=cut
27
28=head2 new($type, %options)
29
30Return, if success, a new data base account object, $type is
31account base type, %options to setup the base.
32
33=cut
34
35sub new {
36    my ($class, $type, %options) = @_;
37
38    my $pclass = ucfirst(lc($type));
39    eval "require LATMOS::Accounts::Bases::$pclass;";
40    if ($@) { return } # error message ?
41    my $base = "LATMOS::Accounts::Bases::$pclass"->new(%options);
42    $base->{_type} = lc($pclass);
43    $base->{_label} = $options{label};
44    $base
45}
46
47sub label {
48    $_[0]->{_label};
49}
50
51sub type {
52    $_[0]->{_type};
53}
54
55sub _load_obj_class {
56    my ($self, $otype) = @_;
57
58    # finding perl class:
59    my $pclass = ref $self;
60    $pclass .= '::' . ucfirst(lc($otype));
61    eval "require $pclass;";
62    if ($@) { return } # error message ?
63    return $pclass;
64}
65
66=head2 list_canonical_fields($otype, $for)
67
68Return the list of supported fields by the database for object type $otype.
69
70Optionnal $for specify the goal for which the list is requested, only supported
71fields will be returns
72
73=cut
74
75sub list_canonical_fields {
76    my ($self, $otype, $for) = @_;
77    $for ||= 'rw';
78    my $pclass = $self->_load_obj_class($otype) or return;
79    $pclass->_canonical_fields($self, $for);
80}
81
82sub delayed_fields {
83    my ($self, $otype, $for) = @_;
84    $for ||= 'rw';
85    my $pclass = $self->_load_obj_class($otype) or return;
86    $pclass->_delayed_fields($self, $for);
87}
88
89=head2 get_field_name($otype, $c_fields, $for)
90
91Return the internal fields name for $otype object for
92canonical fields $c_fields
93
94=cut
95
96sub get_field_name {
97    my ($self, $otype, $c_fields, $for) = @_;
98    $for ||= 'rw';
99    my $pclass = $self->_load_obj_class($otype) or return;
100    $pclass->_get_field_name($c_fields, $self, $for);
101}
102
103=head2 list_supported_objects(@otype)
104
105Return a list of supported object
106
107@type is an additionnal list of objects to check
108
109=cut
110
111sub list_supported_objects {
112    my ($self, @otype) = @_;
113    return grep { $self->is_supported_object($_) }
114        (qw(group user), @otype);
115}
116
117=head2 is_supported_object($otype)
118
119Return true is object type $otype is supported
120
121=cut
122
123sub is_supported_object {
124    my ($self, $otype) = @_;
125    return $self->_load_obj_class($otype) ? 1 : 0;
126}
127
128=head2 list_objects($otype)
129
130Return the list of UID for object of $otype.
131
132=cut
133
134sub list_objects {
135    my ($self, $otype) = @_;
136    my $pclass = $self->_load_obj_class($otype) or return;
137    $pclass->list($self);
138}
139
140=head2 get_object($type, $id)
141
142Return an object of $type (typically user or group) having identifier
143$id.
144
145=cut
146
147sub get_object {
148    my ($self, $otype, $id) = @_;
149
150    return LATMOS::Accounts::Bases::Objects->_new($self, $otype, $id);
151}
152
153=head2 create_object($type, $id, %data)
154
155Create and return an object of type $type with unique id
156$id having %data.
157
158This method should be provided by the data base handler.
159
160=cut
161
162sub create_object {
163    my ($self, $otype, $id, %data) = @_;
164    my $pclass = $self->_load_obj_class($otype);
165    $pclass->_create($self, $id, %data) or return;
166    $self->get_object($otype, $id);
167}
168
169=head2 create_c_object($type, $id, %data)
170
171Create and return an object of type $type with unique id
172$id having %data using canonical fields
173
174=cut
175
176sub create_c_object {
177    my ($self, $otype, $id, %cdata) = @_;
178
179    my %data;
180    foreach my $cfield (keys %cdata) {
181        my $field = $self->get_field_name($otype, $cfield, 'write') or next;
182        $data{$field} = $cdata{$cfield};
183    }
184    keys %data or return 0; # TODO: return an error ?
185    $self->create_object($otype, $id, %data);
186}
187
188=head2 delete_object($otype, $id)
189
190Destroy from data base object type $otype having id $id.
191
192=cut
193
194sub delete_object {
195    my ($self, $otype, $id) = @_;
196    my $pclass = $self->_load_obj_class($otype);
197    $pclass->_delete($self, $id) or return;
198}
199
200=head2 load
201
202Make account base loading data into memory if need.
203Should always be called, if database fetch data on the fly
204(SQL, LDAP), the function just return True.
205
206=cut
207
208sub load { 1 }
209
210=head2 is_transactionnal
211
212Return True is the database support commit and rollback
213
214=cut
215
216sub is_transactionnal {
217    my ($self) = @_;
218    return($self->can('_rollback') && $self->can('_commit'));
219}
220
221=head2 commit
222
223Save change into the database if change are not done immediately.
224This should always be called as you don't know when change are applied.
225
226Return always true if database does not support any transaction.
227
228The driver should provides a _commit functions to save data.
229
230=cut
231
232sub commit {
233    my ($self) = @_;
234    return $self->can('_commit') ? $self->_commit : 1;
235}
236
237=head2 rollback
238
239If database support transaction, rollback changes. Return false
240if database does not support.
241
242If supported, driver should provides a _rollback functions
243
244=cut
245
246sub rollback {
247    my ($self) = @_;
248    return $self->can('_rollback') ? $self->_rollback : 0;
249}
250
251=head2 current_rev
252
253Return the current revision of the database
254
255Must be provide by base driver if incremental synchro is supported
256
257=cut
258
259sub current_rev { return }
260
261=head2 list_objects_from_rev($otype, $rev)
262
263Return the list of UID for object of $otype.
264
265=cut
266
267sub list_objects_from_rev {
268    my ($self, $otype, $rev) = @_;
269    my $pclass = $self->_load_obj_class($otype) or return;
270    if (defined($rev) && $pclass->can('list_from_rev')) {
271        return $pclass->list_from_rev($self, $rev);
272    } else {
273        # no support, return all objects...
274        return $self->list_objects($otype);
275    }
276}
277
278=head2 sync_object
279
280Synchronise an object into this base
281
282=cut
283
284sub sync_object {
285    my ($self, $srcobj, %options) = @_;
286    $self->is_supported_object($srcobj->type) or return;
287    my @fields = $options{attrs}
288        ? @{ $options{attrs} }
289        : $self->list_canonical_fields($srcobj->type, 'w');
290    my %data;
291    foreach (@fields) {
292        $srcobj->get_field_name($_, 'r') or next;
293        $data{$_} = $srcobj->get_c_field($_);
294    }
295    if (my $dstobj = $self->get_object($srcobj->type, $srcobj->id)) {
296        return $dstobj->set_c_fields(%data);
297    } elsif(!$options{nocreate}) {
298        return $self->create_c_object($srcobj->type, $srcobj->id, %data);
299    } else {
300        return 0;
301    }
302}
303
3041;
305
306__END__
307
308=head1 SEE ALSO
309
310=head1 AUTHOR
311
312Thauvin Olivier, E<lt>olivier.thauvin@latmos.ipsl.fr<gt>
313
314=head1 COPYRIGHT AND LICENSE
315
316Copyright (C) 2009 by Thauvin Olivier
317
318This library is free software; you can redistribute it and/or modify
319it under the same terms as Perl itself, either Perl version 5.10.0 or,
320at your option, any later version of Perl 5 you may have available.
321
322=cut
Note: See TracBrowser for help on using the repository browser.