File Coverage

blib/lib/MogileFS/Plugin/FileRefs.pm
Criterion Covered Total %
statement 16 81 19.7
branch 0 40 0.0
condition 0 18 0.0
subroutine 6 15 40.0
pod 4 6 66.6
total 26 160 16.2


line stmt bran cond sub pod time code
1             package MogileFS::Plugin::FileRefs;
2              
3 2     2   567759 use strict;
  2         13  
  2         49  
4 2     2   8 use warnings;
  2         4  
  2         47  
5              
6 2     2   557 use MogileFS::Store;
  2         30997  
  2         47  
7 2     2   582 use MogileFS::Worker::Query;
  2         333401  
  2         63  
8              
9 2     2   13 use constant LOCK_TIMEOUT => 5;
  2         4  
  2         1535  
10              
11             our $VERSION = '0.09';
12             MogileFS::Store->add_extra_tables("file_ref");
13              
14             sub load {
15 0 0   0 0   MogileFS::register_worker_command('add_file_ref', \&add_file_ref) or die;
16              
17 0 0         MogileFS::register_worker_command('del_file_ref', \&del_file_ref) or die;
18              
19 0 0         MogileFS::register_worker_command('rename_if_no_refs', \&rename_if_no_refs) or die;
20              
21 0 0         MogileFS::register_worker_command('list_refs_for_dkey', \&list_refs_for_dkey) or die;
22             }
23              
24             # By virtue of DBI, this returns true if the connection worked.
25             sub _claim_lock {
26 0     0     my ($rv) = Mgd::validate_dbh->selectrow_array("SELECT GET_LOCK(?,?)", {}, "mogile-filerefs-".$_[1]->{domain}."-".$_[1]->{arg1}, LOCK_TIMEOUT());
27 0           return $rv==1;
28             }
29              
30             sub _free_lock {
31 0 0   0     eval { Mgd::validate_dbh->do("SELECT RELEASE_LOCK(?)", {}, "mogile-filerefs-".$_[1]->{domain}."-".$_[1]->{arg1}) or warn "could not free lock: $DBI::errstr"; };
  0            
32 0           return;
33             }
34              
35             sub add_file_ref {
36 0     0 1   my ($query, $args) = @_;
37 0 0         my $dmid = $query->check_domain($args) or return;
38 0           my $dbh = Mgd::validate_dbh();
39 0 0         _claim_lock($query, $args) or return $query->err_line("get_key_lock_fail");
40 0           local $@;
41 0           my $updated = eval { $dbh->do("INSERT INTO file_ref (dmid, dkey, ref) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE ref=ref", {}, $dmid, $args->{arg1}, $args->{arg2}); };
  0            
42 0 0 0       if ($@ || $dbh->err || $updated < 1) {
      0        
43 0           _free_lock($query, $args);
44 0           return $query->err_line("add_file_ref_fail");
45             }
46 0           _free_lock($query, $args);
47 0 0         return $query->ok_line({made_new_ref => $updated>1 ? 0:1});
48             }
49              
50             sub del_file_ref {
51 0     0 1   my ($query, $args) = @_;
52 0           my $dbh = Mgd::validate_dbh();
53 0 0         my $dmid = $query->check_domain($args) or return;
54 0           local $@;
55 0           my $deleted = eval { $dbh->do("DELETE FROM file_ref WHERE dmid = ? AND dkey = ? AND ref = ?", {}, $dmid, $args->{arg1}, $args->{arg2}) };
  0            
56 0 0 0       if ($@ || $dbh->err) {
57 0           return $query->err_line("del_file_ref_fail");
58             }
59 0 0         return $query->ok_line({deleted_ref => $deleted>0 ? 1:0 });
60             }
61              
62             # TODO - use a stored procedure.
63              
64             sub rename_if_no_refs {
65 0     0 1   my ($query, $args) = @_;
66 0           my $dbh = Mgd::validate_dbh();
67              
68 0 0         my $dmid = $query->check_domain($args) or return;
69              
70 0 0         _claim_lock($query, $args) or return $query->err_line("get_key_lock_fail");
71              
72 0           my ($count) = eval { $dbh->selectrow_array("SELECT COUNT(*) FROM file_ref WHERE dmid = ? AND dkey = ?", {}, $dmid, $args->{arg1}) };
  0            
73 0 0 0       if ($@ || $dbh->err) {
74 0           _free_lock($query, $args);
75 0           return $query->err_line("rename_if_no_refs_failed");
76             }
77              
78 0 0         if ($count != 0) {
79 0           _free_lock($query, $args);
80 0           return $query->ok_line({files_outstanding => $count});
81             }
82              
83 0           my $updated = eval { $dbh->do("UPDATE file SET dkey = ? WHERE dmid = ? AND dkey = ?", {}, $args->{arg2}, $dmid, $args->{arg1}); };
  0            
84 0 0 0       if ($@ || $dbh->err) {
85 0           _free_lock($query, $args);
86 0           return $query->err_line("rename_if_no_refs_failed");
87             }
88 0           _free_lock($query, $args);
89              
90 0           return $query->ok_line({files_outstanding => 0, updated => $updated+0});
91             }
92              
93             sub list_refs_for_dkey {
94 0     0 1   my ($query, $args) = @_;
95 0 0         my $dmid = $query->check_domain($args) or return;
96 0           my $dbh = Mgd::validate_dbh();
97 0           my $result = eval {
98 0           $dbh->selectcol_arrayref("SELECT ref FROM file_ref WHERE dmid = ? AND dkey = ?", {}, $dmid, $args->{arg1});
99             };
100 0 0 0       if ($@ || $dbh->err) {
101 0           return $query->err_line("list_refs_for_dkey_failed");
102             }
103 0           my $i;
104             return $query->ok_line({
105             total => scalar(@$result),
106 0           map { "ref_".$i++ => $_ } @{ $result }
  0            
  0            
107             });
108              
109             }
110              
111             sub update_schema {
112 0     0 0   my $store = Mgd::get_store();
113 0           my $dbh = $store->dbh();
114 0 0         $dbh->do($store->filter_create_sql(TABLE_fileref()))
115             or die "Failed to create table file_ref: ". $dbh->errstr;
116              
117 0           return;
118             }
119              
120             BEGIN {
121             *MogileFS::Store::TABLE_file_ref = sub {
122 0     0     q{CREATE TABLE `file_ref` (
123             `dmid` SMALLINT UNSIGNED NOT NULL,
124             `dkey` varchar(255) DEFAULT NULL,
125             `ref` varchar(255) DEFAULT NULL,
126             UNIQUE KEY `i_unique` (`dmid`,`dkey`,`ref`)
127             );
128             };
129 2     2   70 };
130             }
131              
132             1;
133             __END__