1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Luxor_Driver_sql extends Luxor_Driver {
15:
16: 17: 18: 19: 20:
21: var $_params = array();
22:
23: 24: 25: 26: 27:
28: var $_db;
29:
30: 31: 32: 33: 34:
35: var $_source;
36:
37: 38: 39: 40: 41:
42: var $_connected = false;
43:
44: 45: 46: 47: 48:
49: var $_symcache = array();
50:
51: 52: 53: 54: 55:
56: var $_decIdcache = array();
57:
58: 59: 60: 61: 62: 63:
64: function Luxor_Driver_sql($source, $params = array())
65: {
66: $this->_source = $source;
67: $this->_params = $params;
68: }
69:
70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82:
83: function index($symname, $fileId, $line, $langid, $type)
84: {
85: $this->_connect();
86:
87: $symid = $this->symid($symname);
88: if (is_a($symid, 'PEAR_Error')) {
89: return $symid;
90: }
91:
92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102:
103:
104: $query = 'INSERT INTO luxor_indexes (symid, fileid, line, declid)' .
105: ' VALUES (?, ?, ?, ?)';
106: $values = array($symid, $fileId, $line, $this->getDecId($langid, $type));
107: return $this->_db->query($query, $values);
108: }
109:
110: 111: 112: 113: 114: 115: 116: 117: 118: 119:
120: function reference($symname, $fileId, $line)
121: {
122: $this->_connect();
123:
124: $result = $this->_db->query('INSERT INTO luxor_usage (fileid, line, symid) VALUES (?, ?, ?)',
125: array($fileId, $line, $this->symid($symname)));
126: return $result;
127: }
128:
129: 130: 131: 132: 133: 134: 135: 136:
137: function fileId($filename, $tag = '')
138: {
139: static $files = array();
140:
141:
142: if (isset($files[$filename])) {
143: return $files[$filename];
144: }
145:
146: $this->_connect();
147:
148:
149: $query = 'SELECT fileid FROM luxor_files' .
150: ' WHERE tag = ? AND source = ? AND filename = ?';
151: $values = array($tag, $this->_source, $filename);
152:
153: $fileId = $this->_db->getOne($query, $values);
154: if (empty($fileId) || is_a($fileId, 'PEAR_Error')) {
155: return false;
156: }
157: $files[$filename] = $fileId;
158:
159: return $fileId;
160: }
161:
162: 163: 164: 165: 166: 167: 168: 169: 170:
171: function createFileId($filename, $tag = '', $lastmodified)
172: {
173: $this->_connect();
174:
175: $fileId = $this->_db->nextId('luxor_files');
176: if (is_a($fileId, 'PEAR_Error')) {
177: return $fileId;
178: }
179:
180:
181: $query = 'INSERT INTO luxor_files (fileid, filename, source, tag, lastmodified) VALUES (?, ?, ?, ?, ?)';
182: $values = array((int)$fileId,
183: $filename,
184: $this->_source,
185: $tag,
186: $lastmodified);
187:
188: $result = $this->_db->query($query, $values);
189: if (is_a($result, 'PEAR_Error')) {
190: return $result;
191: }
192:
193: return $fileId;
194: }
195:
196: 197: 198: 199: 200: 201: 202:
203: function symid($symname)
204: {
205:
206: if (!isset($this->_symcache[$symname])) {
207: $this->_connect();
208:
209: $query = 'SELECT symid FROM luxor_symbols' .
210: ' WHERE source = ? AND symname = ?';
211: $values = array($this->_source, $symname);
212: $symid = $this->_db->getOne($query, $values);
213: if (is_null($symid) || is_a($symid, 'PEAR_Error')) {
214:
215: $symid = $this->_db->nextId('luxor_symbols');
216: if (is_a($symid, 'PEAR_Error')) {
217: return $symid;
218: }
219: $result = $this->_db->query('INSERT INTO luxor_symbols (symid, symname, source) VALUES (?, ?, ?)',
220: array((int)$symid, $symname, $this->_source));
221: if (is_a($result, 'PEAR_Error')) {
222: return $result;
223: }
224: }
225: $this->_symcache[$symname] = $symid;
226: }
227:
228: return $this->_symcache[$symname];
229: }
230:
231: 232: 233: 234: 235: 236: 237:
238: function symname($symid)
239: {
240:
241: $this->_connect();
242:
243: if (in_array($symid, $this->_symcache)) {
244: return array_key($symid, $this->_symcache);
245: }
246:
247: $query = 'SELECT symname FROM luxor_symbols WHERE symid = ?';
248: $values = array($symid);
249: $symname = $this->_db->getOne($query, $values);
250: $this->_symcache[$symname] = $symid;
251:
252: return $symname;
253: }
254:
255: 256: 257: 258: 259: 260: 261:
262: function isSymbol($symname, $altsources = array())
263: {
264: if (!isset($this->_symcache[$symname])) {
265: $this->_connect();
266:
267: $altsql = '';
268: $altvalues = array();
269: if (!is_array($altsources)) {
270: $altsources = array($altsources);
271: }
272: foreach ($altsources as $source) {
273: $altsql .= ' OR source = ?';
274: $altvalues[] = $source;
275: }
276:
277: array_unshift($altvalues, $this->_source);
278: $values = $altvalues;
279: $values[] = $symname;
280:
281: $symid = $this->_db->getOne('SELECT symid FROM luxor_symbols' .
282: ' WHERE (source = ?' . $altsql . ')' .
283: ' AND symname = ?',
284: $values);
285: $this->_symcache[$symname] = $symid;
286: }
287:
288: return $this->_symcache[$symname];
289: }
290:
291: 292: 293: 294: 295: 296: 297: 298: 299:
300: function toIndex($fileId)
301: {
302: $this->_connect();
303:
304: $status = $this->_db->getOne('SELECT status FROM luxor_status' .
305: ' WHERE fileid = ?',
306: array($fileId));
307: if (empty($status)) {
308: $this->_db->query('INSERT INTO luxor_status (fileid, status)' .
309: ' VALUES (?, 0)',
310: array($fileId + 0));
311: }
312: $query = 'UPDATE luxor_status SET status = 1' .
313: ' WHERE fileid = ? AND status <= 0';
314: $values = array($fileId);
315: return $this->_db->query($query, $values);
316: }
317:
318: 319: 320: 321: 322: 323: 324: 325: 326:
327: function toReference($fileId)
328: {
329: $this->_connect();
330:
331: $query = 'UPDATE luxor_status SET status = 2' .
332: ' WHERE fileid = ? AND status <= 1';
333: $values = array($fileId);
334: return $this->_db->query($query, $values);
335: }
336:
337: 338: 339: 340: 341: 342: 343:
344: function getLastModified($filename)
345: {
346: static $lastModified;
347:
348: if (isset($lastModified[$filename])) {
349: return $lastModified[$filename];
350: }
351:
352: $this->_connect();
353: $query = 'SELECT lastmodified FROM luxor_files' .
354: ' WHERE source = ? AND filename = ?';
355: $values = array($this->_source, $filename);
356: $res = $this->_db->getOne($query, $values);
357: $lastModified[$filename] = is_a($res, 'PEAR_Error') ? 0 : $res;
358:
359: return $lastModified[$filename];
360: }
361:
362: 363: 364: 365: 366: 367: 368:
369: function clearCache()
370: {
371: $this->_symcache = array();
372: }
373:
374: 375: 376: 377: 378: 379:
380: function clearIndex()
381: {
382: $this->_connect();
383:
384: $this->_db->query('DELETE FROM luxor_declarations');
385: $this->_db->query('DELETE FROM luxor_files');
386: $this->_db->query('DELETE FROM luxor_indexes');
387: $this->_db->query('DELETE FROM luxor_status');
388: $this->_db->query('DELETE FROM luxor_symbols');
389: $this->_db->query('DELETE FROM luxor_usage');
390: }
391:
392: 393: 394: 395: 396: 397: 398: 399:
400: function getDecId($lang, $string)
401: {
402: $this->_connect();
403:
404: if (!isset($this->_decIdcache[$lang])) {
405: $this->_decIdcache[$lang] = array();
406: }
407:
408: if (!isset($this->_decIdcache[$lang][$string])) {
409: $query = 'SELECT declid FROM luxor_declarations' .
410: ' WHERE langid = ? AND declaration = ?';
411: $values = array($lang, $string);
412: $decId = $this->_db->getOne($query, $values);
413: if (is_null($decId) || is_a($decId, 'PEAR_Error')) {
414:
415: $decId = $this->_db->nextId('luxor_declarations');
416: if (is_a($decId, 'PEAR_Error')) {
417: return $decId;
418: }
419: $this->_db->query('INSERT INTO luxor_declarations (declid, langid, declaration)' .
420: ' VALUES (?, ?, ?)',
421: array((int)$decId, $lang, $string));
422: }
423: $this->_decIdcache[$lang][$string] = $decId;
424: }
425:
426: return $this->_decIdcache[$lang][$string];
427: }
428:
429: 430: 431: 432: 433: 434: 435: 436: 437:
438: function getIndex($symid, $tag = '')
439: {
440: $this->_connect();
441: $query = 'SELECT filename, line, declaration FROM ' .
442: 'luxor_files, luxor_indexes, luxor_declarations WHERE ' .
443: 'luxor_files.fileid = luxor_indexes.fileid AND ' .
444: 'luxor_indexes.declid = luxor_declarations.declid AND ' .
445: 'luxor_indexes.symid = ? AND ' .
446: 'luxor_files.tag = ? AND ' .
447: 'luxor_files.source = ?';
448: $values = array((int)$symid, $tag, $this->_source);
449:
450: return $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC);
451: }
452:
453: 454: 455: 456: 457: 458: 459: 460:
461: function getReference($symid, $tag = '')
462: {
463: $this->_connect();
464: $query = 'SELECT filename, line FROM ' .
465: 'luxor_usage, luxor_files WHERE ' .
466: 'luxor_usage.fileid = luxor_files.fileid AND ' .
467: 'luxor_usage.symid = ? AND ' .
468: 'luxor_files.tag = ? AND ' .
469: 'luxor_files.source = ?';
470: $values = array((int)$symid, $tag, $this->_source);
471:
472: return $this->_db->getAll($query, $values, DB_FETCHMODE_ASSOC);
473: }
474:
475: 476: 477: 478: 479: 480: 481:
482: function searchSymbols($symbol)
483: {
484: $this->_connect();
485: $query = 'SELECT symid, symid FROM luxor_symbols WHERE symname LIKE ?';
486: $values = array($symbol . '%');
487:
488: return $this->_db->getAssoc($query, false, $values);
489: }
490:
491: 492: 493: 494: 495: 496: 497:
498: function getSourceBySymbol($symid)
499: {
500: $this->_connect();
501:
502: return $this->_db->getOne('SELECT source FROM luxor_symbols' .
503: ' WHERE symid = ?',
504: array($symid));
505: }
506:
507: 508: 509: 510: 511:
512: function _connect()
513: {
514: if (!$this->_connected) {
515: $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'luxor', 'storage');
516: $this->_connected = true;
517: }
518:
519: return true;
520: }
521:
522: }
523: