Completed
Push — master ( 621c80...c2185a )
by Vitaly
02:34
created

Database::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 7
rs 9.4286
cc 1
eloc 5
nc 1
nop 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A Database::quote() 0 4 1
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: egorov
5
 * Date: 09.05.2015
6
 * Time: 13:05
7
 */
8
namespace samsonframework\orm;
9
10
/**
11
 * Class Database
12
 * @package samsonframework\orm
13
 */
14
class Database
15
{
16
    /** @var \PDO Database driver */
17
    protected $driver;
18
19
    /** @var string Database name */
20
    protected $database;
21
22
    /** @var int Amount of milliseconds spent on queries */
23
    protected $elapsed;
24
25
    /** @var int Amount queries executed */
26
    protected $count;
27
28
    /**
29
     * Connect to a database using driver with parameters
30
     * @param string $database Database name
31
     * @param string $username Database username
32
     * @param string $password Database password
33
     * @param string $host Database host(localhost by default)
34
     * @param int $port Database port(3306 by default)
35
     * @param string $driver Database driver for interaction(MySQL by default)
36
     * @param string $charset Database character set
37
     * @return bool True if connection to database was successful
38
     */
39
    public function connect(
40
        $database,
41
        $username,
42
        $password,
43
        $host = 'localhost',
44
        $port = 3306,
45
        $driver = 'mysql',
46
        $charset = 'utf8'
47
    ) {
48
        // If we have not connected yet
49
        if (!isset($this->driver)) {
50
            $this->database = $database;
51
52
            // Check if configured database exists
53
            $this->driver = new PDO($host, $database, $username, $password, $charset, $port, $driver);
0 ignored issues
show
Documentation Bug introduced by
It seems like new \samsonframework\orm...harset, $port, $driver) of type object<samsonframework\orm\PDO> is incompatible with the declared type object<PDO> of property $driver.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
54
55
            // Set correct encodings
56
            $this->query("set character_set_client='utf8'");
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\orm\Database::query() has been deprecated with message: Use execute()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
57
            $this->query("set character_set_results='utf8'");
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\orm\Database::query() has been deprecated with message: Use execute()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
58
            $this->query("set collation_connection='utf8_general_ci'");
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\orm\Database::query() has been deprecated with message: Use execute()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
59
        }
60
    }
61
62
    /**
63
     * Get database name
64
     * @return string
65
     */
66
    public function database()
67
    {
68
        return $this->database;
69
    }
70
71
    /**
72
     * High-level database query executor
73
     * @param string $sql SQL statement
74
     * @return mixed Database query result
75
     * @deprecated Use execute()
76
     */
77
    public function query($sql)
78
    {
79
        return $this->execute($sql);
80
    }
81
82
83
84
    /**
85
     * Intreal error beautifier
86
     * @param \Exception $exception
87
     * @param $sql
88
     */
89
    private function outputError(\Exception $exception, $sql, $text = 'Error executing database query:')
90
    {
91
        echo("\n" . '<div style="font-size:12px; position:relative; background:red; z-index:9999999;">'
92
            .'<div style="padding:4px 10px;">'.$text.'</div>'
93
            .'<div style="padding:0px 10px;">['.htmlspecialchars($exception->getMessage()).']</div>'
94
            .'<textarea style="display:block; width:100%; min-height:100px;">'.$sql . '</textarea></div>');
95
    }
96
97
    /**
98
     * Proxy function for executing database fetching logic with exception,
99
     * error, profile handling
100
     * @param callback $fetcher Callback for fetching
101
     * @return mixed Fetching function result
102
     */
103
    private function executeFetcher($fetcher, $sql)
104
    {
105
        $result = array();
106
107
        if (isset($this->driver)) {
108
            // Store timestamp
109
            $tsLast = microtime(true);
110
111
            try { // Call fetcher
112
                // Get argument and remove first one
113
                $args = func_get_args();
114
                array_shift($args);
115
116
                // Proxy calling of fetcher function with passing parameters
117
                $result = call_user_func_array($fetcher, $args);
118
            } catch (\PDOException $exception) {
119
                $this->outputError($exception, $sql, 'Error executing ['.$fetcher.']');
120
            }
121
122
            // Store queries count
123
            $this->count++;
124
125
            // Count elapsed time
126
            $this->elapsed += microtime(true) - $tsLast;
127
        }
128
129
        return $result;
130
    }
