File Coverage

blib/lib/Wiki/Toolkit/Store/MySQL.pm
Criterion Covered Total %
statement 15 50 30.0
branch 0 16 0.0
condition n/a
subroutine 5 10 50.0
pod 1 1 100.0
total 21 77 27.2


line stmt bran cond sub pod time code
1             package Wiki::Toolkit::Store::MySQL;
2              
3 2     2   1836 use strict;
  2         4  
  2         72  
4              
5 2     2   12 use vars qw( @ISA $VERSION );
  2         4  
  2         125  
6              
7 2     2   695 use Wiki::Toolkit::Store::Database;
  2         6  
  2         64  
8 2     2   13 use Carp qw/carp croak/;
  2         5  
  2         123  
9 2     2   1106 use Digest::SHA qw/ sha1_hex /;
  2         5587  
  2         1138  
10              
11             @ISA = qw( Wiki::Toolkit::Store::Database );
12             $VERSION = 0.07;
13              
14             =head1 NAME
15              
16             Wiki::Toolkit::Store::MySQL - MySQL storage backend for Wiki::Toolkit
17              
18             =head1 REQUIRES
19              
20             Subclasses Wiki::Toolkit::Store::Database.
21              
22             =head1 SYNOPSIS
23              
24             See Wiki::Toolkit::Store::Database
25              
26             =cut
27              
28             # Internal method to return the data source string required by DBI.
29             sub _dsn {
30 0     0     my ($self, $dbname, $dbhost, $dbport) = @_;
31 0           my $dsn = "dbi:mysql:$dbname";
32 0 0         $dsn .= ";host=$dbhost" if $dbhost;
33 0 0         $dsn .= ";port=$dbport" if $dbport;
34 0           return $dsn;
35             }
36              
37             =head1 METHODS
38              
39             =over 4
40              
41             =item B
42              
43             $store->check_and_write_node( node => $node,
44             checksum => $checksum,
45             %other_args );
46              
47             Locks the node, verifies the checksum, calls
48             C with all supplied arguments, unlocks the
49             node. Returns the version of the updated node on successful writing, 0 if
50             checksum doesn't match, -1 if the change was not applied, croaks on error.
51              
52             Note: Uses MySQL's user level locking, so any locks are released when
53             the database handle disconnects. Doing it like this because I can't seem
54             to get it to work properly with transactions.
55              
56             =back
57              
58             =cut
59              
60             sub check_and_write_node {
61 0     0 1   my ($self, %args) = @_;
62 0           my ($node, $checksum) = @args{qw( node checksum )};
63 0 0         $self->_lock_node($node) or croak "Can't lock node";
64 0           my $ok = $self->verify_checksum($node, $checksum);
65 0 0         unless ($ok) {
66 0 0         $self->_unlock_node($node) or carp "Can't unlock node";
67 0           return 0;
68             }
69 0           $ok = $self->write_node_post_locking( %args );
70 0 0         $self->_unlock_node($node) or carp "Can't unlock node";
71 0           return $ok;
72             }
73              
74             # Returns 1 if we can get a lock, 0 if we can't, croaks on error.
75             sub _lock_node {
76 0     0     my ($self, $node) = @_;
77 0           my $dbh = $self->{_dbh};
78             # SHA1 the node name to make sure the lock name isn't >64 characters.
79 0           my $lock_name = $dbh->quote( sha1_hex( $node ) );
80 0           my $sql = "SELECT GET_LOCK( $lock_name, 10 )";
81 0           my $sth = $dbh->prepare($sql);
82 0 0         $sth->execute or croak $dbh->errstr;
83 0           my $locked = $sth->fetchrow_array;
84 0           $sth->finish;
85 0           return $locked;
86             }
87              
88             # Returns 1 if we can unlock, 0 if we can't, croaks on error.
89             sub _unlock_node {
90 0     0     my ($self, $node) = @_;
91 0           my $dbh = $self->{_dbh};
92 0           my $lock_name = $dbh->quote( sha1_hex( $node ) );
93 0           my $sql = "SELECT RELEASE_LOCK( $lock_name )";
94 0           my $sth = $dbh->prepare($sql);
95 0 0         $sth->execute or croak $dbh->errstr;
96 0           my $unlocked = $sth->fetchrow_array;
97 0           $sth->finish;
98 0           return $unlocked;
99             }
100              
101             sub _get_casesensitive_compare_sql {
102 0     0     my ($self, $column) = @_;
103 0           return "BINARY $column = ?";
104             }
105              
106             1;