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