1: | <?php
|
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: |
|
11: |
|
12: | namespace Xmf\Database;
|
13: |
|
14: | use Xmf\Language;
|
15: |
|
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: |
|
34: | class Tables
|
35: | {
|
36: | |
37: | |
38: |
|
39: | protected $db;
|
40: |
|
41: | |
42: | |
43: |
|
44: | protected $databaseName;
|
45: |
|
46: | |
47: | |
48: |
|
49: | protected $tables;
|
50: |
|
51: | |
52: | |
53: |
|
54: | protected $queue;
|
55: |
|
56: | |
57: | |
58: |
|
59: | protected $lastError;
|
60: |
|
61: | |
62: | |
63: |
|
64: | protected $lastErrNo;
|
65: |
|
66: | |
67: | |
68: | |
69: |
|
70: | public function __construct()
|
71: | {
|
72: | Language::load('xmf');
|
73: |
|
74: | $this->db = \XoopsDatabaseFactory::getDatabaseConnection();
|
75: | $this->databaseName = XOOPS_DB_NAME;
|
76: | $this->resetQueue();
|
77: | }
|
78: |
|
79: | |
80: | |
81: | |
82: | |
83: | |
84: | |
85: |
|
86: | protected function name($table)
|
87: | {
|
88: | return $this->db->prefix($table);
|
89: | }
|
90: |
|
91: | |
92: | |
93: | |
94: | |
95: | |
96: | |
97: | |
98: | |
99: |
|
100: | public function addColumn($table, $column, $attributes)
|
101: | {
|
102: | $columnDef = array(
|
103: | 'name' => $column,
|
104: | 'attributes' => $attributes
|
105: | );
|
106: |
|
107: |
|
108: | if (isset($this->tables[$table])) {
|
109: | $tableDef = &$this->tables[$table];
|
110: |
|
111: | if (isset($tableDef['create']) && $tableDef['create']) {
|
112: | array_push($tableDef['columns'], $columnDef);
|
113: | } else {
|
114: | foreach ($tableDef['columns'] as $col) {
|
115: | if (strcasecmp($col['name'], $column) == 0) {
|
116: | return true;
|
117: | }
|
118: | }
|
119: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}`"
|
120: | . " ADD COLUMN `{$column}` {$columnDef['attributes']}";
|
121: | array_push($tableDef['columns'], $columnDef);
|
122: | }
|
123: | } else {
|
124: | return $this->tableNotEstablished();
|
125: | }
|
126: |
|
127: | return true;
|
128: | }
|
129: |
|
130: | |
131: | |
132: | |
133: | |
134: | |
135: | |
136: | |
137: | |
138: |
|
139: | public function addPrimaryKey($table, $column)
|
140: | {
|
141: | $columns = str_getcsv(str_replace(' ', '', $column));
|
142: | $columnList = '';
|
143: | $firstComma = '';
|
144: | foreach ($columns as $col) {
|
145: | $columnList .= "{$firstComma}`{$col}`";
|
146: | $firstComma = ', ';
|
147: | }
|
148: | if (isset($this->tables[$table])) {
|
149: | if (isset($this->tables[$table]['create']) && $this->tables[$table]['create']) {
|
150: | $this->tables[$table]['keys']['PRIMARY']['columns'] = $columnList;
|
151: | } else {
|
152: | $this->queue[] = "ALTER TABLE `{$this->tables[$table]['name']}` ADD PRIMARY KEY({$columnList})";
|
153: | }
|
154: | } else {
|
155: | return $this->tableNotEstablished();
|
156: | }
|
157: |
|
158: | return true;
|
159: | }
|
160: |
|
161: | |
162: | |
163: | |
164: | |
165: | |
166: | |
167: | |
168: | |
169: | |
170: | |
171: |
|
172: | public function addIndex($name, $table, $column, $unique = false)
|
173: | {
|
174: | $columns = str_getcsv($column);
|
175: | $columnList = '';
|
176: | $firstComma = '';
|
177: | foreach ($columns as $col) {
|
178: | $columnList .= $firstComma . $this->quoteIndexColumnName($col);
|
179: | $firstComma = ', ';
|
180: | }
|
181: | if (isset($this->tables[$table])) {
|
182: | if (isset($this->tables[$table]['create']) && $this->tables[$table]['create']) {
|
183: | $this->tables[$table]['keys'][$name]['columns'] = $columnList;
|
184: | $this->tables[$table]['keys'][$name]['unique'] = (bool) $unique;
|
185: | } else {
|
186: | $add = ($unique ? 'ADD UNIQUE INDEX' : 'ADD INDEX');
|
187: | $this->queue[] = "ALTER TABLE `{$this->tables[$table]['name']}` {$add} `{$name}` ({$columnList})";
|
188: | }
|
189: | } else {
|
190: | return $this->tableNotEstablished();
|
191: | }
|
192: |
|
193: | return true;
|
194: | }
|
195: |
|
196: | |
197: | |
198: | |
199: | |
200: | |
201: | |
202: | |
203: | |
204: |
|
205: | protected function quoteIndexColumnName($columnName)
|
206: | {
|
207: | $column = str_replace(' ', '', $columnName);
|
208: | $length = '';
|
209: |
|
210: | $lengthPosition = strpos($column, '(');
|
211: | if ($lengthPosition) {
|
212: | $length = ' ' . substr($column, $lengthPosition);
|
213: | $column = substr($column, 0, $lengthPosition);
|
214: | }
|
215: | $quotedName = "`{$column}`{$length}";
|
216: |
|
217: | return $quotedName;
|
218: | }
|
219: |
|
220: | |
221: | |
222: | |
223: | |
224: | |
225: | |
226: | |
227: |
|
228: | public function addTable($table)
|
229: | {
|
230: | if (isset($this->tables[$table])) {
|
231: | return true;
|
232: | }
|
233: | $tableDef = $this->getTable($table);
|
234: | if (is_array($tableDef)) {
|
235: | $this->tables[$table] = $tableDef;
|
236: |
|
237: | return true;
|
238: | } else {
|
239: | if ($tableDef === true) {
|
240: | $tableDef = array(
|
241: | 'name' => $this->name($table),
|
242: | 'options' => 'ENGINE=InnoDB',
|
243: | 'columns' => array(),
|
244: | 'keys' => array(),
|
245: | 'create' => true,
|
246: | );
|
247: | $this->tables[$table] = $tableDef;
|
248: |
|
249: | $this->queue[] = array('createtable' => $table);
|
250: |
|
251: | return true;
|
252: | } else {
|
253: | return false;
|
254: | }
|
255: | }
|
256: | }
|
257: |
|
258: | |
259: | |
260: | |
261: | |
262: | |
263: | |
264: |
|
265: | public function useTable($table)
|
266: | {
|
267: | if (isset($this->tables[$table])) {
|
268: | return true;
|
269: | }
|
270: | $tableDef = $this->getTable($table);
|
271: | if (is_array($tableDef)) {
|
272: | $this->tables[$table] = $tableDef;
|
273: | return true;
|
274: | }
|
275: | return false;
|
276: | }
|
277: |
|
278: | |
279: | |
280: | |
281: | |
282: | |
283: | |
284: | |
285: |
|
286: | public function getColumnAttributes($table, $column)
|
287: | {
|
288: |
|
289: | if (isset($this->tables[$table])) {
|
290: | $tableDef = $this->tables[$table];
|
291: |
|
292: | foreach ($tableDef['columns'] as $col) {
|
293: | if (strcasecmp($col['name'], $column) === 0) {
|
294: | return $col['attributes'];
|
295: | }
|
296: | }
|
297: | }
|
298: |
|
299: | return false;
|
300: | }
|
301: |
|
302: | |
303: | |
304: | |
305: | |
306: | |
307: | |
308: |
|
309: | public function getTableIndexes($table)
|
310: | {
|
311: |
|
312: | if (isset($this->tables[$table]) && isset($this->tables[$table]['keys'])) {
|
313: | return $this->tables[$table]['keys'];
|
314: | }
|
315: |
|
316: | return false;
|
317: | }
|
318: |
|
319: | |
320: | |
321: | |
322: | |
323: | |
324: | |
325: | |
326: | |
327: | |
328: |
|
329: | public function alterColumn($table, $column, $attributes, $newName = '')
|
330: | {
|
331: | if (empty($newName)) {
|
332: | $newName = $column;
|
333: | }
|
334: |
|
335: | if (isset($this->tables[$table])) {
|
336: | $tableDef = &$this->tables[$table];
|
337: |
|
338: | if (isset($tableDef['create']) && $tableDef['create']) {
|
339: |
|
340: | foreach ($tableDef['columns'] as &$col) {
|
341: | if (strcasecmp($col['name'], $column) == 0) {
|
342: | $col['name'] = $newName;
|
343: | $col['attributes'] = $attributes;
|
344: | break;
|
345: | }
|
346: | }
|
347: |
|
348: | return true;
|
349: | } else {
|
350: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` " .
|
351: | "CHANGE COLUMN `{$column}` `{$newName}` {$attributes} ";
|
352: |
|
353: | foreach ($tableDef['columns'] as &$col) {
|
354: | if (strcasecmp($col['name'], $column) == 0) {
|
355: | $col['name'] = $newName;
|
356: | $col['attributes'] = $attributes;
|
357: | break;
|
358: | }
|
359: | }
|
360: | }
|
361: | } else {
|
362: | return $this->tableNotEstablished();
|
363: | }
|
364: |
|
365: | return true;
|
366: | }
|
367: |
|
368: | |
369: | |
370: | |
371: | |
372: | |
373: | |
374: | |
375: | |
376: | |
377: |
|
378: | public function copyTable($table, $newTable, $withData = false)
|
379: | {
|
380: | if (isset($this->tables[$newTable])) {
|
381: | return true;
|
382: | }
|
383: | $tableDef = $this->getTable($table);
|
384: | $copy = $this->name($newTable);
|
385: | $original = $this->name($table);
|
386: |
|
387: | if (is_array($tableDef)) {
|
388: | $tableDef['name'] = $copy;
|
389: | if ($withData) {
|
390: | $this->queue[] = "CREATE TABLE `{$copy}` LIKE `{$original}` ;";
|
391: | $this->queue[] = "INSERT INTO `{$copy}` SELECT * FROM `{$original}` ;";
|
392: | } else {
|
393: | $tableDef['create'] = true;
|
394: | $this->queue[] = array('createtable' => $newTable);
|
395: | }
|
396: | $this->tables[$newTable] = $tableDef;
|
397: |
|
398: | return true;
|
399: | } else {
|
400: | return false;
|
401: | }
|
402: | }
|
403: |
|
404: | |
405: | |
406: | |
407: | |
408: | |
409: | |
410: | |
411: |
|
412: | public function dropColumn($table, $column)
|
413: | {
|
414: |
|
415: | if (isset($this->tables[$table])) {
|
416: | $tableDef = $this->tables[$table];
|
417: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` DROP COLUMN `{$column}`";
|
418: | } else {
|
419: | return $this->tableNotEstablished();
|
420: | }
|
421: |
|
422: | return true;
|
423: | }
|
424: |
|
425: | |
426: | |
427: | |
428: | |
429: | |
430: | |
431: | |
432: |
|
433: | public function dropIndex($name, $table)
|
434: | {
|
435: | if (isset($this->tables[$table])) {
|
436: | $tableDef = $this->tables[$table];
|
437: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` DROP INDEX `{$name}`";
|
438: | } else {
|
439: | return $this->tableNotEstablished();
|
440: | }
|
441: |
|
442: | return true;
|
443: | }
|
444: |
|
445: | |
446: | |
447: | |
448: | |
449: | |
450: | |
451: | |
452: |
|
453: | public function dropIndexes($table)
|
454: | {
|
455: |
|
456: | if (isset($this->tables[$table])) {
|
457: | $tableDef = &$this->tables[$table];
|
458: |
|
459: | if (isset($tableDef['create']) && $tableDef['create']) {
|
460: |
|
461: | foreach ($tableDef['keys'] as $keyName => $key) {
|
462: | if ($keyName !== 'PRIMARY') {
|
463: | unset($tableDef['keys'][$keyName]);
|
464: | }
|
465: | }
|
466: | } else {
|
467: |
|
468: | foreach ($tableDef['keys'] as $keyName => $key) {
|
469: | if ($keyName !== 'PRIMARY') {
|
470: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` DROP INDEX {$keyName}";
|
471: | }
|
472: | }
|
473: | }
|
474: | } else {
|
475: | return $this->tableNotEstablished();
|
476: | }
|
477: |
|
478: | return true;
|
479: | }
|
480: |
|
481: | |
482: | |
483: | |
484: | |
485: | |
486: | |
487: |
|
488: | public function dropPrimaryKey($table)
|
489: | {
|
490: | if (isset($this->tables[$table])) {
|
491: | $tableDef = $this->tables[$table];
|
492: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` DROP PRIMARY KEY ";
|
493: | } else {
|
494: | return $this->tableNotEstablished();
|
495: | }
|
496: |
|
497: | return true;
|
498: | }
|
499: |
|
500: | |
501: | |
502: | |
503: | |
504: | |
505: | |
506: |
|
507: | public function dropTable($table)
|
508: | {
|
509: | if (isset($this->tables[$table])) {
|
510: | $tableDef = $this->tables[$table];
|
511: | $this->queue[] = "DROP TABLE `{$tableDef['name']}` ";
|
512: | unset($this->tables[$table]);
|
513: | }
|
514: |
|
515: | return true;
|
516: | }
|
517: |
|
518: |
|
519: | |
520: | |
521: | |
522: | |
523: | |
524: | |
525: | |
526: |
|
527: | public function renameTable($table, $newName)
|
528: | {
|
529: | if (isset($this->tables[$table])) {
|
530: | $tableDef = $this->tables[$table];
|
531: | $newTable = $this->name($newName);
|
532: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` RENAME TO `{$newTable}`";
|
533: | $tableDef['name'] = $newTable;
|
534: | $this->tables[$newName] = $tableDef;
|
535: | unset($this->tables[$table]);
|
536: | } else {
|
537: | return $this->tableNotEstablished();
|
538: | }
|
539: |
|
540: | return true;
|
541: | }
|
542: |
|
543: | |
544: | |
545: | |
546: | |
547: | |
548: | |
549: | |
550: | |
551: |
|
552: | public function setTableOptions($table, $options)
|
553: | {
|
554: | if (isset($this->tables[$table])) {
|
555: | $tableDef = &$this->tables[$table];
|
556: |
|
557: | if (isset($tableDef['create']) && $tableDef['create']) {
|
558: | $tableDef['options'] = $options;
|
559: | return true;
|
560: | } else {
|
561: | $this->queue[] = "ALTER TABLE `{$tableDef['name']}` {$options} ";
|
562: | $tableDef['options'] = $options;
|
563: | return true;
|
564: | }
|
565: | } else {
|
566: | return $this->tableNotEstablished();
|
567: | }
|
568: | }
|
569: |
|
570: |
|
571: | |
572: | |
573: | |
574: | |
575: |
|
576: | public function resetQueue()
|
577: | {
|
578: | $this->tables = array();
|
579: | $this->queue = array();
|
580: | }
|
581: |
|
582: | |
583: | |
584: | |
585: | |
586: | |
587: | |
588: |
|
589: | public function executeQueue($force = false)
|
590: | {
|
591: | $this->expandQueue();
|
592: | foreach ($this->queue as &$ddl) {
|
593: | if (is_array($ddl)) {
|
594: | if (isset($ddl['createtable'])) {
|
595: | $ddl = $this->renderTableCreate($ddl['createtable']);
|
596: | }
|
597: | }
|
598: | $result = $this->execSql($ddl, $force);
|
599: | if (!$result) {
|
600: | $this->lastError = $this->db->error();
|
601: | $this->lastErrNo = $this->db->errno();
|
602: |
|
603: | return false;
|
604: | }
|
605: | }
|
606: |
|
607: | return true;
|
608: | }
|
609: |
|
610: |
|
611: | |
612: | |
613: | |
614: | |
615: | |
616: | |
617: | |
618: |
|
619: | public function delete($table, $criteria)
|
620: | {
|
621: | if (isset($this->tables[$table])) {
|
622: | $tableDef = $this->tables[$table];
|
623: | $where = '';
|
624: | if (is_scalar($criteria)) {
|
625: | $where = $criteria;
|
626: | } elseif (is_object($criteria)) {
|
627: |
|
628: | $where = $criteria->renderWhere();
|
629: | }
|
630: | $this->queue[] = "DELETE FROM `{$tableDef['name']}` {$where}";
|
631: | } else {
|
632: | return $this->tableNotEstablished();
|
633: | }
|
634: |
|
635: | return true;
|
636: | }
|
637: |
|
638: | |
639: | |
640: | |
641: | |
642: | |
643: | |
644: | |
645: | |
646: |
|
647: | public function insert($table, $columns, $quoteValue = true)
|
648: | {
|
649: | if (isset($this->tables[$table])) {
|
650: | $tableDef = $this->tables[$table];
|
651: | $colSql = '';
|
652: | $valSql = '';
|
653: | foreach ($tableDef['columns'] as $col) {
|
654: | $comma = empty($colSql) ? '' : ', ';
|
655: | if (isset($columns[$col['name']])) {
|
656: | $colSql .= "{$comma}`{$col['name']}`";
|
657: | $valSql .= $comma
|
658: | . ($quoteValue ? $this->db->quote($columns[$col['name']]) : $columns[$col['name']]);
|
659: | }
|
660: | }
|
661: | $sql = "INSERT INTO `{$tableDef['name']}` ({$colSql}) VALUES({$valSql})";
|
662: | $this->queue[] = $sql;
|
663: |
|
664: | return true;
|
665: | } else {
|
666: | return $this->tableNotEstablished();
|
667: | }
|
668: | }
|
669: |
|
670: | |
671: | |
672: | |
673: | |
674: | |
675: | |
676: | |
677: | |
678: | |
679: |
|
680: | public function update($table, $columns, $criteria, $quoteValue = true)
|
681: | {
|
682: | if (isset($this->tables[$table])) {
|
683: | $tableDef = $this->tables[$table];
|
684: | $where = '';
|
685: | if (is_scalar($criteria)) {
|
686: | $where = $criteria;
|
687: | } elseif (is_object($criteria)) {
|
688: |
|
689: | $where = $criteria->renderWhere();
|
690: | }
|
691: | $colSql = '';
|
692: | foreach ($tableDef['columns'] as $col) {
|
693: | $comma = empty($colSql) ? '' : ', ';
|
694: | if (isset($columns[$col['name']])) {
|
695: | $colSql .= "{$comma}`{$col['name']}` = "
|
696: | . ($quoteValue ? $this->db->quote($columns[$col['name']]) : $columns[$col['name']]);
|
697: | }
|
698: | }
|
699: | $sql = "UPDATE `{$tableDef['name']}` SET {$colSql} {$where}";
|
700: | $this->queue[] = $sql;
|
701: |
|
702: | return true;
|
703: | } else {
|
704: | return $this->tableNotEstablished();
|
705: | }
|
706: | }
|
707: |
|
708: | |
709: | |
710: | |
711: | |
712: | |
713: | |
714: |
|
715: | public function truncate($table)
|
716: | {
|
717: | if (isset($this->tables[$table])) {
|
718: | $tableDef = $this->tables[$table];
|
719: | $this->queue[] = "TRUNCATE TABLE `{$tableDef['name']}`";
|
720: | } else {
|
721: | return $this->tableNotEstablished();
|
722: | }
|
723: |
|
724: | return true;
|
725: | }
|
726: |
|
727: |
|
728: |
|
729: | |
730: | |
731: | |
732: | |
733: | |
734: | |
735: | |
736: | |
737: | |
738: |
|
739: | protected function renderTableCreate($table, $prefixed = false)
|
740: | {
|
741: | if (isset($this->tables[$table])) {
|
742: | $tableDef = $this->tables[$table];
|
743: | $tableName = ($prefixed ? $tableDef['name'] : $table);
|
744: | $sql = "CREATE TABLE `{$tableName}` (";
|
745: | $firstComma = '';
|
746: | foreach ($tableDef['columns'] as $col) {
|
747: | $sql .= "{$firstComma}\n `{$col['name']}` {$col['attributes']}";
|
748: | $firstComma = ',';
|
749: | }
|
750: | $keySql = '';
|
751: | foreach ($tableDef['keys'] as $keyName => $key) {
|
752: | if ($keyName === 'PRIMARY') {
|
753: | $keySql .= ",\n PRIMARY KEY ({$key['columns']})";
|
754: | } else {
|
755: | $unique = $key['unique'] ? 'UNIQUE ' : '';
|
756: | $keySql .= ",\n {$unique}KEY {$keyName} ({$key['columns']})";
|
757: | }
|
758: | }
|
759: | $sql .= $keySql;
|
760: | $sql .= "\n) {$tableDef['options']}";
|
761: |
|
762: | return $sql;
|
763: | } else {
|
764: | return $this->tableNotEstablished();
|
765: | }
|
766: | }
|
767: |
|
768: | |
769: | |
770: | |
771: | |
772: | |
773: | |
774: | |
775: | |
776: | |
777: | |
778: |
|
779: | protected function execSql($sql, $force = false)
|
780: | {
|
781: | if ($force) {
|
782: | $result = $this->db->queryF($sql);
|
783: | } else {
|
784: | $result = $this->db->query($sql);
|
785: | }
|
786: |
|
787: | if (!$result) {
|
788: | $this->lastError = $this->db->error();
|
789: | $this->lastErrNo = $this->db->errno();
|
790: | }
|
791: |
|
792: | return $result;
|
793: | }
|
794: |
|
795: | |
796: | |
797: | |
798: | |
799: | |
800: | |
801: |
|
802: | protected function fetch($result)
|
803: | {
|
804: | return $this->db->fetchArray($result);
|
805: | }
|
806: |
|
807: | |
808: | |
809: | |
810: | |
811: | |
812: | |
813: |
|
814: | protected function quoteDefaultClause($default)
|
815: | {
|
816: |
|
817: |
|
818: | if (null===$default) {
|
819: | return '';
|
820: | }
|
821: |
|
822: |
|
823: |
|
824: |
|
825: | if ($default === 'CURRENT_TIMESTAMP') {
|
826: | return ' DEFAULT CURRENT_TIMESTAMP ';
|
827: | }
|
828: |
|
829: |
|
830: | return " DEFAULT '{$default}' ";
|
831: | }
|
832: |
|
833: | |
834: | |
835: | |
836: | |
837: | |
838: | |
839: | |
840: |
|
841: | protected function getTable($table)
|
842: | {
|
843: | $tableDef = array();
|
844: |
|
845: | $sql = 'SELECT TABLE_NAME, ENGINE, CHARACTER_SET_NAME ';
|
846: | $sql .= ' FROM `INFORMATION_SCHEMA`.`TABLES` t, ';
|
847: | $sql .= ' `INFORMATION_SCHEMA`.`COLLATIONS` c ';
|
848: | $sql .= ' WHERE t.TABLE_SCHEMA = \'' . $this->databaseName . '\' ';
|
849: | $sql .= ' AND t.TABLE_NAME = \'' . $this->name($table) . '\' ';
|
850: | $sql .= ' AND t.TABLE_COLLATION = c.COLLATION_NAME ';
|
851: |
|
852: | $result = $this->execSql($sql);
|
853: | if (!$result) {
|
854: | return false;
|
855: | }
|
856: | $tableSchema = $this->fetch($result);
|
857: | if (empty($tableSchema)) {
|
858: | return true;
|
859: | }
|
860: | $tableDef['name'] = $tableSchema['TABLE_NAME'];
|
861: | $tableDef['options'] = 'ENGINE=' . $tableSchema['ENGINE'] . ' '
|
862: | . 'DEFAULT CHARSET=' . $tableSchema['CHARACTER_SET_NAME'];
|
863: |
|
864: | $sql = 'SELECT * ';
|
865: | $sql .= ' FROM `INFORMATION_SCHEMA`.`COLUMNS` ';
|
866: | $sql .= ' WHERE TABLE_SCHEMA = \'' . $this->databaseName . '\' ';
|
867: | $sql .= ' AND TABLE_NAME = \'' . $this->name($table) . '\' ';
|
868: | $sql .= ' ORDER BY `ORDINAL_POSITION` ';
|
869: |
|
870: | $result = $this->execSql($sql);
|
871: |
|
872: | while ($column = $this->fetch($result)) {
|
873: | $attributes = ' ' . $column['COLUMN_TYPE'] . ' '
|
874: | . (($column['IS_NULLABLE'] === 'NO') ? ' NOT NULL ' : '')
|
875: | . $this->quoteDefaultClause($column['COLUMN_DEFAULT'])
|
876: |
|
877: | . str_replace('DEFAULT_GENERATED ', '', $column['EXTRA']);
|
878: |
|
879: | $columnDef = array(
|
880: | 'name' => $column['COLUMN_NAME'],
|
881: | 'attributes' => $attributes
|
882: | );
|
883: |
|
884: | $tableDef['columns'][] = $columnDef;
|
885: | };
|
886: |
|
887: | $sql = 'SELECT `INDEX_NAME`, `SEQ_IN_INDEX`, `NON_UNIQUE`, ';
|
888: | $sql .= ' `COLUMN_NAME`, `SUB_PART` ';
|
889: | $sql .= ' FROM `INFORMATION_SCHEMA`.`STATISTICS` ';
|
890: | $sql .= ' WHERE TABLE_SCHEMA = \'' . $this->databaseName . '\' ';
|
891: | $sql .= ' AND TABLE_NAME = \'' . $this->name($table) . '\' ';
|
892: | $sql .= ' ORDER BY `INDEX_NAME`, `SEQ_IN_INDEX` ';
|
893: |
|
894: | $result = $this->execSql($sql);
|
895: |
|
896: | $lastKey = '';
|
897: | $keyCols = '';
|
898: | $keyUnique = false;
|
899: | while ($key = $this->fetch($result)) {
|
900: | if ($lastKey != $key['INDEX_NAME']) {
|
901: | if (!empty($lastKey)) {
|
902: | $tableDef['keys'][$lastKey]['columns'] = $keyCols;
|
903: | $tableDef['keys'][$lastKey]['unique'] = $keyUnique;
|
904: | }
|
905: | $lastKey = $key['INDEX_NAME'];
|
906: | $keyCols = $key['COLUMN_NAME'];
|
907: | if (!empty($key['SUB_PART'])) {
|
908: | $keyCols .= ' (' . $key['SUB_PART'] . ')';
|
909: | }
|
910: | $keyUnique = !$key['NON_UNIQUE'];
|
911: | } else {
|
912: | $keyCols .= ', ' . $key['COLUMN_NAME'];
|
913: | if (!empty($key['SUB_PART'])) {
|
914: | $keyCols .= ' (' . $key['SUB_PART'] . ')';
|
915: | }
|
916: | }
|
917: | };
|
918: | if (!empty($lastKey)) {
|
919: | $tableDef['keys'][$lastKey]['columns'] = $keyCols;
|
920: | $tableDef['keys'][$lastKey]['unique'] = $keyUnique;
|
921: | }
|
922: |
|
923: | return $tableDef;
|
924: | }
|
925: |
|
926: | |
927: | |
928: | |
929: | |
930: | |
931: | |
932: | |
933: |
|
934: | protected function expandQueue()
|
935: | {
|
936: | foreach ($this->queue as &$ddl) {
|
937: | if (is_array($ddl)) {
|
938: | if (isset($ddl['createtable'])) {
|
939: | $ddl = $this->renderTableCreate($ddl['createtable'], true);
|
940: | }
|
941: | }
|
942: | }
|
943: | }
|
944: |
|
945: | |
946: | |
947: | |
948: | |
949: |
|
950: | public function getLastError()
|
951: | {
|
952: | return $this->lastError;
|
953: | }
|
954: |
|
955: | |
956: | |
957: | |
958: | |
959: |
|
960: | public function getLastErrNo()
|
961: | {
|
962: | return $this->lastErrNo;
|
963: | }
|
964: |
|
965: | |
966: | |
967: | |
968: | |
969: |
|
970: | public function dumpTables()
|
971: | {
|
972: | return $this->tables;
|
973: | }
|
974: |
|
975: | |
976: | |
977: | |
978: | |
979: |
|
980: | public function dumpQueue()
|
981: | {
|
982: | $this->expandQueue();
|
983: |
|
984: | return $this->queue;
|
985: | }
|
986: |
|
987: | |
988: | |
989: | |
990: | |
991: | |
992: | |
993: |
|
994: | public function addToQueue($sql)
|
995: | {
|
996: | $this->queue[] = $sql;
|
997: | }
|
998: |
|
999: | |
1000: | |
1001: | |
1002: | |
1003: |
|
1004: | protected function tableNotEstablished()
|
1005: | {
|
1006: | $this->lastError = _DB_XMF_TABLE_IS_NOT_DEFINED;
|
1007: | $this->lastErrNo = -1;
|
1008: | return false;
|
1009: | }
|
1010: | }
|
1011: | |