6 * @copyright (c) 2005 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
14 if (!defined('IN_PHPBB'))
26 function main($id, $mode)
28 global $db, $user, $auth, $template, $table_prefix;
30 $user->add_lang('acp/database');
32 $this->tpl_name
= 'acp_database';
33 $this->page_title
= 'ACP_DATABASE';
35 $action = request_var('action', '');
36 $submit = phpbb_request
::is_set_post('submit');
38 $template->assign_vars(array(
46 $this->page_title
= 'ACP_BACKUP';
51 $type = request_var('type', '');
52 $table = request_var('table', array(''));
53 $format = request_var('method', '');
54 $where = request_var('where', '');
58 trigger_error($user->lang
['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action
), E_USER_WARNING
);
61 $store = $download = $structure = $schema_data = false;
63 if ($where == 'store_and_download' ||
$where == 'store')
68 if ($where == 'store_and_download' ||
$where == 'download')
73 if ($type == 'full' ||
$type == 'structure')
78 if ($type == 'full' ||
$type == 'data')
83 @set_time_limit
(1200);
87 $filename = 'backup_' . $time . '_' . unique_id();
88 switch ($db->dbms_type
)
91 $extractor = new mysql_extractor($download, $store, $format, $filename, $time);
95 $extractor = new sqlite_extractor($download, $store, $format, $filename, $time);
99 $extractor = new postgres_extractor($download, $store, $format, $filename, $time);
103 $extractor = new oracle_extractor($download, $store, $format, $filename, $time);
107 $extractor = new mssql_extractor($download, $store, $format, $filename, $time);
111 $extractor = new firebird_extractor($download, $store, $format, $filename, $time);
115 $extractor = new db2_extractor($download, $store, $format, $filename, $time);
119 $extractor->write_start($table_prefix);
121 foreach ($table as $table_name)
123 // Get the table structure
126 $extractor->write_table($table_name);
130 // We might wanna empty out all that junk :D
131 switch ($db->dbms_type
)
136 $extractor->flush('DELETE FROM ' . $table_name . ";\n");
140 $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
144 $extractor->flush('TRUNCATE TABLE ' . $table_name . "\\\n");
148 $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
156 $extractor->write_data($table_name);
160 $extractor->write_end();
162 add_log('admin', 'LOG_DB_BACKUP');
164 if ($download == true)
169 trigger_error($user->lang
['BACKUP_SUCCESS'] . adm_back_link($this->u_action
));
173 include(PHPBB_ROOT_PATH
. 'includes/functions_install.' . PHP_EXT
);
174 $tables = get_tables($db);
176 foreach ($tables as $table_name)
178 if (strlen($table_prefix) === 0 ||
stripos($table_name, $table_prefix) === 0)
180 $template->assign_block_vars('tables', array(
181 'TABLE' => $table_name
187 $template->assign_vars(array(
188 'U_ACTION' => $this->u_action
. '&action=download'
191 $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
193 foreach ($available_methods as $type => $module)
195 if (!@extension_loaded
($module))
200 $template->assign_block_vars('methods', array(
205 $template->assign_block_vars('methods', array(
214 $this->page_title
= 'ACP_RESTORE';
219 $delete = request_var('delete', '');
220 $file = request_var('file', '');
222 if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
224 trigger_error($user->lang
['BACKUP_INVALID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
227 $file_name = PHPBB_ROOT_PATH
. 'store/' . $matches[0];
229 if (!file_exists($file_name) ||
!is_readable($file_name))
231 trigger_error($user->lang
['BACKUP_INVALID'] . adm_back_link($this->u_action
), E_USER_WARNING
);
236 if (confirm_box(true))
239 add_log('admin', 'LOG_DB_DELETE');
240 trigger_error($user->lang
['BACKUP_DELETE'] . adm_back_link($this->u_action
));
244 confirm_box(false, $user->lang
['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
249 $download = request_var('download', '');
258 $mimetype = 'text/x-sql';
261 $mimetype = 'application/x-bzip2';
264 $mimetype = 'application/x-gzip';
268 header('Pragma: no-cache');
269 header("Content-Type: $mimetype; name=\"$name\"");
270 header("Content-disposition: attachment; filename=$name");
274 $fp = @fopen
($file_name, 'rb');
280 echo fread($fp, 8192);
292 $fp = fopen($file_name, 'rb');
301 $fp = bzopen($file_name, 'r');
306 $fgetd = 'fgetd_seekless';
310 $fp = gzopen($file_name, 'rb');
319 switch ($db->dbms_type
)
324 while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
326 $db->sql_query($sql);
332 while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
335 if (substr($query, 0, 8) === 'SET TERM')
337 $delim = $query[9] . "\n";
340 $db->sql_query($query);
346 while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
350 if (substr($query, 0, 13) == 'CREATE DOMAIN')
352 list(, , $domain) = explode(' ', $query);
353 $sql = "SELECT domain_name
354 FROM information_schema.domains
355 WHERE domain_name = '$domain';";
356 $result = $db->sql_query($sql);
357 if (!$db->sql_fetchrow($result))
359 $db->sql_query($query);
361 $db->sql_freeresult($result);
365 $db->sql_query($query);
368 if (substr($query, 0, 4) == 'COPY')
370 while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
374 trigger_error($user->lang
['RESTORE_FAILURE'] . adm_back_link($this->u_action
), E_USER_WARNING
);
376 pg_put_line($db->db_connect_id
, $sub . "\n");
378 pg_put_line($db->db_connect_id
, "\\.\n");
379 pg_end_copy($db->db_connect_id
);
385 while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
387 $db->sql_query($sql);
392 while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
394 $db->sql_query($sql);
401 // Purge the cache due to updated data
402 phpbb
::$acm->purge();
404 add_log('admin', 'LOG_DB_RESTORE');
405 trigger_error($user->lang
['RESTORE_SUCCESS'] . adm_back_link($this->u_action
));
410 $methods = array('sql');
411 $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
413 foreach ($available_methods as $type => $module)
415 if (!@extension_loaded
($module))
422 $dir = PHPBB_ROOT_PATH
. 'store/';
423 $dh = @opendir
($dir);
427 while (($file = readdir($dh)) !== false)
429 if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
431 $supported = in_array($matches[2], $methods);
433 if ($supported == 'true')
435 $template->assign_block_vars('files', array(
437 'NAME' => gmdate("d-m-Y H:i:s", $matches[1]),
438 'SUPPORTED' => $supported
446 $template->assign_vars(array(
447 'U_ACTION' => $this->u_action
. '&action=submit'
469 var $run_comp = false;
471 function __construct($download = false, $store = false, $format, $filename, $time)
473 $this->download
= $download;
474 $this->store
= $store;
476 $this->format
= $format;
483 $this->write
= 'fwrite';
484 $this->close
= 'fclose';
485 $mimetype = 'text/x-sql';
490 $this->write
= 'bzwrite';
491 $this->close
= 'bzclose';
492 $mimetype = 'application/x-bzip2';
497 $this->write
= 'gzwrite';
498 $this->close
= 'gzclose';
499 $mimetype = 'application/x-gzip';
503 if ($download == true)
505 $name = $filename . $ext;
506 header('Pragma: no-cache');
507 header("Content-Type: $mimetype; name=\"$name\"");
508 header("Content-disposition: attachment; filename=$name");
517 if ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'msie') === false)
519 ob_start('ob_gzhandler');
523 $this->run_comp
= true;
531 $file = PHPBB_ROOT_PATH
. 'store/' . $filename . $ext;
533 $this->fp
= $open($file, 'w');
537 trigger_error('Unable to write temporary file to storage folder', E_USER_ERROR
);
549 $close = $this->close
;
554 // bzip2 must be written all the way at the end
555 if ($this->download
&& $this->format
=== 'bzip2')
562 function flush($data)
565 if ($this->store
=== true)
569 $write = $this->write
;
571 $write($this->fp
, $data);
574 if ($this->download
=== true)
576 if ($this->format
=== 'bzip2' ||
$this->format
=== 'text' ||
($this->format
=== 'gzip' && !$this->run_comp
))
581 // we can write the gzip data as soon as we get it
582 if ($this->format
=== 'gzip')
586 echo gzencode($data);
601 class mysql_extractor
extends base_extractor
603 function write_start($table_prefix)
606 $sql_data .= "# phpBB Backup Script\n";
607 $sql_data .= "# Dump of tables for $table_prefix\n";
608 $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
610 $this->flush($sql_data);
613 function write_table($table_name)
617 $sql = 'SHOW CREATE TABLE ' . $table_name;
618 $result = $db->sql_query($sql);
619 $row = $db->sql_fetchrow($result);
621 $sql_data = '# Table: ' . $table_name . "\n";
622 $sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
623 $this->flush($sql_data . $row['Create Table'] . ";\n\n");
625 $db->sql_freeresult($result);
628 function write_data($table_name)
631 if ($db->sql_layer
=== 'mysqli')
633 $this->write_data_mysqli($table_name);
637 $this->write_data_mysql($table_name);
641 function write_data_mysqli($table_name)
646 $result = mysqli_query($db->db_connect_id
, $sql, MYSQLI_USE_RESULT
);
647 if ($result != false)
649 $fields_cnt = mysqli_num_fields($result);
651 // Get field information
652 $field = mysqli_fetch_fields($result);
653 $field_set = array();
655 for ($j = 0; $j < $fields_cnt; $j++
)
657 $field_set[] = $field[$j]->name
;
660 $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
661 $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
662 $fields = implode(', ', $field_set);
663 $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
666 $max_len = get_usable_memory();
668 while ($row = mysqli_fetch_row($result))
673 $query = $sql_data . '(';
680 for ($j = 0; $j < $fields_cnt; $j++
)
682 if (!isset($row[$j]) ||
is_null($row[$j]))
684 $values[$j] = 'NULL';
686 else if (($field[$j]->flags
& 32768) && !($field[$j]->flags
& 1024))
688 $values[$j] = $row[$j];
692 $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
695 $query .= implode(', ', $values) . ')';
697 $query_len +
= strlen($query);
698 if ($query_len > $max_len)
700 $this->flush($query . ";\n\n");
710 mysqli_free_result($result);
712 // check to make sure we have nothing left to flush
713 if (!$first_set && $query)
715 $this->flush($query . ";\n\n");
720 function write_data_mysql($table_name)
725 $result = mysql_unbuffered_query($sql, $db->db_connect_id
);
727 if ($result != false)
729 $fields_cnt = mysql_num_fields($result);
731 // Get field information
733 for ($i = 0; $i < $fields_cnt; $i++
)
735 $field[] = mysql_fetch_field($result, $i);
737 $field_set = array();
739 for ($j = 0; $j < $fields_cnt; $j++
)
741 $field_set[] = $field[$j]->name
;
744 $search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
745 $replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
746 $fields = implode(', ', $field_set);
747 $sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
750 $max_len = get_usable_memory();
752 while ($row = mysql_fetch_row($result))
757 $query = $sql_data . '(';
764 for ($j = 0; $j < $fields_cnt; $j++
)
766 if (!isset($row[$j]) ||
is_null($row[$j]))
768 $values[$j] = 'NULL';
770 else if ($field[$j]->numeric && ($field[$j]->type
!== 'timestamp'))
772 $values[$j] = $row[$j];
776 $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
779 $query .= implode(', ', $values) . ')';
781 $query_len +
= strlen($query);
782 if ($query_len > $max_len)
784 $this->flush($query . ";\n\n");
794 mysql_free_result($result);
796 // check to make sure we have nothing left to flush
797 if (!$first_set && $query)
799 $this->flush($query . ";\n\n");
808 class sqlite_extractor
extends base_extractor
810 function write_start($prefix)
813 $sql_data .= "-- phpBB Backup Script\n";
814 $sql_data .= "-- Dump of tables for $prefix\n";
815 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
817 $sql_data .= "BEGIN TRANSACTION;\n";
818 $this->flush($sql_data);
821 function write_table($table_name)
824 $sql_data = '-- Table: ' . $table_name . "\n";
825 $sql_data .= "DROP TABLE $table_name;\n";
830 AND name = '" . $db->sql_escape($table_name) . "'
831 ORDER BY type DESC, name;";
832 $result = $db->sql_query($sql);
833 $row = $db->sql_fetchrow($result);
834 $db->sql_freeresult($result);
837 $sql_data .= $row['sql'] . ";\n";
839 $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
842 while ($row = $db->sql_fetchrow($result))
846 $db->sql_freeresult($result);
848 foreach ($ar as $value)
850 if (strpos($value['name'], 'autoindex') !== false)
855 $result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
858 while ($row = $db->sql_fetchrow($result))
860 $fields[] = $row['name'];
862 $db->sql_freeresult($result);
864 $sql_data .= 'CREATE ' . ($value['unique'] ?
'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
867 $this->flush($sql_data . "\n");
870 function write_data($table_name)
875 if (is_null($proper))
877 $proper = version_compare(PHP_VERSION
, '5.1.3', '>=');
882 $col_types = sqlite_fetch_column_types($db->db_connect_id
, $table_name);
889 AND name = '" . $table_name . "'";
890 $table_data = sqlite_single_query($db->db_connect_id
, $sql);
891 $table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data);
892 $table_data = trim($table_data);
894 preg_match('#\((.*)\)#s', $table_data, $matches);
896 $table_cols = explode(',', trim($matches[1]));
897 foreach ($table_cols as $declaration)
899 $entities = preg_split('#\s+#', trim($declaration));
900 $column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]);
902 // Hit a primary key, those are not what we need :D
903 if (empty($entities[1]) ||
(strtolower($entities[0]) === 'primary' && strtolower($entities[1]) === 'key'))
907 $col_types[$column_name] = $entities[1];
913 $result = sqlite_unbuffered_query($db->db_connect_id
, $sql);
914 $rows = sqlite_fetch_all($result, SQLITE_ASSOC
);
915 $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
916 foreach ($rows as $row)
918 foreach ($row as $column_name => $column_data)
920 if (is_null($column_data))
922 $row[$column_name] = 'NULL';
924 else if ($column_data == '')
926 $row[$column_name] = "''";
928 else if (strpos($col_types[$column_name], 'text') !== false ||
strpos($col_types[$column_name], 'char') !== false ||
strpos($col_types[$column_name], 'blob') !== false)
930 $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
933 $this->flush($sql_insert . implode(', ', $row) . ");\n");
939 $this->flush("COMMIT;\n");
947 class postgres_extractor
extends base_extractor
949 function write_start($prefix)
952 $sql_data .= "-- phpBB Backup Script\n";
953 $sql_data .= "-- Dump of tables for $prefix\n";
954 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
956 $sql_data .= "BEGIN TRANSACTION;\n";
957 $this->flush($sql_data);
960 function write_table($table_name)
963 static $domains_created = array();
965 $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
966 FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
967 WHERE a.domain_name = b.domain_name
968 AND b.table_name = '{$table_name}'";
969 $result = $db->sql_query($sql);
970 while ($row = $db->sql_fetchrow($result))
972 if (empty($domains_created[$row['domain_name']]))
974 $domains_created[$row['domain_name']] = true;
975 //$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
976 $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
977 if (!empty($row['character_maximum_length']))
979 $sql_data .= '(' . $row['character_maximum_length'] . ')';
981 $sql_data .= ' NOT NULL';
982 if (!empty($row['domain_default']))
984 $sql_data .= ' DEFAULT ' . $row['domain_default'];
986 $this->flush($sql_data . ";\n");
990 $sql_data = '-- Table: ' . $table_name . "\n";
991 $sql_data .= "DROP TABLE $table_name;\n";
992 // PGSQL does not "tightly" bind sequences and tables, we must guess...
993 $sql = "SELECT relname
996 AND relname = '{$table_name}_seq'";
997 $result = $db->sql_query($sql);
998 // We don't even care about storing the results. We already know the answer if we get rows back.
999 if ($db->sql_fetchrow($result))
1001 $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
1002 $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
1004 $db->sql_freeresult($result);
1006 $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
1007 FROM pg_class c, pg_attribute a, pg_type t
1008 WHERE c.relname = '" . $db->sql_escape($table_name) . "'
1010 AND a.attrelid = c.oid
1011 AND a.atttypid = t.oid
1013 $result = $db->sql_query($field_query);
1015 $sql_data .= "CREATE TABLE $table_name(\n";
1017 while ($row = $db->sql_fetchrow($result))
1019 // Get the data from the table
1020 $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1021 FROM pg_attrdef d, pg_class c
1022 WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
1023 AND (c.oid = d.adrelid)
1024 AND d.adnum = " . $row['attnum'];
1025 $def_res = $db->sql_query($sql_get_default);
1029 unset($row['rowdefault']);
1033 $row['rowdefault'] = $db->sql_fetchfield('rowdefault', $def_res);
1035 $db->sql_freeresult($def_res);
1037 if ($row['type'] == 'bpchar')
1039 // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
1040 $row['type'] = 'char';
1043 $line = ' ' . $row['field'] . ' ' . $row['type'];
1045 if (strpos($row['type'], 'char') !== false)
1047 if ($row['lengthvar'] > 0)
1049 $line .= '(' . ($row['lengthvar'] - 4) . ')';
1053 if (strpos($row['type'], 'numeric') !== false)
1056 $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
1060 if (isset($row['rowdefault']))
1062 $line .= ' DEFAULT ' . $row['rowdefault'];
1065 if ($row['notnull'] == 't')
1067 $line .= ' NOT NULL';
1072 $db->sql_freeresult($result);
1075 // Get the listing of primary keys.
1076 $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
1077 FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
1078 WHERE (bc.oid = i.indrelid)
1079 AND (ic.oid = i.indexrelid)
1080 AND (ia.attrelid = i.indexrelid)
1081 AND (ta.attrelid = bc.oid)
1082 AND (bc.relname = '" . $db->sql_escape($table_name) . "')
1083 AND (ta.attrelid = i.indrelid)
1084 AND (ta.attnum = i.indkey[ia.attnum-1])
1085 ORDER BY index_name, tab_name, column_name";
1087 $result = $db->sql_query($sql_pri_keys);
1089 $index_create = $index_rows = $primary_key = array();
1091 // We do this in two steps. It makes placing the comma easier
1092 while ($row = $db->sql_fetchrow($result))
1094 if ($row['primary_key'] == 't')
1096 $primary_key[] = $row['column_name'];
1097 $primary_key_name = $row['index_name'];
1101 // We have to store this all this info because it is possible to have a multi-column key...
1102 // we can loop through it again and build the statement
1103 $index_rows[$row['index_name']]['table'] = $table_name;
1104 $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ?
true : false;
1105 $index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
1108 $db->sql_freeresult($result);
1110 if (!empty($index_rows))
1112 foreach ($index_rows as $idx_name => $props)
1114 $index_create[] = 'CREATE ' . ($props['unique'] ?
'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
1118 if (!empty($primary_key))
1120 $lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
1123 // Generate constraint clauses for CHECK constraints
1124 $sql_checks = "SELECT conname as index_name, consrc
1125 FROM pg_constraint, pg_class bc
1126 WHERE conrelid = bc.oid
1127 AND bc.relname = '" . $db->sql_escape($table_name) . "'
1130 FROM pg_constraint as c, pg_inherits as i
1131 WHERE i.inhrelid = pg_constraint.conrelid
1132 AND c.conname = pg_constraint.conname
1133 AND c.consrc = pg_constraint.consrc
1134 AND c.conrelid = i.inhparent
1136 $result = $db->sql_query($sql_checks);
1138 // Add the constraints to the sql file.
1139 while ($row = $db->sql_fetchrow($result))
1141 if (!is_null($row['consrc']))
1143 $lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
1146 $db->sql_freeresult($result);
1148 $sql_data .= implode(", \n", $lines);
1149 $sql_data .= "\n);\n";
1151 if (!empty($index_create))
1153 $sql_data .= implode("\n", $index_create) . "\n\n";
1155 $this->flush($sql_data);
1158 function write_data($table_name)
1161 // Grab all of the data from current table.
1164 $result = $db->sql_query($sql);
1166 $i_num_fields = pg_num_fields($result);
1169 for ($i = 0; $i < $i_num_fields; $i++
)
1171 $ary_type[] = pg_field_type($result, $i);
1172 $ary_name[] = pg_field_name($result, $i);
1175 $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1176 FROM pg_attrdef d, pg_class c
1177 WHERE (c.relname = '{$table_name}')
1178 AND (c.oid = d.adrelid)
1179 AND d.adnum = " . strval($i +
1);
1180 $result2 = $db->sql_query($sql);
1181 if ($row = $db->sql_fetchrow($result2))
1183 // Determine if we must reset the sequences
1184 if (strpos($row['rowdefault'], "nextval('") === 0)
1186 $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";
1191 $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
1192 while ($row = $db->sql_fetchrow($result))
1194 $schema_vals = array();
1196 // Build the SQL statement to recreate the data.
1197 for ($i = 0; $i < $i_num_fields; $i++
)
1199 $str_val = $row[$ary_name[$i]];
1201 if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
1203 $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
1211 if (empty($str_val) && $str_val !== '0')
1213 $str_val = $str_empty;
1216 $schema_vals[] = $str_val;
1219 // Take the ordered fields and their associated data and build it
1220 // into a valid sql statement to recreate that field in the data.
1221 $this->flush(implode("\t", $schema_vals) . "\n");
1223 $db->sql_freeresult($result);
1224 $this->flush("\\.\n");
1226 // Write out the sequence statements
1230 function write_end()
1232 $this->flush("COMMIT;\n");
1233 parent
::write_end();
1240 class mssql_extractor
extends base_extractor
1242 function write_end()
1244 $this->flush("COMMIT\nGO\n");
1245 parent
::write_end();
1248 function write_start($prefix)
1251 $sql_data .= "-- phpBB Backup Script\n";
1252 $sql_data .= "-- Dump of tables for $prefix\n";
1253 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
1254 $sql_data .= "--\n";
1255 $sql_data .= "BEGIN TRANSACTION\n";
1256 $sql_data .= "GO\n";
1257 $this->flush($sql_data);
1260 function write_table($table_name)
1263 $sql_data = '-- Table: ' . $table_name . "\n";
1264 $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
1265 $sql_data .= "DROP TABLE $table_name;\n";
1266 $sql_data .= "GO\n";
1267 $sql_data .= "\nCREATE TABLE [$table_name] (\n";
1272 $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
1273 FROM INFORMATION_SCHEMA.COLUMNS
1274 WHERE TABLE_NAME = '$table_name'";
1275 $result = $db->sql_query($sql);
1277 while ($row = $db->sql_fetchrow($result))
1279 $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
1281 if ($row['DATA_TYPE'] == 'text')
1286 if ($row['IS_IDENTITY'])
1288 $line .= ' IDENTITY (1 , 1)';
1291 if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
1293 $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
1296 if ($row['IS_NULLABLE'] == 'YES')
1302 $line .= ' NOT NULL';
1305 if ($row['COLUMN_DEFAULT'])
1307 $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
1312 $db->sql_freeresult($result);
1314 $sql_data .= implode(",\n", $rows);
1315 $sql_data .= "\n) ON [PRIMARY]";
1319 $sql_data .= " TEXTIMAGE_ON [PRIMARY]";
1322 $sql_data .= "\nGO\n\n";
1325 $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
1326 FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
1327 WHERE TABLE_NAME = '$table_name'";
1328 $result = $db->sql_query($sql);
1329 while ($row = $db->sql_fetchrow($result))
1333 $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
1334 $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n";
1336 $rows[] = "\t\t[{$row['COLUMN_NAME']}]";
1340 $sql_data .= implode(",\n", $rows);
1341 $sql_data .= "\n\t) ON [PRIMARY] \nGO\n";
1343 $db->sql_freeresult($result);
1346 $sql = "EXEC sp_statistics '$table_name'";
1347 $result = $db->sql_query($sql);
1348 while ($row = $db->sql_fetchrow($result))
1350 if ($row['TYPE'] == 3)
1352 $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
1355 $db->sql_freeresult($result);
1357 foreach ($index as $index_name => $column_name)
1359 $index[$index_name] = implode(', ', $column_name);
1362 foreach ($index as $index_name => $columns)
1364 $sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
1366 $this->flush($sql_data);
1369 function write_data($table_name)
1373 if ($db->sql_layer
=== 'mssql')
1375 $this->write_data_mssql($table_name);
1377 else if ($db->sql_layer
=== 'mssql_odbc')
1379 $this->write_data_odbc($table_name);
1383 // @todo: write code for MS SQL 2005 DBAL
1384 trigger_error('KungFuDeathGrip');
1388 function write_data_mssql($table_name)
1391 $ary_type = $ary_name = array();
1395 // Grab all of the data from current table.
1398 $result = $db->sql_query($sql);
1400 $retrieved_data = mssql_num_rows($result);
1402 $i_num_fields = mssql_num_fields($result);
1404 for ($i = 0; $i < $i_num_fields; $i++
)
1406 $ary_type[$i] = mssql_field_type($result, $i);
1407 $ary_name[$i] = mssql_field_name($result, $i);
1410 if ($retrieved_data)
1412 $sql = "SELECT 1 as has_identity
1413 FROM INFORMATION_SCHEMA.COLUMNS
1414 WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1415 $result2 = $db->sql_query($sql);
1416 $row2 = $db->sql_fetchrow($result2);
1417 if (!empty($row2['has_identity']))
1419 $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1422 $db->sql_freeresult($result2);
1425 while ($row = $db->sql_fetchrow($result))
1427 $schema_vals = $schema_fields = array();
1429 // Build the SQL statement to recreate the data.
1430 for ($i = 0; $i < $i_num_fields; $i++
)
1432 $str_val = $row[$ary_name[$i]];
1434 if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1438 $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1440 else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1442 if (empty($str_val))
1454 $str_empty = 'NULL';
1457 if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) ||
is_float($str_val)))
1459 $str_val = $str_empty;
1462 $schema_vals[$i] = $str_quote . $str_val . $str_quote;
1463 $schema_fields[$i] = $ary_name[$i];
1466 // Take the ordered fields and their associated data and build it
1467 // into a valid sql statement to recreate that field in the data.
1468 $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1470 $this->flush($sql_data);
1473 $db->sql_freeresult($result);
1475 if ($retrieved_data && $ident_set)
1477 $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1479 $this->flush($sql_data);
1482 function write_data_odbc($table_name)
1485 $ary_type = $ary_name = array();
1489 // Grab all of the data from current table.
1492 $result = $db->sql_query($sql);
1494 $retrieved_data = odbc_num_rows($result);
1496 if ($retrieved_data)
1498 $sql = "SELECT 1 as has_identity
1499 FROM INFORMATION_SCHEMA.COLUMNS
1500 WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1501 $result2 = $db->sql_query($sql);
1502 $row2 = $db->sql_fetchrow($result2);
1503 if (!empty($row2['has_identity']))
1505 $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1508 $db->sql_freeresult($result2);
1511 $i_num_fields = odbc_num_fields($result);
1513 for ($i = 0; $i < $i_num_fields; $i++
)
1515 $ary_type[$i] = odbc_field_type($result, $i +
1);
1516 $ary_name[$i] = odbc_field_name($result, $i +
1);
1519 while ($row = $db->sql_fetchrow($result))
1521 $schema_vals = $schema_fields = array();
1523 // Build the SQL statement to recreate the data.
1524 for ($i = 0; $i < $i_num_fields; $i++
)
1526 $str_val = $row[$ary_name[$i]];
1528 if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1532 $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1534 else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1536 if (empty($str_val))
1548 $str_empty = 'NULL';
1551 if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) ||
is_float($str_val)))
1553 $str_val = $str_empty;
1556 $schema_vals[$i] = $str_quote . $str_val . $str_quote;
1557 $schema_fields[$i] = $ary_name[$i];
1560 // Take the ordered fields and their associated data and build it
1561 // into a valid sql statement to recreate that field in the data.
1562 $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1564 $this->flush($sql_data);
1569 $db->sql_freeresult($result);
1571 if ($retrieved_data && $ident_set)
1573 $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1575 $this->flush($sql_data);
1583 class db2_extractor
extends base_extractor
1585 function write_start($prefix)
1588 $sql_data .= "-- phpBB Backup Script\n";
1589 $sql_data .= "-- Dump of tables for $prefix\n";
1590 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
1591 $sql_data .= "--\n";
1592 $this->flush($sql_data);
1595 function write_table($table_name)
1598 $sql_data = '-- Table: ' . $table_name . "\n";
1599 $sql_data .= "\nCREATE TABLE $table_name (\n";
1602 // switch to db2_columns()?
1603 $sql = "SELECT colname, typename, length, default, identity, nulls
1605 WHERE tabname = '$table_name'";
1606 $result = $db->sql_query($sql);
1608 while ($row = $db->sql_fetchrow($result))
1610 $line = "\t{$row['colname']} {$row['typename']}";
1612 if ($row['identity'] == 'Y')
1614 $line .= ' GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1)';
1617 if ($row['typename'] == 'VARCHAR' ||
$row['typename'] == 'CHARACTER' ||
$row['typename'] == 'CLOB')
1619 $line .= ' (' . $row['length'] . ')';
1622 if ($row['nulls'] == 'N')
1624 $line .= ' NOT NULL';
1631 if ($row['default'] !== null)
1633 $line .= ' DEFAULT ' . $row['default'];
1638 $db->sql_freeresult($result);
1640 // switch to db2_columns()?
1641 $sql = "SELECT colname
1642 FROM SYSCAT.KEYCOLUSE
1643 WHERE tabname = '$table_name'";
1644 $result = $db->sql_query($sql);
1645 $prim_cols = array();
1646 while ($row = $db->sql_fetchrow($result))
1648 $prim_cols[] = $row['colname'];
1650 $db->sql_freeresult($result);
1651 if (sizeof($prim_cols))
1653 $rows[] = "\tPRIMARY KEY (" . implode($prim_cols) . ')';
1656 $sql_data .= implode(",\n", $rows);
1657 $sql_data .= "\n);\n\n";
1660 $sql = "SELECT colnames, indname
1662 WHERE TABNAME = '$table_name'
1663 AND UNIQUERULE <> 'P'";
1664 $result = $db->sql_query($sql);
1666 while ($row = $db->sql_fetchrow($result))
1668 $inds = explode('+', $row['colnames']);
1670 $sql_data .= 'CREATE INDEX ' . $row['indname'] . ' ON ' . $table_name . ' (' . implode(', ', $inds) . ") PCTFREE 10 MINPCTUSED 10 ALLOW REVERSE SCANS PAGE SPLIT SYMMETRIC COLLECT SAMPLED DETAILED STATISTICS;\n";
1672 $db->sql_freeresult($result);
1674 $this->flush($sql_data);
1677 function write_data($table_name)
1680 $ary_type = $ary_name = array();
1681 $result = db2_columns($db->db_connect_id
, '', '%', $table_name);
1683 while ($row = $db->sql_fetchrow($result))
1685 $ary_type[$i] = $row['type_name'];
1686 $ary_name[$i++
] = strtolower($row['column_name']);
1688 $db->sql_freeresult($result);
1690 // Grab all of the data from current table.
1693 $result = $db->sql_query($sql);
1698 while ($row = $db->sql_fetchrow($result))
1700 $schema_vals = $schema_fields = array();
1702 // Build the SQL statement to recreate the data.
1703 for ($i = 0; $i < $i_num_fields; $i++
)
1705 $str_val = $row[$ary_name[$i]];
1707 if (preg_match('#char|clob#i', $ary_type[$i]))
1711 $str_val = sanitize_data_generic(str_replace("'", "''", $str_val));
1713 else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1715 if (empty($str_val))
1727 $str_empty = 'NULL';
1730 if (empty($str_val) && $str_val !== '0')
1732 $str_val = $str_empty;
1735 $schema_vals[$i] = $str_quote . $str_val . $str_quote;
1736 $schema_fields[$i] = '"' . $ary_name[$i] . "'";
1739 // Take the ordered fields and their associated data and build it
1740 // into a valid sql statement to recreate that field in the data.
1741 $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1743 $this->flush($sql_data);
1745 $db->sql_freeresult($result);
1752 class oracle_extractor
extends base_extractor
1754 function write_table($table_name)
1757 $sql_data = '-- Table: ' . $table_name . "\n";
1758 $sql_data .= "DROP TABLE $table_name;\n";
1759 $sql_data .= '\\' . "\n";
1760 $sql_data .= "\nCREATE TABLE $table_name (\n";
1762 $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
1764 WHERE table_name = '{$table_name}'";
1765 $result = $db->sql_query($sql);
1768 while ($row = $db->sql_fetchrow($result))
1770 $line = ' "' . $row['column_name'] . '" ' . $row['data_type'];
1772 if ($row['data_type'] !== 'CLOB')
1774 if ($row['data_type'] !== 'VARCHAR2')
1776 $line .= '(' . $row['data_precision'] . ')';
1780 $line .= '(' . $row['data_length'] . ')';
1784 if (!empty($row['data_default']))
1786 $line .= ' DEFAULT ' . $row['data_default'];
1789 if ($row['nullable'] == 'N')
1791 $line .= ' NOT NULL';
1795 $db->sql_freeresult($result);
1797 $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1798 FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1799 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1800 AND B.CONSTRAINT_TYPE = 'P'
1801 AND A.TABLE_NAME = '{$table_name}'";
1802 $result = $db->sql_query($sql);
1804 while ($row = $db->sql_fetchrow($result))
1806 $rows[] = " CONSTRAINT {$row['constraint_name']} PRIMARY KEY ({$row['column_name']})";
1808 $db->sql_freeresult($result);
1810 $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1811 FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1812 WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1813 AND B.CONSTRAINT_TYPE = 'U'
1814 AND A.TABLE_NAME = '{$table_name}'";
1815 $result = $db->sql_query($sql);
1817 while ($row = $db->sql_fetchrow($result))
1819 $rows[] = " CONSTRAINT {$row['constraint_name']} UNIQUE ({$row['column_name']})";
1821 $db->sql_freeresult($result);
1823 $sql_data .= implode(",\n", $rows);
1824 $sql_data .= "\n)\n\\";
1826 $sql = "SELECT A.REFERENCED_NAME
1827 FROM USER_DEPENDENCIES A, USER_TRIGGERS B
1828 WHERE A.REFERENCED_TYPE = 'SEQUENCE'
1829 AND A.NAME = B.TRIGGER_NAME
1830 AND B.TABLE_NAME = '{$table_name}'";
1831 $result = $db->sql_query($sql);
1832 while ($row = $db->sql_fetchrow($result))
1834 $sql_data .= "\nCREATE SEQUENCE {$row['referenced_name']}\\\n";
1836 $db->sql_freeresult($result);
1838 $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
1840 WHERE TABLE_NAME = '{$table_name}'";
1841 $result = $db->sql_query($sql);
1842 while ($row = $db->sql_fetchrow($result))
1844 $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\\";
1846 $db->sql_freeresult($result);
1848 $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
1849 FROM USER_INDEXES A, USER_IND_COLUMNS B
1850 WHERE A.UNIQUENESS = 'NONUNIQUE'
1851 AND A.INDEX_NAME = B.INDEX_NAME
1852 AND B.TABLE_NAME = '{$table_name}'";
1853 $result = $db->sql_query($sql);
1857 while ($row = $db->sql_fetchrow($result))
1859 $index[$row['index_name']][] = $row['column_name'];
1862 foreach ($index as $index_name => $column_names)
1864 $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n\\";
1866 $db->sql_freeresult($result);
1867 $this->flush($sql_data);
1870 function write_data($table_name)
1873 $ary_type = $ary_name = array();
1875 // Grab all of the data from current table.
1878 $result = $db->sql_query($sql);
1880 $i_num_fields = ocinumcols($result);
1882 for ($i = 0; $i < $i_num_fields; $i++
)
1884 $ary_type[$i] = ocicolumntype($result, $i +
1);
1885 $ary_name[$i] = ocicolumnname($result, $i +
1);
1890 while ($row = $db->sql_fetchrow($result))
1892 $schema_vals = $schema_fields = array();
1894 // Build the SQL statement to recreate the data.
1895 for ($i = 0; $i < $i_num_fields; $i++
)
1897 $str_val = $row[$ary_name[$i]];
1899 if (preg_match('#char|text|bool|raw#i', $ary_type[$i]))
1903 $str_val = sanitize_data_oracle($str_val);
1905 else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1907 if (empty($str_val))
1919 $str_empty = 'NULL';
1922 if (empty($str_val) && $str_val !== '0')
1924 $str_val = $str_empty;
1927 $schema_vals[$i] = $str_quote . $str_val . $str_quote;
1928 $schema_fields[$i] = '"' . $ary_name[$i] . "'";
1931 // Take the ordered fields and their associated data and build it
1932 // into a valid sql statement to recreate that field in the data.
1933 $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1935 $this->flush($sql_data);
1937 $db->sql_freeresult($result);
1940 function write_start($prefix)
1943 $sql_data .= "-- phpBB Backup Script\n";
1944 $sql_data .= "-- Dump of tables for $prefix\n";
1945 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
1946 $sql_data .= "--\n";
1947 $this->flush($sql_data);
1954 class firebird_extractor
extends base_extractor
1956 function write_start($prefix)
1959 $sql_data .= "-- phpBB Backup Script\n";
1960 $sql_data .= "-- Dump of tables for $prefix\n";
1961 $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time
) . " GMT\n";
1962 $sql_data .= "--\n";
1963 $this->flush($sql_data);
1966 function write_data($table_name)
1969 $ary_type = $ary_name = array();
1971 // Grab all of the data from current table.
1974 $result = $db->sql_query($sql);
1976 $i_num_fields = ibase_num_fields($result);
1978 for ($i = 0; $i < $i_num_fields; $i++
)
1980 $info = ibase_field_info($result, $i);
1981 $ary_type[$i] = $info['type'];
1982 $ary_name[$i] = $info['name'];
1985 while ($row = $db->sql_fetchrow($result))
1987 $schema_vals = $schema_fields = array();
1989 // Build the SQL statement to recreate the data.
1990 for ($i = 0; $i < $i_num_fields; $i++
)
1992 $str_val = $row[strtolower($ary_name[$i])];
1994 if (preg_match('#char|text|bool|varbinary|blob#i', $ary_type[$i]))
1998 $str_val = sanitize_data_generic(str_replace("'", "''", $str_val));
2000 else if (preg_match('#date|timestamp#i', $ary_type[$i]))
2002 if (empty($str_val))
2014 $str_empty = 'NULL';
2017 if (empty($str_val) && $str_val !== '0')
2019 $str_val = $str_empty;
2022 $schema_vals[$i] = $str_quote . $str_val . $str_quote;
2023 $schema_fields[$i] = '"' . $ary_name[$i] . '"';
2026 // Take the ordered fields and their associated data and build it
2027 // into a valid sql statement to recreate that field in the data.
2028 $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
2030 $this->flush($sql_data);
2032 $db->sql_freeresult($result);
2035 function write_table($table_name)
2039 $sql_data = '-- Table: ' . $table_name . "\n";
2040 $sql_data .= "DROP TABLE $table_name;\n";
2042 $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');
2044 $sql_data .= "\nCREATE TABLE $table_name (\n";
2046 $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
2047 FROM RDB$RELATION_FIELDS R
2048 JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME
2049 LEFT JOIN RDB$FIELD_DIMENSIONS D ON R.RDB$FIELD_SOURCE = D.RDB$FIELD_NAME
2050 WHERE F.RDB$SYSTEM_FLAG = 0
2051 AND R.RDB$RELATION_NAME = \''. $table_name . '\'
2052 ORDER BY R.RDB$FIELD_POSITION';
2053 $result = $db->sql_query($sql);
2056 while ($row = $db->sql_fetchrow($result))
2058 $line = "\t" . '"' . $row['fname'] . '" ' . $data_types[$row['ftype']];
2060 if ($row['ftype'] == 261 && $row['stype'] == 1)
2062 $line .= ' SUB_TYPE TEXT';
2065 if ($row['ftype'] == 37 ||
$row['ftype'] == 14)
2067 $line .= ' (' . $row['flen'] . ')';
2070 if (!empty($row['dsource']))
2072 $line .= ' ' . $row['dsource'];
2075 if (!empty($row['nflag']))
2077 $line .= ' NOT NULL';
2081 $db->sql_freeresult($result);
2083 $sql_data .= implode(",\n", $rows);
2084 $sql_data .= "\n);\n";
2087 $sql = 'SELECT I.RDB$FIELD_NAME as NAME
2088 FROM RDB$RELATION_CONSTRAINTS RC, RDB$INDEX_SEGMENTS I, RDB$INDICES IDX
2089 WHERE (I.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2090 AND (IDX.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2091 AND (RC.RDB$RELATION_NAME = \''. $table_name . '\')
2092 ORDER BY I.RDB$FIELD_POSITION';
2093 $result = $db->sql_query($sql);
2095 while ($row = $db->sql_fetchrow($result))
2097 $keys[] = $row['name'];
2102 $sql_data .= "\nALTER TABLE $table_name ADD PRIMARY KEY (" . implode(', ', $keys) . ');';
2105 $db->sql_freeresult($result);
2107 $sql = 'SELECT I.RDB$INDEX_NAME as INAME, I.RDB$UNIQUE_FLAG as UFLAG, S.RDB$FIELD_NAME as FNAME
2108 FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON S.RDB$INDEX_NAME=I.RDB$INDEX_NAME
2109 WHERE (I.RDB$SYSTEM_FLAG IS NULL OR I.RDB$SYSTEM_FLAG=0)
2110 AND I.RDB$FOREIGN_KEY IS NULL
2111 AND I.RDB$RELATION_NAME = \''. $table_name . '\'
2112 AND I.RDB$INDEX_NAME NOT STARTING WITH \'RDB$\'
2113 ORDER BY S.RDB$FIELD_POSITION';
2114 $result = $db->sql_query($sql);
2117 while ($row = $db->sql_fetchrow($result))
2119 $index[$row['iname']]['unique'] = !empty($row['uflag']);
2120 $index[$row['iname']]['values'][] = $row['fname'];
2123 foreach ($index as $index_name => $data)
2125 $sql_data .= "\nCREATE ";
2126 if ($data['unique'])
2128 $sql_data .= 'UNIQUE ';
2130 $sql_data .= "INDEX $index_name ON $table_name(" . implode(', ', $data['values']) . ");";
2134 $db->sql_freeresult($result);
2136 $sql = 'SELECT D1.RDB$DEPENDENT_NAME as DNAME, D1.RDB$FIELD_NAME as FNAME, D1.RDB$DEPENDENT_TYPE, R1.RDB$RELATION_NAME
2137 FROM RDB$DEPENDENCIES D1
2138 LEFT JOIN RDB$RELATIONS R1 ON ((D1.RDB$DEPENDENT_NAME = R1.RDB$RELATION_NAME) AND (NOT (R1.RDB$VIEW_BLR IS NULL)))
2139 WHERE (D1.RDB$DEPENDED_ON_TYPE = 0)
2140 AND (D1.RDB$DEPENDENT_TYPE <> 3)
2141 AND (D1.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2142 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
2143 LEFT JOIN RDB$RELATIONS R2 ON ((F2.RDB$RELATION_NAME = R2.RDB$RELATION_NAME) AND (NOT (R2.RDB$VIEW_BLR IS NULL)))
2144 WHERE (D2.RDB$DEPENDENT_TYPE = 3)
2145 AND (D2.RDB$DEPENDENT_NAME = F2.RDB$FIELD_SOURCE)
2146 AND (D2.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2148 $result = $db->sql_query($sql);
2149 while ($row = $db->sql_fetchrow($result))
2151 $sql = 'SELECT T1.RDB$DEPENDED_ON_NAME as GEN, T1.RDB$FIELD_NAME, T1.RDB$DEPENDED_ON_TYPE
2152 FROM RDB$DEPENDENCIES T1
2153 WHERE (T1.RDB$DEPENDENT_NAME = \'' . $row['dname'] . '\')
2154 AND (T1.RDB$DEPENDENT_TYPE = 2 AND T1.RDB$DEPENDED_ON_TYPE = 14)
2155 UNION ALL SELECT DISTINCT D.RDB$DEPENDED_ON_NAME, D.RDB$FIELD_NAME, D.RDB$DEPENDED_ON_TYPE
2156 FROM RDB$DEPENDENCIES D, RDB$RELATION_FIELDS F
2157 WHERE (D.RDB$DEPENDENT_TYPE = 3)
2158 AND (D.RDB$DEPENDENT_NAME = F.RDB$FIELD_SOURCE)
2159 AND (F.RDB$RELATION_NAME = \'' . $row['dname'] . '\')
2161 $result2 = $db->sql_query($sql);
2162 $row2 = $db->sql_fetchrow($result2);
2163 $db->sql_freeresult($result2);
2164 $gen_name = $row2['gen'];
2166 $sql_data .= "\nDROP GENERATOR " . $gen_name . ";";
2167 $sql_data .= "\nSET TERM ^ ;";
2168 $sql_data .= "\nCREATE GENERATOR " . $gen_name . "^";
2169 $sql_data .= "\nSET GENERATOR " . $gen_name . " TO 0^\n";
2170 $sql_data .= "\nCREATE TRIGGER {$row['dname']} FOR $table_name";
2171 $sql_data .= "\nBEFORE INSERT\nAS\nBEGIN";
2172 $sql_data .= "\n NEW.{$row['fname']} = GEN_ID(" . $gen_name . ", 1);";
2173 $sql_data .= "\nEND^\n";
2174 $sql_data .= "\nSET TERM ; ^\n";
2177 $this->flush($sql_data);
2179 $db->sql_freeresult($result);
2183 // 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)
2184 function get_usable_memory()
2186 $val = trim(@ini_get
('memory_limit'));
2188 if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
2190 $memory_limit = (int) $regs[1];
2196 $memory_limit *= 1024;
2201 $memory_limit *= 1048576;
2206 $memory_limit *= 1073741824;
2210 // how much memory PHP requires at the start of export (it is really a little less)
2211 if ($memory_limit > 6100000)
2213 $memory_limit -= 6100000;
2216 // allow us to consume half of the total memory available
2221 // set the buffer to 1M if we have no clue how much memory PHP will give us :P
2222 $memory_limit = 1048576;
2225 return $memory_limit;
2228 function sanitize_data_mssql($text)
2230 $data = preg_split('/[\n\t\r\b\f]/', $text);
2231 preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2235 foreach ($data as $value)
2239 $val[] = "'" . $value . "'";
2241 if (sizeof($matches[0]))
2243 $val[] = 'char(' . ord(array_shift($matches[0])) . ')';
2247 return implode('+', $val);
2250 function sanitize_data_oracle($text)
2252 $data = preg_split('/[\0\n\t\r\b\f\'"\\\]/', $text);
2253 preg_match_all('/[\0\n\t\r\b\f\'"\\\]/', $text, $matches);
2257 foreach ($data as $value)
2261 $val[] = "'" . $value . "'";
2263 if (sizeof($matches[0]))
2265 $val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
2269 return implode('||', $val);
2272 function sanitize_data_generic($text)
2274 $data = preg_split('/[\n\t\r\b\f]/', $text);
2275 preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2279 foreach ($data as $value)
2283 $val[] = "'" . $value . "'";
2285 if (sizeof($matches[0]))
2287 $val[] = "'" . array_shift($matches[0]) . "'";
2291 return implode('||', $val);
2294 // modified from PHP.net
2295 function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2298 $delim_len = strlen($delim);
2302 $pos = strpos($record, $delim);
2305 $record .= $read($fp, $buffer);
2306 if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
2308 $seek($fp, $pos +
$delim_len - strlen($record), SEEK_CUR
);
2309 return substr($record, 0, $pos);
2314 $seek($fp, $pos +
$delim_len - strlen($record), SEEK_CUR
);
2315 return substr($record, 0, $pos);
2322 function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2324 static $array = array();
2325 static $record = '';
2327 if (!sizeof($array))
2331 if (strpos($record, $delim) !== false)
2333 $array = explode($delim, $record);
2334 $record = array_pop($array);
2339 $record .= $read($fp, $buffer);
2342 if ($eof($fp) && strpos($record, $delim) !== false)
2344 $array = explode($delim, $record);
2345 $record = array_pop($array);
2351 return array_shift($array);