source: server/trunk/web/lib/Sophie/Base/RpmsPath.pm @ 46

Last change on this file since 46 was 42, checked in by nanardon, 14 years ago
  • add dump/load distrib config using Yaml
  • separate DB connection for session
File size: 5.2 KB
Line 
1package Sophie::Base::RpmsPath;
2
3use strict;
4use warnings;
5use base qw(Sophie::Base);
6use Sophie::Base::Header;
7use RPM4;
8use File::Temp;
9use File::Copy;
10use Archive::Cpio;
11use Encode::Guess;
12use Encode;
13
14sub new {
15    my ($class, $pathkey) = @_;
16
17    bless({ key => $pathkey }, $class);
18}
19
20sub key { $_[0]->{key} }
21
22sub path {
23    my ($self) = @_;
24   
25    my $sth = $self->db->prepare_cached(
26        q{select path from d_path where d_path_key = ?}
27    );
28    $sth->execute($self->key);
29    my $res = $sth->fetchrow_hashref;
30    $sth->finish;
31    return $res->{path}
32}
33
34sub ls_rpms {
35    my ($self) = @_;
36
37    my $sth = $self->db->prepare_cached(
38        q{select * from rpmfiles where d_path = ?}
39    );
40    $sth->execute($self->key);
41    $sth->fetchall_hashref([ 'filename' ]);
42}
43
44sub local_ls_rpms {
45    my ($self) = @_;
46
47    if (opendir(my $dh, $self->path)) {
48        my %list;
49        while (my $entry = readdir($dh)) {
50            $entry eq '.' and next;
51            $entry eq '..' and next;
52            $list{$entry} = 1;
53        }
54        closedir($dh);
55        return \%list;
56    } else {
57        return;
58    }
59}
60
61sub find_delta {
62    my ($self) = @_;
63
64    warn $self->path;
65
66    my $localrpms = $self->local_ls_rpms || {};
67    my $baserpms  = $self->ls_rpms;
68
69    my %list;
70    foreach (keys %{ $localrpms }, keys %{ $baserpms }) {
71        $list{$_} = 1;
72    }
73    my @delta;
74
75    foreach my $rpm (sort { $b cmp $a } keys %list) {
76        if ($localrpms->{$rpm} && $baserpms->{$rpm}) {
77            # nothing to do
78        } elsif ($localrpms->{$rpm}) {
79            push(@delta, { rpm => $rpm, delta => 'A' });
80        } elsif ($baserpms->{$rpm}) {
81            push(@delta, { rpm => $rpm, delta => 'R' });
82        }
83    }
84    @delta;
85}
86sub update_content {
87    my ($self, @delta) = @_;
88    foreach (@delta) {
89        if (!$_->{delta}) {
90        }
91        elsif ($_->{delta} eq 'A') {
92            $self->add_rpm($_->{rpm});
93        }
94        elsif ($_->{delta} eq 'R') {
95            $self->remove_rpm($_->{rpm});
96        }
97    }
98}
99
100sub set_updated {
101    my ($self) = @_;
102    warn "UPD";
103    $self->db->prepare_cached(q{
104        update d_path set updated = now() where d_path_key = ?
105        })->execute($self->key);
106    $self->db->commit;
107}
108
109
110sub remove_rpm {
111    my ($self, $rpm) = @_;
112    my $remove = $self->db->prepare_cached(
113        q{
114        DELETE FROM rpmfiles where d_path = ? and filename = ?
115        }
116    );
117    for (1 .. 3) {
118        if ($remove->execute($self->key, $rpm)) { 
119            warn "deleting $rpm";
120            $self->db->commit;
121            return 1;
122        }
123        $self->db->rollback;
124    }
125}
126
127sub add_rpm {
128    my ($self, $rpm) = @_;
129
130    for (1 .. 3) {
131        if (defined(my $pkgid = $self->_add_header($rpm))) {
132            $pkgid or return;
133            my $register = $self->db->prepare_cached(
134                q{
135                INSERT INTO rpmfiles (d_path, filename, pkgid)
136                values (?,?,?)
137                }
138            );
139            if ($register->execute($self->key, $rpm, $pkgid)) {
140                warn "adding $rpm";
141                $self->db->commit;
142                return;
143            }
144
145        }
146        $self->db->rollback;
147    }
148}
149
150sub _add_header {
151    my ($self, $rpm) = @_;
152
153    my $header;
154    eval {
155        $header = RPM4::Header->new($self->path . '/' . $rpm) 
156    };
157    $header or do {
158        warn "Cannot read " . $self->path . '/' . $rpm;
159        return "";
160    };
161
162    {
163        my $find = $self->db->prepare_cached(q{
164            select pkgid from rpms where pkgid = ?
165        });
166        $find->execute($header->queryformat('%{PKGID}'));
167        my $rows = $find->rows;
168        $find->finish;
169        if ($rows) {
170            warn "Find";
171            return $header->queryformat('%{PKGID}');
172        }
173    }
174    my $tmp = File::Temp->new( UNLINK => 1, SUFFIX => '.hdr' );
175    unlink($tmp->filename);
176    $header->write($tmp, 0);
177    seek($tmp, 0, 0);
178    my $string = '';
179    while (read($tmp, my $str, 1024)) { $string .= $str }
180    $tmp = undef;
181    my $add_header = $self->db->prepare_cached(
182        q{
183        INSERT into rpms (pkgid, name, header, evr, issrc, description, summary)
184        values (?,?,rpmheader_in(decode(?, 'hex')::bytea),?,?,?,?)
185        }
186    );
187    my $description = $header->queryformat('%{DESCRIPTION}');
188    {
189        my $enc = guess_encoding($description, qw/latin1/);
190        $description = $enc->decode($description) if ($enc && ref $enc);
191    }
192    my $summary = $header->queryformat('%{SUMMARY}');
193    {
194        my $enc = guess_encoding($summary, qw/latin1/);
195        $summary = $enc->decode($summary) if ($enc && ref $enc);
196    }
197
198    $add_header->execute(
199        $header->queryformat('%{PKGID}'),
200        $header->queryformat('%{name}'),
201        unpack('H*', $string),
202        $header->queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}'),
203        $header->hastag('SOURCERPM') ? 'f' : 't',
204        $description,
205        $summary,
206    );
207    my $index_tag = $self->db->prepare_cached(
208        q{
209        select index_rpms(?);
210        }
211    );
212    $index_tag->execute($header->queryformat('%{PKGID}')) or return;
213    $index_tag->finish;
214    Sophie::Base::Header->new($header->queryformat('%{PKGID}'))
215        ->addfiles_content({ path => $self->path, filename => $rpm}) or return;
216
217    $header->queryformat('%{PKGID}');
218}
219
2201;
Note: See TracBrowser for help on using the repository browser.