[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package acp 5 * @version $Id$ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * @ignore 13 */ 14 if (!defined('IN_PHPBB')) 15 { 16 exit; 17 } 18 19 /** 20 * @package acp 21 */ 22 class acp_database 23 { 24 var $db_tools; 25 var $u_action; 26 27 function main($id, $mode) 28 { 29 global $cache, $db, $user, $auth, $template, $table_prefix; 30 global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; 31 32 if (!class_exists('phpbb_db_tools')) 33 { 34 require($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); 35 } 36 $this->db_tools = new phpbb_db_tools($db); 37 38 $user->add_lang('acp/database'); 39 40 $this->tpl_name = 'acp_database'; 41 $this->page_title = 'ACP_DATABASE'; 42 43 $action = request_var('action', ''); 44 $submit = (isset($_POST['submit'])) ? true : false; 45 46 $template->assign_vars(array( 47 'MODE' => $mode 48 )); 49 50 switch ($mode) 51 { 52 case 'backup': 53 54 $this->page_title = 'ACP_BACKUP'; 55 56 switch ($action) 57 { 58 case 'download': 59 $type = request_var('type', ''); 60 $table = array_intersect($this->db_tools->sql_list_tables(), request_var('table', array(''))); 61 $format = request_var('method', ''); 62 $where = request_var('where', ''); 63 64 if (!sizeof($table)) 65 { 66 trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); 67 } 68 69 $store = $download = $structure = $schema_data = false; 70 71 if ($where == 'store_and_download' || $where == 'store') 72 { 73 $store = true; 74 } 75 76 if ($where == 'store_and_download' || $where == 'download') 77 { 78 $download = true; 79 } 80 81 if ($type == 'full' || $type == 'structure') 82 { 83 $structure = true; 84 } 85 86 if ($type == 'full' || $type == 'data') 87 { 88 $schema_data = true; 89 } 90 91 @set_time_limit(1200); 92 @set_time_limit(0); 93 94 $time = time(); 95 96 $filename = 'backup_' . $time . '_' . unique_id(); 97 switch ($db->sql_layer) 98 { 99 case 'mysqli': 100 case 'mysql4': 101 case 'mysql': 102 $extractor = new mysql_extractor($download, $store, $format, $filename, $time); 103 break; 104 105 case 'sqlite': 106 $extractor = new sqlite_extractor($download, $store, $format, $filename, $time); 107 break; 108 109 case 'postgres': 110 $extractor = new postgres_extractor($download, $store, $format, $filename, $time); 111 break; 112 113 case 'oracle': 114 $extractor = new oracle_extractor($download, $store, $format, $filename, $time); 115 break; 116 117 case 'mssql': 118 case 'mssql_odbc': 119 case 'mssqlnative': 120 $extractor = new mssql_extractor($download, $store, $format, $filename, $time); 121 break; 122 123 case 'firebird': 124 $extractor = new firebird_extractor($download, $store, $format, $filename, $time); 125 break; 126 } 127 128 $extractor->write_start($table_prefix); 129 130 foreach ($table as $table_name) 131 { 132 // Get the table structure 133 if ($structure) 134 { 135 $extractor->write_table($table_name); 136 } 137 else 138 { 139 // We might wanna empty out all that junk :D 140 switch ($db->sql_layer) 141 { 142 case 'sqlite': 143 case 'firebird': 144 $extractor->flush('DELETE FROM ' . $table_name . ";\n"); 145 break; 146 147 case 'mssql': 148 case 'mssql_odbc': 149 case 'mssqlnative': 150 $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n"); 151 break; 152 153 case 'oracle': 154 $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n"); 155 break; 156 157 default: 158 $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n"); 159 break; 160 } 161 } 162 163 // Data 164 if ($schema_data) 165 { 166 $extractor->write_data($table_name); 167 } 168 } 169 170 $extractor->write_end(); 171 172 add_log('admin', 'LOG_DB_BACKUP'); 173 174 if ($download == true) 175 { 176 exit; 177 } 178 179 trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action)); 180 break; 181 182 default: 183 $tables = $this->db_tools->sql_list_tables(); 184 asort($tables); 185 foreach ($tables as $table_name) 186 { 187 if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0) 188 { 189 $template->assign_block_vars('tables', array( 190 'TABLE' => $table_name 191 )); 192 } 193 } 194 unset($tables); 195 196 $template->assign_vars(array( 197 'U_ACTION' => $this->u_action . '&action=download' 198 )); 199 200 $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2'); 201 202 foreach ($available_methods as $type => $module) 203 { 204 if (!@extension_loaded($module)) 205 { 206 continue; 207 } 208 209 $template->assign_block_vars('methods', array( 210 'TYPE' => $type 211 )); 212 } 213 214 $template->assign_block_vars('methods', array( 215 'TYPE' => 'text' 216 )); 217 break; 218 } 219 break; 220 221 case 'restore': 222 223 $this->page_title = 'ACP_RESTORE'; 224 225 switch ($action) 226 { 227 case 'submit': 228 $delete = request_var('delete', ''); 229 $file = request_var('file', ''); 230 $download = request_var('download', ''); 231 232 if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches)) 233 { 234 trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); 235 } 236 237 $file_name = $phpbb_root_path . 'store/' . $matches[0]; 238 239 if (!file_exists($file_name) || !is_readable($file_name)) 240 { 241 trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); 242 } 243 244 if ($delete) 245 { 246 if (confirm_box(true)) 247 { 248 unlink($file_name); 249 add_log('admin', 'LOG_DB_DELETE'); 250 trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action)); 251 } 252 else 253 { 254 confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file))); 255 } 256 } 257 else if ($download || confirm_box(true)) 258 { 259 if ($download) 260 { 261 $name = $matches[0]; 262 263 switch ($matches[1]) 264 { 265 case 'sql': 266 $mimetype = 'text/x-sql'; 267 break; 268 case 'sql.bz2': 269 $mimetype = 'application/x-bzip2'; 270 break; 271 case 'sql.gz': 272 $mimetype = 'application/x-gzip'; 273 break; 274 } 275 276 header('Pragma: no-cache'); 277 header("Content-Type: $mimetype; name=\"$name\""); 278 header("Content-disposition: attachment; filename=$name"); 279 280 @set_time_limit(0); 281 282 $fp = @fopen($file_name, 'rb'); 283 284 if ($fp !== false) 285 { 286 while (!feof($fp)) 287 { 288 echo fread($fp, 8192); 289 } 290 fclose($fp); 291 } 292 293 flush(); 294 exit; 295 } 296 297 switch ($matches[1]) 298 { 299 case 'sql': 300 $fp = fopen($file_name, 'rb'); 301 $read = 'fread'; 302 $seek = 'fseek'; 303 $eof = 'feof'; 304 $close = 'fclose'; 305 $fgetd = 'fgetd'; 306 break; 307 308 case 'sql.bz2': 309 $fp = bzopen($file_name, 'r'); 310 $read = 'bzread'; 311 $seek = ''; 312 $eof = 'feof'; 313 $close = 'bzclose'; 314 $fgetd = 'fgetd_seekless'; 315 break; 316 317 case 'sql.gz': 318 $fp = gzopen($file_name, 'rb'); 319 $read = 'gzread'; 320 $seek = 'gzseek'; 321 $eof = 'gzeof'; 322 $close = 'gzclose'; 323 $fgetd = 'fgetd'; 324 break; 325 } 326 327 switch ($db->sql_layer) 328 { 329 case 'mysql': 330 case 'mysql4': 331 case 'mysqli': 332 case 'sqlite': 333 while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false) 334 { 335 $db->sql_query($sql); 336 } 337 break; 338 339 case 'firebird': 340 $delim = ";\n"; 341 while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false) 342 { 343 $query = trim($sql); 344 if (substr($query, 0, 8) === 'SET TERM') 345 { 346 $delim = $query[9] . "\n"; 347 continue; 348 } 349 $db->sql_query($query); 350 } 351 break; 352 353 case 'postgres': 354 $delim = ";\n"; 355 while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false) 356 { 357 $query = trim($sql); 358 359 if (substr($query, 0, 13) == 'CREATE DOMAIN') 360 { 361 list(, , $domain) = explode(' ', $query); 362 $sql = "SELECT domain_name 363 FROM information_schema.domains 364 WHERE domain_name = '$domain';"; 365 $result = $db->sql_query($sql); 366 if (!$db->sql_fetchrow($result)) 367 { 368 $db->sql_query($query); 369 } 370 $db->sql_freeresult($result); 371 } 372 else 373 { 374 $db->sql_query($query); 375 } 376 377 if (substr($query, 0, 4) == 'COPY') 378 { 379 while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.') 380 { 381 if ($sub === false) 382 { 383 trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING); 384 } 385 pg_put_line($db->db_connect_id, $sub . "\n"); 386 } 387 pg_put_line($db->db_connect_id, "\\.\n"); 388 pg_end_copy($db->db_connect_id); 389 } 390 } 391 break; 392 393 case 'oracle': 394 while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false) 395 { 396 $db->sql_query($sql); 397 } 398 break; 399 400 case 'mssql': 401 case 'mssql_odbc': 402 case 'mssqlnative': 403 while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false) 404 { 405 $db->sql_query($sql); 406 } 407 break; 408 } 409 410 $close($fp); 411 412 // Purge the cache due to updated data 413 $cache->purge(); 414 415 add_log('admin', 'LOG_DB_RESTORE'); 416 trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action)); 417 break; 418 } 419 else if (!$download) 420 { 421 confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file))); 422 } 423 424 default: 425 $methods = array('sql'); 426 $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2'); 427 428 foreach ($available_methods as $type => $module) 429 { 430 if (!@extension_loaded($module)) 431 { 432 continue; 433 } 434 $methods[] = $type; 435 } 436 437 $dir = $phpbb_root_path . 'store/'; 438 $dh = @opendir($dir); 439 440 $backup_files = array(); 441 442 if ($dh) 443 { 444 while (($file = readdir($dh)) !== false) 445 { 446 if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches)) 447 { 448 if (in_array($matches[2], $methods)) 449 { 450 $backup_files[(int) $matches[1]] = $file; 451 } 452 } 453 } 454 closedir($dh); 455 } 456 457 if (!empty($backup_files)) 458 { 459 krsort($backup_files); 460 461 foreach ($backup_files as $name => $file) 462 { 463 $template->assign_block_vars('files', array( 464 'FILE' => $file, 465 'NAME' => $user->format_date($name, 'd-m-Y H:i:s', true), 466 'SUPPORTED' => true, 467 )); 468 } 469 } 470 471 $template->assign_vars(array( 472 'U_ACTION' => $this->u_action . '&action=submit' 473 )); 474 break; 475 } 476 break; 477 } 478 } 479 } 480 481 /** 482 * @package acp 483 */ 484 class base_extractor 485 { 486 var $fh; 487 var $fp; 488 var $write; 489 var $close; 490 var $store; 491 var $download; 492 var $time; 493 var $format; 494 var $run_comp = false; 495 496 function base_extractor($download = false, $store = false, $format, $filename, $time) 497 { 498 $this->download = $download; 499 $this->store = $store; 500 $this->time = $time; 501 $this->format = $format; 502 503 switch ($format) 504 { 505 case 'text': 506 $ext = '.sql'; 507 $open = 'fopen'; 508 $this->write = 'fwrite'; 509 $this->close = 'fclose'; 510 $mimetype = 'text/x-sql'; 511 break; 512 case 'bzip2': 513 $ext = '.sql.bz2'; 514 $open = 'bzopen'; 515 $this->write = 'bzwrite'; 516 $this->close = 'bzclose'; 517 $mimetype = 'application/x-bzip2'; 518 break; 519 case 'gzip': 520 $ext = '.sql.gz'; 521 $open = 'gzopen'; 522 $this->write = 'gzwrite'; 523 $this->close = 'gzclose'; 524 $mimetype = 'application/x-gzip'; 525 break; 526 } 527 528 if ($download == true) 529 { 530 $name = $filename . $ext; 531 header('Pragma: no-cache'); 532 header("Content-Type: $mimetype; name=\"$name\""); 533 header("Content-disposition: attachment; filename=$name"); 534 535 switch ($format) 536 { 537 case 'bzip2': 538 ob_start(); 539 break; 540 541 case 'gzip': 542 if ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'msie') === false) 543 { 544 ob_start('ob_gzhandler'); 545 } 546 else 547 { 548 $this->run_comp = true; 549 } 550 break; 551 } 552 } 553 554 if ($store == true) 555 { 556 global $phpbb_root_path; 557 $file = $phpbb_root_path . 'store/' . $filename . $ext; 558 559 $this->fp = $open($file, 'w'); 560 561 if (!$this->fp) 562 { 563 trigger_error('FILE_WRITE_FAIL', E_USER_ERROR); 564 } 565 } 566 } 567 568 function write_end() 569 { 570 static $close; 571 572 if ($this->store) 573 { 574 if ($close === null) 575 { 576 $close = $this->close; 577 } 578 $close($this->fp); 579 } 580 581 // bzip2 must be written all the way at the end 582 if ($this->download && $this->format === 'bzip2') 583 { 584 $c = ob_get_clean(); 585 echo bzcompress($c); 586 } 587 } 588 589 function flush($data) 590 { 591 static $write; 592 if ($this->store === true) 593 { 594 if ($write === null) 595 { 596 $write = $this->write; 597 } 598 $write($this->fp, $data); 599 } 600 601 if ($this->download === true) 602 { 603 if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp)) 604 { 605 echo $data; 606 } 607 608 // we can write the gzip data as soon as we get it 609 if ($this->format === 'gzip') 610 { 611 if ($this->run_comp) 612 { 613 echo gzencode($data); 614 } 615 else 616 { 617 ob_flush(); 618 flush(); 619 } 620 } 621 } 622 } 623 } 624 625 /** 626 * @package acp 627 */ 628 class mysql_extractor extends base_extractor 629 { 630 function write_start($table_prefix) 631 { 632 $sql_data = "#\n"; 633 $sql_data .= "# phpBB Backup Script\n"; 634 $sql_data .= "# Dump of tables for $table_prefix\n"; 635 $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 636 $sql_data .= "#\n"; 637 $this->flush($sql_data); 638 } 639 640 function write_table($table_name) 641 { 642 global $db; 643 static $new_extract; 644 645 if ($new_extract === null) 646 { 647 if ($db->sql_layer === 'mysqli' || version_compare($db->sql_server_info(true), '3.23.20', '>=')) 648 { 649 $new_extract = true; 650 } 651 else 652 { 653 $new_extract = false; 654 } 655 } 656 657 if ($new_extract) 658 { 659 $this->new_write_table($table_name); 660 } 661 else 662 { 663 $this->old_write_table($table_name); 664 } 665 } 666 667 function write_data($table_name) 668 { 669 global $db; 670 if ($db->sql_layer === 'mysqli') 671 { 672 $this->write_data_mysqli($table_name); 673 } 674 else 675 { 676 $this->write_data_mysql($table_name); 677 } 678 } 679 680 function write_data_mysqli($table_name) 681 { 682 global $db; 683 $sql = "SELECT * 684 FROM $table_name"; 685 $result = mysqli_query($db->db_connect_id, $sql, MYSQLI_USE_RESULT); 686 if ($result != false) 687 { 688 $fields_cnt = mysqli_num_fields($result); 689 690 // Get field information 691 $field = mysqli_fetch_fields($result); 692 $field_set = array(); 693 694 for ($j = 0; $j < $fields_cnt; $j++) 695 { 696 $field_set[] = $field[$j]->name; 697 } 698 699 $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); 700 $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); 701 $fields = implode(', ', $field_set); 702 $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; 703 $first_set = true; 704 $query_len = 0; 705 $max_len = get_usable_memory(); 706 707 while ($row = mysqli_fetch_row($result)) 708 { 709 $values = array(); 710 if ($first_set) 711 { 712 $query = $sql_data . '('; 713 } 714 else 715 { 716 $query .= ',('; 717 } 718 719 for ($j = 0; $j < $fields_cnt; $j++) 720 { 721 if (!isset($row[$j]) || is_null($row[$j])) 722 { 723 $values[$j] = 'NULL'; 724 } 725 else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024)) 726 { 727 $values[$j] = $row[$j]; 728 } 729 else 730 { 731 $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; 732 } 733 } 734 $query .= implode(', ', $values) . ')'; 735 736 $query_len += strlen($query); 737 if ($query_len > $max_len) 738 { 739 $this->flush($query . ";\n\n"); 740 $query = ''; 741 $query_len = 0; 742 $first_set = true; 743 } 744 else 745 { 746 $first_set = false; 747 } 748 } 749 mysqli_free_result($result); 750 751 // check to make sure we have nothing left to flush 752 if (!$first_set && $query) 753 { 754 $this->flush($query . ";\n\n"); 755 } 756 } 757 } 758 759 function write_data_mysql($table_name) 760 { 761 global $db; 762 $sql = "SELECT * 763 FROM $table_name"; 764 $result = mysql_unbuffered_query($sql, $db->db_connect_id); 765 766 if ($result != false) 767 { 768 $fields_cnt = mysql_num_fields($result); 769 770 // Get field information 771 $field = array(); 772 for ($i = 0; $i < $fields_cnt; $i++) 773 { 774 $field[] = mysql_fetch_field($result, $i); 775 } 776 $field_set = array(); 777 778 for ($j = 0; $j < $fields_cnt; $j++) 779 { 780 $field_set[] = $field[$j]->name; 781 } 782 783 $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"'); 784 $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"'); 785 $fields = implode(', ', $field_set); 786 $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES '; 787 $first_set = true; 788 $query_len = 0; 789 $max_len = get_usable_memory(); 790 791 while ($row = mysql_fetch_row($result)) 792 { 793 $values = array(); 794 if ($first_set) 795 { 796 $query = $sql_data . '('; 797 } 798 else 799 { 800 $query .= ',('; 801 } 802 803 for ($j = 0; $j < $fields_cnt; $j++) 804 { 805 if (!isset($row[$j]) || is_null($row[$j])) 806 { 807 $values[$j] = 'NULL'; 808 } 809 else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp')) 810 { 811 $values[$j] = $row[$j]; 812 } 813 else 814 { 815 $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'"; 816 } 817 } 818 $query .= implode(', ', $values) . ')'; 819 820 $query_len += strlen($query); 821 if ($query_len > $max_len) 822 { 823 $this->flush($query . ";\n\n"); 824 $query = ''; 825 $query_len = 0; 826 $first_set = true; 827 } 828 else 829 { 830 $first_set = false; 831 } 832 } 833 mysql_free_result($result); 834 835 // check to make sure we have nothing left to flush 836 if (!$first_set && $query) 837 { 838 $this->flush($query . ";\n\n"); 839 } 840 } 841 } 842 843 function new_write_table($table_name) 844 { 845 global $db; 846 847 $sql = 'SHOW CREATE TABLE ' . $table_name; 848 $result = $db->sql_query($sql); 849 $row = $db->sql_fetchrow($result); 850 851 $sql_data = '# Table: ' . $table_name . "\n"; 852 $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; 853 $this->flush($sql_data . $row['Create Table'] . ";\n\n"); 854 855 $db->sql_freeresult($result); 856 } 857 858 function old_write_table($table_name) 859 { 860 global $db; 861 862 $sql_data = '# Table: ' . $table_name . "\n"; 863 $sql_data .= "DROP TABLE IF EXISTS $table_name;\n"; 864 $sql_data .= "CREATE TABLE $table_name(\n"; 865 $rows = array(); 866 867 $sql = "SHOW FIELDS 868 FROM $table_name"; 869 $result = $db->sql_query($sql); 870 871 while ($row = $db->sql_fetchrow($result)) 872 { 873 $line = ' ' . $row['Field'] . ' ' . $row['Type']; 874 875 if (!is_null($row['Default'])) 876 { 877 $line .= " DEFAULT '{$row['Default']}'"; 878 } 879 880 if ($row['Null'] != 'YES') 881 { 882 $line .= ' NOT NULL'; 883 } 884 885 if ($row['Extra'] != '') 886 { 887 $line .= ' ' . $row['Extra']; 888 } 889 890 $rows[] = $line; 891 } 892 $db->sql_freeresult($result); 893 894 $sql = "SHOW KEYS 895 FROM $table_name"; 896 897 $result = $db->sql_query($sql); 898 899 $index = array(); 900 while ($row = $db->sql_fetchrow($result)) 901 { 902 $kname = $row['Key_name']; 903 904 if ($kname != 'PRIMARY') 905 { 906 if ($row['Non_unique'] == 0) 907 { 908 $kname = "UNIQUE|$kname"; 909 } 910 } 911 912 if ($row['Sub_part']) 913 { 914 $row['Column_name'] .= '(' . $row['Sub_part'] . ')'; 915 } 916 $index[$kname][] = $row['Column_name']; 917 } 918 $db->sql_freeresult($result); 919 920 foreach ($index as $key => $columns) 921 { 922 $line = ' '; 923 924 if ($key == 'PRIMARY') 925 { 926 $line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')'; 927 } 928 else if (strpos($key, 'UNIQUE') === 0) 929 { 930 $line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')'; 931 } 932 else if (strpos($key, 'FULLTEXT') === 0) 933 { 934 $line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')'; 935 } 936 else 937 { 938 $line .= "KEY $key (" . implode(', ', $columns) . ')'; 939 } 940 941 $rows[] = $line; 942 } 943 944 $sql_data .= implode(",\n", $rows); 945 $sql_data .= "\n);\n\n"; 946 947 $this->flush($sql_data); 948 } 949 } 950 951 /** 952 * @package acp 953 */ 954 class sqlite_extractor extends base_extractor 955 { 956 function write_start($prefix) 957 { 958 $sql_data = "--\n"; 959 $sql_data .= "-- phpBB Backup Script\n"; 960 $sql_data .= "-- Dump of tables for $prefix\n"; 961 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 962 $sql_data .= "--\n"; 963 $sql_data .= "BEGIN TRANSACTION;\n"; 964 $this->flush($sql_data); 965 } 966 967 function write_table($table_name) 968 { 969 global $db; 970 $sql_data = '-- Table: ' . $table_name . "\n"; 971 $sql_data .= "DROP TABLE $table_name;\n"; 972 973 $sql = "SELECT sql 974 FROM sqlite_master 975 WHERE type = 'table' 976 AND name = '" . $db->sql_escape($table_name) . "' 977 ORDER BY type DESC, name;"; 978 $result = $db->sql_query($sql); 979 $row = $db->sql_fetchrow($result); 980 $db->sql_freeresult($result); 981 982 // Create Table 983 $sql_data .= $row['sql'] . ";\n"; 984 985 $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');"); 986 987 $ar = array(); 988 while ($row = $db->sql_fetchrow($result)) 989 { 990 $ar[] = $row; 991 } 992 $db->sql_freeresult($result); 993 994 foreach ($ar as $value) 995 { 996 if (strpos($value['name'], 'autoindex') !== false) 997 { 998 continue; 999 } 1000 1001 $result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');"); 1002 1003 $fields = array(); 1004 while ($row = $db->sql_fetchrow($result)) 1005 { 1006 $fields[] = $row['name']; 1007 } 1008 $db->sql_freeresult($result); 1009 1010 $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n"; 1011 } 1012 1013 $this->flush($sql_data . "\n"); 1014 } 1015 1016 function write_data($table_name) 1017 { 1018 global $db; 1019 static $proper; 1020 1021 if (is_null($proper)) 1022 { 1023 $proper = version_compare(PHP_VERSION, '5.1.3', '>='); 1024 } 1025 1026 if ($proper) 1027 { 1028 $col_types = sqlite_fetch_column_types($db->db_connect_id, $table_name); 1029 } 1030 else 1031 { 1032 $sql = "SELECT sql 1033 FROM sqlite_master 1034 WHERE type = 'table' 1035 AND name = '" . $table_name . "'"; 1036 $table_data = sqlite_single_query($db->db_connect_id, $sql); 1037 $table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data); 1038 $table_data = trim($table_data); 1039 1040 preg_match('#\((.*)\)#s', $table_data, $matches); 1041 1042 $table_cols = explode(',', trim($matches[1])); 1043 foreach ($table_cols as $declaration) 1044 { 1045 $entities = preg_split('#\s+#', trim($declaration)); 1046 $column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]); 1047 1048 // Hit a primary key, those are not what we need :D 1049 if (empty($entities[1]) || (strtolower($entities[0]) === 'primary' && strtolower($entities[1]) === 'key')) 1050 { 1051 continue; 1052 } 1053 $col_types[$column_name] = $entities[1]; 1054 } 1055 } 1056 1057 $sql = "SELECT * 1058 FROM $table_name"; 1059 $result = sqlite_unbuffered_query($db->db_connect_id, $sql); 1060 $rows = sqlite_fetch_all($result, SQLITE_ASSOC); 1061 $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES ('; 1062 foreach ($rows as $row) 1063 { 1064 foreach ($row as $column_name => $column_data) 1065 { 1066 if (is_null($column_data)) 1067 { 1068 $row[$column_name] = 'NULL'; 1069 } 1070 else if ($column_data == '') 1071 { 1072 $row[$column_name] = "''"; 1073 } 1074 else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false) 1075 { 1076 $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data)); 1077 } 1078 } 1079 $this->flush($sql_insert . implode(', ', $row) . ");\n"); 1080 } 1081 } 1082 1083 function write_end() 1084 { 1085 $this->flush("COMMIT;\n"); 1086 parent::write_end(); 1087 } 1088 } 1089 1090 /** 1091 * @package acp 1092 */ 1093 class postgres_extractor extends base_extractor 1094 { 1095 function write_start($prefix) 1096 { 1097 $sql_data = "--\n"; 1098 $sql_data .= "-- phpBB Backup Script\n"; 1099 $sql_data .= "-- Dump of tables for $prefix\n"; 1100 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 1101 $sql_data .= "--\n"; 1102 $sql_data .= "BEGIN TRANSACTION;\n"; 1103 $this->flush($sql_data); 1104 } 1105 1106 function write_table($table_name) 1107 { 1108 global $db; 1109 static $domains_created = array(); 1110 1111 $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default 1112 FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b 1113 WHERE a.domain_name = b.domain_name 1114 AND b.table_name = '{$table_name}'"; 1115 $result = $db->sql_query($sql); 1116 while ($row = $db->sql_fetchrow($result)) 1117 { 1118 if (empty($domains_created[$row['domain_name']])) 1119 { 1120 $domains_created[$row['domain_name']] = true; 1121 //$sql_data = "DROP DOMAIN {$row['domain_name']};\n"; 1122 $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}"; 1123 if (!empty($row['character_maximum_length'])) 1124 { 1125 $sql_data .= '(' . $row['character_maximum_length'] . ')'; 1126 } 1127 $sql_data .= ' NOT NULL'; 1128 if (!empty($row['domain_default'])) 1129 { 1130 $sql_data .= ' DEFAULT ' . $row['domain_default']; 1131 } 1132 $this->flush($sql_data . ";\n"); 1133 } 1134 } 1135 1136 $sql_data = '-- Table: ' . $table_name . "\n"; 1137 $sql_data .= "DROP TABLE $table_name;\n"; 1138 // PGSQL does not "tightly" bind sequences and tables, we must guess... 1139 $sql = "SELECT relname 1140 FROM pg_class 1141 WHERE relkind = 'S' 1142 AND relname = '{$table_name}_seq'"; 1143 $result = $db->sql_query($sql); 1144 // We don't even care about storing the results. We already know the answer if we get rows back. 1145 if ($db->sql_fetchrow($result)) 1146 { 1147 $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n"; 1148 $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n"; 1149 } 1150 $db->sql_freeresult($result); 1151 1152 $field_query = "SELECT a.attnum, a.attname as field, t.typname as type, a.attlen as length, a.atttypmod as lengthvar, a.attnotnull as notnull 1153 FROM pg_class c, pg_attribute a, pg_type t 1154 WHERE c.relname = '" . $db->sql_escape($table_name) . "' 1155 AND a.attnum > 0 1156 AND a.attrelid = c.oid 1157 AND a.atttypid = t.oid 1158 ORDER BY a.attnum"; 1159 $result = $db->sql_query($field_query); 1160 1161 $sql_data .= "CREATE TABLE $table_name(\n"; 1162 $lines = array(); 1163 while ($row = $db->sql_fetchrow($result)) 1164 { 1165 // Get the data from the table 1166 $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault 1167 FROM pg_attrdef d, pg_class c 1168 WHERE (c.relname = '" . $db->sql_escape($table_name) . "') 1169 AND (c.oid = d.adrelid) 1170 AND d.adnum = " . $row['attnum']; 1171 $def_res = $db->sql_query($sql_get_default); 1172 $def_row = $db->sql_fetchrow($def_res); 1173 $db->sql_freeresult($def_res); 1174 1175 if (empty($def_row)) 1176 { 1177 unset($row['rowdefault']); 1178 } 1179 else 1180 { 1181 $row['rowdefault'] = $def_row['rowdefault']; 1182 } 1183 1184 if ($row['type'] == 'bpchar') 1185 { 1186 // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement. 1187 $row['type'] = 'char'; 1188 } 1189 1190 $line = ' ' . $row['field'] . ' ' . $row['type']; 1191 1192 if (strpos($row['type'], 'char') !== false) 1193 { 1194 if ($row['lengthvar'] > 0) 1195 { 1196 $line .= '(' . ($row['lengthvar'] - 4) . ')'; 1197 } 1198 } 1199 1200 if (strpos($row['type'], 'numeric') !== false) 1201 { 1202 $line .= '('; 1203 $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff)); 1204 $line .= ')'; 1205 } 1206 1207 if (isset($row['rowdefault'])) 1208 { 1209 $line .= ' DEFAULT ' . $row['rowdefault']; 1210 } 1211 1212 if ($row['notnull'] == 't') 1213 { 1214 $line .= ' NOT NULL'; 1215 } 1216 1217 $lines[] = $line; 1218 } 1219 $db->sql_freeresult($result); 1220 1221 1222 // Get the listing of primary keys. 1223 $sql_pri_keys = "SELECT ic.relname as index_name, bc.relname as tab_name, ta.attname as column_name, i.indisunique as unique_key, i.indisprimary as primary_key 1224 FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia 1225 WHERE (bc.oid = i.indrelid) 1226 AND (ic.oid = i.indexrelid) 1227 AND (ia.attrelid = i.indexrelid) 1228 AND (ta.attrelid = bc.oid) 1229 AND (bc.relname = '" . $db->sql_escape($table_name) . "') 1230 AND (ta.attrelid = i.indrelid) 1231 AND (ta.attnum = i.indkey[ia.attnum-1]) 1232 ORDER BY index_name, tab_name, column_name"; 1233 1234 $result = $db->sql_query($sql_pri_keys); 1235 1236 $index_create = $index_rows = $primary_key = array(); 1237 1238 // We do this in two steps. It makes placing the comma easier 1239 while ($row = $db->sql_fetchrow($result)) 1240 { 1241 if ($row['primary_key'] == 't') 1242 { 1243 $primary_key[] = $row['column_name']; 1244 $primary_key_name = $row['index_name']; 1245 } 1246 else 1247 { 1248 // We have to store this all this info because it is possible to have a multi-column key... 1249 // we can loop through it again and build the statement 1250 $index_rows[$row['index_name']]['table'] = $table_name; 1251 $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false; 1252 $index_rows[$row['index_name']]['column_names'][] = $row['column_name']; 1253 } 1254 } 1255 $db->sql_freeresult($result); 1256 1257 if (!empty($index_rows)) 1258 { 1259 foreach ($index_rows as $idx_name => $props) 1260 { 1261 $index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");"; 1262 } 1263 } 1264 1265 if (!empty($primary_key)) 1266 { 1267 $lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")"; 1268 } 1269 1270 // Generate constraint clauses for CHECK constraints 1271 $sql_checks = "SELECT conname as index_name, consrc 1272 FROM pg_constraint, pg_class bc 1273 WHERE conrelid = bc.oid 1274 AND bc.relname = '" . $db->sql_escape($table_name) . "' 1275 AND NOT EXISTS ( 1276 SELECT * 1277 FROM pg_constraint as c, pg_inherits as i 1278 WHERE i.inhrelid = pg_constraint.conrelid 1279 AND c.conname = pg_constraint.conname 1280 AND c.consrc = pg_constraint.consrc 1281 AND c.conrelid = i.inhparent 1282 )"; 1283 $result = $db->sql_query($sql_checks); 1284 1285 // Add the constraints to the sql file. 1286 while ($row = $db->sql_fetchrow($result)) 1287 { 1288 if (!is_null($row['consrc'])) 1289 { 1290 $lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc']; 1291 } 1292 } 1293 $db->sql_freeresult($result); 1294 1295 $sql_data .= implode(", \n", $lines); 1296 $sql_data .= "\n);\n"; 1297 1298 if (!empty($index_create)) 1299 { 1300 $sql_data .= implode("\n", $index_create) . "\n\n"; 1301 } 1302 $this->flush($sql_data); 1303 } 1304 1305 function write_data($table_name) 1306 { 1307 global $db; 1308 // Grab all of the data from current table. 1309 $sql = "SELECT * 1310 FROM $table_name"; 1311 $result = $db->sql_query($sql); 1312 1313 $i_num_fields = pg_num_fields($result); 1314 $seq = ''; 1315 1316 for ($i = 0; $i < $i_num_fields; $i++) 1317 { 1318 $ary_type[] = pg_field_type($result, $i); 1319 $ary_name[] = pg_field_name($result, $i); 1320 1321 1322 $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault 1323 FROM pg_attrdef d, pg_class c 1324 WHERE (c.relname = '{$table_name}') 1325 AND (c.oid = d.adrelid) 1326 AND d.adnum = " . strval($i + 1); 1327 $result2 = $db->sql_query($sql); 1328 if ($row = $db->sql_fetchrow($result2)) 1329 { 1330 // Determine if we must reset the sequences 1331 if (strpos($row['rowdefault'], "nextval('") === 0) 1332 { 1333 $seq .= "SELECT SETVAL('{$table_name}_seq',(select case when max({$ary_name[$i]})>0 then max({$ary_name[$i]})+1 else 1 end FROM {$table_name}));\n"; 1334 } 1335 } 1336 } 1337 1338 $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n"); 1339 while ($row = $db->sql_fetchrow($result)) 1340 { 1341 $schema_vals = array(); 1342 1343 // Build the SQL statement to recreate the data. 1344 for ($i = 0; $i < $i_num_fields; $i++) 1345 { 1346 $str_val = $row[$ary_name[$i]]; 1347 1348 if (preg_match('#char|text|bool|bytea#i', $ary_type[$i])) 1349 { 1350 $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val)); 1351 $str_empty = ''; 1352 } 1353 else 1354 { 1355 $str_empty = '\N'; 1356 } 1357 1358 if (empty($str_val) && $str_val !== '0') 1359 { 1360 $str_val = $str_empty; 1361 } 1362 1363 $schema_vals[] = $str_val; 1364 } 1365 1366 // Take the ordered fields and their associated data and build it 1367 // into a valid sql statement to recreate that field in the data. 1368 $this->flush(implode("\t", $schema_vals) . "\n"); 1369 } 1370 $db->sql_freeresult($result); 1371 $this->flush("\\.\n"); 1372 1373 // Write out the sequence statements 1374 $this->flush($seq); 1375 } 1376 1377 function write_end() 1378 { 1379 $this->flush("COMMIT;\n"); 1380 parent::write_end(); 1381 } 1382 } 1383 1384 /** 1385 * @package acp 1386 */ 1387 class mssql_extractor extends base_extractor 1388 { 1389 function write_end() 1390 { 1391 $this->flush("COMMIT\nGO\n"); 1392 parent::write_end(); 1393 } 1394 1395 function write_start($prefix) 1396 { 1397 $sql_data = "--\n"; 1398 $sql_data .= "-- phpBB Backup Script\n"; 1399 $sql_data .= "-- Dump of tables for $prefix\n"; 1400 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 1401 $sql_data .= "--\n"; 1402 $sql_data .= "BEGIN TRANSACTION\n"; 1403 $sql_data .= "GO\n"; 1404 $this->flush($sql_data); 1405 } 1406 1407 function write_table($table_name) 1408 { 1409 global $db; 1410 $sql_data = '-- Table: ' . $table_name . "\n"; 1411 $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n"; 1412 $sql_data .= "DROP TABLE $table_name;\n"; 1413 $sql_data .= "GO\n"; 1414 $sql_data .= "\nCREATE TABLE [$table_name] (\n"; 1415 $rows = array(); 1416 1417 $text_flag = false; 1418 1419 $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY 1420 FROM INFORMATION_SCHEMA.COLUMNS 1421 WHERE TABLE_NAME = '$table_name'"; 1422 $result = $db->sql_query($sql); 1423 1424 while ($row = $db->sql_fetchrow($result)) 1425 { 1426 $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]"; 1427 1428 if ($row['DATA_TYPE'] == 'text') 1429 { 1430 $text_flag = true; 1431 } 1432 1433 if ($row['IS_IDENTITY']) 1434 { 1435 $line .= ' IDENTITY (1 , 1)'; 1436 } 1437 1438 if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text') 1439 { 1440 $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')'; 1441 } 1442 1443 if ($row['IS_NULLABLE'] == 'YES') 1444 { 1445 $line .= ' NULL'; 1446 } 1447 else 1448 { 1449 $line .= ' NOT NULL'; 1450 } 1451 1452 if ($row['COLUMN_DEFAULT']) 1453 { 1454 $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT']; 1455 } 1456 1457 $rows[] = $line; 1458 } 1459 $db->sql_freeresult($result); 1460 1461 $sql_data .= implode(",\n", $rows); 1462 $sql_data .= "\n) ON [PRIMARY]"; 1463 1464 if ($text_flag) 1465 { 1466 $sql_data .= " TEXTIMAGE_ON [PRIMARY]"; 1467 } 1468 1469 $sql_data .= "\nGO\n\n"; 1470 $rows = array(); 1471 1472 $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME 1473 FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 1474 WHERE TABLE_NAME = '$table_name'"; 1475 $result = $db->sql_query($sql); 1476 while ($row = $db->sql_fetchrow($result)) 1477 { 1478 if (!sizeof($rows)) 1479 { 1480 $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n"; 1481 $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n"; 1482 } 1483 $rows[] = "\t\t[{$row['COLUMN_NAME']}]"; 1484 } 1485 if (sizeof($rows)) 1486 { 1487 $sql_data .= implode(",\n", $rows); 1488 $sql_data .= "\n\t) ON [PRIMARY] \nGO\n"; 1489 } 1490 $db->sql_freeresult($result); 1491 1492 $index = array(); 1493 $sql = "EXEC sp_statistics '$table_name'"; 1494 $result = $db->sql_query($sql); 1495 while ($row = $db->sql_fetchrow($result)) 1496 { 1497 if ($row['TYPE'] == 3) 1498 { 1499 $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']'; 1500 } 1501 } 1502 $db->sql_freeresult($result); 1503 1504 foreach ($index as $index_name => $column_name) 1505 { 1506 $index[$index_name] = implode(', ', $column_name); 1507 } 1508 1509 foreach ($index as $index_name => $columns) 1510 { 1511 $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n"; 1512 } 1513 $this->flush($sql_data); 1514 } 1515 1516 function write_data($table_name) 1517 { 1518 global $db; 1519 1520 if ($db->sql_layer === 'mssql') 1521 { 1522 $this->write_data_mssql($table_name); 1523 } 1524 else if($db->sql_layer === 'mssqlnative') 1525 { 1526 $this->write_data_mssqlnative($table_name); 1527 } 1528 else 1529 { 1530 $this->write_data_odbc($table_name); 1531 } 1532 } 1533 1534 function write_data_mssql($table_name) 1535 { 1536 global $db; 1537 $ary_type = $ary_name = array(); 1538 $ident_set = false; 1539 $sql_data = ''; 1540 1541 // Grab all of the data from current table. 1542 $sql = "SELECT * 1543 FROM $table_name"; 1544 $result = $db->sql_query($sql); 1545 1546 $retrieved_data = mssql_num_rows($result); 1547 1548 $i_num_fields = mssql_num_fields($result); 1549 1550 for ($i = 0; $i < $i_num_fields; $i++) 1551 { 1552 $ary_type[$i] = mssql_field_type($result, $i); 1553 $ary_name[$i] = mssql_field_name($result, $i); 1554 } 1555 1556 if ($retrieved_data) 1557 { 1558 $sql = "SELECT 1 as has_identity 1559 FROM INFORMATION_SCHEMA.COLUMNS 1560 WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; 1561 $result2 = $db->sql_query($sql); 1562 $row2 = $db->sql_fetchrow($result2); 1563 if (!empty($row2['has_identity'])) 1564 { 1565 $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; 1566 $ident_set = true; 1567 } 1568 $db->sql_freeresult($result2); 1569 } 1570 1571 while ($row = $db->sql_fetchrow($result)) 1572 { 1573 $schema_vals = $schema_fields = array(); 1574 1575 // Build the SQL statement to recreate the data. 1576 for ($i = 0; $i < $i_num_fields; $i++) 1577 { 1578 $str_val = $row[$ary_name[$i]]; 1579 1580 if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) 1581 { 1582 $str_quote = ''; 1583 $str_empty = "''"; 1584 $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); 1585 } 1586 else if (preg_match('#date|timestamp#i', $ary_type[$i])) 1587 { 1588 if (empty($str_val)) 1589 { 1590 $str_quote = ''; 1591 } 1592 else 1593 { 1594 $str_quote = "'"; 1595 } 1596 } 1597 else 1598 { 1599 $str_quote = ''; 1600 $str_empty = 'NULL'; 1601 } 1602 1603 if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) 1604 { 1605 $str_val = $str_empty; 1606 } 1607 1608 $schema_vals[$i] = $str_quote . $str_val . $str_quote; 1609 $schema_fields[$i] = $ary_name[$i]; 1610 } 1611 1612 // Take the ordered fields and their associated data and build it 1613 // into a valid sql statement to recreate that field in the data. 1614 $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; 1615 1616 $this->flush($sql_data); 1617 $sql_data = ''; 1618 } 1619 $db->sql_freeresult($result); 1620 1621 if ($retrieved_data && $ident_set) 1622 { 1623 $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; 1624 } 1625 $this->flush($sql_data); 1626 } 1627 1628 function write_data_mssqlnative($table_name) 1629 { 1630 global $db; 1631 $ary_type = $ary_name = array(); 1632 $ident_set = false; 1633 $sql_data = ''; 1634 1635 // Grab all of the data from current table. 1636 $sql = "SELECT * FROM $table_name"; 1637 $db->mssqlnative_set_query_options(array('Scrollable' => SQLSRV_CURSOR_STATIC)); 1638 $result = $db->sql_query($sql); 1639 1640 $retrieved_data = $db->mssqlnative_num_rows($result); 1641 1642 if (!$retrieved_data) 1643 { 1644 $db->sql_freeresult($result); 1645 return; 1646 } 1647 1648 $sql = "SELECT * FROM $table_name"; 1649 $result_fields = $db->sql_query_limit($sql, 1); 1650 1651 $row = new result_mssqlnative($result_fields); 1652 $i_num_fields = $row->num_fields(); 1653 1654 for ($i = 0; $i < $i_num_fields; $i++) 1655 { 1656 $ary_type[$i] = $row->field_type($i); 1657 $ary_name[$i] = $row->field_name($i); 1658 } 1659 $db->sql_freeresult($result_fields); 1660 1661 $sql = "SELECT 1 as has_identity 1662 FROM INFORMATION_SCHEMA.COLUMNS 1663 WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; 1664 $result2 = $db->sql_query($sql); 1665 $row2 = $db->sql_fetchrow($result2); 1666 1667 if (!empty($row2['has_identity'])) 1668 { 1669 $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; 1670 $ident_set = true; 1671 } 1672 $db->sql_freeresult($result2); 1673 1674 while ($row = $db->sql_fetchrow($result)) 1675 { 1676 $schema_vals = $schema_fields = array(); 1677 1678 // Build the SQL statement to recreate the data. 1679 for ($i = 0; $i < $i_num_fields; $i++) 1680 { 1681 $str_val = $row[$ary_name[$i]]; 1682 1683 // defaults to type number - better quote just to be safe, so check for is_int too 1684 if (is_int($ary_type[$i]) || preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) 1685 { 1686 $str_quote = ''; 1687 $str_empty = "''"; 1688 $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); 1689 } 1690 else if (preg_match('#date|timestamp#i', $ary_type[$i])) 1691 { 1692 if (empty($str_val)) 1693 { 1694 $str_quote = ''; 1695 } 1696 else 1697 { 1698 $str_quote = "'"; 1699 } 1700 } 1701 else 1702 { 1703 $str_quote = ''; 1704 $str_empty = 'NULL'; 1705 } 1706 1707 if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) 1708 { 1709 $str_val = $str_empty; 1710 } 1711 1712 $schema_vals[$i] = $str_quote . $str_val . $str_quote; 1713 $schema_fields[$i] = $ary_name[$i]; 1714 } 1715 1716 // Take the ordered fields and their associated data and build it 1717 // into a valid sql statement to recreate that field in the data. 1718 $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; 1719 1720 $this->flush($sql_data); 1721 $sql_data = ''; 1722 } 1723 $db->sql_freeresult($result); 1724 1725 if ($ident_set) 1726 { 1727 $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; 1728 } 1729 $this->flush($sql_data); 1730 } 1731 1732 function write_data_odbc($table_name) 1733 { 1734 global $db; 1735 $ary_type = $ary_name = array(); 1736 $ident_set = false; 1737 $sql_data = ''; 1738 1739 // Grab all of the data from current table. 1740 $sql = "SELECT * 1741 FROM $table_name"; 1742 $result = $db->sql_query($sql); 1743 1744 $retrieved_data = odbc_num_rows($result); 1745 1746 if ($retrieved_data) 1747 { 1748 $sql = "SELECT 1 as has_identity 1749 FROM INFORMATION_SCHEMA.COLUMNS 1750 WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1"; 1751 $result2 = $db->sql_query($sql); 1752 $row2 = $db->sql_fetchrow($result2); 1753 if (!empty($row2['has_identity'])) 1754 { 1755 $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n"; 1756 $ident_set = true; 1757 } 1758 $db->sql_freeresult($result2); 1759 } 1760 1761 $i_num_fields = odbc_num_fields($result); 1762 1763 for ($i = 0; $i < $i_num_fields; $i++) 1764 { 1765 $ary_type[$i] = odbc_field_type($result, $i + 1); 1766 $ary_name[$i] = odbc_field_name($result, $i + 1); 1767 } 1768 1769 while ($row = $db->sql_fetchrow($result)) 1770 { 1771 $schema_vals = $schema_fields = array(); 1772 1773 // Build the SQL statement to recreate the data. 1774 for ($i = 0; $i < $i_num_fields; $i++) 1775 { 1776 $str_val = $row[$ary_name[$i]]; 1777 1778 if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i])) 1779 { 1780 $str_quote = ''; 1781 $str_empty = "''"; 1782 $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val)); 1783 } 1784 else if (preg_match('#date|timestamp#i', $ary_type[$i])) 1785 { 1786 if (empty($str_val)) 1787 { 1788 $str_quote = ''; 1789 } 1790 else 1791 { 1792 $str_quote = "'"; 1793 } 1794 } 1795 else 1796 { 1797 $str_quote = ''; 1798 $str_empty = 'NULL'; 1799 } 1800 1801 if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val))) 1802 { 1803 $str_val = $str_empty; 1804 } 1805 1806 $schema_vals[$i] = $str_quote . $str_val . $str_quote; 1807 $schema_fields[$i] = $ary_name[$i]; 1808 } 1809 1810 // Take the ordered fields and their associated data and build it 1811 // into a valid sql statement to recreate that field in the data. 1812 $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n"; 1813 1814 $this->flush($sql_data); 1815 1816 $sql_data = ''; 1817 1818 } 1819 $db->sql_freeresult($result); 1820 1821 if ($retrieved_data && $ident_set) 1822 { 1823 $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n"; 1824 } 1825 $this->flush($sql_data); 1826 } 1827 1828 } 1829 1830 /** 1831 * @package acp 1832 */ 1833 class oracle_extractor extends base_extractor 1834 { 1835 function write_table($table_name) 1836 { 1837 global $db; 1838 $sql_data = '-- Table: ' . $table_name . "\n"; 1839 $sql_data .= "DROP TABLE $table_name\n/\n"; 1840 $sql_data .= "\nCREATE TABLE $table_name (\n"; 1841 1842 $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT 1843 FROM ALL_TAB_COLS 1844 WHERE table_name = '{$table_name}'"; 1845 $result = $db->sql_query($sql); 1846 1847 $rows = array(); 1848 while ($row = $db->sql_fetchrow($result)) 1849 { 1850 $line = ' "' . $row['column_name'] . '" ' . $row['data_type']; 1851 1852 if ($row['data_type'] !== 'CLOB') 1853 { 1854 if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR') 1855 { 1856 $line .= '(' . $row['data_precision'] . ')'; 1857 } 1858 else 1859 { 1860 $line .= '(' . $row['data_length'] . ')'; 1861 } 1862 } 1863 1864 if (!empty($row['data_default'])) 1865 { 1866 $line .= ' DEFAULT ' . $row['data_default']; 1867 } 1868 1869 if ($row['nullable'] == 'N') 1870 { 1871 $line .= ' NOT NULL'; 1872 } 1873 $rows[] = $line; 1874 } 1875 $db->sql_freeresult($result); 1876 1877 $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME 1878 FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B 1879 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME 1880 AND B.CONSTRAINT_TYPE = 'P' 1881 AND A.TABLE_NAME = '{$table_name}'"; 1882 $result = $db->sql_query($sql); 1883 1884 $primary_key = array(); 1885 $contraint_name = ''; 1886 while ($row = $db->sql_fetchrow($result)) 1887 { 1888 $constraint_name = '"' . $row['constraint_name'] . '"'; 1889 $primary_key[] = '"' . $row['column_name'] . '"'; 1890 } 1891 $db->sql_freeresult($result); 1892 1893 if (sizeof($primary_key)) 1894 { 1895 $rows[] = " CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')'; 1896 } 1897 1898 $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME 1899 FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B 1900 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME 1901 AND B.CONSTRAINT_TYPE = 'U' 1902 AND A.TABLE_NAME = '{$table_name}'"; 1903 $result = $db->sql_query($sql); 1904 1905 $unique = array(); 1906 $contraint_name = ''; 1907 while ($row = $db->sql_fetchrow($result)) 1908 { 1909 $constraint_name = '"' . $row['constraint_name'] . '"'; 1910 $unique[] = '"' . $row['column_name'] . '"'; 1911 } 1912 $db->sql_freeresult($result); 1913 1914 if (sizeof($unique)) 1915 { 1916 $rows[] = " CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')'; 1917 } 1918 1919 $sql_data .= implode(",\n", $rows); 1920 $sql_data .= "\n)\n/\n"; 1921 1922 $sql = "SELECT A.REFERENCED_NAME, C.* 1923 FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C 1924 WHERE A.REFERENCED_TYPE = 'SEQUENCE' 1925 AND A.NAME = B.TRIGGER_NAME 1926 AND B.TABLE_NAME = '{$table_name}' 1927 AND C.SEQUENCE_NAME = A.REFERENCED_NAME"; 1928 $result = $db->sql_query($sql); 1929 1930 $type = request_var('type', ''); 1931 1932 while ($row = $db->sql_fetchrow($result)) 1933 { 1934 $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n"; 1935 $sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\""; 1936 1937 if ($type == 'full') 1938 { 1939 $sql_data .= ' START WITH ' . $row['last_number']; 1940 } 1941 1942 $sql_data .= "\n/\n"; 1943 } 1944 $db->sql_freeresult($result); 1945 1946 $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY 1947 FROM USER_TRIGGERS 1948 WHERE TABLE_NAME = '{$table_name}'"; 1949 $result = $db->sql_query($sql); 1950 while ($row = $db->sql_fetchrow($result)) 1951 { 1952 $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n"; 1953 } 1954 $db->sql_freeresult($result); 1955 1956 $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME 1957 FROM USER_INDEXES A, USER_IND_COLUMNS B 1958 WHERE A.UNIQUENESS = 'NONUNIQUE' 1959 AND A.INDEX_NAME = B.INDEX_NAME 1960 AND B.TABLE_NAME = '{$table_name}'"; 1961 $result = $db->sql_query($sql); 1962 1963 $index = array(); 1964 1965 while ($row = $db->sql_fetchrow($result)) 1966 { 1967 $index[$row['index_name']][] = $row['column_name']; 1968 } 1969 1970 foreach ($index as $index_name => $column_names) 1971 { 1972 $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n"; 1973 } 1974 $db->sql_freeresult($result); 1975 $this->flush($sql_data); 1976 } 1977 1978 function write_data($table_name) 1979 { 1980 global $db; 1981 $ary_type = $ary_name = array(); 1982 1983 // Grab all of the data from current table. 1984 $sql = "SELECT * 1985 FROM $table_name"; 1986 $result = $db->sql_query($sql); 1987 1988 $i_num_fields = ocinumcols($result); 1989 1990 for ($i = 0; $i < $i_num_fields; $i++) 1991 { 1992 $ary_type[$i] = ocicolumntype($result, $i + 1); 1993 $ary_name[$i] = ocicolumnname($result, $i + 1); 1994 } 1995 1996 $sql_data = ''; 1997 1998 while ($row = $db->sql_fetchrow($result)) 1999 { 2000 $schema_vals = $schema_fields = array(); 2001 2002 // Build the SQL statement to recreate the data. 2003 for ($i = 0; $i < $i_num_fields; $i++) 2004 { 2005 // Oracle uses uppercase - we use lowercase 2006 $str_val = $row[strtolower($ary_name[$i])]; 2007 2008 if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i])) 2009 { 2010 $str_quote = ''; 2011 $str_empty = "''"; 2012 $str_val = sanitize_data_oracle($str_val); 2013 } 2014 else if (preg_match('#date|timestamp#i', $ary_type[$i])) 2015 { 2016 if (empty($str_val)) 2017 { 2018 $str_quote = ''; 2019 } 2020 else 2021 { 2022 $str_quote = "'"; 2023 } 2024 } 2025 else 2026 { 2027 $str_quote = ''; 2028 $str_empty = 'NULL'; 2029 } 2030 2031 if (empty($str_val) && $str_val !== '0') 2032 { 2033 $str_val = $str_empty; 2034 } 2035 2036 $schema_vals[$i] = $str_quote . $str_val . $str_quote; 2037 $schema_fields[$i] = '"' . $ary_name[$i] . '"'; 2038 } 2039 2040 // Take the ordered fields and their associated data and build it 2041 // into a valid sql statement to recreate that field in the data. 2042 $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n"; 2043 2044 $this->flush($sql_data); 2045 } 2046 $db->sql_freeresult($result); 2047 } 2048 2049 function write_start($prefix) 2050 { 2051 $sql_data = "--\n"; 2052 $sql_data .= "-- phpBB Backup Script\n"; 2053 $sql_data .= "-- Dump of tables for $prefix\n"; 2054 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 2055 $sql_data .= "--\n"; 2056 $this->flush($sql_data); 2057 } 2058 } 2059 2060 /** 2061 * @package acp 2062 */ 2063 class firebird_extractor extends base_extractor 2064 { 2065 function write_start($prefix) 2066 { 2067 $sql_data = "--\n"; 2068 $sql_data .= "-- phpBB Backup Script\n"; 2069 $sql_data .= "-- Dump of tables for $prefix\n"; 2070 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n"; 2071 $sql_data .= "--\n"; 2072 $this->flush($sql_data); 2073 } 2074 2075 function write_data($table_name) 2076 { 2077 global $db; 2078 $ary_type = $ary_name = array(); 2079 2080 // Grab all of the data from current table. 2081 $sql = "SELECT * 2082 FROM $table_name"; 2083 $result = $db->sql_query($sql); 2084 2085 $i_num_fields = ibase_num_fields($result); 2086 2087 for ($i = 0; $i < $i_num_fields; $i++) 2088 { 2089 $info = ibase_field_info($result, $i); 2090 $ary_type[$i] = $info['type']; 2091 $ary_name[$i] = $info['name']; 2092 } 2093 2094 while ($row = $db->sql_fetchrow($result)) 2095 { 2096 $schema_vals = $schema_fields = array(); 2097 2098 // Build the SQL statement to recreate the data. 2099 for ($i = 0; $i < $i_num_fields; $i++) 2100 { 2101 $str_val = $row[strtolower($ary_name[$i])]; 2102 2103 if (preg_match('#char|text|bool|varbinary|blob#i', $ary_type[$i])) 2104 { 2105 $str_quote = ''; 2106 $str_empty = "''"; 2107 $str_val = sanitize_data_generic(str_replace("'", "''", $str_val)); 2108 } 2109 else if (preg_match('#date|timestamp#i', $ary_type[$i])) 2110 { 2111 if (empty($str_val)) 2112 { 2113 $str_quote = ''; 2114 } 2115 else 2116 { 2117 $str_quote = "'"; 2118 } 2119 } 2120 else 2121 { 2122 $str_quote = ''; 2123 $str_empty = 'NULL'; 2124 } 2125 2126 if (empty($str_val) && $str_val !== '0') 2127 { 2128 $str_val = $str_empty; 2129 } 2130 2131 $schema_vals[$i] = $str_quote . $str_val . $str_quote; 2132 $schema_fields[$i] = '"' . $ary_name[$i] . '"'; 2133 } 2134 2135 // Take the ordered fields and their associated data and build it 2136 // into a valid sql statement to recreate that field in the data. 2137 $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n"; 2138 2139 $this->flush($sql_data); 2140 } 2141 $db->sql_freeresult($result); 2142 } 2143 2144 function write_table($table_name) 2145 { 2146 global $db; 2147 2148 $sql_data = '-- Table: ' . $table_name . "\n"; 2149 $sql_data .= "DROP TABLE $table_name;\n"; 2150 2151 $data_types = array(7 => 'SMALLINT', 8 => 'INTEGER', 10 => 'FLOAT', 12 => 'DATE', 13 => 'TIME', 14 => 'CHARACTER', 27 => 'DOUBLE PRECISION', 35 => 'TIMESTAMP', 37 => 'VARCHAR', 40 => 'CSTRING', 261 => 'BLOB', 701 => 'DECIMAL', 702 => 'NUMERIC'); 2152 2153 $sql_data .= "\nCREATE TABLE $table_name (\n"; 2154 2155 $sql = 'SELECT DISTINCT R.RDB$FIELD_NAME as FNAME, R.RDB$NULL_FLAG as NFLAG, R.RDB$DEFAULT_SOURCE as DSOURCE, F.RDB$FIELD_TYPE as FTYPE, F.RDB$FIELD_SUB_TYPE as STYPE, F.RDB$FIELD_LENGTH as FLEN 2156 FROM RDB$RELATION_FIELDS R 2157 JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME 2158 LEFT JOIN RDB$FIELD_DIMENSIONS D ON R.RDB$FIELD_SOURCE = D.RDB$FIELD_NAME 2159 WHERE F.RDB$SYSTEM_FLAG = 0 2160 AND R.RDB$RELATION_NAME = \''. $table_name . '\' 2161 ORDER BY R.RDB$FIELD_POSITION'; 2162 $result = $db->sql_query($sql); 2163 2164 $rows = array(); 2165 while ($row = $db->sql_fetchrow($result)) 2166 { 2167 $line = "\t" . '"' . $row['fname'] . '" ' . $data_types[$row['ftype']]; 2168 2169 if ($row['ftype'] == 261 && $row['stype'] == 1) 2170 { 2171 $line .= ' SUB_TYPE TEXT'; 2172 } 2173 2174 if ($row['ftype'] == 37 || $row['ftype'] == 14) 2175 { 2176 $line .= ' (' . $row['flen'] . ')'; 2177 } 2178 2179 if (!empty($row['dsource'])) 2180 { 2181 $line .= ' ' . $row['dsource']; 2182 } 2183 2184 if (!empty($row['nflag'])) 2185 { 2186 $line .= ' NOT NULL'; 2187 } 2188 $rows[] = $line; 2189 } 2190 $db->sql_freeresult($result); 2191 2192 $sql_data .= implode(",\n", $rows); 2193 $sql_data .= "\n);\n"; 2194 $keys = array(); 2195 2196 $sql = 'SELECT I.RDB$FIELD_NAME as NAME 2197 FROM RDB$RELATION_CONSTRAINTS RC, RDB$INDEX_SEGMENTS I, RDB$INDICES IDX 2198 WHERE (I.RDB$INDEX_NAME = RC.RDB$INDEX_NAME) 2199 AND (IDX.RDB$INDEX_NAME = RC.RDB$INDEX_NAME) 2200 AND (RC.RDB$RELATION_NAME = \''. $table_name . '\') 2201 ORDER BY I.RDB$FIELD_POSITION'; 2202 $result = $db->sql_query($sql); 2203 2204 while ($row = $db->sql_fetchrow($result)) 2205 { 2206 $keys[] = $row['name']; 2207 } 2208 2209 if (sizeof($keys)) 2210 { 2211 $sql_data .= "\nALTER TABLE $table_name ADD PRIMARY KEY (" . implode(', ', $keys) . ');'; 2212 } 2213 2214 $db->sql_freeresult($result); 2215 2216 $sql = 'SELECT I.RDB$INDEX_NAME as INAME, I.RDB$UNIQUE_FLAG as UFLAG, S.RDB$FIELD_NAME as FNAME 2217 FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON S.RDB$INDEX_NAME=I.RDB$INDEX_NAME 2218 WHERE (I.RDB$SYSTEM_FLAG IS NULL OR I.RDB$SYSTEM_FLAG=0) 2219 AND I.RDB$FOREIGN_KEY IS NULL 2220 AND I.RDB$RELATION_NAME = \''. $table_name . '\' 2221 AND I.RDB$INDEX_NAME NOT STARTING WITH \'RDB$\' 2222 ORDER BY S.RDB$FIELD_POSITION'; 2223 $result = $db->sql_query($sql); 2224 2225 $index = array(); 2226 while ($row = $db->sql_fetchrow($result)) 2227 { 2228 $index[$row['iname']]['unique'] = !empty($row['uflag']); 2229 $index[$row['iname']]['values'][] = $row['fname']; 2230 } 2231 2232 foreach ($index as $index_name => $data) 2233 { 2234 $sql_data .= "\nCREATE "; 2235 if ($data['unique']) 2236 { 2237 $sql_data .= 'UNIQUE '; 2238 } 2239 $sql_data .= "INDEX $index_name ON $table_name(" . implode(', ', $data['values']) . ");"; 2240 } 2241 $sql_data .= "\n"; 2242 2243 $db->sql_freeresult($result); 2244 2245 $sql = 'SELECT D1.RDB$DEPENDENT_NAME as DNAME, D1.RDB$FIELD_NAME as FNAME, D1.RDB$DEPENDENT_TYPE, R1.RDB$RELATION_NAME 2246 FROM RDB$DEPENDENCIES D1 2247 LEFT JOIN RDB$RELATIONS R1 ON ((D1.RDB$DEPENDENT_NAME = R1.RDB$RELATION_NAME) AND (NOT (R1.RDB$VIEW_BLR IS NULL))) 2248 WHERE (D1.RDB$DEPENDED_ON_TYPE = 0) 2249 AND (D1.RDB$DEPENDENT_TYPE <> 3) 2250 AND (D1.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\') 2251 UNION SELECT DISTINCT F2.RDB$RELATION_NAME, D2.RDB$FIELD_NAME, D2.RDB$DEPENDENT_TYPE, R2.RDB$RELATION_NAME FROM RDB$DEPENDENCIES D2, RDB$RELATION_FIELDS F2 2252 LEFT JOIN RDB$RELATIONS R2 ON ((F2.RDB$RELATION_NAME = R2.RDB$RELATION_NAME) AND (NOT (R2.RDB$VIEW_BLR IS NULL))) 2253 WHERE (D2.RDB$DEPENDENT_TYPE = 3) 2254 AND (D2.RDB$DEPENDENT_NAME = F2.RDB$FIELD_SOURCE) 2255 AND (D2.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\') 2256 ORDER BY 1, 2'; 2257 $result = $db->sql_query($sql); 2258 while ($row = $db->sql_fetchrow($result)) 2259 { 2260 $sql = 'SELECT T1.RDB$DEPENDED_ON_NAME as GEN, T1.RDB$FIELD_NAME, T1.RDB$DEPENDED_ON_TYPE 2261 FROM RDB$DEPENDENCIES T1 2262 WHERE (T1.RDB$DEPENDENT_NAME = \'' . $row['dname'] . '\') 2263 AND (T1.RDB$DEPENDENT_TYPE = 2 AND T1.RDB$DEPENDED_ON_TYPE = 14) 2264 UNION ALL SELECT DISTINCT D.RDB$DEPENDED_ON_NAME, D.RDB$FIELD_NAME, D.RDB$DEPENDED_ON_TYPE 2265 FROM RDB$DEPENDENCIES D, RDB$RELATION_FIELDS F 2266 WHERE (D.RDB$DEPENDENT_TYPE = 3) 2267 AND (D.RDB$DEPENDENT_NAME = F.RDB$FIELD_SOURCE) 2268 AND (F.RDB$RELATION_NAME = \'' . $row['dname'] . '\') 2269 ORDER BY 1,2'; 2270 $result2 = $db->sql_query($sql); 2271 $row2 = $db->sql_fetchrow($result2); 2272 $db->sql_freeresult($result2); 2273 $gen_name = $row2['gen']; 2274 2275 $sql_data .= "\nDROP GENERATOR " . $gen_name . ";"; 2276 $sql_data .= "\nSET TERM ^ ;"; 2277 $sql_data .= "\nCREATE GENERATOR " . $gen_name . "^"; 2278 $sql_data .= "\nSET GENERATOR " . $gen_name . " TO 0^\n"; 2279 $sql_data .= "\nCREATE TRIGGER {$row['dname']} FOR $table_name"; 2280 $sql_data .= "\nBEFORE INSERT\nAS\nBEGIN"; 2281 $sql_data .= "\n NEW.{$row['fname']} = GEN_ID(" . $gen_name . ", 1);"; 2282 $sql_data .= "\nEND^\n"; 2283 $sql_data .= "\nSET TERM ; ^\n"; 2284 } 2285 2286 $this->flush($sql_data); 2287 2288 $db->sql_freeresult($result); 2289 } 2290 } 2291 2292 // get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P) 2293 function get_usable_memory() 2294 { 2295 $val = trim(@ini_get('memory_limit')); 2296 2297 if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs)) 2298 { 2299 $memory_limit = (int) $regs[1]; 2300 switch ($regs[2]) 2301 { 2302 2303 case 'k': 2304 case 'K': 2305 $memory_limit *= 1024; 2306 break; 2307 2308 case 'm': 2309 case 'M': 2310 $memory_limit *= 1048576; 2311 break; 2312 2313 case 'g': 2314 case 'G': 2315 $memory_limit *= 1073741824; 2316 break; 2317 } 2318 2319 // how much memory PHP requires at the start of export (it is really a little less) 2320 if ($memory_limit > 6100000) 2321 { 2322 $memory_limit -= 6100000; 2323 } 2324 2325 // allow us to consume half of the total memory available 2326 $memory_limit /= 2; 2327 } 2328 else 2329 { 2330 // set the buffer to 1M if we have no clue how much memory PHP will give us :P 2331 $memory_limit = 1048576; 2332 } 2333 2334 return $memory_limit; 2335 } 2336 2337 function sanitize_data_mssql($text) 2338 { 2339 $data = preg_split('/[\n\t\r\b\f]/', $text); 2340 preg_match_all('/[\n\t\r\b\f]/', $text, $matches); 2341 2342 $val = array(); 2343 2344 foreach ($data as $value) 2345 { 2346 if (strlen($value)) 2347 { 2348 $val[] = "'" . $value . "'"; 2349 } 2350 if (sizeof($matches[0])) 2351 { 2352 $val[] = 'char(' . ord(array_shift($matches[0])) . ')'; 2353 } 2354 } 2355 2356 return implode('+', $val); 2357 } 2358 2359 function sanitize_data_oracle($text) 2360 { 2361 // $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text); 2362 // preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches); 2363 $data = preg_split('/[\0\b\f\'\/]/', $text); 2364 preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches); 2365 2366 $val = array(); 2367 2368 foreach ($data as $value) 2369 { 2370 if (strlen($value)) 2371 { 2372 $val[] = "'" . $value . "'"; 2373 } 2374 if (sizeof($matches[0])) 2375 { 2376 $val[] = 'chr(' . ord(array_shift($matches[0])) . ')'; 2377 } 2378 } 2379 2380 return implode('||', $val); 2381 } 2382 2383 function sanitize_data_generic($text) 2384 { 2385 $data = preg_split('/[\n\t\r\b\f]/', $text); 2386 preg_match_all('/[\n\t\r\b\f]/', $text, $matches); 2387 2388 $val = array(); 2389 2390 foreach ($data as $value) 2391 { 2392 if (strlen($value)) 2393 { 2394 $val[] = "'" . $value . "'"; 2395 } 2396 if (sizeof($matches[0])) 2397 { 2398 $val[] = "'" . array_shift($matches[0]) . "'"; 2399 } 2400 } 2401 2402 return implode('||', $val); 2403 } 2404 2405 // modified from PHP.net 2406 function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) 2407 { 2408 $record = ''; 2409 $delim_len = strlen($delim); 2410 2411 while (!$eof($fp)) 2412 { 2413 $pos = strpos($record, $delim); 2414 if ($pos === false) 2415 { 2416 $record .= $read($fp, $buffer); 2417 if ($eof($fp) && ($pos = strpos($record, $delim)) !== false) 2418 { 2419 $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); 2420 return substr($record, 0, $pos); 2421 } 2422 } 2423 else 2424 { 2425 $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); 2426 return substr($record, 0, $pos); 2427 } 2428 } 2429 2430 return false; 2431 } 2432 2433 function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) 2434 { 2435 static $array = array(); 2436 static $record = ''; 2437 2438 if (!sizeof($array)) 2439 { 2440 while (!$eof($fp)) 2441 { 2442 if (strpos($record, $delim) !== false) 2443 { 2444 $array = explode($delim, $record); 2445 $record = array_pop($array); 2446 break; 2447 } 2448 else 2449 { 2450 $record .= $read($fp, $buffer); 2451 } 2452 } 2453 if ($eof($fp) && strpos($record, $delim) !== false) 2454 { 2455 $array = explode($delim, $record); 2456 $record = array_pop($array); 2457 } 2458 } 2459 2460 if (sizeof($array)) 2461 { 2462 return array_shift($array); 2463 } 2464 2465 return false; 2466 } 2467 2468 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Oct 2 15:03:47 2013 | Cross-referenced by PHPXref 0.7.1 |