PDODatabase::getOptions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 1
cts 1
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
namespace DAL;
3
4
use \Exception;
5
use \PDO;
6
use \PDOException;
7
use \PDOStatement;
8
use \DAL\Exceptions\DatabaseException;
9
10
class PDODatabase extends AbstractSQLDatabase
11
{
12
13 14
    private static function bindToStatement(PDOStatement $stmt, array $bindVariables)
14
    {
15 14
        if (count(array_filter(array_keys($bindVariables), 'is_string'))) {
16
            foreach ($bindVariables as $key => $variable) {
17
                $stmt->bindValue($key, $variable);
18
            }
19
        } else {
20 14
            $index = 0;
21 14
            $count = count($bindVariables);
22 14
            while ($index < $count) {
23 13
                $stmt->bindValue($index + 1, $bindVariables[$index]);
24 13
                $index++;
25 13
            }
26
        }
27 14
    }
28
29
    private $connection;
30
    private $dsn;
31
    private $username;
32
    private $password;
33
    private $options;
34
    private $defaults = [
35
        PDO::ATTR_STRINGIFY_FETCHES => true
36
    ];
37
38 24
    /**
39
     * Creates a new PDODatabase with the "Data Source Name", username, password, and extra options.
40 24
     *
41 24
     * The arguments MUST be compatiable with the PDO constructor.
42 24
     *
43 24
     * @param string      $dsn
44 24
     * @param string|null $username
45 24
     * @param string|null $password
46
     * @param array       $options
47
     */
48
    public function __construct($dsn, $username = null, $password = null, array $options = [])
49
    {
50 16
        $this->dsn      = $dsn;
51
        $this->username = $username;
52 16
        $this->password = $password;
53
        $this->options  = $options;
54 15
        parent::__construct();
55
    }
56
57
    /**
58
     * @return PDO|null
59
     */
60 19
    public function getConnection()
61
    {
62 19
        $this->initalizeConnection();
63
64
        return $this->connection;
65 2
    }
66
67 2
    /**
68 2
     * Gets the connection string for PDO.
69
     *
70
     * @return string
71
     */
72
    public function getConnectionString()
73 19
    {
74
        return $this->dsn;
75 19
    }
76
77
    /**
78 1
     * Returns the username for PDO.
79
     *
80 1
     * @return string|null
81 1
     */
82
    public function getUsername()
83
    {
84
        return $this->username;
85
    }
86 19
87
    /**
88 19
     * Returns the password for PDO.
89
     *
90
     * @return string|null
91 1
     */
92
    public function getPassword()
93 1
    {
94 1
        return $this->password;
95
    }
96
97
    /**
98
     * @return array
99 17
     */
100
    public function getOptions()
101 17
    {
102
        return $this->options;
103
    }
104
105
    /**
106
     * @return integer
107 2
     */
108
    public function lastIdCreated()
109 2
    {
110
        $this->initalizeConnection();
111
        return (int) $this->connection->lastInsertId();
112 1
    }
113
114 1
    /**
115 1
     * @param SqlStatementBuilder $statement
116
     * @param array               $options
117
     * @param bool                $returnResult
118
     * @return array[]|null
119
     *
120 1
     * @throws DatabaseException If there was an error connecting to the database.
121
     */
122 1
    protected function sendQueryToDatabase(SqlStatementBuilder $statement, array $options, $returnResult)
123 1
    {
124
        $compiled = self::compileQueriesAndBindings($statement, $options);
125
        $query    = $compiled[0];
126
        $bindings = $compiled[1];
127
128
        $this->initalizeConnection();
129
        try {
130
            $stmt = $this->getConnection()->prepare($query);
131
            if ($stmt !== false) {
132
                self::bindToStatement($stmt, $bindings);
133
                if ($stmt->execute()) {
134 14
                    if (0 !== $stmt->columnCount()) {
135
                        /* We need to return some data. */
136 14
                        $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
137 14
                        if ($data !== false) {
138 14
                            return $data;
139
                        }
140 14
                    } else {
141
                        return null;
142 14
                    }
143 14
                }
144 14
                $errorInfo = $stmt->errorInfo();
145 14
                $error     = $errorInfo[2];
146 14
147
                $message = 'Unable to query the database! Error: {' . $error . '} SQL: {'
148 10
                    . $query . '}';
149 10
                throw $this->logException(new DatabaseException($message));
150 10
            }
151
        } catch (PDOException $e) {
152
            $this->getLogger()->error($e);
153 4
            throw $this->logException(new DatabaseException(
154
                'Unable to execute query! ' . $e->getMessage(),
155
                0,
156
                $e
157
            ));
158
        }
159
        $errorInfo = $this->connection->errorInfo();
160
        $error     = $errorInfo[2];
161
        throw $this->logException(new DatabaseException(
162
            'Unable to prepare query! Error: {' . $error . '}'
163
        ));
164
    }
165
166
    private function initalizeConnection()
167
    {
168
        if ($this->connection === null) {
169
            try {
170
                $this->connection = new PDO(
171
                    $this->getConnectionString(),
172
                    $this->getUsername(),
173
                    $this->getPassword(),
174
                    $this->defaults + $this->getOptions()
175
                );
176
            } catch (PDOException $error) {
177
                $this->getLogger()->error($error);
178 16
                $this->connection = null;
179
                throw $this->logException(
180 16
                    new DatabaseException('Unable to connect to database!', 0, $error)
181
                );
182 16
            }
183 16
            $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
184 16
            $this->connection->setAttribute(PDO::ATTR_TIMEOUT, 5);
185 16
        }
186 16
    }
187
}
188