Completed
Push — pr21 ( ec1d9e )
by Kamil
02:27
created

MySqlLock   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 80.7%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 16
c 3
b 0
f 0
lcom 1
cbo 1
dl 0
loc 155
ccs 46
cts 57
cp 0.807
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A __clone() 0 5 1
A acquireLock() 0 8 2
A isLocked() 0 15 3
A setupPDO() 0 11 2
B releaseLock() 0 24 3
A getLock() 0 12 2
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
34
    /**
35
     * Provide data for PDO connection
36
     *
37
     * @param string $user
38
     * @param string $password
39
     * @param string $host
40
     * @param int $port
41
     * @param string $classname class name to create as PDO connection
42
     */
43
    public function __construct($user, $password, $host, $port = 3306, $classname = 'PDO')
44
    {
45
        parent::__construct();
46
47
        $this->user = $user;
48
        $this->password = $password;
49
        $this->host = $host;
50
        $this->port = $port;
51
        $this->classname = $classname;
52
    }
53
54 5
    public function __clone()
55
    {
56 5
        parent::__clone();
57 5
        $this->pdo = array();
58 5
    }
59
60
    /**
61
     * Acquire lock
62
     *
63
     * @param  string   $name    name of lock
64
     * @param  null|int $timeout 1. null if you want blocking lock
65
     *                           2. 0 if you want just lock and go
66
     *                           3. $timeout > 0 if you want to wait for lock some time (in milliseconds)
67
     * @return bool
68
     */
69 16
    public function acquireLock($name, $timeout = null)
70
    {
71 16
        if (!$this->setupPDO($name)) {
72
            return false;
73
        }
74
75 16
        return parent::acquireLock($name, $timeout);
76
    }
77
78
    /**
79
     * @param  string $name
80
     * @param  bool   $blocking
81
     * @return bool
82
     */
83 16
    protected function getLock($name, $blocking)
84
    {
85 16
        return !$this->isLocked($name) && $this->pdo[$name]->query(
86 16
            sprintf(
87 16
                'SELECT GET_LOCK(%s, %d)',
88 16
                $this->pdo[$name]->quote($name),
89
                0
90
            ),
91 16
            PDO::FETCH_COLUMN,
92
            0
93 16
        )->fetch();
94
    }
95
96
    /**
97
     * Release lock
98
     *
99
     * @param  string $name name of lock
100
     * @return bool
101
     */
102 16
    public function releaseLock($name)
103
    {
104 16
        if (!$this->setupPDO($name)) {
105
            return false;
106
        }
107
108 16
        $released = (bool) $this->pdo[$name]->query(
109 16
            sprintf(
110 16
                'SELECT RELEASE_LOCK(%s)',
111 16
                $this->pdo[$name]->quote($name)
112
            ),
113 16
            PDO::FETCH_COLUMN,
114
            0
115 16
        )->fetch();
116
117 16
        if (!$released) {
118 2
            return false;
119
        }
120
121 16
        unset($this->pdo[$name]);
122 16
        unset($this->locks[$name]);
123
124 16
        return true;
125
    }
126
127
    /**
128
     * Check if lock is locked
129
     *
130
     * @param  string $name name of lock
131
     * @return bool
132
     */
133 16
    public function isLocked($name)
134
    {
135 16
        if (empty($this->pdo) && !$this->setupPDO($name)) {
136
            return false;
137
        }
138
139 16
        return !current($this->pdo)->query(
140 16
            sprintf(
141 16
                'SELECT IS_FREE_LOCK(%s)',
142 16
                current($this->pdo)->quote($name)
143
            ),
144 16
            PDO::FETCH_COLUMN,
145
            0
146 16
        )->fetch();
147
    }
148
149
    /**
150
     * @param  string $name
151
     * @return bool
152
     */
153 16
    protected function setupPDO($name)
154
    {
155 16
        if (isset($this->pdo[$name])) {
156 16
            return true;
157
        }
158
159 16
        $dsn = sprintf('mysql:host=%s;port=%d', $this->host, $this->port);
160 16
        $this->pdo[$name] = new $this->classname($dsn, $this->user, $this->password);
161
162 16
        return true;
163
    }
164
165 5
    public function __destruct()
166
    {
167 5
        parent::__destruct();
168
169 5
        foreach($this->pdo as $name => $pdo) {
170 3
            unset($this->pdo[$name]);
171
        }
172 5
    }
173
}
174