131
132
    /**
133
     * High-level database query executor
134
     * @param string $sql SQL statement
135
     * @return mixed Database query result
136
     */
137
    private function innerQuery($sql)
138
    {
139
        try {
140
            // Perform database query
141
            return $this->driver->prepare($sql)->execute();
142
        } catch (\PDOException $e) {
143
            $this->outputError($e, $sql);
144
        }
145
146
        return null;
147
    }
148
149
    /**
150
     * Retrieve array of records from a database, if $className is passed method
151
     * will try to create an object of that type. If request has failed than
152
     * method will return empty array of stdClass all arrays regarding to $className is
153
     * passed or not.
154
     *
155
     * @param string $sql SQL statement
156
     * @return array Collection of arrays or objects
157
     */
158
    private function innerFetch($sql, $className = null)
159
    {
160
        try {
161
            // Perform database query
162
            if (!isset($className)) { // Return array
163
                return $this->driver->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
164
            } else { // Create object of passed class name
165
                return $this->driver->query($sql)->fetchAll(\PDO::FETCH_CLASS, $className, array(&$this));
166
            }
167
        } catch (\PDOException $e) {
168
            $this->outputError($e, $sql, 'Fetching database records:');
169
        }
170
171
        return array();
172
    }
173
174
    /**
175
     * Special accelerated function to retrieve db record fields instead of objects
176
     *
177
     * @param string $sql SQL statement
178
     * @param int $columnIndex Needed column index
179
     *
180
     * @return array Database records column value collection
181
     */
182
    private function innerFetchColumn($sql, $columnIndex)
183
    {
184
        try {
185
            // Perform database query
186
            return $this->driver->query($sql)->fetchAll(\PDO::FETCH_COLUMN, $columnIndex);
187
        } catch (\PDOException $e) {
188
            $this->outputError($e, $sql, 'Error fetching records column values:');
189
        }
190
191
        return array();
192
    }
193
194
    /**
195
     * High-level database query executor
196
     * @param string $sql SQL statement
197
     * @return mixed Database query result
198
     */
199
    public function execute($sql)
200
    {
201
        return $this->executeFetcher(array($this, 'innerQuery'), $sql);
202
    }
203
204
    /**
205
     * Retrieve array of records from a database, if $className is passed method
206
     * will try to create an object of that type. If request has failed than
207
     * method will return empty array of stdClass all arrays regarding to $className is
208
     * passed or not.
209
     *
210
     * @param string $sql SQL statement
211
     * @return array Collection of arrays or objects
212
     */
213
    public function fetch($sql)
214
    {
215
        return $this->executeFetcher(array($this, 'innerFetch'), $sql);
216
    }
217
218
    /**
219
     * Special accelerated function to retrieve db record fields instead of objects
220
     * TODO: Change to be independent of query and class name, just SQL, this SQL
221
     * should only have one column in SELECT part and then we do not need parameter
222
     * for this as we can always take 0.
223
     *
224
     * @param string $className
225
     * @param mixed $query
226
     * @param string $field
227
     *
228
     * @return array
229
     */
230
    public function fetchColumn($className, $query, $field)
231
    {
232
        // Get SQL
233
        $sql = $this->prepareSQL($className, $query);
0 ignored issues
show
Bug introduced by
The method prepareSQL() does not seem to exist on object<samsonframework\orm\Database>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
234
235
        // TODO: Remove old attributes retrieval
236
        // Get table column index by its name
237
        $columnIndex = array_search($field, array_values($className::$_table_attributes));
238
239
        return $this->executeFetcher(array($this, 'innerFetchColumn'), $sql, $columnIndex);
240
    }
241
242
    /**
243
     * Quote variable for security reasons.
244
     *
245
     * @param string $value
246
     * @return string Quoted value
247
     */
248
    protected function quote($value)
249
    {
250
        return $this->driver->quote($value);
251
    }
252
}
253