Completed
Push — master ( a8ce98...1b7d94 )
by Hong
02:38
created

StatementAbstract::closeResult()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
/**
3
 * Phossa Project
4
 *
5
 * PHP version 5.4
6
 *
7
 * @category  Library
8
 * @package   Phossa2\Db
9
 * @copyright Copyright (c) 2016 phossa.com
10
 * @license   http://mit-license.org/ MIT License
11
 * @link      http://www.phossa.com/
12
 */
13
/*# declare(strict_types=1); */
14
15
namespace Phossa2\Db\Driver;
16
17
use Phossa2\Db\Message\Message;
18
use Phossa2\Db\Traits\DriverAwareTrait;
19
use Phossa2\Shared\Base\ObjectAbstract;
20
use Phossa2\Db\Interfaces\ResultInterface;
21
use Phossa2\Db\Exception\RuntimeException;
22
use Phossa2\Db\Exception\NotFoundException;
23
use Phossa2\Db\Interfaces\StatementInterface;
24
25
/**
26
 * StatementAbstract
27
 *
28
 * @package Phossa2\Db
29
 * @author  Hong Zhang <[email protected]>
30
 * @see     ObjectAbstract
31
 * @see     StatementInterface
32
 * @version 2.0.0
33
 * @since   2.0.0 added
34
 */
35
abstract class StatementAbstract extends ObjectAbstract implements StatementInterface
36
{
37
    use DriverAwareTrait;
38
39
    /**
40
     * prepared statement
41
     *
42
     * @var    mixed
43
     * @access protected
44
     */
45
    protected $prepared;
46
47
    /**
48
     * Result prototype
49
     *
50
     * @var    ResultInterface
51
     * @access protected
52
     */
53
    protected $result_prototype;
54
55
    /**
56
     * @var    ResultInterface
57
     * @access protected
58
     */
59
    protected $result;
60
61
    /**
62
     * Desctructor
63
     *
64
     * @access public
65
     */
66
    public function __destruct()
67
    {
68
        $this->close();
69
    }
70
71
    /**
72
     * {@inheritDoc}
73
     */
74
    public function prepare(/*# string */ $sql)/*# : bool */
75
    {
76
        // close previous prepared sql if any
77
        $this->close();
78
79
        // prepare sql
80
        try {
81
            $res = $this->realPrepare($this->getDriver()->getLink(), $sql);
82
            if (false !== $res) {
83
                $this->prepared = $res;
84
                $this->getDriver()->getProfiler()->setSql($sql);
85
                return true;
86
            }
87
        } catch (\Exception $e) {
88
            throw new RuntimeException($e->getMessage(), (int) $e->getCode(), $e);
89
        }
90
        throw new RuntimeException(
91
            Message::get(Message::DB_STMT_PREPARE_FAIL, $sql),
92
            Message::DB_STMT_PREPARE_FAIL
93
        );
94
    }
95
96
    /**
97
     * {@inheritDoc}
98
     */
99
    public function execute(array $parameters = [])/*# : bool */
100
    {
101
        // must be prepared
102
        $this->checkPreparation();
103
104
        // int profiler
105
        $time = microtime(true);
106
        $this->getDriver()->getProfiler()->setParameters($parameters);
107
108
        try {
109
            if ($this->realExecute($parameters)) {
110
                $result = clone $this->result_prototype;
111
                $this->result = $result($this->prepared);
112
                $this->getDriver()->getProfiler()
113
                    ->setExecutionTime(microtime(true) - $time);
114
                return true;
115
            }
116
        } catch (\Exception $e) {
117
            throw new RuntimeException($e->getMessage(), (int) $e->getCode(), $e);
118
        }
119
        throw new RuntimeException(
120
            Message::get(
121
                Message::DB_STMT_EXECUTE_FAIL,
122
                $this->getDriver()->getProfiler()->getSql()
123
            ), Message::DB_STMT_EXECUTE_FAIL
124
        );
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130
    public function getResult()/*# : ResultInterface */
131
    {
132
        if (null === $this->result) {
133
            throw new NotFoundException(
134
                Message::get(Message::DB_STMT_NO_RESULT),
135
                Message::DB_STMT_NO_RESULT
136
            );
137
        }
138
        return $this->result;
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function close()
145
    {
146
        if ($this->prepared) {
147
            // close result
148
            $this->closeResult();
149
150
            // close statement
151
            $this->realClose($this->prepared);
152
            $this->prepared = null;
153
        }
154
    }
155
156
    /**
157
     * Throw exception if not prepared
158
     *
159
     * @throws RuntimeException
160
     * @access protected
161
     */
162
    protected function checkPreparation()
163
    {
164
        // must be prepared
165
        if (null === $this->prepared) {
166
            throw new RuntimeException(
167
                Message::get(Message::DB_STMT_NOTPREPARED),
168
                Message::DB_STMT_NOTPREPARED
169
            );
170
        }
171
172
        // close any previous resultset
173
        $this->closeResult();
174
    }
175
176
    /**
177
     * Close resultset if any
178
     *
179
     * @access protected
180
     */
181
    protected function closeResult()
182
    {
183
        if ($this->result) {
184
            $this->result->close();
185
            $this->result = null;
186
        }
187
    }
188
189
    /**
190
     * Driver specific prepare statement
191
     *
192
     * @param  mixed $link db link resource
193
     * @param  string $sql
194
     * @return mixed
195
     * @throws RuntimeException
196
     * @access protected
197
     */
198
    abstract protected function realPrepare($link, /*# string */ $sql);
199
200
    /**
201
     * Driver specific statement execution
202
     *
203
     * @param  array $parameters
204
     * @return bool
205
     * @throws RuntimeException
206
     * @access protected
207
     */
208
    abstract protected function realExecute(array $parameters)/*# : bool */;
209
210
    /**
211
     * Close statement
212
     *
213
     * @param  mixed prepared low-level statement
214
     * @access protected
215
     */
216
    abstract protected function realClose($stmt);
217
}
218