Completed
Push — fix_travis ( 785058...ce7855 )
by Kamil
02:06
created

MySqlLock::getLock()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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