File: DB.pm

package info (click to toggle)
systeminstaller 1.04-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 748 kB
  • ctags: 261
  • sloc: perl: 5,769; makefile: 70
file content (242 lines) | stat: -rw-r--r-- 6,485 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package SIS::DB;

#   $Id: DB.pm,v 1.2 2002/12/17 17:25:48 mchasal Exp $

#   Copyright (c) 2002 International Business Machines

#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
 
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
 
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#   Sean Dague <sean@dague.net>

=head1 NAME

SIS::DB - SIS Interface for client, image, and adapter objects

=head1 SYNOPSIS

  use SIS::DB;

  my @clients = list_client();
  my $name = $clients[0]->name();
  del_client($name);
  my $newname = "test";
  $clients[0]->name($newname) or croak("Can't set name on client");
  set_client($clients[0]);

=head1 DESCRIPTION

The SIS::DB interface gives one access to the System Installation
Suite Database.  There exists 4 functions for every object type:
exists_X, list_X, set_X, del_X.  (These will be discussed in detail
later).

=head1 ENVIRONMENTAL VARIABLES

The behavior of this module may be changed by setting certain
environmental variables before calling use.

=head1 FUNCTIONS

=over 4

=head2 exists_X

exists_X($name) - does this object exist?

returns true if the object with that name exists, false otherwise.
This is used for quick lookups to see if something is defined.  (note:
exists_adapter is different, and needs ($devname, $client) passed to
it) 

=head2 list_X

list_X([n1 => v1, ...])  - return list of objects of type X that
satisfy criteria n1 => v1.

If called with no args, it returns the list of all the objects of type
X.  With args, it will return the list of objects that satisfy the
criteria listed (like 'imagename => myimage').

If called in scalar context, and if the criteria matches only one
object, it will return the single object instead of the list.  If
called in scalar context, if the criteria matches multiple objects,
the function will return 'undef'.

=head2 set_X

set_X($object1[, $object2...]) - store objects of type X.

=head2 del_X

del_X($primkey) - detele object of type X by key using $primkey as the
value.

=back

=head1 AUTHORS

  Copyright 2002 International Business Machines
  Sean Dague <sean@dague.net>

=cut

use strict;
use Carp;
use GDBM_File;
use Data::Dumper;
use MLDBM qw(GDBM_File);
use Fcntl;
use base qw(Exporter);
use vars qw($VERSION $DBPATH $DBMAP @EXPORT);

$VERSION = sprintf("%d.%02d", q$Revision: 1.2 $ =~ /(\d+)\.(\d+)/);

@EXPORT = qw(exists_image list_image set_image del_image
             exists_client list_client set_client del_client
             exists_adapter list_adapter set_adapter del_adapter);

$DBPATH = $ENV{SIS_DBPATH} || "/var/lib/sis";
if($ENV{SIS_DBTYPE} and ($ENV{SIS_DBTYPE} eq "Storable")) {
    $MLDBM::Serializer = "Storable";
}

$DBMAP = {
          'SIS::Client' => {
                            file => 'client',
                           },
          'SIS::Image' => {
                           file => 'image',
                          },
          'SIS::Adapter' => {
                             file => 'adapter',
                            },
          'SIS::Trigger' => {
                             file => 'trigger',
                            },
         };

# lisp has the tendency to us p as a typable replacement for ?

sub match_p {
    my ($obj, $criteria) = @_;
    foreach my $key (sort keys %$criteria) {
        unless($obj->get($key) eq $criteria->{$key}) {
            return undef;
        }
    }
    return 1;
}

sub exists_image {
    my ($name) = @_;
    my @images = list_image(name => $name);
    return scalar(@images);
}

sub list_image {return _list_obj('SIS::Image',@_)}
sub del_image {return sisdel('SIS::Image',@_)}
sub set_image {return sisset('SIS::Image',@_)}

sub exists_client {
    my ($name) = @_;
    my @images = list_client(name => $name);
    return scalar(@images);
}

sub list_client {return _list_obj('SIS::Client',@_)}
sub del_client {return sisdel('SIS::Client',@_)}
sub set_client {return sisset('SIS::Client',@_)}

sub exists_adapter {
    my ($name, $client) = @_;
    my @images = list_adapter(devname => $name, client => $client);
    return scalar(@images);
}
sub list_adapter {return _list_obj('SIS::Adapter',@_)}
sub del_adapter {return sisdel('SIS::Adapter',@_)}
sub set_adapter {return sisset('SIS::Adapter',@_)}

sub _list_obj {
    my $type = shift;
    my %criteria = @_;
    my @obj = ();
    my @temp = sisget($type);
    foreach my $obj (@temp) {
        if(match_p($obj, \%criteria)) {
            push @obj, $obj->clone;
        }
    }
    if(wantarray) {
        return @obj;
    } elsif(scalar(@obj) == 1) {
        return $obj[0];
    } else {
        return undef;
    }
}

sub _dbfile {
    my $type = shift;
    my $file = $DBPATH . "/" . $DBMAP->{$type}->{file};
    if(-e $file) {
        return $file;
    }
    croak("Can't find db file $file!");
}

sub sisget {
    my $type = shift;
    my %dbh = ();
    my $file = _dbfile($type);
    return () if -z $file;
    my $rc = tie (%dbh, 'MLDBM', $file, GDBM_READER(), 0444) or croak("Couldn't open MLDBM $file: $!");
    my @obj =  (sort {$a->primkey cmp $b->primkey} values %dbh);
    # This must be done to get rid of the untie warning
    undef $rc;
    untie %dbh;
    return @obj;
}

sub sisset {
    my $type = shift;
    my @obj = @_;
    my %dbh = ();
    my $file = _dbfile($type);
    my $rc = tie (%dbh, 'MLDBM', $file, GDBM_WRCREAT(), 0640) or croak("Couldn't open MLDBM $file: $!");
    foreach my $o (@obj) {
        $dbh{$o->primkey} = $o;
    }
    # This must be done to get rid of the untie warning
    undef $rc;
    untie %dbh;
    return 1;
}

sub sisdel {
    my $type = shift;
    my @keys = @_;
    my %dbh = ();
    my $file = _dbfile($type);
    my $rc = tie (%dbh, 'MLDBM', $file, GDBM_WRCREAT(), 0640) or croak("Couldn't open MLDBM $file: $!");
    foreach my $key (@keys) {
        delete $dbh{$key};
    }
    # This must be done to get rid of the untie warning
    undef $rc;
    untie %dbh;
    return 1;
}

42;