1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19:
20: class NConnection extends PDO
21: {
22:
23: private $driver;
24:
25:
26: private $preprocessor;
27:
28:
29: public $databaseReflection;
30:
31:
32: public $cache;
33:
34:
35: public $substitutions = array();
36:
37:
38: public $onQuery;
39:
40:
41:
42: public function __construct($dsn, $username = NULL, $password = NULL, array $options = NULL)
43: {
44: parent::__construct($dsn, $username, $password, $options);
45: $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
46: $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('NStatement', array($this)));
47:
48: $class = 'NPdo' . $this->getAttribute(PDO::ATTR_DRIVER_NAME) . 'Driver';
49: if (class_exists($class)) {
50: $this->driver = new $class($this, (array) $options);
51: }
52:
53: $this->preprocessor = new NSqlPreprocessor($this);
54:
55: $this->databaseReflection = new NDatabaseReflection; 56:
57: if (!NDebug::$productionMode) {
58: NDebug::addPanel($panel = new NDatabasePanel($dsn));
59: $this->onQuery[] = callback($panel, 'logQuery');
60: }
61: }
62:
63:
64:
65:
66: public function getSupplementalDriver()
67: {
68: return $this->driver;
69: }
70:
71:
72:
73: 74: 75: 76: 77: 78:
79: public function query($statement)
80: {
81: $args = func_get_args();
82: return $this->queryArgs(array_shift($args), $args);
83: }
84:
85:
86:
87: 88: 89: 90: 91: 92:
93: public function exec($statement)
94: {
95: $args = func_get_args();
96: return $this->queryArgs(array_shift($args), $args)->rowCount();
97: }
98:
99:
100:
101: 102: 103: 104: 105:
106: public function queryArgs($statement, $params)
107: {
108: foreach ($params as $value) {
109: if (is_array($value) || is_object($value)) {
110: $need = TRUE; break;
111: }
112: }
113: if (isset($need) || strpos($statement, ':') !== FALSE && $this->preprocessor !== NULL) {
114: list($statement, $params) = $this->preprocessor->process($statement, $params);
115: }
116:
117: return $this->prepare($statement)->execute($params);
118: }
119:
120:
121:
122:
123:
124:
125:
126: 127: 128: 129: 130: 131:
132: public function fetch($args)
133: {
134: $args = func_get_args();
135: return $this->queryArgs(array_shift($args), $args)->fetch();
136: }
137:
138:
139:
140: 141: 142: 143: 144: 145:
146: public function fetchColumn($args)
147: {
148: $args = func_get_args();
149: return $this->queryArgs(array_shift($args), $args)->fetchColumn();
150: }
151:
152:
153:
154: 155: 156: 157: 158: 159:
160: public function fetchPairs($args)
161: {
162: $args = func_get_args();
163: return $this->queryArgs(array_shift($args), $args)->fetchPairs();
164: }
165:
166:
167:
168: 169: 170: 171: 172: 173:
174: public function fetchAll($args)
175: {
176: $args = func_get_args();
177: return $this->queryArgs(array_shift($args), $args)->fetchAll();
178: }
179:
180:
181:
182:
183:
184:
185:
186: 187: 188: 189: 190:
191: public function table($table)
192: {
193: return new NTableSelection($table, $this);
194: }
195:
196:
197:
198:
199:
200:
201:
202: 203: 204: 205: 206:
207: public function loadFile($file)
208: {
209: @set_time_limit(0); 210:
211: $handle = @fopen($file, 'r'); 212: if (!$handle) {
213: throw new FileNotFoundException("Cannot open file '$file'.");
214: }
215:
216: $count = 0;
217: $sql = '';
218: while (!feof($handle)) {
219: $s = fgets($handle);
220: $sql .= $s;
221: if (substr(rtrim($s), -1) === ';') {
222: parent::exec($sql); 223: $sql = '';
224: $count++;
225: }
226: }
227: fclose($handle);
228: return $count;
229: }
230:
231:
232:
233: 234: 235: 236: 237:
238: public static function highlightSql($sql)
239: {
240: static $keywords1 = 'SELECT|UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE';
241: static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|TRUE|FALSE';
242:
243: 244: $sql = " $sql ";
245: $sql = preg_replace("#(?<=[\\s,(])($keywords1)(?=[\\s,)])#i", "\n\$1", $sql);
246:
247: 248: $sql = preg_replace('#[ \t]{2,}#', " ", $sql);
249:
250: $sql = wordwrap($sql, 100);
251: $sql = preg_replace("#([ \t]*\r?\n){2,}#", "\n", $sql);
252:
253: 254: $sql = htmlSpecialChars($sql);
255: $sql = preg_replace_callback("#(/\\*.+?\\*/)|(\\*\\*.+?\\*\\*)|(?<=[\\s,(])($keywords1)(?=[\\s,)])|(?<=[\\s,(=])($keywords2)(?=[\\s,)=])#is", create_function('$matches', '
256: if (!empty($matches[1])) // comment
257: return \'<em style="color:gray">\' . $matches[1] . \'</em>\';
258:
259: if (!empty($matches[2])) // error
260: return \'<strong style="color:red">\' . $matches[2] . \'</strong>\';
261:
262: if (!empty($matches[3])) // most important keywords
263: return \'<strong style="color:blue">\' . $matches[3] . \'</strong>\';
264:
265: if (!empty($matches[4])) // other keywords
266: return \'<strong style="color:green">\' . $matches[4] . \'</strong>\';
267: '), $sql);
268:
269: return '<pre class="dump">' . trim($sql) . "</pre>\n";
270: }
271:
272:
273:
274:
275:
276:
277:
278: 279: 280:
281: public function getReflection()
282: {
283: return new NClassReflection($this);
284: }
285:
286:
287:
288: public function __call($name, $args)
289: {
290: return NObjectMixin::call($this, $name, $args);
291: }
292:
293:
294:
295: public function &__get($name)
296: {
297: return NObjectMixin::get($this, $name);
298: }
299:
300:
301:
302: public function __set($name, $value)
303: {
304: return NObjectMixin::set($this, $name, $value);
305: }
306:
307:
308:
309: public function __isset($name)
310: {
311: return NObjectMixin::has($this, $name);
312: }
313:
314:
315:
316: public function __unset($name)
317: {
318: NObjectMixin::remove($this, $name);
319: }
320:
321: }
322: