Completed
Push — master ( eea790...427bc5 )
by Lars
05:00 queued 02:52
created

Prepare::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.6666
cc 1
eloc 5
nc 1
nop 2
crap 1
1
<?php
2
3
namespace voku\db;
4
5
/**
6
 * Prepare: this handles the prepare-statement from "DB"-Class
7
 *
8
 * @package   voku\db
9
 */
10
final class Prepare extends \mysqli_stmt
11
{
12
13
  /**
14
   * @var string
15
   */
16
  private $_sql;
17
18
  /**
19
   * @var DB
20
   */
21
  private $_db;
22
23
  /**
24
   * @var Debug
25
   */
26
  private $_debug;
27
28
  /**
29
   * Prepare constructor.
30
   *
31
   * @param DB     $db
32
   * @param string $query
33
   */
34 2
  public function __construct(DB $db, $query)
35
  {
36 2
    $this->_db = $db;
37 2
    $this->_debug = $db->getDebugger();
38
39 2
    parent::__construct($db->getLink(), $query);
40
41 2
    $this->prepare($query);
42 2
  }
43
44
  /**
45
   * Executes a prepared Query
46
   *
47
   * @link  http://php.net/manual/en/mysqli-stmt.execute.php
48
   * @return bool true on success or false on failure.
49
   * @since 5.0
50
   */
51 2
  public function execute()
52
  {
53 2
    $query_start_time = microtime(true);
54 2
    $bool = parent::execute();
55 2
    $query_duration = microtime(true) - $query_start_time;
56
57 2
    $this->_debug->logQuery($this->_sql, $query_duration, $this->num_rows);
58
59 2
    if ($bool === false) {
60 1
      $this->queryErrorHandling($this->error, $this->_sql);
61 1
    }
62
63 2
    return $bool;
64
  }
65
66
  /**
67
   * Error-handling for the sql-query.
68
   *
69
   * @param string $errorMsg
70
   * @param string $sql
71
   *
72
   * @throws \Exception
73
   */
74 1 View Code Duplication
  protected function queryErrorHandling($errorMsg, $sql)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
  {
76 1
    if ($errorMsg === 'DB server has gone away' || $errorMsg === 'MySQL server has gone away') {
77
      static $reconnectCounter;
78
79
      // exit if we have more then 3 "DB server has gone away"-errors
80
      if ($reconnectCounter > 3) {
81
        $this->_debug->mailToAdmin('SQL-Fatal-Error', $errorMsg . ":\n<br />" . $sql, 5);
82
        throw new \Exception($errorMsg);
83
      } else {
84
        $this->_debug->mailToAdmin('SQL-Error', $errorMsg . ":\n<br />" . $sql);
85
86
        // reconnect
87
        $reconnectCounter++;
88
        $this->_db->reconnect(true);
89
90
        // re-run the current query
91
        $this->execute();
92
      }
93
    } else {
94 1
      $this->_debug->mailToAdmin('SQL-Warning', $errorMsg . ":\n<br />" . $sql);
95
96
      // this query returned an error, we must display it (only for dev) !!!
97 1
      $this->_debug->displayError($errorMsg . ' | ' . $sql);
98
    }
99 1
  }
100
101
  /**
102
   * Prepare an SQL statement for execution
103
   *
104
   * @link  http://php.net/manual/en/mysqli-stmt.prepare.php
105
   *
106
   * @param string $query <p>
107
   *                      The query, as a string. It must consist of a single SQL statement.
108
   *                      </p>
109
   *                      <p>
110
   *                      You can include one or more parameter markers in the SQL statement by
111
   *                      embedding question mark (?) characters at the
112
   *                      appropriate positions.
113
   *                      </p>
114
   *                      <p>
115
   *                      You should not add a terminating semicolon or \g
116
   *                      to the statement.
117
   *                      </p>
118
   *                      <p>
119
   *                      The markers are legal only in certain places in SQL statements.
120
   *                      For example, they are allowed in the VALUES() list of an INSERT statement
121
   *                      (to specify column values for a row), or in a comparison with a column in
122
   *                      a WHERE clause to specify a comparison value.
123
   *                      </p>
124
   *                      <p>
125
   *                      However, they are not allowed for identifiers (such as table or column names),
126
   *                      in the select list that names the columns to be returned by a SELECT statement),
127
   *                      or to specify both operands of a binary operator such as the =
128
   *                      equal sign. The latter restriction is necessary because it would be impossible
129
   *                      to determine the parameter type. In general, parameters are legal only in Data
130
   *                      Manipulation Language (DML) statements, and not in Data Definition Language
131
   *                      (DDL) statements.
132
   *                      </p>
133
   *
134
   * @return mixed true on success or false on failure.
135
   * @since 5.0
136
   */
137 2
  public function prepare($query)
138
  {
139 2
    $this->_sql = $query;
140
141 2
    if (!$this->_db->isReady()) {
142
      return false;
143
    }
144
145 2 View Code Duplication
    if (!$query || $query === '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
      $this->_debug->displayError('Can\'t prepare an empty Query', false);
147
148
      return false;
149
    }
150
151 2
    $bool = parent::prepare($query);
152
153 2
    if ($bool === false) {
154 1
      $this->_debug->displayError('Can\'t prepare Query: ' . $query . ' | ' . $this->error, false);
155 1
    }
156
157 2
    return true;
158
  }
159
}
160