1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Database;
9:
10: use Nette;
11: use PDO;
12: use PDOException;
13:
14:
15: 16: 17:
18: class Connection
19: {
20: use Nette\SmartObject;
21:
22:
23: public $onConnect;
24:
25:
26: public $onQuery;
27:
28:
29: private $params;
30:
31:
32: private $options;
33:
34:
35: private $driver;
36:
37:
38: private $preprocessor;
39:
40:
41: private $pdo;
42:
43:
44: public function __construct($dsn, $user = null, $password = null, array $options = null)
45: {
46: if (func_num_args() > 4) {
47: trigger_error(__METHOD__ . " fifth argument is deprecated, use \$options['driverClass'].", E_USER_DEPRECATED);
48: $options['driverClass'] = func_get_arg(4);
49: }
50: $this->params = [$dsn, $user, $password];
51: $this->options = (array) $options;
52:
53: if (empty($options['lazy'])) {
54: $this->connect();
55: }
56: }
57:
58:
59:
60: public function connect()
61: {
62: if ($this->pdo) {
63: return;
64: }
65:
66: try {
67: $this->pdo = new PDO($this->params[0], $this->params[1], $this->params[2], $this->options);
68: $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
69: } catch (PDOException $e) {
70: throw ConnectionException::from($e);
71: }
72:
73: $class = empty($this->options['driverClass'])
74: ? 'Nette\Database\Drivers\\' . ucfirst(str_replace('sql', 'Sql', $this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME))) . 'Driver'
75: : $this->options['driverClass'];
76: $this->driver = new $class($this, $this->options);
77: $this->preprocessor = new SqlPreprocessor($this);
78: $this->onConnect($this);
79: }
80:
81:
82:
83: public function reconnect()
84: {
85: $this->disconnect();
86: $this->connect();
87: }
88:
89:
90:
91: public function disconnect()
92: {
93: $this->pdo = null;
94: }
95:
96:
97:
98: public function getDsn()
99: {
100: return $this->params[0];
101: }
102:
103:
104:
105: public function getPdo()
106: {
107: $this->connect();
108: return $this->pdo;
109: }
110:
111:
112:
113: public function getSupplementalDriver()
114: {
115: $this->connect();
116: return $this->driver;
117: }
118:
119:
120: 121: 122: 123:
124: public function getInsertId($name = null)
125: {
126: try {
127: $res = $this->getPdo()->lastInsertId($name);
128: return $res === false ? '0' : $res;
129: } catch (PDOException $e) {
130: throw $this->driver->convertException($e);
131: }
132: }
133:
134:
135: 136: 137: 138: 139:
140: public function quote($string, $type = PDO::PARAM_STR)
141: {
142: try {
143: return $this->getPdo()->quote($string, $type);
144: } catch (PDOException $e) {
145: throw DriverException::from($e);
146: }
147: }
148:
149:
150:
151: public function beginTransaction()
152: {
153: $this->query('::beginTransaction');
154: }
155:
156:
157:
158: public function commit()
159: {
160: $this->query('::commit');
161: }
162:
163:
164:
165: public function rollBack()
166: {
167: $this->query('::rollBack');
168: }
169:
170:
171: 172: 173: 174: 175:
176: public function query($sql, ...$params)
177: {
178: list($sql, $params) = $this->preprocess($sql, ...$params);
179: try {
180: $result = new ResultSet($this, $sql, $params);
181: } catch (PDOException $e) {
182: $this->onQuery($this, $e);
183: throw $e;
184: }
185: $this->onQuery($this, $result);
186: return $result;
187: }
188:
189:
190: 191: 192: 193:
194: public function queryArgs($sql, array $params)
195: {
196: return $this->query($sql, ...$params);
197: }
198:
199:
200: 201: 202:
203: public function preprocess($sql, ...$params)
204: {
205: $this->connect();
206: return $params
207: ? $this->preprocessor->process(func_get_args())
208: : [$sql, []];
209: }
210:
211:
212:
213:
214:
215: 216: 217: 218: 219:
220: public function fetch($sql, ...$params)
221: {
222: return $this->query($sql, ...$params)->fetch();
223: }
224:
225:
226: 227: 228: 229: 230:
231: public function fetchField($sql, ...$params)
232: {
233: return $this->query($sql, ...$params)->fetchField();
234: }
235:
236:
237: 238: 239: 240: 241:
242: public function fetchPairs($sql, ...$params)
243: {
244: return $this->query($sql, ...$params)->fetchPairs();
245: }
246:
247:
248: 249: 250: 251: 252:
253: public function fetchAll($sql, ...$params)
254: {
255: return $this->query($sql, ...$params)->fetchAll();
256: }
257:
258:
259: 260: 261:
262: public static function literal($value, ...$params)
263: {
264: return new SqlLiteral($value, $params);
265: }
266: }
267: