Completed
Pull Request — master (#32)
by Guillaume
28:13 queued 11s
created

MySqlLock   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 74.63%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 18
c 4
b 0
f 0
lcom 1
cbo 1
dl 0
loc 165
ccs 50
cts 67
cp 0.7463
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A __clone() 0 5 1
A acquireLock() 0 8 2
A getLock() 0 12 2
B releaseLock() 0 24 3
A isLocked() 0 15 3
A setupPDO() 0 19 4
A __destruct() 0 8 2
1
<?php
2
/**
3
 * This file is part of ninja-mutex.
4
 *
5
 * (C) Kamil Dziedzic <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace NinjaMutex\Lock;
11
12
use PDO;
13
14
/**
15
 * Lock implementor using MySql
16
 *
17
 * @author Kamil Dziedzic <[email protected]>
18
 */
19
class MySqlLock extends LockAbstract
20
{
21
    /**
22
     * MySql connections
23
     *
24
     * @var PDO[]
25
     */
26
    protected $pdo = array();
27
28
    protected $user;
29
    protected $password;
30
    protected $host;
31
    protected $port;
32
    protected $classname;
33
    protected $ssl_ca_cert;
34
35
    /**
36
     * Provide data for PDO connection
37
     *
38
     * @param string $user
39
     * @param string $password
40
     * @param string $host
41
     * @param int $port
42
     * @param string $classname class name to create as PDO connection
43
     */
44
    public function __construct($user, $password, $host, $port = 3306, $classname = 'PDO', $ssl_ca_cert = NULL)
45
    {
46
        parent::__construct();
47
48
        $this->user = $user;
49
        $this->password = $password;
50
        $this->host = $host;
51
        $this->port = $port;
52
        $this->classname = $classname;
53
        $this->ssl_ca_cert = $ssl_ca_cert;
54
    }
55
56 10
    public function __clone()
57
    {
58 10
        parent::__clone();
59 10
        $this->pdo = array();
60 10
    }
61
62
    /**
63
     * Acquire lock
64
     *
65
     * @param  string   $name    name of lock
66
     * @param  null|int $timeout 1. null if you want blocking lock
67
     *                           2. 0 if you want just lock and go
68
     *                           3. $timeout > 0 if you want to wait for lock some time (in milliseconds)
69
     * @return bool
70
     */
71 32
    public function acquireLock($name, $timeout = null)
72
    {
73 32
        if (!$this->setupPDO($name)) {
74
            return false;
75
        }
76
77 32
        return parent::acquireLock($name, $timeout);
78
    }
79
80
    /**
81
     * @param  string $name
82
     * @param  bool   $blocking
83
     * @return bool
84
     */
85 32
    protected function getLock($name, $blocking)
86
    {
87 32
        return !$this->isLocked($name) && $this->pdo[$name]->query(
88 32
            sprintf(
89 32
                'SELECT GET_LOCK("%s", %d)',
90 32
                $name,
91
                0
92 32
            ),
93 32
            PDO::FETCH_COLUMN,
94
            0
95 32
        )->fetch();
96
    }
97
98
    /**
99
     * Release lock
100
     *
101
     * @param  string $name name of lock
102
     * @return bool
103
     */
104 32
    public function releaseLock($name)
105
    {
106 32
        if (!$this->setupPDO($name)) {
107
            return false;
108
        }
109
110 32
        $released = (bool) $this->pdo[$name]->query(
111 32
            sprintf(
112 32
                'SELECT RELEASE_LOCK("%s")',
113
                $name
114 32
            ),
115 32
            PDO::FETCH_COLUMN,
116
            0
117 32
        )->fetch();
118
119 32
        if (!$released) {
120 4
            return false;
121
        }
122
123 32
        unset($this->pdo[$name]);
124 32
        unset($this->locks[$name]);
125
126 32
        return true;
127
    }
128
129
    /**
130
     * Check if lock is locked
131
     *
132
     * @param  string $name name of lock
133
     * @return bool
134
     */
135 32
    public function isLocked($name)
136
    {
137 32
        if (empty($this->pdo) && !$this->setupPDO($name)) {
138
            return false;
139
        }
140
141 32
        return !current($this->pdo)->query(
142 32
            sprintf(
143 32
                'SELECT IS_FREE_LOCK("%s")',
144
                $name
145 32
            ),
146 32
            PDO::FETCH_COLUMN,
147
            0
148 32
        )->fetch();
149
    }
150
151
    /**
152
     * @param  string $name
153
     * @return bool
154
     */
155 32
    protected function setupPDO($name)
156
    {
157 32
        if (isset($this->pdo[$name])) {
158 32
            return true;
159
        }
160
161 32
        $dsn = sprintf('mysql:host=%s;port=%d', $this->host, $this->port);
162 32
        $opts = array();
163 32
        if (!empty($this->ssl_ca_cert)) {
164
            if (file_exists($this->ssl_ca_cert)) {
165
                $opts[\PDO::MYSQL_ATTR_SSL_CA] = $this->ssl_ca_cert;
166
            } else {
167
                error_log("Warning: specified SSL CA Certificate file doesn't exist.");
168
            }
169
        }
170 32
        $this->pdo[$name] = new $this->classname($dsn, $this->user, $this->password, $opts);
171
172 32
        return true;
173
    }
174
175 10
    public function __destruct()
176
    {
177 10
        parent::__destruct();
178
179 10
        foreach($this->pdo as $name => $pdo) {
180 6
            unset($this->pdo[$name]);
181 10
        }
182 10
    }
183
}
184