| 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: | |