5
* @version $Id: acp_database.php,v 1.82 2007/10/05 14:36:32 acydburn Exp $
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;
29
global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
31
$user->add_lang('acp/database');
33
$this->tpl_name = 'acp_database';
34
$this->page_title = 'ACP_DATABASE';
36
$action = request_var('action', '');
37
$submit = (isset($_POST['submit'])) ? true : false;
39
$template->assign_vars(array(
47
$this->page_title = 'ACP_BACKUP';
52
$type = request_var('type', '');
53
$table = request_var('table', array(''));
54
$format = request_var('method', '');
55
$where = request_var('where', '');
59
trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
62
$store = $download = $structure = $schema_data = false;
64
if ($where == 'store_and_download' || $where == 'store')
69
if ($where == 'store_and_download' || $where == 'download')
74
if ($type == 'full' || $type == 'structure')
79
if ($type == 'full' || $type == 'data')
84
@set_time_limit(1200);
88
$filename = 'backup_' . $time . '_' . unique_id();
89
switch ($db->sql_layer)
94
$extractor = new mysql_extractor($download, $store, $format, $filename, $time);
98
$extractor = new sqlite_extractor($download, $store, $format, $filename, $time);
102
$extractor = new postgres_extractor($download, $store, $format, $filename, $time);
106
$extractor = new oracle_extractor($download, $store, $format, $filename, $time);
111
$extractor = new mssql_extractor($download, $store, $format, $filename, $time);
115
$extractor = new firebird_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->sql_layer)
135
$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
if ($download == true)
167
add_log('admin', 'LOG_DB_BACKUP');
168
trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
172
include($phpbb_root_path . 'includes/functions_install.' . $phpEx);
173
$tables = get_tables($db);
174
foreach ($tables as $table_name)
176
if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
178
$template->assign_block_vars('tables', array(
179
'TABLE' => $table_name
185
$template->assign_vars(array(
186
'U_ACTION' => $this->u_action . '&action=download'
189
$available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
191
foreach ($available_methods as $type => $module)
193
if (!@extension_loaded($module))
198
$template->assign_block_vars('methods', array(
203
$template->assign_block_vars('methods', array(
212
$this->page_title = 'ACP_RESTORE';
217
$delete = request_var('delete', '');
218
$file = request_var('file', '');
220
if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
222
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
225
$file_name = $phpbb_root_path . 'store/' . $matches[0];
227
if (!file_exists($file_name) || !is_readable($file_name))
229
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
234
if (confirm_box(true))
237
add_log('admin', 'LOG_DB_DELETE');
238
trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
242
confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
247
$download = request_var('download', '');
256
$mimetype = 'text/x-sql';
259
$mimetype = 'application/x-bzip2';
262
$mimetype = 'application/x-gzip';
266
header('Pragma: no-cache');
267
header("Content-Type: $mimetype; name=\"$name\"");
268
header("Content-disposition: attachment; filename=$name");
272
$fp = @fopen($file_name, 'rb');
278
echo fread($fp, 8192);
290
$fp = fopen($file_name, 'rb');
299
$fp = bzopen($file_name, 'r');
304
$fgetd = 'fgetd_seekless';
308
$fp = gzopen($file_name, 'rb');
317
switch ($db->sql_layer)
323
while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
325
$db->sql_query($sql);
331
while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
334
if (substr($query, 0, 8) === 'SET TERM')
336
$delim = $query[9] . "\n";
339
$db->sql_query($query);
344
while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
347
$db->sql_query($query);
348
if (substr($query, 0, 4) == 'COPY')
350
while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
354
trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
356
pg_put_line($db->db_connect_id, $sub . "\n");
358
pg_put_line($db->db_connect_id, "\\.\n");
359
pg_end_copy($db->db_connect_id);
365
while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
367
$db->sql_query($sql);
373
while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
375
$db->sql_query($sql);
382
add_log('admin', 'LOG_DB_RESTORE');
383
trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
388
$methods = array('sql');
389
$available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
391
foreach ($available_methods as $type => $module)
393
if (!@extension_loaded($module))
400
$dir = $phpbb_root_path . 'store/';
401
$dh = @opendir($dir);
405
while (($file = readdir($dh)) !== false)
407
if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
409
$supported = in_array($matches[2], $methods);
411
if ($supported == 'true')
413
$template->assign_block_vars('files', array(
415
'NAME' => gmdate("d-m-Y H:i:s", $matches[1]),
416
'SUPPORTED' => $supported
424
$template->assign_vars(array(
425
'U_ACTION' => $this->u_action . '&action=submit'
447
var $run_comp = false;
449
function base_extractor($download = false, $store = false, $format, $filename, $time)
451
$this->download = $download;
452
$this->store = $store;
454
$this->format = $format;
461
$this->write = 'fwrite';
462
$this->close = 'fclose';
463
$mimetype = 'text/x-sql';
468
$this->write = 'bzwrite';
469
$this->close = 'bzclose';
470
$mimetype = 'application/x-bzip2';
475
$this->write = 'gzwrite';
476
$this->close = 'gzclose';
477
$mimetype = 'application/x-gzip';
481
if ($download == true)
483
$name = $filename . $ext;
484
header('Pragma: no-cache');
485
header("Content-Type: $mimetype; name=\"$name\"");
486
header("Content-disposition: attachment; filename=$name");
495
if ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'msie') === false)
497
ob_start('ob_gzhandler');
501
$this->run_comp = true;
509
global $phpbb_root_path;
510
$file = $phpbb_root_path . 'store/' . $filename . $ext;
512
$this->fp = $open($file, 'w');
516
trigger_error('Unable to write temporary file to storage folder', E_USER_ERROR);
528
$close = $this->close;
533
// bzip2 must be written all the way at the end
534
if ($this->download && $this->format === 'bzip2')
541
function flush($data)
544
if ($this->store === true)
548
$write = $this->write;
550
$write($this->fp, $data);
553
if ($this->download === true)
555
if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp))
560
// we can write the gzip data as soon as we get it
561
if ($this->format === 'gzip')
565
echo gzencode($data);
580
class mysql_extractor extends base_extractor
582
function write_start($table_prefix)
585
$sql_data .= "# phpBB Backup Script\n";
586
$sql_data .= "# Dump of tables for $table_prefix\n";
587
$sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
589
$this->flush($sql_data);
592
function write_table($table_name)
597
if ($new_extract === null)
599
if ($db->sql_layer === 'mysqli' || version_compare($db->mysql_version, '3.23.20', '>='))
605
$new_extract = false;
611
$this->new_write_table($table_name);
615
$this->old_write_table($table_name);
619
function write_data($table_name)
622
if ($db->sql_layer === 'mysqli')
624
$this->write_data_mysqli($table_name);
628
$this->write_data_mysql($table_name);
632
function write_data_mysqli($table_name)
637
$result = mysqli_query($db->db_connect_id, $sql, MYSQLI_USE_RESULT);
638
if ($result != false)
640
$fields_cnt = mysqli_num_fields($result);
642
// Get field information
643
$field = mysqli_fetch_fields($result);
644
$field_set = array();
646
for ($j = 0; $j < $fields_cnt; $j++)
648
$field_set[] = $field[$j]->name;
651
$search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
652
$replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
653
$fields = implode(', ', $field_set);
654
$sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
657
$max_len = get_usable_memory();
659
while ($row = mysqli_fetch_row($result))
664
$query = $sql_data . '(';
671
for ($j = 0; $j < $fields_cnt; $j++)
673
if (!isset($row[$j]) || is_null($row[$j]))
675
$values[$j] = 'NULL';
677
else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024))
679
$values[$j] = $row[$j];
683
$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
686
$query .= implode(', ', $values) . ')';
688
$query_len += strlen($query);
689
if ($query_len > $max_len)
691
$this->flush($query . ";\n\n");
701
mysqli_free_result($result);
703
// check to make sure we have nothing left to flush
704
if (!$first_set && $query)
706
$this->flush($query . ";\n\n");
711
function write_data_mysql($table_name)
716
$result = mysql_unbuffered_query($sql, $db->db_connect_id);
718
if ($result != false)
720
$fields_cnt = mysql_num_fields($result);
722
// Get field information
724
for ($i = 0; $i < $fields_cnt; $i++)
726
$field[] = mysql_fetch_field($result, $i);
728
$field_set = array();
730
for ($j = 0; $j < $fields_cnt; $j++)
732
$field_set[] = $field[$j]->name;
735
$search = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
736
$replace = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
737
$fields = implode(', ', $field_set);
738
$sql_data = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
741
$max_len = get_usable_memory();
743
while ($row = mysql_fetch_row($result))
748
$query = $sql_data . '(';
755
for ($j = 0; $j < $fields_cnt; $j++)
757
if (!isset($row[$j]) || is_null($row[$j]))
759
$values[$j] = 'NULL';
761
else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
763
$values[$j] = $row[$j];
767
$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
770
$query .= implode(', ', $values) . ')';
772
$query_len += strlen($query);
773
if ($query_len > $max_len)
775
$this->flush($query . ";\n\n");
785
mysql_free_result($result);
787
// check to make sure we have nothing left to flush
788
if (!$first_set && $query)
790
$this->flush($query . ";\n\n");
795
function new_write_table($table_name)
799
$sql = 'SHOW CREATE TABLE ' . $table_name;
800
$result = $db->sql_query($sql);
801
$row = $db->sql_fetchrow($result);
803
$sql_data = '# Table: ' . $table_name . "\n";
804
$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
805
$this->flush($sql_data . $row['Create Table'] . ";\n\n");
807
$db->sql_freeresult($result);
810
function old_write_table($table_name)
814
$sql_data = '# Table: ' . $table_name . "\n";
815
$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
816
$sql_data .= "CREATE TABLE $table_name(\n";
821
$result = $db->sql_query($sql);
823
while ($row = $db->sql_fetchrow($result))
825
$line = ' ' . $row['Field'] . ' ' . $row['Type'];
827
if (!is_null($row['Default']))
829
$line .= " DEFAULT '{$row['Default']}'";
832
if ($row['Null'] != 'YES')
834
$line .= ' NOT NULL';
837
if ($row['Extra'] != '')
839
$line .= ' ' . $row['Extra'];
844
$db->sql_freeresult($result);
849
$result = $db->sql_query($sql);
852
while ($row = $db->sql_fetchrow($result))
854
$kname = $row['Key_name'];
856
if ($kname != 'PRIMARY')
858
if ($row['Non_unique'] == 0)
860
$kname = "UNIQUE|$kname";
864
if ($row['Sub_part'])
866
$row['Column_name'] .= '(' . $row['Sub_part'] . ')';
868
$index[$kname][] = $row['Column_name'];
870
$db->sql_freeresult($result);
872
foreach ($index as $key => $columns)
876
if ($key == 'PRIMARY')
878
$line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')';
880
else if (strpos($key, 'UNIQUE') === 0)
882
$line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')';
884
else if (strpos($key, 'FULLTEXT') === 0)
886
$line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')';
890
$line .= "KEY $key (" . implode(', ', $columns) . ')';
896
$sql_data .= implode(",\n", $rows);
897
$sql_data .= "\n);\n\n";
899
$this->flush($sql_data);
906
class sqlite_extractor extends base_extractor
908
function write_start($prefix)
911
$sql_data .= "-- phpBB Backup Script\n";
912
$sql_data .= "-- Dump of tables for $prefix\n";
913
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
915
$sql_data .= "BEGIN TRANSACTION;\n";
916
$this->flush($sql_data);
919
function write_table($table_name)
922
$sql_data = '-- Table: ' . $table_name . "\n";
923
$sql_data .= "DROP TABLE $table_name;\n";
928
AND name = '" . $db->sql_escape($table_name) . "'
929
ORDER BY type DESC, name;";
930
$result = $db->sql_query($sql);
931
$row = $db->sql_fetchrow($result);
932
$db->sql_freeresult($result);
935
$sql_data .= $row['sql'] . ";\n";
937
$result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
940
while ($row = $db->sql_fetchrow($result))
944
$db->sql_freeresult($result);
946
foreach ($ar as $value)
948
if (strpos($value['name'], 'autoindex') !== false)
953
$result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
956
while ($row = $db->sql_fetchrow($result))
958
$fields[] = $row['name'];
960
$db->sql_freeresult($result);
962
$sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
965
$this->flush($sql_data . "\n");
968
function write_data($table_name)
973
if (is_null($proper))
975
$proper = version_compare(PHP_VERSION, '5.1.3', '>=');
980
$col_types = sqlite_fetch_column_types($db->db_connect_id, $table_name);
987
AND name = '" . $table_name . "'";
988
$table_data = sqlite_single_query($db->db_connect_id, $sql);
989
$table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data);
990
$table_data = trim($table_data);
992
preg_match('#\((.*)\)#s', $table_data, $matches);
994
$table_cols = explode(',', trim($matches[1]));
995
foreach ($table_cols as $declaration)
997
$entities = preg_split('#\s+#', trim($declaration));
998
$column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]);
1000
// Hit a primary key, those are not what we need :D
1001
if (empty($entities[1]) || (strtolower($entities[0]) === 'primary' && strtolower($entities[1]) === 'key'))
1005
$col_types[$column_name] = $entities[1];
1011
$result = sqlite_unbuffered_query($db->db_connect_id, $sql);
1012
$rows = sqlite_fetch_all($result, SQLITE_ASSOC);
1013
$sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
1014
foreach ($rows as $row)
1016
foreach ($row as $column_name => $column_data)
1018
if (is_null($column_data))
1020
$row[$column_name] = 'NULL';
1022
else if ($column_data == '')
1024
$row[$column_name] = "''";
1026
else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false)
1028
$row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
1031
$this->flush($sql_insert . implode(', ', $row) . ");\n");
1035
function write_end()
1037
$this->flush("COMMIT;\n");
1038
parent::write_end();
1045
class postgres_extractor extends base_extractor
1047
function write_start($prefix)
1050
$sql_data .= "-- phpBB Backup Script\n";
1051
$sql_data .= "-- Dump of tables for $prefix\n";
1052
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1053
$sql_data .= "--\n";
1054
$sql_data .= "BEGIN TRANSACTION;\n";
1055
$this->flush($sql_data);
1058
function write_table($table_name)
1061
static $domains_created = array();
1063
$sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
1064
FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
1065
WHERE a.domain_name = b.domain_name
1066
AND b.table_name = '{$table_name}'";
1067
$result = $db->sql_query($sql);
1068
while ($row = $db->sql_fetchrow($result))
1070
if (empty($domains_created[$row['domain_name']]))
1072
$domains_created[$row['domain_name']] = true;
1073
//$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
1074
$sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
1075
if (!empty($row['character_maximum_length']))
1077
$sql_data .= '(' . $row['character_maximum_length'] . ')';
1079
$sql_data .= ' NOT NULL';
1080
if (!empty($row['domain_default']))
1082
$sql_data .= ' DEFAULT ' . $row['domain_default'];
1084
$this->flush($sql_data . ";\n");
1088
$sql_data = '-- Table: ' . $table_name . "\n";
1089
//$sql_data .= "DROP TABLE $table_name;\n";
1090
// PGSQL does not "tightly" bind sequences and tables, we must guess...
1091
$sql = "SELECT relname
1094
AND relname = '{$table_name}_seq'";
1095
$result = $db->sql_query($sql);
1096
// We don't even care about storing the results. We already know the answer if we get rows back.
1097
if ($db->sql_fetchrow($result))
1099
$sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
1100
$sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
1102
$db->sql_freeresult($result);
1104
$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
1105
FROM pg_class c, pg_attribute a, pg_type t
1106
WHERE c.relname = '" . $db->sql_escape($table_name) . "'
1108
AND a.attrelid = c.oid
1109
AND a.atttypid = t.oid
1111
$result = $db->sql_query($field_query);
1113
$sql_data .= "CREATE TABLE $table_name(\n";
1115
while ($row = $db->sql_fetchrow($result))
1117
// Get the data from the table
1118
$sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1119
FROM pg_attrdef d, pg_class c
1120
WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
1121
AND (c.oid = d.adrelid)
1122
AND d.adnum = " . $row['attnum'];
1123
$def_res = $db->sql_query($sql_get_default);
1127
unset($row['rowdefault']);
1131
$row['rowdefault'] = $db->sql_fetchfield('rowdefault', false, $def_res);
1133
$db->sql_freeresult($def_res);
1135
if ($row['type'] == 'bpchar')
1137
// Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
1138
$row['type'] = 'char';
1141
$line = ' ' . $row['field'] . ' ' . $row['type'];
1143
if (strpos($row['type'], 'char') !== false)
1145
if ($row['lengthvar'] > 0)
1147
$line .= '(' . ($row['lengthvar'] - 4) . ')';
1151
if (strpos($row['type'], 'numeric') !== false)
1154
$line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
1158
if (!empty($row['rowdefault']))
1160
$line .= ' DEFAULT ' . $row['rowdefault'];
1163
if ($row['notnull'] == 't')
1165
$line .= ' NOT NULL';
1170
$db->sql_freeresult($result);
1173
// Get the listing of primary keys.
1174
$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
1175
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
1176
WHERE (bc.oid = i.indrelid)
1177
AND (ic.oid = i.indexrelid)
1178
AND (ia.attrelid = i.indexrelid)
1179
AND (ta.attrelid = bc.oid)
1180
AND (bc.relname = '" . $db->sql_escape($table_name) . "')
1181
AND (ta.attrelid = i.indrelid)
1182
AND (ta.attnum = i.indkey[ia.attnum-1])
1183
ORDER BY index_name, tab_name, column_name";
1185
$result = $db->sql_query($sql_pri_keys);
1187
$index_create = $index_rows = $primary_key = array();
1189
// We do this in two steps. It makes placing the comma easier
1190
while ($row = $db->sql_fetchrow($result))
1192
if ($row['primary_key'] == 't')
1194
$primary_key[] = $row['column_name'];
1195
$primary_key_name = $row['index_name'];
1199
// We have to store this all this info because it is possible to have a multi-column key...
1200
// we can loop through it again and build the statement
1201
$index_rows[$row['index_name']]['table'] = $table_name;
1202
$index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false;
1203
$index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
1206
$db->sql_freeresult($result);
1208
if (!empty($index_rows))
1210
foreach ($index_rows as $idx_name => $props)
1212
$index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
1216
if (!empty($primary_key))
1218
$lines[] = " CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
1221
// Generate constraint clauses for CHECK constraints
1222
$sql_checks = "SELECT conname as index_name, consrc
1223
FROM pg_constraint, pg_class bc
1224
WHERE conrelid = bc.oid
1225
AND bc.relname = '" . $db->sql_escape($table_name) . "'
1228
FROM pg_constraint as c, pg_inherits as i
1229
WHERE i.inhrelid = pg_constraint.conrelid
1230
AND c.conname = pg_constraint.conname
1231
AND c.consrc = pg_constraint.consrc
1232
AND c.conrelid = i.inhparent
1234
$result = $db->sql_query($sql_checks);
1236
// Add the constraints to the sql file.
1237
while ($row = $db->sql_fetchrow($result))
1239
if (!is_null($row['consrc']))
1241
$lines[] = ' CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
1244
$db->sql_freeresult($result);
1246
$sql_data .= implode(", \n", $lines);
1247
$sql_data .= "\n);\n";
1249
if (!empty($index_create))
1251
$sql_data .= implode("\n", $index_create) . "\n\n";
1253
$this->flush($sql_data);
1256
function write_data($table_name)
1259
// Grab all of the data from current table.
1262
$result = $db->sql_query($sql);
1264
$i_num_fields = pg_num_fields($result);
1267
for ($i = 0; $i < $i_num_fields; $i++)
1269
$ary_type[] = pg_field_type($result, $i);
1270
$ary_name[] = pg_field_name($result, $i);
1273
$sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
1274
FROM pg_attrdef d, pg_class c
1275
WHERE (c.relname = '{$table_name}')
1276
AND (c.oid = d.adrelid)
1277
AND d.adnum = " . strval($i + 1);
1278
$result2 = $db->sql_query($sql);
1279
if ($row = $db->sql_fetchrow($result2))
1281
// Determine if we must reset the sequences
1282
if (strpos($row['rowdefault'], "nextval('") === 0)
1284
$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";
1289
$this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
1290
while ($row = $db->sql_fetchrow($result))
1292
$schema_vals = array();
1294
// Build the SQL statement to recreate the data.
1295
for ($i = 0; $i < $i_num_fields; $i++)
1297
$str_val = $row[$ary_name[$i]];
1299
if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
1301
$str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
1309
if (empty($str_val) && $str_val !== '0')
1311
$str_val = $str_empty;
1314
$schema_vals[] = $str_val;
1317
// Take the ordered fields and their associated data and build it
1318
// into a valid sql statement to recreate that field in the data.
1319
$this->flush(implode("\t", $schema_vals) . "\n");
1321
$db->sql_freeresult($result);
1322
$this->flush("\\.\n");
1324
// Write out the sequence statements
1328
function write_end()
1330
$this->flush("COMMIT;\n");
1331
parent::write_end();
1338
class mssql_extractor extends base_extractor
1340
function write_end()
1342
$this->flush("COMMIT\nGO\n");
1343
parent::write_end();
1346
function write_start($prefix)
1349
$sql_data .= "-- phpBB Backup Script\n";
1350
$sql_data .= "-- Dump of tables for $prefix\n";
1351
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1352
$sql_data .= "--\n";
1353
$sql_data .= "BEGIN TRANSACTION\n";
1354
$sql_data .= "GO\n";
1355
$this->flush($sql_data);
1358
function write_table($table_name)
1361
$sql_data = '-- Table: ' . $table_name . "\n";
1362
$sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
1363
$sql_data .= "DROP TABLE $table_name;\n";
1364
$sql_data .= "GO\n";
1365
$sql_data .= "\nCREATE TABLE [$table_name] (\n";
1370
$sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
1371
FROM INFORMATION_SCHEMA.COLUMNS
1372
WHERE TABLE_NAME = '$table_name'";
1373
$result = $db->sql_query($sql);
1375
while ($row = $db->sql_fetchrow($result))
1377
$line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
1379
if ($row['DATA_TYPE'] == 'text')
1384
if ($row['IS_IDENTITY'])
1386
$line .= ' IDENTITY (1 , 1)';
1389
if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
1391
$line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
1394
if ($row['IS_NULLABLE'] == 'YES')
1400
$line .= ' NOT NULL';
1403
if ($row['COLUMN_DEFAULT'])
1405
$line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
1410
$db->sql_freeresult($result);
1412
$sql_data .= implode(",\n", $rows);
1413
$sql_data .= "\n) ON [PRIMARY]";
1417
$sql_data .= " TEXTIMAGE_ON [PRIMARY]";
1420
$sql_data .= "\nGO\n\n";
1423
$sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
1424
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
1425
WHERE TABLE_NAME = '$table_name'";
1426
$result = $db->sql_query($sql);
1427
while ($row = $db->sql_fetchrow($result))
1431
$sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
1432
$sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY CLUSTERED \n\t(\n";
1434
$rows[] = "\t\t[{$row['COLUMN_NAME']}]";
1438
$sql_data .= implode(",\n", $rows);
1439
$sql_data .= "\n\t) ON [PRIMARY] \nGO\n";
1441
$db->sql_freeresult($result);
1444
$sql = "EXEC sp_statistics '$table_name'";
1445
$result = $db->sql_query($sql);
1446
while ($row = $db->sql_fetchrow($result))
1448
if ($row['TYPE'] == 3)
1450
$index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
1453
$db->sql_freeresult($result);
1455
foreach ($index as $index_name => $column_name)
1457
$index[$index_name] = implode(', ', $column_name);
1460
foreach ($index as $index_name => $columns)
1462
$sql_data .= "\nCREATE INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
1464
$this->flush($sql_data);
1467
function write_data($table_name)
1471
if ($db->sql_layer === 'mssql')
1473
$this->write_data_mssql($table_name);
1477
$this->write_data_odbc($table_name);
1481
function write_data_mssql($table_name)
1484
$ary_type = $ary_name = array();
1488
// Grab all of the data from current table.
1491
$result = $db->sql_query($sql);
1493
$retrieved_data = mssql_num_rows($result);
1495
$i_num_fields = mssql_num_fields($result);
1497
for ($i = 0; $i < $i_num_fields; $i++)
1499
$ary_type[$i] = mssql_field_type($result, $i);
1500
$ary_name[$i] = mssql_field_name($result, $i);
1503
if ($retrieved_data)
1505
$sql = "SELECT 1 as has_identity
1506
FROM INFORMATION_SCHEMA.COLUMNS
1507
WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1508
$result2 = $db->sql_query($sql);
1509
$row2 = $db->sql_fetchrow($result2);
1510
if (!empty($row2['has_identity']))
1512
$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1515
$db->sql_freeresult($result2);
1518
while ($row = $db->sql_fetchrow($result))
1520
$schema_vals = $schema_fields = array();
1522
// Build the SQL statement to recreate the data.
1523
for ($i = 0; $i < $i_num_fields; $i++)
1525
$str_val = $row[$ary_name[$i]];
1527
if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1531
$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1533
else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1535
if (empty($str_val))
1547
$str_empty = 'NULL';
1550
if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
1552
$str_val = $str_empty;
1555
$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1556
$schema_fields[$i] = $ary_name[$i];
1559
// Take the ordered fields and their associated data and build it
1560
// into a valid sql statement to recreate that field in the data.
1561
$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1563
$this->flush($sql_data);
1566
$db->sql_freeresult($result);
1568
if ($retrieved_data && $ident_set)
1570
$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1572
$this->flush($sql_data);
1575
function write_data_odbc($table_name)
1578
$ary_type = $ary_name = array();
1582
// Grab all of the data from current table.
1585
$result = $db->sql_query($sql);
1587
$retrieved_data = odbc_num_rows($result);
1589
if ($retrieved_data)
1591
$sql = "SELECT 1 as has_identity
1592
FROM INFORMATION_SCHEMA.COLUMNS
1593
WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
1594
$result2 = $db->sql_query($sql);
1595
$row2 = $db->sql_fetchrow($result2);
1596
if (!empty($row2['has_identity']))
1598
$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
1601
$db->sql_freeresult($result2);
1604
$i_num_fields = odbc_num_fields($result);
1606
for ($i = 0; $i < $i_num_fields; $i++)
1608
$ary_type[$i] = odbc_field_type($result, $i + 1);
1609
$ary_name[$i] = odbc_field_name($result, $i + 1);
1612
while ($row = $db->sql_fetchrow($result))
1614
$schema_vals = $schema_fields = array();
1616
// Build the SQL statement to recreate the data.
1617
for ($i = 0; $i < $i_num_fields; $i++)
1619
$str_val = $row[$ary_name[$i]];
1621
if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
1625
$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
1627
else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1629
if (empty($str_val))
1641
$str_empty = 'NULL';
1644
if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
1646
$str_val = $str_empty;
1649
$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1650
$schema_fields[$i] = $ary_name[$i];
1653
// Take the ordered fields and their associated data and build it
1654
// into a valid sql statement to recreate that field in the data.
1655
$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
1657
$this->flush($sql_data);
1662
$db->sql_freeresult($result);
1664
if ($retrieved_data && $ident_set)
1666
$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
1668
$this->flush($sql_data);
1676
class oracle_extractor extends base_extractor
1678
function write_table($table_name)
1681
$sql_data = '-- Table: ' . $table_name . "\n";
1682
$sql_data .= "DROP TABLE $table_name;\n";
1683
$sql_data .= '\\' . "\n";
1684
$sql_data .= "\nCREATE TABLE $table_name (\n";
1686
$sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
1688
WHERE table_name = '{$table_name}'";
1689
$result = $db->sql_query($sql);
1692
while ($row = $db->sql_fetchrow($result))
1694
$line = ' "' . $row['column_name'] . '" ' . $row['data_type'];
1696
if ($row['data_type'] !== 'CLOB')
1698
if ($row['data_type'] !== 'VARCHAR2')
1700
$line .= '(' . $row['data_precision'] . ')';
1704
$line .= '(' . $row['data_length'] . ')';
1708
if (!empty($row['data_default']))
1710
$line .= ' DEFAULT ' . $row['data_default'];
1713
if ($row['nullable'] == 'N')
1715
$line .= ' NOT NULL';
1719
$db->sql_freeresult($result);
1721
$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1722
FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1723
WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1724
AND B.CONSTRAINT_TYPE = 'P'
1725
AND A.TABLE_NAME = '{$table_name}'";
1726
$result = $db->sql_query($sql);
1728
while ($row = $db->sql_fetchrow($result))
1730
$rows[] = " CONSTRAINT {$row['constraint_name']} PRIMARY KEY ({$row['column_name']})";
1732
$db->sql_freeresult($result);
1734
$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
1735
FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
1736
WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
1737
AND B.CONSTRAINT_TYPE = 'U'
1738
AND A.TABLE_NAME = '{$table_name}'";
1739
$result = $db->sql_query($sql);
1741
while ($row = $db->sql_fetchrow($result))
1743
$rows[] = " CONSTRAINT {$row['constraint_name']} UNIQUE ({$row['column_name']})";
1745
$db->sql_freeresult($result);
1747
$sql_data .= implode(",\n", $rows);
1748
$sql_data .= "\n)\n\\";
1750
$sql = "SELECT A.REFERENCED_NAME
1751
FROM USER_DEPENDENCIES A, USER_TRIGGERS B
1752
WHERE A.REFERENCED_TYPE = 'SEQUENCE'
1753
AND A.NAME = B.TRIGGER_NAME
1754
AND B. TABLE_NAME = '{$table_name}'";
1755
$result = $db->sql_query($sql);
1756
while ($row = $db->sql_fetchrow($result))
1758
$sql_data .= "\nCREATE SEQUENCE {$row['referenced_name']}\\\n";
1760
$db->sql_freeresult($result);
1762
$sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
1764
WHERE TABLE_NAME = '{$table_name}'";
1765
$result = $db->sql_query($sql);
1766
while ($row = $db->sql_fetchrow($result))
1768
$sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\\";
1770
$db->sql_freeresult($result);
1772
$sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
1773
FROM USER_INDEXES A, USER_IND_COLUMNS B
1774
WHERE A.UNIQUENESS = 'NONUNIQUE'
1775
AND A.INDEX_NAME = B.INDEX_NAME
1776
AND B.TABLE_NAME = '{$table_name}'";
1777
$result = $db->sql_query($sql);
1781
while ($row = $db->sql_fetchrow($result))
1783
$index[$row['index_name']][] = $row['column_name'];
1786
foreach ($index as $index_name => $column_names)
1788
$sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n\\";
1790
$db->sql_freeresult($result);
1791
$this->flush($sql_data);
1794
function write_data($table_name)
1797
$ary_type = $ary_name = array();
1799
// Grab all of the data from current table.
1802
$result = $db->sql_query($sql);
1804
$i_num_fields = ocinumcols($result);
1806
for ($i = 0; $i < $i_num_fields; $i++)
1808
$ary_type[$i] = ocicolumntype($result, $i + 1);
1809
$ary_name[$i] = ocicolumnname($result, $i + 1);
1814
while ($row = $db->sql_fetchrow($result))
1816
$schema_vals = $schema_fields = array();
1818
// Build the SQL statement to recreate the data.
1819
for ($i = 0; $i < $i_num_fields; $i++)
1821
$str_val = $row[$ary_name[$i]];
1823
if (preg_match('#char|text|bool|raw#i', $ary_type[$i]))
1827
$str_val = sanitize_data_oracle($str_val);
1829
else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1831
if (empty($str_val))
1843
$str_empty = 'NULL';
1846
if (empty($str_val) && $str_val !== '0')
1848
$str_val = $str_empty;
1851
$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1852
$schema_fields[$i] = '"' . $ary_name[$i] . "'";
1855
// Take the ordered fields and their associated data and build it
1856
// into a valid sql statement to recreate that field in the data.
1857
$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1859
$this->flush($sql_data);
1861
$db->sql_freeresult($result);
1864
function write_start($prefix)
1867
$sql_data .= "-- phpBB Backup Script\n";
1868
$sql_data .= "-- Dump of tables for $prefix\n";
1869
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1870
$sql_data .= "--\n";
1871
$this->flush($sql_data);
1878
class firebird_extractor extends base_extractor
1880
function write_start($prefix)
1883
$sql_data .= "-- phpBB Backup Script\n";
1884
$sql_data .= "-- Dump of tables for $prefix\n";
1885
$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
1886
$sql_data .= "--\n";
1887
$this->flush($sql_data);
1890
function write_data($table_name)
1893
$ary_type = $ary_name = array();
1895
// Grab all of the data from current table.
1898
$result = $db->sql_query($sql);
1900
$i_num_fields = ibase_num_fields($result);
1902
for ($i = 0; $i < $i_num_fields; $i++)
1904
$info = ibase_field_info($result, $i);
1905
$ary_type[$i] = $info['type'];
1906
$ary_name[$i] = $info['name'];
1909
while ($row = $db->sql_fetchrow($result))
1911
$schema_vals = $schema_fields = array();
1913
// Build the SQL statement to recreate the data.
1914
for ($i = 0; $i < $i_num_fields; $i++)
1916
$str_val = $row[strtolower($ary_name[$i])];
1918
if (preg_match('#char|text|bool|varbinary|blob#i', $ary_type[$i]))
1922
$str_val = sanitize_data_generic(str_replace("'", "''", $str_val));
1924
else if (preg_match('#date|timestamp#i', $ary_type[$i]))
1926
if (empty($str_val))
1938
$str_empty = 'NULL';
1941
if (empty($str_val) && $str_val !== '0')
1943
$str_val = $str_empty;
1946
$schema_vals[$i] = $str_quote . $str_val . $str_quote;
1947
$schema_fields[$i] = '"' . $ary_name[$i] . '"';
1950
// Take the ordered fields and their associated data and build it
1951
// into a valid sql statement to recreate that field in the data.
1952
$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
1954
$this->flush($sql_data);
1956
$db->sql_freeresult($result);
1959
function write_table($table_name)
1963
$sql_data = '-- Table: ' . $table_name . "\n";
1964
$sql_data .= "DROP TABLE $table_name;\n";
1966
$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');
1968
$sql_data .= "\nCREATE TABLE $table_name (\n";
1970
$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
1971
FROM RDB$RELATION_FIELDS R
1972
JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME
1973
LEFT JOIN RDB$FIELD_DIMENSIONS D ON R.RDB$FIELD_SOURCE = D.RDB$FIELD_NAME
1974
WHERE F.RDB$SYSTEM_FLAG = 0
1975
AND R.RDB$RELATION_NAME = \''. $table_name . '\'
1976
ORDER BY R.RDB$FIELD_POSITION';
1977
$result = $db->sql_query($sql);
1980
while ($row = $db->sql_fetchrow($result))
1982
$line = "\t" . '"' . $row['fname'] . '" ' . $data_types[$row['ftype']];
1984
if ($row['ftype'] == 261 && $row['stype'] == 1)
1986
$line .= ' SUB_TYPE TEXT';
1989
if ($row['ftype'] == 37 || $row['ftype'] == 14)
1991
$line .= ' (' . $row['flen'] . ')';
1994
if (!empty($row['dsource']))
1996
$line .= ' ' . $row['dsource'];
1999
if (!empty($row['nflag']))
2001
$line .= ' NOT NULL';
2005
$db->sql_freeresult($result);
2007
$sql_data .= implode(",\n", $rows);
2008
$sql_data .= "\n);\n";
2011
$sql = 'SELECT I.RDB$FIELD_NAME as NAME
2012
FROM RDB$RELATION_CONSTRAINTS RC, RDB$INDEX_SEGMENTS I, RDB$INDICES IDX
2013
WHERE (I.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2014
AND (IDX.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
2015
AND (RC.RDB$RELATION_NAME = \''. $table_name . '\')
2016
ORDER BY I.RDB$FIELD_POSITION';
2017
$result = $db->sql_query($sql);
2019
while ($row = $db->sql_fetchrow($result))
2021
$keys[] = $row['name'];
2026
$sql_data .= "\nALTER TABLE $table_name ADD PRIMARY KEY (" . implode(', ', $keys) . ');';
2029
$db->sql_freeresult($result);
2031
$sql = 'SELECT I.RDB$INDEX_NAME as INAME, I.RDB$UNIQUE_FLAG as UFLAG, S.RDB$FIELD_NAME as FNAME
2032
FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON S.RDB$INDEX_NAME=I.RDB$INDEX_NAME
2033
WHERE (I.RDB$SYSTEM_FLAG IS NULL OR I.RDB$SYSTEM_FLAG=0)
2034
AND I.RDB$FOREIGN_KEY IS NULL
2035
AND I.RDB$RELATION_NAME = \''. $table_name . '\'
2036
AND I.RDB$INDEX_NAME NOT STARTING WITH \'RDB$\'
2037
ORDER BY S.RDB$FIELD_POSITION';
2038
$result = $db->sql_query($sql);
2041
while ($row = $db->sql_fetchrow($result))
2043
$index[$row['iname']]['unique'] = !empty($row['uflag']);
2044
$index[$row['iname']]['values'][] = $row['fname'];
2047
foreach ($index as $index_name => $data)
2049
$sql_data .= "\nCREATE ";
2050
if ($data['unique'])
2052
$sql_data .= 'UNIQUE ';
2054
$sql_data .= "INDEX $index_name ON $table_name(" . implode(', ', $data['values']) . ");";
2058
$db->sql_freeresult($result);
2060
$sql = 'SELECT D1.RDB$DEPENDENT_NAME as DNAME, D1.RDB$FIELD_NAME as FNAME, D1.RDB$DEPENDENT_TYPE, R1.RDB$RELATION_NAME
2061
FROM RDB$DEPENDENCIES D1
2062
LEFT JOIN RDB$RELATIONS R1 ON ((D1.RDB$DEPENDENT_NAME = R1.RDB$RELATION_NAME) AND (NOT (R1.RDB$VIEW_BLR IS NULL)))
2063
WHERE (D1.RDB$DEPENDED_ON_TYPE = 0)
2064
AND (D1.RDB$DEPENDENT_TYPE <> 3)
2065
AND (D1.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2066
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
2067
LEFT JOIN RDB$RELATIONS R2 ON ((F2.RDB$RELATION_NAME = R2.RDB$RELATION_NAME) AND (NOT (R2.RDB$VIEW_BLR IS NULL)))
2068
WHERE (D2.RDB$DEPENDENT_TYPE = 3)
2069
AND (D2.RDB$DEPENDENT_NAME = F2.RDB$FIELD_SOURCE)
2070
AND (D2.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
2072
$result = $db->sql_query($sql);
2073
while ($row = $db->sql_fetchrow($result))
2075
$sql = 'SELECT T1.RDB$DEPENDED_ON_NAME as GEN, T1.RDB$FIELD_NAME, T1.RDB$DEPENDED_ON_TYPE
2076
FROM RDB$DEPENDENCIES T1
2077
WHERE (T1.RDB$DEPENDENT_NAME = \'' . $row['dname'] . '\')
2078
AND (T1.RDB$DEPENDENT_TYPE = 2 AND T1.RDB$DEPENDED_ON_TYPE = 14)
2079
UNION ALL SELECT DISTINCT D.RDB$DEPENDED_ON_NAME, D.RDB$FIELD_NAME, D.RDB$DEPENDED_ON_TYPE
2080
FROM RDB$DEPENDENCIES D, RDB$RELATION_FIELDS F
2081
WHERE (D.RDB$DEPENDENT_TYPE = 3)
2082
AND (D.RDB$DEPENDENT_NAME = F.RDB$FIELD_SOURCE)
2083
AND (F.RDB$RELATION_NAME = \'' . $row['dname'] . '\')
2085
$result2 = $db->sql_query($sql);
2086
$row2 = $db->sql_fetchrow($result2);
2087
$db->sql_freeresult($result2);
2088
$gen_name = $row2['gen'];
2090
$sql_data .= "\nDROP GENERATOR " . $gen_name . ";";
2091
$sql_data .= "\nSET TERM ^ ;";
2092
$sql_data .= "\nCREATE GENERATOR " . $gen_name . "^";
2093
$sql_data .= "\nSET GENERATOR " . $gen_name . " TO 0^\n";
2094
$sql_data .= "\nCREATE TRIGGER {$row['dname']} FOR $table_name";
2095
$sql_data .= "\nBEFORE INSERT\nAS\nBEGIN";
2096
$sql_data .= "\n NEW.{$row['fname']} = GEN_ID(" . $gen_name . ", 1);";
2097
$sql_data .= "\nEND^\n";
2098
$sql_data .= "\nSET TERM ; ^\n";
2101
$this->flush($sql_data);
2103
$db->sql_freeresult($result);
2107
// 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)
2108
function get_usable_memory()
2110
$val = trim(@ini_get('memory_limit'));
2112
if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
2114
$memory_limit = (int) $regs[1];
2120
$memory_limit *= 1024;
2125
$memory_limit *= 1048576;
2130
$memory_limit *= 1073741824;
2134
// how much memory PHP requires at the start of export (it is really a little less)
2135
if ($memory_limit > 6100000)
2137
$memory_limit -= 6100000;
2140
// allow us to consume half of the total memory available
2145
// set the buffer to 1M if we have no clue how much memory PHP will give us :P
2146
$memory_limit = 1048576;
2149
return $memory_limit;
2152
function sanitize_data_mssql($text)
2154
$data = preg_split('/[\n\t\r\b\f]/', $text);
2155
preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2159
foreach ($data as $value)
2163
$val[] = "'" . $value . "'";
2165
if (sizeof($matches[0]))
2167
$val[] = 'char(' . ord(array_shift($matches[0])) . ')';
2171
return implode('+', $val);
2174
function sanitize_data_oracle($text)
2176
$data = preg_split('/[\0\n\t\r\b\f\'"\\\]/', $text);
2177
preg_match_all('/[\0\n\t\r\b\f\'"\\\]/', $text, $matches);
2181
foreach ($data as $value)
2185
$val[] = "'" . $value . "'";
2187
if (sizeof($matches[0]))
2189
$val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
2193
return implode('||', $val);
2196
function sanitize_data_generic($text)
2198
$data = preg_split('/[\n\t\r\b\f]/', $text);
2199
preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
2203
foreach ($data as $value)
2207
$val[] = "'" . $value . "'";
2209
if (sizeof($matches[0]))
2211
$val[] = "'" . array_shift($matches[0]) . "'";
2215
return implode('||', $val);
2218
// modified from PHP.net
2219
function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2222
$delim_len = strlen($delim);
2226
$pos = strpos($record, $delim);
2229
$record .= $read($fp, $buffer);
2230
if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
2232
$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
2233
return substr($record, 0, $pos);
2238
$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
2239
return substr($record, 0, $pos);
2246
function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
2248
static $array = array();
2249
static $record = '';
2251
if (!sizeof($array))
2255
if (strpos($record, $delim) !== false)
2257
$array = explode($delim, $record);
2258
$record = array_pop($array);
2263
$record .= $read($fp, $buffer);
2266
if ($eof($fp) && strpos($record, $delim) !== false)
2268
$array = explode($delim, $record);
2269
$record = array_pop($array);
2275
return array_shift($array);
b'\\ No newline at end of file'