Completed
Push — pr21 ( e66eee...5bbff6 )
by Kamil
02:36
created

MySqlLock   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 81.97%

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 50
cts 61
cp 0.8197
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 getLock() 0 12 2
A setupPDO() 0 11 2
A __destruct() 0 8 2
B releaseLock() 0 24 3
A isLocked() 0 15 3
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 10
    public function __clone()
55
    {
56 10
        parent::__clone();
57 10
        $this->pdo = array();
58 10
    }
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 32
    public function acquireLock($name, $timeout = null)
70
    {
71 32
        if (!$this->setupPDO($name)) {
72
            return false;
73
        }
74
75 32
        return parent::acquireLock($name, $timeout);
76
    }
77
78
    /**
79
     * @param  string $name
80
     * @param  bool   $blocking
81
     * @return bool
82
     */
83 32
    protected function getLock($name, $blocking)
84
    {
85 32
        return !$this->isLocked($name) && $this->pdo[$name]->query(
86 32
            sprintf(
87 32
                'SELECT GET_LOCK(%s, %d)',
88 32
                $this->pdo[$name]->quote($name),
89
                0
90 32
            ),
91 32
            PDO::FETCH_COLUMN,
92
            0
93 32
        )->fetch();
94
    }
95
96
    /**
97
     * Release lock
98
     *
99
     * @param  string $name name of lock
100
     * @return bool
101
     */
102 32
    public function releaseLock($name)
103
    {
104 32
        if (!$this->setupPDO($name)) {
105
            return false;
106
        }
107
108 32
        $released = (bool) $this->pdo[$name]->query(
109 32
            sprintf(
110 32
                'SELECT RELEASE_LOCK(%s)',
111 32
                $this->pdo[$name]->quote($name)
112 32
            ),
113 32
            PDO::FETCH_COLUMN,
114
            0
115 32
        )->fetch();
116
117 32
        if (!$released) {
118 4
            return false;
119
        }
120
121 32
        unset($this->pdo[$name]);
122 32
        unset($this->locks[$name]);
123
124 32
        return true;
125
    }
126
127
    /**
128
     * Check if lock is locked
129
     *
130
     * @param  string $name name of lock
131
     * @return bool
132
     */
133 32
    public function isLocked($name)
134
    {
135 32
        if (empty($this->pdo) && !$this->setupPDO($name)) {
136
            return false;
137
        }
138
139 32
        return !current($this->pdo)->query(
140 32
            sprintf(
141 32
                'SELECT IS_FREE_LOCK(%s)',
142 32
                current($this->pdo)->quote($name)
143 32
            ),
144 32
            PDO::FETCH_COLUMN,
145
            0
146 32
        )->fetch();
147
    }
148
149
    /**
150
     * @param  string $name
151
     * @return bool
152
     */
153 32
    protected function setupPDO($name)
154
    {
155 32
        if (isset($this->pdo[$name])) {
156 32
            return true;
157
        }
158
159 32
        $dsn = sprintf('mysql:host=%s;port=%d', $this->host, $this->port);
160 32
        $this->pdo[$name] = new $this->classname($dsn, $this->user, $this->password);
161
162 32
        return true;
163
    }
164
165 10
    public function __destruct()
166
    {
167 10
        parent::__destruct();
168
169 10
        foreach($this->pdo as $name => $pdo) {
170 6
            unset($this->pdo[$name]);
171 10
        }
172 10
    }
173
}
174