Blame Extras/phpBB/3.0.4/includes/acp/acp_database.php

4c79b5
4c79b5
/**
4c79b5
*
4c79b5
* @package acp
4c79b5
* @version $Id: acp_database.php 8814 2008-09-04 12:01:47Z acydburn $
4c79b5
* @copyright (c) 2005 phpBB Group
4c79b5
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
4c79b5
*
4c79b5
*/
4c79b5
4c79b5
/**
4c79b5
* @ignore
4c79b5
*/
4c79b5
if (!defined('IN_PHPBB'))
4c79b5
{
4c79b5
	exit;
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class acp_database
4c79b5
{
4c79b5
	var $u_action;
4c79b5
4c79b5
	function main($id, $mode)
4c79b5
	{
4c79b5
		global $cache, $db, $user, $auth, $template, $table_prefix;
4c79b5
		global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
4c79b5
		
4c79b5
		$user->add_lang('acp/database');
4c79b5
4c79b5
		$this->tpl_name = 'acp_database';
4c79b5
		$this->page_title = 'ACP_DATABASE';
4c79b5
4c79b5
		$action	= request_var('action', '');
4c79b5
		$submit = (isset($_POST['submit'])) ? true : false;
4c79b5
4c79b5
		$template->assign_vars(array(
4c79b5
			'MODE'	=> $mode
4c79b5
		));
4c79b5
4c79b5
		switch ($mode)
4c79b5
		{
4c79b5
			case 'backup':
4c79b5
4c79b5
				$this->page_title = 'ACP_BACKUP';
4c79b5
4c79b5
				switch ($action)
4c79b5
				{
4c79b5
					case 'download':
4c79b5
						$type	= request_var('type', '');
4c79b5
						$table	= request_var('table', array(''));
4c79b5
						$format	= request_var('method', '');
4c79b5
						$where	= request_var('where', '');
4c79b5
4c79b5
						if (!sizeof($table))
4c79b5
						{
4c79b5
							trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
4c79b5
						}
4c79b5
4c79b5
						$store = $download = $structure = $schema_data = false;
4c79b5
4c79b5
						if ($where == 'store_and_download' || $where == 'store')
4c79b5
						{
4c79b5
							$store = true;
4c79b5
						}
4c79b5
4c79b5
						if ($where == 'store_and_download' || $where == 'download')
4c79b5
						{
4c79b5
							$download = true;
4c79b5
						}
4c79b5
4c79b5
						if ($type == 'full' || $type == 'structure')
4c79b5
						{
4c79b5
							$structure = true;
4c79b5
						}
4c79b5
4c79b5
						if ($type == 'full' || $type == 'data')
4c79b5
						{
4c79b5
							$schema_data = true;
4c79b5
						}
4c79b5
4c79b5
						@set_time_limit(1200);
4c79b5
4c79b5
						$time = time();
4c79b5
4c79b5
						$filename = 'backup_' . $time . '_' . unique_id();
4c79b5
						switch ($db->sql_layer)
4c79b5
						{
4c79b5
							case 'mysqli':
4c79b5
							case 'mysql4':
4c79b5
							case 'mysql':
4c79b5
								$extractor = new mysql_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
4c79b5
							case 'sqlite':
4c79b5
								$extractor = new sqlite_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
4c79b5
							case 'postgres':
4c79b5
								$extractor = new postgres_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
4c79b5
							case 'oracle':
4c79b5
								$extractor = new oracle_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
4c79b5
							case 'mssql':
4c79b5
							case 'mssql_odbc':
4c79b5
								$extractor = new mssql_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
4c79b5
							case 'firebird':
4c79b5
								$extractor = new firebird_extractor($download, $store, $format, $filename, $time);
4c79b5
							break;
4c79b5
						}
4c79b5
4c79b5
						$extractor->write_start($table_prefix);
4c79b5
4c79b5
						foreach ($table as $table_name)
4c79b5
						{
4c79b5
							// Get the table structure
4c79b5
							if ($structure)
4c79b5
							{
4c79b5
								$extractor->write_table($table_name);
4c79b5
							}
4c79b5
							else
4c79b5
							{
4c79b5
								// We might wanna empty out all that junk :D
4c79b5
								switch ($db->sql_layer)
4c79b5
								{
4c79b5
									case 'sqlite':
4c79b5
									case 'firebird':
4c79b5
										$extractor->flush('DELETE FROM ' . $table_name . ";\n");
4c79b5
									break;
4c79b5
4c79b5
									case 'mssql':
4c79b5
									case 'mssql_odbc':
4c79b5
										$extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
4c79b5
									break;
4c79b5
4c79b5
									case 'oracle':
4c79b5
										$extractor->flush('TRUNCATE TABLE ' . $table_name . "\\\n");
4c79b5
									break;
4c79b5
4c79b5
									default:
4c79b5
										$extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
4c79b5
									break;
4c79b5
								}
4c79b5
							}
4c79b5
4c79b5
							// Data
4c79b5
							if ($schema_data)
4c79b5
							{
4c79b5
								$extractor->write_data($table_name);
4c79b5
							}
4c79b5
						}
4c79b5
4c79b5
						$extractor->write_end();
4c79b5
4c79b5
						add_log('admin', 'LOG_DB_BACKUP');
4c79b5
4c79b5
						if ($download == true)
4c79b5
						{
4c79b5
							exit;
4c79b5
						}
4c79b5
4c79b5
						trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
4c79b5
					break;
4c79b5
4c79b5
					default:
4c79b5
						include($phpbb_root_path . 'includes/functions_install.' . $phpEx);
4c79b5
						$tables = get_tables($db);
4c79b5
						asort($tables);
4c79b5
						foreach ($tables as $table_name)
4c79b5
						{
4c79b5
							if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
4c79b5
							{
4c79b5
								$template->assign_block_vars('tables', array(
4c79b5
									'TABLE'	=> $table_name
4c79b5
								));
4c79b5
							}
4c79b5
						}
4c79b5
						unset($tables);
4c79b5
4c79b5
						$template->assign_vars(array(
4c79b5
							'U_ACTION'	=> $this->u_action . '&action=download'
4c79b5
						));
4c79b5
						
4c79b5
						$available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
4c79b5
4c79b5
						foreach ($available_methods as $type => $module)
4c79b5
						{
4c79b5
							if (!@extension_loaded($module))
4c79b5
							{
4c79b5
								continue;
4c79b5
							}
4c79b5
4c79b5
							$template->assign_block_vars('methods', array(
4c79b5
								'TYPE'	=> $type
4c79b5
							));
4c79b5
						}
4c79b5
4c79b5
						$template->assign_block_vars('methods', array(
4c79b5
							'TYPE'	=> 'text'
4c79b5
						));
4c79b5
					break;
4c79b5
				}
4c79b5
			break;
4c79b5
4c79b5
			case 'restore':
4c79b5
4c79b5
				$this->page_title = 'ACP_RESTORE';
4c79b5
4c79b5
				switch ($action)
4c79b5
				{
4c79b5
					case 'submit':
4c79b5
						$delete = request_var('delete', '');
4c79b5
						$file = request_var('file', '');
4c79b5
4c79b5
						if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
4c79b5
						{
4c79b5
							trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
4c79b5
						}
4c79b5
4c79b5
						$file_name = $phpbb_root_path . 'store/' . $matches[0];
4c79b5
4c79b5
						if (!file_exists($file_name) || !is_readable($file_name))
4c79b5
						{
4c79b5
							trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
4c79b5
						}
4c79b5
4c79b5
						if ($delete)
4c79b5
						{
4c79b5
							if (confirm_box(true))
4c79b5
							{
4c79b5
								unlink($file_name);
4c79b5
								add_log('admin', 'LOG_DB_DELETE');
4c79b5
								trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
4c79b5
							}
4c79b5
							else
4c79b5
							{
4c79b5
								confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
4c79b5
							}
4c79b5
						}
4c79b5
						else
4c79b5
						{
4c79b5
							$download = request_var('download', '');
4c79b5
4c79b5
							if ($download)
4c79b5
							{
4c79b5
								$name = $matches[0];
4c79b5
4c79b5
								switch ($matches[1])
4c79b5
								{
4c79b5
									case 'sql':
4c79b5
										$mimetype = 'text/x-sql';
4c79b5
									break;
4c79b5
									case 'sql.bz2':
4c79b5
										$mimetype = 'application/x-bzip2';
4c79b5
									break;
4c79b5
									case 'sql.gz':
4c79b5
										$mimetype = 'application/x-gzip';
4c79b5
									break;
4c79b5
								}
4c79b5
4c79b5
								header('Pragma: no-cache');
4c79b5
								header("Content-Type: $mimetype; name=\"$name\"");
4c79b5
								header("Content-disposition: attachment; filename=$name");
4c79b5
4c79b5
								@set_time_limit(0);
4c79b5
4c79b5
								$fp = @fopen($file_name, 'rb');
4c79b5
4c79b5
								if ($fp !== false)
4c79b5
								{
4c79b5
									while (!feof($fp))
4c79b5
									{
4c79b5
										echo fread($fp, 8192);
4c79b5
									}
4c79b5
									fclose($fp);
4c79b5
								}
4c79b5
4c79b5
								flush();
4c79b5
								exit;
4c79b5
							}
4c79b5
4c79b5
							switch ($matches[1])
4c79b5
							{
4c79b5
								case 'sql':
4c79b5
									$fp = fopen($file_name, 'rb');
4c79b5
									$read = 'fread';
4c79b5
									$seek = 'fseek';
4c79b5
									$eof = 'feof';
4c79b5
									$close = 'fclose';
4c79b5
									$fgetd = 'fgetd';
4c79b5
								break;
4c79b5
4c79b5
								case 'sql.bz2':
4c79b5
									$fp = bzopen($file_name, 'r');
4c79b5
									$read = 'bzread';
4c79b5
									$seek = '';
4c79b5
									$eof = 'feof';
4c79b5
									$close = 'bzclose';
4c79b5
									$fgetd = 'fgetd_seekless';
4c79b5
								break;
4c79b5
4c79b5
								case 'sql.gz':
4c79b5
									$fp = gzopen($file_name, 'rb');
4c79b5
									$read = 'gzread';
4c79b5
									$seek = 'gzseek';
4c79b5
									$eof = 'gzeof';
4c79b5
									$close = 'gzclose';
4c79b5
									$fgetd = 'fgetd';
4c79b5
								break;
4c79b5
							}
4c79b5
4c79b5
							switch ($db->sql_layer)
4c79b5
							{
4c79b5
								case 'mysql':
4c79b5
								case 'mysql4':
4c79b5
								case 'mysqli':
4c79b5
								case 'sqlite':
4c79b5
									while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
4c79b5
									{
4c79b5
										$db->sql_query($sql);
4c79b5
									}
4c79b5
								break;
4c79b5
4c79b5
								case 'firebird':
4c79b5
									$delim = ";\n";
4c79b5
									while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
4c79b5
									{
4c79b5
										$query = trim($sql);
4c79b5
										if (substr($query, 0, 8) === 'SET TERM')
4c79b5
										{
4c79b5
											$delim = $query[9] . "\n";
4c79b5
											continue;
4c79b5
										}
4c79b5
										$db->sql_query($query);
4c79b5
									}
4c79b5
								break;
4c79b5
4c79b5
								case 'postgres':
4c79b5
									$delim = ";\n";
4c79b5
									while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
4c79b5
									{
4c79b5
										$query = trim($sql);
4c79b5
4c79b5
										if (substr($query, 0, 13) == 'CREATE DOMAIN')
4c79b5
										{
4c79b5
											list(, , $domain) = explode(' ', $query);
4c79b5
											$sql = "SELECT domain_name
4c79b5
												FROM information_schema.domains
4c79b5
												WHERE domain_name = '$domain';";
4c79b5
											$result = $db->sql_query($sql);
4c79b5
											if (!$db->sql_fetchrow($result))
4c79b5
											{
4c79b5
												$db->sql_query($query);
4c79b5
											}
4c79b5
											$db->sql_freeresult($result);
4c79b5
										}
4c79b5
										else
4c79b5
										{
4c79b5
											$db->sql_query($query);
4c79b5
										}
4c79b5
4c79b5
										if (substr($query, 0, 4) == 'COPY')
4c79b5
										{
4c79b5
											while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
4c79b5
											{
4c79b5
												if ($sub === false)
4c79b5
												{
4c79b5
													trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
4c79b5
												}
4c79b5
												pg_put_line($db->db_connect_id, $sub . "\n");
4c79b5
											}
4c79b5
											pg_put_line($db->db_connect_id, "\\.\n");
4c79b5
											pg_end_copy($db->db_connect_id);
4c79b5
										}
4c79b5
									}
4c79b5
								break;
4c79b5
4c79b5
								case 'oracle':
4c79b5
									while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
4c79b5
									{
4c79b5
										$db->sql_query($sql);
4c79b5
									}
4c79b5
								break;
4c79b5
4c79b5
								case 'mssql':
4c79b5
								case 'mssql_odbc':
4c79b5
									while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
4c79b5
									{
4c79b5
										$db->sql_query($sql);
4c79b5
									}
4c79b5
								break;
4c79b5
							}
4c79b5
4c79b5
							$close($fp);
4c79b5
4c79b5
							// Purge the cache due to updated data
4c79b5
							$cache->purge();
4c79b5
4c79b5
							add_log('admin', 'LOG_DB_RESTORE');
4c79b5
							trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
4c79b5
							break;
4c79b5
						}
4c79b5
4c79b5
					default:
4c79b5
						$methods = array('sql');
4c79b5
						$available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
4c79b5
4c79b5
						foreach ($available_methods as $type => $module)
4c79b5
						{
4c79b5
							if (!@extension_loaded($module))
4c79b5
							{
4c79b5
								continue;
4c79b5
							}
4c79b5
							$methods[] = $type;
4c79b5
						}
4c79b5
4c79b5
						$dir = $phpbb_root_path . 'store/';
4c79b5
						$dh = @opendir($dir);
4c79b5
4c79b5
						if ($dh)
4c79b5
						{
4c79b5
							while (($file = readdir($dh)) !== false)
4c79b5
							{
4c79b5
								if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
4c79b5
								{
4c79b5
									$supported = in_array($matches[2], $methods);
4c79b5
4c79b5
									if ($supported == 'true')
4c79b5
									{
4c79b5
										$template->assign_block_vars('files', array(
4c79b5
											'FILE'		=> $file,
4c79b5
											'NAME'		=> gmdate("d-m-Y H:i:s", $matches[1]),
4c79b5
											'SUPPORTED'	=> $supported
4c79b5
										));
4c79b5
									}
4c79b5
								}
4c79b5
							}
4c79b5
							closedir($dh);
4c79b5
						}
4c79b5
4c79b5
						$template->assign_vars(array(
4c79b5
							'U_ACTION'	=> $this->u_action . '&action=submit'
4c79b5
						));
4c79b5
					break;
4c79b5
				}
4c79b5
			break;
4c79b5
		}
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class base_extractor
4c79b5
{
4c79b5
	var $fh;
4c79b5
	var $fp;
4c79b5
	var $write;
4c79b5
	var $close;
4c79b5
	var $store;
4c79b5
	var $download;
4c79b5
	var $time;
4c79b5
	var $format;
4c79b5
	var $run_comp = false;
4c79b5
4c79b5
	function base_extractor($download = false, $store = false, $format, $filename, $time)
4c79b5
	{
4c79b5
		$this->download = $download;
4c79b5
		$this->store = $store;
4c79b5
		$this->time = $time;
4c79b5
		$this->format = $format;
4c79b5
4c79b5
		switch ($format)
4c79b5
		{
4c79b5
			case 'text':
4c79b5
				$ext = '.sql';
4c79b5
				$open = 'fopen';
4c79b5
				$this->write = 'fwrite';
4c79b5
				$this->close = 'fclose';
4c79b5
				$mimetype = 'text/x-sql';
4c79b5
			break;
4c79b5
			case 'bzip2':
4c79b5
				$ext = '.sql.bz2';
4c79b5
				$open = 'bzopen';
4c79b5
				$this->write = 'bzwrite';
4c79b5
				$this->close = 'bzclose';
4c79b5
				$mimetype = 'application/x-bzip2';
4c79b5
			break;
4c79b5
			case 'gzip':
4c79b5
				$ext = '.sql.gz';
4c79b5
				$open = 'gzopen';
4c79b5
				$this->write = 'gzwrite';
4c79b5
				$this->close = 'gzclose';
4c79b5
				$mimetype = 'application/x-gzip';
4c79b5
			break;
4c79b5
		}
4c79b5
4c79b5
		if ($download == true)
4c79b5
		{
4c79b5
			$name = $filename . $ext;
4c79b5
			header('Pragma: no-cache');
4c79b5
			header("Content-Type: $mimetype; name=\"$name\"");
4c79b5
			header("Content-disposition: attachment; filename=$name");
4c79b5
	
4c79b5
			switch ($format)
4c79b5
			{
4c79b5
				case 'bzip2':
4c79b5
					ob_start();
4c79b5
				break;
4c79b5
4c79b5
				case 'gzip':
4c79b5
					if ((isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false) && strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'msie') === false)
4c79b5
					{
4c79b5
						ob_start('ob_gzhandler');
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$this->run_comp = true;
4c79b5
					}
4c79b5
				break;
4c79b5
			}
4c79b5
		}
4c79b5
		
4c79b5
		if ($store == true)
4c79b5
		{
4c79b5
			global $phpbb_root_path;
4c79b5
			$file = $phpbb_root_path . 'store/' . $filename . $ext;
4c79b5
	
4c79b5
			$this->fp = $open($file, 'w');
4c79b5
	
4c79b5
			if (!$this->fp)
4c79b5
			{
4c79b5
				trigger_error('Unable to write temporary file to storage folder', E_USER_ERROR);
4c79b5
			}
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_end()
4c79b5
	{
4c79b5
		static $close;
4c79b5
		if ($this->store)
4c79b5
		{
4c79b5
			if ($close === null)
4c79b5
			{
4c79b5
				$close = $this->close;
4c79b5
			}
4c79b5
			$close($this->fp);
4c79b5
		}
4c79b5
4c79b5
		// bzip2 must be written all the way at the end
4c79b5
		if ($this->download && $this->format === 'bzip2')
4c79b5
		{
4c79b5
			$c = ob_get_clean();
4c79b5
			echo bzcompress($c);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function flush($data)
4c79b5
	{
4c79b5
		static $write;
4c79b5
		if ($this->store === true)
4c79b5
		{
4c79b5
			if ($write === null)
4c79b5
			{
4c79b5
				$write = $this->write;
4c79b5
			}
4c79b5
			$write($this->fp, $data);
4c79b5
		}
4c79b5
4c79b5
		if ($this->download === true)
4c79b5
		{
4c79b5
			if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp))
4c79b5
			{
4c79b5
				echo $data;
4c79b5
			}
4c79b5
4c79b5
			// we can write the gzip data as soon as we get it
4c79b5
			if ($this->format === 'gzip')
4c79b5
			{
4c79b5
				if ($this->run_comp)
4c79b5
				{
4c79b5
					echo gzencode($data);
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					ob_flush();
4c79b5
					flush();
4c79b5
				}
4c79b5
			}
4c79b5
		}
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class mysql_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_start($table_prefix)
4c79b5
	{
4c79b5
		$sql_data = "#\n";
4c79b5
		$sql_data .= "# phpBB Backup Script\n";
4c79b5
		$sql_data .= "# Dump of tables for $table_prefix\n";
4c79b5
		$sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "#\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		static $new_extract;
4c79b5
4c79b5
		if ($new_extract === null)
4c79b5
		{
4c79b5
			if ($db->sql_layer === 'mysqli' || version_compare($db->sql_server_info(true), '3.23.20', '>='))
4c79b5
			{
4c79b5
				$new_extract = true;
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				$new_extract = false;
4c79b5
			}
4c79b5
		}
4c79b5
4c79b5
		if ($new_extract)
4c79b5
		{
4c79b5
			$this->new_write_table($table_name);
4c79b5
		}
4c79b5
		else
4c79b5
		{
4c79b5
			$this->old_write_table($table_name);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		if ($db->sql_layer === 'mysqli')
4c79b5
		{
4c79b5
			$this->write_data_mysqli($table_name);
4c79b5
		}
4c79b5
		else
4c79b5
		{
4c79b5
			$this->write_data_mysql($table_name);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_data_mysqli($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = mysqli_query($db->db_connect_id, $sql, MYSQLI_USE_RESULT);
4c79b5
		if ($result != false)
4c79b5
		{
4c79b5
			$fields_cnt = mysqli_num_fields($result);
4c79b5
		
4c79b5
			// Get field information
4c79b5
			$field = mysqli_fetch_fields($result);
4c79b5
			$field_set = array();
4c79b5
		
4c79b5
			for ($j = 0; $j < $fields_cnt; $j++)
4c79b5
			{
4c79b5
				$field_set[] = $field[$j]->name;
4c79b5
			}
4c79b5
4c79b5
			$search			= array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
4c79b5
			$replace		= array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
4c79b5
			$fields			= implode(', ', $field_set);
4c79b5
			$sql_data		= 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
4c79b5
			$first_set		= true;
4c79b5
			$query_len		= 0;
4c79b5
			$max_len		= get_usable_memory();
4c79b5
		
4c79b5
			while ($row = mysqli_fetch_row($result))
4c79b5
			{
4c79b5
				$values	= array();
4c79b5
				if ($first_set)
4c79b5
				{
4c79b5
					$query = $sql_data . '(';
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$query  .= ',(';
4c79b5
				}
4c79b5
4c79b5
				for ($j = 0; $j < $fields_cnt; $j++)
4c79b5
				{
4c79b5
					if (!isset($row[$j]) || is_null($row[$j]))
4c79b5
					{
4c79b5
						$values[$j] = 'NULL';
4c79b5
					}
4c79b5
					else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024))
4c79b5
					{
4c79b5
						$values[$j] = $row[$j];
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
4c79b5
					}
4c79b5
				}
4c79b5
				$query .= implode(', ', $values) . ')';
4c79b5
4c79b5
				$query_len += strlen($query);
4c79b5
				if ($query_len > $max_len)
4c79b5
				{
4c79b5
					$this->flush($query . ";\n\n");
4c79b5
					$query = '';
4c79b5
					$query_len = 0;
4c79b5
					$first_set = true;
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$first_set = false;
4c79b5
				}
4c79b5
			}
4c79b5
			mysqli_free_result($result);
4c79b5
4c79b5
			// check to make sure we have nothing left to flush
4c79b5
			if (!$first_set && $query)
4c79b5
			{
4c79b5
				$this->flush($query . ";\n\n");
4c79b5
			}
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_data_mysql($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = mysql_unbuffered_query($sql, $db->db_connect_id);
4c79b5
4c79b5
		if ($result != false)
4c79b5
		{
4c79b5
			$fields_cnt = mysql_num_fields($result);
4c79b5
4c79b5
			// Get field information
4c79b5
			$field = array();
4c79b5
			for ($i = 0; $i < $fields_cnt; $i++)
4c79b5
			{
4c79b5
				$field[] = mysql_fetch_field($result, $i);
4c79b5
			}
4c79b5
			$field_set = array();
4c79b5
			
4c79b5
			for ($j = 0; $j < $fields_cnt; $j++)
4c79b5
			{
4c79b5
				$field_set[] = $field[$j]->name;
4c79b5
			}
4c79b5
4c79b5
			$search			= array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
4c79b5
			$replace		= array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
4c79b5
			$fields			= implode(', ', $field_set);
4c79b5
			$sql_data		= 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
4c79b5
			$first_set		= true;
4c79b5
			$query_len		= 0;
4c79b5
			$max_len		= get_usable_memory();
4c79b5
4c79b5
			while ($row = mysql_fetch_row($result))
4c79b5
			{
4c79b5
				$values = array();
4c79b5
				if ($first_set)
4c79b5
				{
4c79b5
					$query = $sql_data . '(';
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$query  .= ',(';
4c79b5
				}
4c79b5
4c79b5
				for ($j = 0; $j < $fields_cnt; $j++)
4c79b5
				{
4c79b5
					if (!isset($row[$j]) || is_null($row[$j]))
4c79b5
					{
4c79b5
						$values[$j] = 'NULL';
4c79b5
					}
4c79b5
					else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
4c79b5
					{
4c79b5
						$values[$j] = $row[$j];
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
4c79b5
					}
4c79b5
				}
4c79b5
				$query .= implode(', ', $values) . ')';
4c79b5
4c79b5
				$query_len += strlen($query);
4c79b5
				if ($query_len > $max_len)
4c79b5
				{
4c79b5
					$this->flush($query . ";\n\n");
4c79b5
					$query = '';
4c79b5
					$query_len = 0;
4c79b5
					$first_set = true;
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$first_set = false;
4c79b5
				}
4c79b5
			}
4c79b5
			mysql_free_result($result);
4c79b5
4c79b5
			// check to make sure we have nothing left to flush
4c79b5
			if (!$first_set && $query)
4c79b5
			{
4c79b5
				$this->flush($query . ";\n\n");
4c79b5
			}
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function new_write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
4c79b5
		$sql = 'SHOW CREATE TABLE ' . $table_name;
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		$row = $db->sql_fetchrow($result);
4c79b5
4c79b5
		$sql_data = '# Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
4c79b5
		$this->flush($sql_data . $row['Create Table'] . ";\n\n");
4c79b5
4c79b5
		$db->sql_freeresult($result);
4c79b5
	}
4c79b5
4c79b5
	function old_write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
4c79b5
		$sql_data = '# Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
4c79b5
		$sql_data .= "CREATE TABLE $table_name(\n";
4c79b5
		$rows = array();
4c79b5
4c79b5
		$sql = "SHOW FIELDS
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$line = '   ' . $row['Field'] . ' ' . $row['Type'];
4c79b5
4c79b5
			if (!is_null($row['Default']))
4c79b5
			{
4c79b5
				$line .= " DEFAULT '{$row['Default']}'";
4c79b5
			}
4c79b5
4c79b5
			if ($row['Null'] != 'YES')
4c79b5
			{
4c79b5
				$line .= ' NOT NULL';
4c79b5
			}
4c79b5
4c79b5
			if ($row['Extra'] != '')
4c79b5
			{
4c79b5
				$line .= ' ' . $row['Extra'];
4c79b5
			}
4c79b5
4c79b5
			$rows[] = $line;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = "SHOW KEYS
4c79b5
			FROM $table_name";
4c79b5
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$index = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$kname = $row['Key_name'];
4c79b5
4c79b5
			if ($kname != 'PRIMARY')
4c79b5
			{
4c79b5
				if ($row['Non_unique'] == 0)
4c79b5
				{
4c79b5
					$kname = "UNIQUE|$kname";
4c79b5
				}
4c79b5
			}
4c79b5
4c79b5
			if ($row['Sub_part'])
4c79b5
			{
4c79b5
				$row['Column_name'] .= '(' . $row['Sub_part'] . ')';
4c79b5
			}
4c79b5
			$index[$kname][] = $row['Column_name'];
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		foreach ($index as $key => $columns)
4c79b5
		{
4c79b5
			$line = '   ';
4c79b5
4c79b5
			if ($key == 'PRIMARY')
4c79b5
			{
4c79b5
				$line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')';
4c79b5
			}
4c79b5
			else if (strpos($key, 'UNIQUE') === 0)
4c79b5
			{
4c79b5
				$line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')';
4c79b5
			}
4c79b5
			else if (strpos($key, 'FULLTEXT') === 0)
4c79b5
			{
4c79b5
				$line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')';
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				$line .= "KEY $key (" . implode(', ', $columns) . ')';
4c79b5
			}
4c79b5
4c79b5
			$rows[] = $line;
4c79b5
		}
4c79b5
4c79b5
		$sql_data .= implode(",\n", $rows);
4c79b5
		$sql_data .= "\n);\n\n";
4c79b5
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class sqlite_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_start($prefix)
4c79b5
	{
4c79b5
		$sql_data = "--\n";
4c79b5
		$sql_data .= "-- phpBB Backup Script\n";
4c79b5
		$sql_data .= "-- Dump of tables for $prefix\n";
4c79b5
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "--\n";
4c79b5
		$sql_data .= "BEGIN TRANSACTION;\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$sql_data = '-- Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE $table_name;\n";
4c79b5
4c79b5
		$sql = "SELECT sql
4c79b5
			FROM sqlite_master
4c79b5
			WHERE type = 'table'
4c79b5
				AND name = '" . $db->sql_escape($table_name) . "'
4c79b5
			ORDER BY type DESC, name;";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		$row = $db->sql_fetchrow($result);
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		// Create Table
4c79b5
		$sql_data .= $row['sql'] . ";\n";
4c79b5
4c79b5
		$result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
4c79b5
4c79b5
		$ar = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$ar[] = $row;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
		
4c79b5
		foreach ($ar as $value)
4c79b5
		{
4c79b5
			if (strpos($value['name'], 'autoindex') !== false)
4c79b5
			{
4c79b5
				continue;
4c79b5
			}
4c79b5
4c79b5
			$result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
4c79b5
4c79b5
			$fields = array();
4c79b5
			while ($row = $db->sql_fetchrow($result))
4c79b5
			{
4c79b5
				$fields[] = $row['name'];
4c79b5
			}
4c79b5
			$db->sql_freeresult($result);
4c79b5
4c79b5
			$sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
4c79b5
		}
4c79b5
4c79b5
		$this->flush($sql_data . "\n");
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		static $proper;
4c79b5
4c79b5
		if (is_null($proper))
4c79b5
		{
4c79b5
			$proper = version_compare(PHP_VERSION, '5.1.3', '>=');
4c79b5
		}
4c79b5
4c79b5
		if ($proper)
4c79b5
		{
4c79b5
			$col_types = sqlite_fetch_column_types($db->db_connect_id, $table_name);
4c79b5
		}
4c79b5
		else
4c79b5
		{
4c79b5
			$sql = "SELECT sql
4c79b5
				FROM sqlite_master
4c79b5
				WHERE type = 'table'
4c79b5
					AND name = '" . $table_name . "'";
4c79b5
			$table_data = sqlite_single_query($db->db_connect_id, $sql);
4c79b5
			$table_data = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', '', $table_data);
4c79b5
			$table_data = trim($table_data);
4c79b5
4c79b5
			preg_match('#\((.*)\)#s', $table_data, $matches);
4c79b5
4c79b5
			$table_cols = explode(',', trim($matches[1]));
4c79b5
			foreach ($table_cols as $declaration)
4c79b5
			{
4c79b5
				$entities = preg_split('#\s+#', trim($declaration));
4c79b5
				$column_name = preg_replace('/"?([^"]+)"?/', '\1', $entities[0]);
4c79b5
4c79b5
				// Hit a primary key, those are not what we need :D
4c79b5
				if (empty($entities[1]) || (strtolower($entities[0]) === 'primary' && strtolower($entities[1]) === 'key'))
4c79b5
				{
4c79b5
					continue;
4c79b5
				}
4c79b5
				$col_types[$column_name] = $entities[1];
4c79b5
			}
4c79b5
		}
4c79b5
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = sqlite_unbuffered_query($db->db_connect_id, $sql);
4c79b5
		$rows = sqlite_fetch_all($result, SQLITE_ASSOC);
4c79b5
		$sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
4c79b5
		foreach ($rows as $row)
4c79b5
		{
4c79b5
			foreach ($row as $column_name => $column_data)
4c79b5
			{
4c79b5
				if (is_null($column_data))
4c79b5
				{
4c79b5
					$row[$column_name] = 'NULL';
4c79b5
				}
4c79b5
				else if ($column_data == '')
4c79b5
				{
4c79b5
					$row[$column_name] = "''";
4c79b5
				}
4c79b5
				else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false)
4c79b5
				{
4c79b5
					$row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
4c79b5
				}
4c79b5
			}
4c79b5
			$this->flush($sql_insert . implode(', ', $row) . ");\n");
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_end()
4c79b5
	{
4c79b5
		$this->flush("COMMIT;\n");
4c79b5
		parent::write_end();
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class postgres_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_start($prefix)
4c79b5
	{
4c79b5
		$sql_data = "--\n";
4c79b5
		$sql_data .= "-- phpBB Backup Script\n";
4c79b5
		$sql_data .= "-- Dump of tables for $prefix\n";
4c79b5
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "--\n";
4c79b5
		$sql_data .= "BEGIN TRANSACTION;\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		static $domains_created = array();
4c79b5
4c79b5
		$sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
4c79b5
			FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
4c79b5
			WHERE a.domain_name = b.domain_name
4c79b5
				AND b.table_name = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			if (empty($domains_created[$row['domain_name']]))
4c79b5
			{
4c79b5
				$domains_created[$row['domain_name']] = true;
4c79b5
				//$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
4c79b5
				$sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
4c79b5
				if (!empty($row['character_maximum_length']))
4c79b5
				{
4c79b5
					$sql_data .= '(' . $row['character_maximum_length'] . ')';
4c79b5
				}
4c79b5
				$sql_data .= ' NOT NULL';
4c79b5
				if (!empty($row['domain_default']))
4c79b5
				{
4c79b5
					$sql_data .= ' DEFAULT ' . $row['domain_default'];
4c79b5
				}
4c79b5
				$this->flush($sql_data . ";\n");
4c79b5
			}
4c79b5
		}
4c79b5
4c79b5
		$sql_data = '-- Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE $table_name;\n";
4c79b5
		// PGSQL does not "tightly" bind sequences and tables, we must guess...
4c79b5
		$sql = "SELECT relname
4c79b5
			FROM pg_class
4c79b5
			WHERE relkind = 'S'
4c79b5
				AND relname = '{$table_name}_seq'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		// We don't even care about storing the results. We already know the answer if we get rows back.
4c79b5
		if ($db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
4c79b5
			$sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	
4c79b5
		$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
4c79b5
			FROM pg_class c, pg_attribute a, pg_type t
4c79b5
			WHERE c.relname = '" . $db->sql_escape($table_name) . "'
4c79b5
				AND a.attnum > 0
4c79b5
				AND a.attrelid = c.oid
4c79b5
				AND a.atttypid = t.oid
4c79b5
			ORDER BY a.attnum";
4c79b5
		$result = $db->sql_query($field_query);
4c79b5
4c79b5
		$sql_data .= "CREATE TABLE $table_name(\n";
4c79b5
		$lines = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			// Get the data from the table
4c79b5
			$sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
4c79b5
				FROM pg_attrdef d, pg_class c
4c79b5
				WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
4c79b5
					AND (c.oid = d.adrelid)
4c79b5
					AND d.adnum = " . $row['attnum'];
4c79b5
			$def_res = $db->sql_query($sql_get_default);
4c79b5
4c79b5
			if (!$def_res)
4c79b5
			{
4c79b5
				unset($row['rowdefault']);
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				$row['rowdefault'] = $db->sql_fetchfield('rowdefault', false, $def_res);
4c79b5
			}
4c79b5
			$db->sql_freeresult($def_res);
4c79b5
4c79b5
			if ($row['type'] == 'bpchar')
4c79b5
			{
4c79b5
				// Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
4c79b5
				$row['type'] = 'char';
4c79b5
			}
4c79b5
4c79b5
			$line = '  ' . $row['field'] . ' ' . $row['type'];
4c79b5
4c79b5
			if (strpos($row['type'], 'char') !== false)
4c79b5
			{
4c79b5
				if ($row['lengthvar'] > 0)
4c79b5
				{
4c79b5
					$line .= '(' . ($row['lengthvar'] - 4) . ')';
4c79b5
				}
4c79b5
			}
4c79b5
4c79b5
			if (strpos($row['type'], 'numeric') !== false)
4c79b5
			{
4c79b5
				$line .= '(';
4c79b5
				$line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
4c79b5
				$line .= ')';
4c79b5
			}
4c79b5
4c79b5
			if (isset($row['rowdefault']))
4c79b5
			{
4c79b5
				$line .= ' DEFAULT ' . $row['rowdefault'];
4c79b5
			}
4c79b5
4c79b5
			if ($row['notnull'] == 't')
4c79b5
			{
4c79b5
				$line .= ' NOT NULL';
4c79b5
			}
4c79b5
			
4c79b5
			$lines[] = $line;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
4c79b5
		// Get the listing of primary keys.
4c79b5
		$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
4c79b5
			FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
4c79b5
			WHERE (bc.oid = i.indrelid)
4c79b5
				AND (ic.oid = i.indexrelid)
4c79b5
				AND (ia.attrelid = i.indexrelid)
4c79b5
				AND	(ta.attrelid = bc.oid)
4c79b5
				AND (bc.relname = '" . $db->sql_escape($table_name) . "')
4c79b5
				AND (ta.attrelid = i.indrelid)
4c79b5
				AND (ta.attnum = i.indkey[ia.attnum-1])
4c79b5
			ORDER BY index_name, tab_name, column_name";
4c79b5
4c79b5
		$result = $db->sql_query($sql_pri_keys);
4c79b5
4c79b5
		$index_create = $index_rows = $primary_key = array();
4c79b5
4c79b5
		// We do this in two steps. It makes placing the comma easier
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			if ($row['primary_key'] == 't')
4c79b5
			{
4c79b5
				$primary_key[] = $row['column_name'];
4c79b5
				$primary_key_name = $row['index_name'];
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				// We have to store this all this info because it is possible to have a multi-column key...
4c79b5
				// we can loop through it again and build the statement
4c79b5
				$index_rows[$row['index_name']]['table'] = $table_name;
4c79b5
				$index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false;
4c79b5
				$index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
4c79b5
			}
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		if (!empty($index_rows))
4c79b5
		{
4c79b5
			foreach ($index_rows as $idx_name => $props)
4c79b5
			{
4c79b5
				$index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
4c79b5
			}
4c79b5
		}
4c79b5
4c79b5
		if (!empty($primary_key))
4c79b5
		{
4c79b5
			$lines[] = "  CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
4c79b5
		}
4c79b5
4c79b5
		// Generate constraint clauses for CHECK constraints
4c79b5
		$sql_checks = "SELECT conname as index_name, consrc
4c79b5
			FROM pg_constraint, pg_class bc
4c79b5
			WHERE conrelid = bc.oid
4c79b5
				AND bc.relname = '" . $db->sql_escape($table_name) . "'
4c79b5
				AND NOT EXISTS (
4c79b5
					SELECT *
4c79b5
						FROM pg_constraint as c, pg_inherits as i
4c79b5
						WHERE i.inhrelid = pg_constraint.conrelid
4c79b5
							AND c.conname = pg_constraint.conname
4c79b5
							AND c.consrc = pg_constraint.consrc
4c79b5
							AND c.conrelid = i.inhparent
4c79b5
				)";
4c79b5
		$result = $db->sql_query($sql_checks);
4c79b5
4c79b5
		// Add the constraints to the sql file.
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			if (!is_null($row['consrc']))
4c79b5
			{
4c79b5
				$lines[] = '  CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
4c79b5
			}
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql_data .= implode(", \n", $lines);
4c79b5
		$sql_data .= "\n);\n";
4c79b5
4c79b5
		if (!empty($index_create))
4c79b5
		{
4c79b5
			$sql_data .= implode("\n", $index_create) . "\n\n";
4c79b5
		}
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		// Grab all of the data from current table.
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$i_num_fields = pg_num_fields($result);
4c79b5
		$seq = '';
4c79b5
4c79b5
		for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
		{
4c79b5
			$ary_type[] = pg_field_type($result, $i);
4c79b5
			$ary_name[] = pg_field_name($result, $i);
4c79b5
4c79b5
4c79b5
			$sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
4c79b5
				FROM pg_attrdef d, pg_class c
4c79b5
				WHERE (c.relname = '{$table_name}')
4c79b5
					AND (c.oid = d.adrelid)
4c79b5
					AND d.adnum = " . strval($i + 1);
4c79b5
			$result2 = $db->sql_query($sql);
4c79b5
			if ($row = $db->sql_fetchrow($result2))
4c79b5
			{
4c79b5
				// Determine if we must reset the sequences
4c79b5
				if (strpos($row['rowdefault'], "nextval('") === 0)
4c79b5
				{
4c79b5
					$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";
4c79b5
				}
4c79b5
			}
4c79b5
		}
4c79b5
4c79b5
		$this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$schema_vals = array();
4c79b5
4c79b5
			// Build the SQL statement to recreate the data.
4c79b5
			for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
			{
4c79b5
				$str_val = $row[$ary_name[$i]];
4c79b5
4c79b5
				if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					$str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
4c79b5
					$str_empty = '';
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$str_empty = '\N';
4c79b5
				}
4c79b5
4c79b5
				if (empty($str_val) && $str_val !== '0')
4c79b5
				{
4c79b5
					$str_val = $str_empty;
4c79b5
				}
4c79b5
4c79b5
				$schema_vals[] = $str_val;
4c79b5
			}
4c79b5
4c79b5
			// Take the ordered fields and their associated data and build it
4c79b5
			// into a valid sql statement to recreate that field in the data.
4c79b5
			$this->flush(implode("\t", $schema_vals) . "\n");
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
		$this->flush("\\.\n");
4c79b5
4c79b5
		// Write out the sequence statements
4c79b5
		$this->flush($seq);
4c79b5
	}
4c79b5
4c79b5
	function write_end()
4c79b5
	{
4c79b5
		$this->flush("COMMIT;\n");
4c79b5
		parent::write_end();
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class mssql_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_end()
4c79b5
	{
4c79b5
		$this->flush("COMMIT\nGO\n");
4c79b5
		parent::write_end();
4c79b5
	}
4c79b5
4c79b5
	function write_start($prefix)
4c79b5
	{
4c79b5
		$sql_data = "--\n";
4c79b5
		$sql_data .= "-- phpBB Backup Script\n";
4c79b5
		$sql_data .= "-- Dump of tables for $prefix\n";
4c79b5
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "--\n";
4c79b5
		$sql_data .= "BEGIN TRANSACTION\n";
4c79b5
		$sql_data .= "GO\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$sql_data = '-- Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
4c79b5
		$sql_data .= "DROP TABLE $table_name;\n";
4c79b5
		$sql_data .= "GO\n";
4c79b5
		$sql_data .= "\nCREATE TABLE [$table_name] (\n";
4c79b5
		$rows = array();
4c79b5
	
4c79b5
		$text_flag = false;
4c79b5
	
4c79b5
		$sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
4c79b5
			FROM INFORMATION_SCHEMA.COLUMNS
4c79b5
			WHERE TABLE_NAME = '$table_name'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
	
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
4c79b5
	
4c79b5
			if ($row['DATA_TYPE'] == 'text')
4c79b5
			{
4c79b5
				$text_flag = true;
4c79b5
			}
4c79b5
	
4c79b5
			if ($row['IS_IDENTITY'])
4c79b5
			{
4c79b5
				$line .= ' IDENTITY (1 , 1)';
4c79b5
			}
4c79b5
	
4c79b5
			if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
4c79b5
			{
4c79b5
				$line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
4c79b5
			}
4c79b5
	
4c79b5
			if ($row['IS_NULLABLE'] == 'YES')
4c79b5
			{
4c79b5
				$line .= ' NULL';
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				$line .= ' NOT NULL';
4c79b5
			}
4c79b5
	
4c79b5
			if ($row['COLUMN_DEFAULT'])
4c79b5
			{
4c79b5
				$line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
4c79b5
			}
4c79b5
	
4c79b5
			$rows[] = $line;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	
4c79b5
		$sql_data .= implode(",\n", $rows);
4c79b5
		$sql_data .= "\n) ON [PRIMARY]";
4c79b5
	
4c79b5
		if ($text_flag)
4c79b5
		{
4c79b5
			$sql_data .= " TEXTIMAGE_ON [PRIMARY]";
4c79b5
		}
4c79b5
	
4c79b5
		$sql_data .= "\nGO\n\n";
4c79b5
		$rows = array();
4c79b5
	
4c79b5
		$sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
4c79b5
			FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
4c79b5
			WHERE TABLE_NAME = '$table_name'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			if (!sizeof($rows))
4c79b5
			{
4c79b5
				$sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
4c79b5
				$sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY  CLUSTERED \n\t(\n";
4c79b5
			}
4c79b5
			$rows[] = "\t\t[{$row['COLUMN_NAME']}]";
4c79b5
		}
4c79b5
		if (sizeof($rows))
4c79b5
		{
4c79b5
			$sql_data .= implode(",\n", $rows);
4c79b5
			$sql_data .= "\n\t)  ON [PRIMARY] \nGO\n";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	
4c79b5
		$index = array();
4c79b5
		$sql = "EXEC sp_statistics '$table_name'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			if ($row['TYPE'] == 3)
4c79b5
			{
4c79b5
				$index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
4c79b5
			}
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	
4c79b5
		foreach ($index as $index_name => $column_name)
4c79b5
		{
4c79b5
			$index[$index_name] = implode(', ', $column_name);
4c79b5
		}
4c79b5
	
4c79b5
		foreach ($index as $index_name => $columns)
4c79b5
		{
4c79b5
			$sql_data .= "\nCREATE  INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
4c79b5
		}
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
4c79b5
		if ($db->sql_layer === 'mssql')
4c79b5
		{
4c79b5
			$this->write_data_mssql($table_name);
4c79b5
		}
4c79b5
		else
4c79b5
		{
4c79b5
			$this->write_data_odbc($table_name);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	function write_data_mssql($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$ary_type = $ary_name = array();
4c79b5
		$ident_set = false;
4c79b5
		$sql_data = '';
4c79b5
		
4c79b5
		// Grab all of the data from current table.
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$retrieved_data = mssql_num_rows($result);
4c79b5
4c79b5
		$i_num_fields = mssql_num_fields($result);
4c79b5
4c79b5
		for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
		{
4c79b5
			$ary_type[$i] = mssql_field_type($result, $i);
4c79b5
			$ary_name[$i] = mssql_field_name($result, $i);
4c79b5
		}
4c79b5
4c79b5
		if ($retrieved_data)
4c79b5
		{
4c79b5
			$sql = "SELECT 1 as has_identity
4c79b5
				FROM INFORMATION_SCHEMA.COLUMNS
4c79b5
				WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
4c79b5
			$result2 = $db->sql_query($sql);
4c79b5
			$row2 = $db->sql_fetchrow($result2);
4c79b5
			if (!empty($row2['has_identity']))
4c79b5
			{
4c79b5
				$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
4c79b5
				$ident_set = true;
4c79b5
			}
4c79b5
			$db->sql_freeresult($result2);
4c79b5
		}
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$schema_vals = $schema_fields = array();
4c79b5
4c79b5
			// Build the SQL statement to recreate the data.
4c79b5
			for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
			{
4c79b5
				$str_val = $row[$ary_name[$i]];
4c79b5
4c79b5
				if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = "''";
4c79b5
					$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
4c79b5
				}
4c79b5
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					if (empty($str_val))
4c79b5
					{
4c79b5
						$str_quote = '';
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$str_quote = "'";
4c79b5
					}
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = 'NULL';
4c79b5
				}
4c79b5
4c79b5
				if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
4c79b5
				{
4c79b5
					$str_val = $str_empty;
4c79b5
				}
4c79b5
4c79b5
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
4c79b5
				$schema_fields[$i] = $ary_name[$i];
4c79b5
			}
4c79b5
4c79b5
			// Take the ordered fields and their associated data and build it
4c79b5
			// into a valid sql statement to recreate that field in the data.
4c79b5
			$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
4c79b5
4c79b5
			$this->flush($sql_data);
4c79b5
			$sql_data = '';
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		if ($retrieved_data && $ident_set)
4c79b5
		{
4c79b5
			$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
4c79b5
		}
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_data_odbc($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$ary_type = $ary_name = array();
4c79b5
		$ident_set = false;
4c79b5
		$sql_data = '';
4c79b5
		
4c79b5
		// Grab all of the data from current table.
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$retrieved_data = odbc_num_rows($result);
4c79b5
4c79b5
		if ($retrieved_data)
4c79b5
		{
4c79b5
			$sql = "SELECT 1 as has_identity
4c79b5
				FROM INFORMATION_SCHEMA.COLUMNS
4c79b5
				WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
4c79b5
			$result2 = $db->sql_query($sql);
4c79b5
			$row2 = $db->sql_fetchrow($result2);
4c79b5
			if (!empty($row2['has_identity']))
4c79b5
			{
4c79b5
				$sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
4c79b5
				$ident_set = true;
4c79b5
			}
4c79b5
			$db->sql_freeresult($result2);
4c79b5
		}
4c79b5
4c79b5
		$i_num_fields = odbc_num_fields($result);
4c79b5
4c79b5
		for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
		{
4c79b5
			$ary_type[$i] = odbc_field_type($result, $i + 1);
4c79b5
			$ary_name[$i] = odbc_field_name($result, $i + 1);
4c79b5
		}
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$schema_vals = $schema_fields = array();
4c79b5
4c79b5
			// Build the SQL statement to recreate the data.
4c79b5
			for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
			{
4c79b5
				$str_val = $row[$ary_name[$i]];
4c79b5
4c79b5
				if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = "''";
4c79b5
					$str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
4c79b5
				}
4c79b5
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					if (empty($str_val))
4c79b5
					{
4c79b5
						$str_quote = '';
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$str_quote = "'";
4c79b5
					}
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = 'NULL';
4c79b5
				}
4c79b5
4c79b5
				if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
4c79b5
				{
4c79b5
					$str_val = $str_empty;
4c79b5
				}
4c79b5
4c79b5
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
4c79b5
				$schema_fields[$i] = $ary_name[$i];
4c79b5
			}
4c79b5
4c79b5
			// Take the ordered fields and their associated data and build it
4c79b5
			// into a valid sql statement to recreate that field in the data.
4c79b5
			$sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
4c79b5
4c79b5
			$this->flush($sql_data);
4c79b5
4c79b5
			$sql_data = '';
4c79b5
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		if ($retrieved_data && $ident_set)
4c79b5
		{
4c79b5
			$sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
4c79b5
		}
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class oracle_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$sql_data = '-- Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE $table_name;\n";
4c79b5
		$sql_data .= '\\' . "\n";
4c79b5
		$sql_data .= "\nCREATE TABLE $table_name (\n";
4c79b5
4c79b5
		$sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
4c79b5
			FROM ALL_TAB_COLS
4c79b5
			WHERE table_name = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$rows = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$line = '  "' . $row['column_name'] . '" ' . $row['data_type'];
4c79b5
4c79b5
			if ($row['data_type'] !== 'CLOB')
4c79b5
			{
4c79b5
				if ($row['data_type'] !== 'VARCHAR2')
4c79b5
				{
4c79b5
					$line .= '(' . $row['data_precision'] . ')';
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$line .= '(' . $row['data_length'] . ')';
4c79b5
				}
4c79b5
			}
4c79b5
4c79b5
			if (!empty($row['data_default']))
4c79b5
			{
4c79b5
				$line .= ' DEFAULT ' . $row['data_default'];
4c79b5
			}
4c79b5
4c79b5
			if ($row['nullable'] == 'N')
4c79b5
			{
4c79b5
				$line .= ' NOT NULL';
4c79b5
			}
4c79b5
			$rows[] = $line;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
4c79b5
			FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
4c79b5
			WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
4c79b5
				AND B.CONSTRAINT_TYPE = 'P'
4c79b5
				AND A.TABLE_NAME = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$rows[] = "  CONSTRAINT {$row['constraint_name']} PRIMARY KEY ({$row['column_name']})";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
4c79b5
			FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
4c79b5
			WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
4c79b5
				AND B.CONSTRAINT_TYPE = 'U'
4c79b5
				AND A.TABLE_NAME = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$rows[] = "  CONSTRAINT {$row['constraint_name']} UNIQUE ({$row['column_name']})";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql_data .= implode(",\n", $rows);
4c79b5
		$sql_data .= "\n)\n\\";
4c79b5
4c79b5
		$sql = "SELECT A.REFERENCED_NAME
4c79b5
			FROM USER_DEPENDENCIES A, USER_TRIGGERS B
4c79b5
			WHERE A.REFERENCED_TYPE = 'SEQUENCE'
4c79b5
				AND A.NAME = B.TRIGGER_NAME
4c79b5
				AND B. TABLE_NAME = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$sql_data .= "\nCREATE SEQUENCE {$row['referenced_name']}\\\n";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
4c79b5
			FROM USER_TRIGGERS
4c79b5
			WHERE TABLE_NAME = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\\";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
4c79b5
			FROM USER_INDEXES A, USER_IND_COLUMNS B
4c79b5
			WHERE A.UNIQUENESS = 'NONUNIQUE'
4c79b5
				AND A.INDEX_NAME = B.INDEX_NAME
4c79b5
				AND B.TABLE_NAME = '{$table_name}'";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$index = array();
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$index[$row['index_name']][] = $row['column_name'];
4c79b5
		}
4c79b5
4c79b5
		foreach ($index as $index_name => $column_names)
4c79b5
		{
4c79b5
			$sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n\\";
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$ary_type = $ary_name = array();
4c79b5
		
4c79b5
		// Grab all of the data from current table.
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$i_num_fields = ocinumcols($result);
4c79b5
4c79b5
		for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
		{
4c79b5
			$ary_type[$i] = ocicolumntype($result, $i + 1);
4c79b5
			$ary_name[$i] = ocicolumnname($result, $i + 1);
4c79b5
		}
4c79b5
4c79b5
		$sql_data = '';
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$schema_vals = $schema_fields = array();
4c79b5
4c79b5
			// Build the SQL statement to recreate the data.
4c79b5
			for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
			{
4c79b5
				$str_val = $row[$ary_name[$i]];
4c79b5
4c79b5
				if (preg_match('#char|text|bool|raw#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = "''";
4c79b5
					$str_val = sanitize_data_oracle($str_val);
4c79b5
				}
4c79b5
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					if (empty($str_val))
4c79b5
					{
4c79b5
						$str_quote = '';
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$str_quote = "'";
4c79b5
					}
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = 'NULL';
4c79b5
				}
4c79b5
4c79b5
				if (empty($str_val) && $str_val !== '0')
4c79b5
				{
4c79b5
					$str_val = $str_empty;
4c79b5
				}
4c79b5
4c79b5
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
4c79b5
				$schema_fields[$i] = '"' . $ary_name[$i] . "'";
4c79b5
			}
4c79b5
4c79b5
			// Take the ordered fields and their associated data and build it
4c79b5
			// into a valid sql statement to recreate that field in the data.
4c79b5
			$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
4c79b5
4c79b5
			$this->flush($sql_data);
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	}
4c79b5
4c79b5
	function write_start($prefix)
4c79b5
	{
4c79b5
		$sql_data = "--\n";
4c79b5
		$sql_data .= "-- phpBB Backup Script\n";
4c79b5
		$sql_data .= "-- Dump of tables for $prefix\n";
4c79b5
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "--\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
/**
4c79b5
* @package acp
4c79b5
*/
4c79b5
class firebird_extractor extends base_extractor
4c79b5
{
4c79b5
	function write_start($prefix)
4c79b5
	{
4c79b5
		$sql_data = "--\n";
4c79b5
		$sql_data .= "-- phpBB Backup Script\n";
4c79b5
		$sql_data .= "-- Dump of tables for $prefix\n";
4c79b5
		$sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
4c79b5
		$sql_data .= "--\n";
4c79b5
		$this->flush($sql_data);
4c79b5
	}
4c79b5
4c79b5
	function write_data($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
		$ary_type = $ary_name = array();
4c79b5
		
4c79b5
		// Grab all of the data from current table.
4c79b5
		$sql = "SELECT *
4c79b5
			FROM $table_name";
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$i_num_fields = ibase_num_fields($result);
4c79b5
4c79b5
		for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
		{
4c79b5
			$info = ibase_field_info($result, $i);
4c79b5
			$ary_type[$i] = $info['type'];
4c79b5
			$ary_name[$i] = $info['name'];
4c79b5
		}
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$schema_vals = $schema_fields = array();
4c79b5
4c79b5
			// Build the SQL statement to recreate the data.
4c79b5
			for ($i = 0; $i < $i_num_fields; $i++)
4c79b5
			{
4c79b5
				$str_val = $row[strtolower($ary_name[$i])];
4c79b5
4c79b5
				if (preg_match('#char|text|bool|varbinary|blob#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = "''";
4c79b5
					$str_val = sanitize_data_generic(str_replace("'", "''", $str_val));
4c79b5
				}
4c79b5
				else if (preg_match('#date|timestamp#i', $ary_type[$i]))
4c79b5
				{
4c79b5
					if (empty($str_val))
4c79b5
					{
4c79b5
						$str_quote = '';
4c79b5
					}
4c79b5
					else
4c79b5
					{
4c79b5
						$str_quote = "'";
4c79b5
					}
4c79b5
				}
4c79b5
				else
4c79b5
				{
4c79b5
					$str_quote = '';
4c79b5
					$str_empty = 'NULL';
4c79b5
				}
4c79b5
4c79b5
				if (empty($str_val) && $str_val !== '0')
4c79b5
				{
4c79b5
					$str_val = $str_empty;
4c79b5
				}
4c79b5
4c79b5
				$schema_vals[$i] = $str_quote . $str_val . $str_quote;
4c79b5
				$schema_fields[$i] = '"' . $ary_name[$i] . '"';
4c79b5
			}
4c79b5
4c79b5
			// Take the ordered fields and their associated data and build it
4c79b5
			// into a valid sql statement to recreate that field in the data.
4c79b5
			$sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\n";
4c79b5
4c79b5
			$this->flush($sql_data);
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
	}
4c79b5
4c79b5
	function write_table($table_name)
4c79b5
	{
4c79b5
		global $db;
4c79b5
4c79b5
		$sql_data = '-- Table: ' . $table_name . "\n";
4c79b5
		$sql_data .= "DROP TABLE $table_name;\n";
4c79b5
4c79b5
		$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');
4c79b5
4c79b5
		$sql_data .= "\nCREATE TABLE $table_name (\n";
4c79b5
4c79b5
		$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
4c79b5
			FROM RDB$RELATION_FIELDS R
4c79b5
			JOIN RDB$FIELDS F ON R.RDB$FIELD_SOURCE=F.RDB$FIELD_NAME
4c79b5
			LEFT JOIN RDB$FIELD_DIMENSIONS D ON R.RDB$FIELD_SOURCE = D.RDB$FIELD_NAME
4c79b5
			WHERE F.RDB$SYSTEM_FLAG = 0
4c79b5
				AND R.RDB$RELATION_NAME = \''. $table_name . '\'
4c79b5
			ORDER BY R.RDB$FIELD_POSITION';
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$rows = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$line = "\t" . '"' . $row['fname'] . '" ' . $data_types[$row['ftype']];
4c79b5
4c79b5
			if ($row['ftype'] == 261 && $row['stype'] == 1)
4c79b5
			{
4c79b5
				$line .= ' SUB_TYPE TEXT';
4c79b5
			}
4c79b5
4c79b5
			if ($row['ftype'] == 37 || $row['ftype'] == 14)
4c79b5
			{
4c79b5
				$line .= ' (' . $row['flen'] . ')';
4c79b5
			}
4c79b5
4c79b5
			if (!empty($row['dsource']))
4c79b5
			{
4c79b5
				$line .= ' ' . $row['dsource'];
4c79b5
			}
4c79b5
4c79b5
			if (!empty($row['nflag']))
4c79b5
			{
4c79b5
				$line .= ' NOT NULL';
4c79b5
			}
4c79b5
			$rows[] = $line;
4c79b5
		}
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql_data .= implode(",\n", $rows);
4c79b5
		$sql_data .= "\n);\n";
4c79b5
		$keys = array();
4c79b5
4c79b5
		$sql = 'SELECT I.RDB$FIELD_NAME as NAME
4c79b5
			FROM RDB$RELATION_CONSTRAINTS RC, RDB$INDEX_SEGMENTS I, RDB$INDICES IDX
4c79b5
			WHERE (I.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
4c79b5
				AND (IDX.RDB$INDEX_NAME = RC.RDB$INDEX_NAME)
4c79b5
				AND (RC.RDB$RELATION_NAME = \''. $table_name . '\')
4c79b5
			ORDER BY I.RDB$FIELD_POSITION';
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$keys[] = $row['name'];
4c79b5
		}
4c79b5
4c79b5
		if (sizeof($keys))
4c79b5
		{
4c79b5
			$sql_data .= "\nALTER TABLE $table_name ADD PRIMARY KEY (" . implode(', ', $keys) . ');';
4c79b5
		}
4c79b5
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = 'SELECT I.RDB$INDEX_NAME as INAME, I.RDB$UNIQUE_FLAG as UFLAG, S.RDB$FIELD_NAME as FNAME
4c79b5
			FROM RDB$INDICES I JOIN RDB$INDEX_SEGMENTS S ON S.RDB$INDEX_NAME=I.RDB$INDEX_NAME
4c79b5
			WHERE (I.RDB$SYSTEM_FLAG IS NULL  OR  I.RDB$SYSTEM_FLAG=0)
4c79b5
				AND I.RDB$FOREIGN_KEY IS NULL
4c79b5
				AND I.RDB$RELATION_NAME = \''. $table_name . '\'
4c79b5
				AND I.RDB$INDEX_NAME NOT STARTING WITH \'RDB$\'
4c79b5
			ORDER BY S.RDB$FIELD_POSITION';
4c79b5
		$result = $db->sql_query($sql);
4c79b5
4c79b5
		$index = array();
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$index[$row['iname']]['unique'] = !empty($row['uflag']);
4c79b5
			$index[$row['iname']]['values'][] = $row['fname'];
4c79b5
		}
4c79b5
4c79b5
		foreach ($index as $index_name => $data)
4c79b5
		{
4c79b5
			$sql_data .= "\nCREATE ";
4c79b5
			if ($data['unique'])
4c79b5
			{
4c79b5
				$sql_data .= 'UNIQUE ';
4c79b5
			}
4c79b5
			$sql_data .= "INDEX $index_name ON $table_name(" . implode(', ', $data['values']) . ");";
4c79b5
		}
4c79b5
		$sql_data .= "\n";
4c79b5
4c79b5
		$db->sql_freeresult($result);
4c79b5
4c79b5
		$sql = 'SELECT D1.RDB$DEPENDENT_NAME as DNAME, D1.RDB$FIELD_NAME as FNAME, D1.RDB$DEPENDENT_TYPE, R1.RDB$RELATION_NAME
4c79b5
			FROM RDB$DEPENDENCIES D1
4c79b5
			LEFT JOIN RDB$RELATIONS R1 ON ((D1.RDB$DEPENDENT_NAME = R1.RDB$RELATION_NAME) AND (NOT (R1.RDB$VIEW_BLR IS NULL)))
4c79b5
			WHERE (D1.RDB$DEPENDED_ON_TYPE = 0)
4c79b5
				AND (D1.RDB$DEPENDENT_TYPE <> 3)
4c79b5
				AND (D1.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
4c79b5
			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
4c79b5
			LEFT JOIN RDB$RELATIONS R2 ON ((F2.RDB$RELATION_NAME = R2.RDB$RELATION_NAME) AND (NOT (R2.RDB$VIEW_BLR IS NULL)))
4c79b5
			WHERE (D2.RDB$DEPENDENT_TYPE = 3)
4c79b5
				AND (D2.RDB$DEPENDENT_NAME = F2.RDB$FIELD_SOURCE)
4c79b5
				AND (D2.RDB$DEPENDED_ON_NAME = \'' . $table_name . '\')
4c79b5
			ORDER BY 1, 2';
4c79b5
		$result = $db->sql_query($sql);
4c79b5
		while ($row = $db->sql_fetchrow($result))
4c79b5
		{
4c79b5
			$sql = 'SELECT T1.RDB$DEPENDED_ON_NAME as GEN, T1.RDB$FIELD_NAME, T1.RDB$DEPENDED_ON_TYPE
4c79b5
				FROM RDB$DEPENDENCIES T1
4c79b5
				WHERE (T1.RDB$DEPENDENT_NAME = \'' . $row['dname'] . '\')
4c79b5
					AND (T1.RDB$DEPENDENT_TYPE = 2 AND T1.RDB$DEPENDED_ON_TYPE = 14)
4c79b5
				UNION ALL SELECT DISTINCT D.RDB$DEPENDED_ON_NAME, D.RDB$FIELD_NAME, D.RDB$DEPENDED_ON_TYPE
4c79b5
				FROM RDB$DEPENDENCIES D, RDB$RELATION_FIELDS F
4c79b5
				WHERE (D.RDB$DEPENDENT_TYPE = 3)
4c79b5
					AND (D.RDB$DEPENDENT_NAME = F.RDB$FIELD_SOURCE)
4c79b5
					AND (F.RDB$RELATION_NAME = \'' . $row['dname'] . '\')
4c79b5
				ORDER BY 1,2';
4c79b5
			$result2 = $db->sql_query($sql);
4c79b5
			$row2 = $db->sql_fetchrow($result2);
4c79b5
			$db->sql_freeresult($result2);
4c79b5
			$gen_name = $row2['gen'];
4c79b5
4c79b5
			$sql_data .= "\nDROP GENERATOR " . $gen_name . ";";
4c79b5
			$sql_data .= "\nSET TERM ^ ;";
4c79b5
			$sql_data .= "\nCREATE GENERATOR " . $gen_name . "^";
4c79b5
			$sql_data .= "\nSET GENERATOR  " . $gen_name . " TO 0^\n";
4c79b5
			$sql_data .= "\nCREATE TRIGGER {$row['dname']} FOR $table_name";
4c79b5
			$sql_data .= "\nBEFORE INSERT\nAS\nBEGIN";
4c79b5
			$sql_data .= "\n  NEW.{$row['fname']} = GEN_ID(" . $gen_name . ", 1);";
4c79b5
			$sql_data .= "\nEND^\n";
4c79b5
			$sql_data .= "\nSET TERM ; ^\n";
4c79b5
		}
4c79b5
4c79b5
		$this->flush($sql_data);
4c79b5
4c79b5
		$db->sql_freeresult($result);
4c79b5
	}
4c79b5
}
4c79b5
4c79b5
// 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)
4c79b5
function get_usable_memory()
4c79b5
{
4c79b5
	$val = trim(@ini_get('memory_limit'));
4c79b5
4c79b5
	if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
4c79b5
	{
4c79b5
		$memory_limit = (int) $regs[1];
4c79b5
		switch ($regs[2])
4c79b5
		{
4c79b5
4c79b5
			case 'k':
4c79b5
			case 'K':
4c79b5
				$memory_limit *= 1024;
4c79b5
			break;
4c79b5
4c79b5
			case 'm':
4c79b5
			case 'M':
4c79b5
				$memory_limit *= 1048576;
4c79b5
			break;
4c79b5
4c79b5
			case 'g':
4c79b5
			case 'G':
4c79b5
				$memory_limit *= 1073741824;
4c79b5
			break;
4c79b5
		}
4c79b5
4c79b5
		// how much memory PHP requires at the start of export (it is really a little less)
4c79b5
		if ($memory_limit > 6100000)
4c79b5
		{
4c79b5
			$memory_limit -= 6100000;
4c79b5
		}
4c79b5
4c79b5
		// allow us to consume half of the total memory available
4c79b5
		$memory_limit /= 2;
4c79b5
	}
4c79b5
	else
4c79b5
	{
4c79b5
		// set the buffer to 1M if we have no clue how much memory PHP will give us :P
4c79b5
		$memory_limit = 1048576;
4c79b5
	}
4c79b5
4c79b5
	return $memory_limit;
4c79b5
}
4c79b5
4c79b5
function sanitize_data_mssql($text)
4c79b5
{
4c79b5
	$data = preg_split('/[\n\t\r\b\f]/', $text);
4c79b5
	preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
4c79b5
4c79b5
	$val = array();
4c79b5
4c79b5
	foreach ($data as $value)
4c79b5
	{
4c79b5
		if (strlen($value))
4c79b5
		{
4c79b5
			$val[] = "'" . $value . "'";
4c79b5
		}
4c79b5
		if (sizeof($matches[0]))
4c79b5
		{
4c79b5
			$val[] = 'char(' . ord(array_shift($matches[0])) . ')';
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	return implode('+', $val);
4c79b5
}
4c79b5
4c79b5
function sanitize_data_oracle($text)
4c79b5
{
4c79b5
	$data = preg_split('/[\0\n\t\r\b\f\'"\\\]/', $text);
4c79b5
	preg_match_all('/[\0\n\t\r\b\f\'"\\\]/', $text, $matches);
4c79b5
4c79b5
	$val = array();
4c79b5
4c79b5
	foreach ($data as $value)
4c79b5
	{
4c79b5
		if (strlen($value))
4c79b5
		{
4c79b5
			$val[] = "'" . $value . "'";
4c79b5
		}
4c79b5
		if (sizeof($matches[0]))
4c79b5
		{
4c79b5
			$val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	return implode('||', $val);
4c79b5
}
4c79b5
4c79b5
function sanitize_data_generic($text)
4c79b5
{
4c79b5
	$data = preg_split('/[\n\t\r\b\f]/', $text);
4c79b5
	preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
4c79b5
4c79b5
	$val = array();
4c79b5
4c79b5
	foreach ($data as $value)
4c79b5
	{
4c79b5
		if (strlen($value))
4c79b5
		{
4c79b5
			$val[] = "'" . $value . "'";
4c79b5
		}
4c79b5
		if (sizeof($matches[0]))
4c79b5
		{
4c79b5
			$val[] = "'" . array_shift($matches[0]) . "'";
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	return implode('||', $val);
4c79b5
}
4c79b5
4c79b5
// modified from PHP.net
4c79b5
function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
4c79b5
{
4c79b5
	$record = '';
4c79b5
	$delim_len = strlen($delim);
4c79b5
	
4c79b5
	while (!$eof($fp))
4c79b5
	{
4c79b5
		$pos = strpos($record, $delim);
4c79b5
		if ($pos === false)
4c79b5
		{
4c79b5
			$record .= $read($fp, $buffer);
4c79b5
			if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
4c79b5
			{
4c79b5
				$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
4c79b5
				return substr($record, 0, $pos);
4c79b5
			}
4c79b5
		}
4c79b5
		else
4c79b5
		{
4c79b5
			$seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
4c79b5
			return substr($record, 0, $pos);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	return false;
4c79b5
}
4c79b5
4c79b5
function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
4c79b5
{
4c79b5
	static $array = array();
4c79b5
	static $record = '';
4c79b5
4c79b5
	if (!sizeof($array))
4c79b5
	{
4c79b5
		while (!$eof($fp))
4c79b5
		{
4c79b5
			if (strpos($record, $delim) !== false)
4c79b5
			{
4c79b5
				$array = explode($delim, $record);
4c79b5
				$record = array_pop($array);
4c79b5
				break;
4c79b5
			}
4c79b5
			else
4c79b5
			{
4c79b5
				$record .= $read($fp, $buffer);
4c79b5
			}
4c79b5
		}
4c79b5
		if ($eof($fp) && strpos($record, $delim) !== false)
4c79b5
		{
4c79b5
			$array = explode($delim, $record);
4c79b5
			$record = array_pop($array);
4c79b5
		}
4c79b5
	}
4c79b5
4c79b5
	if (sizeof($array))
4c79b5
	{
4c79b5
		return array_shift($array);
4c79b5
	}
4c79b5
4c79b5
	return false;
4c79b5
}
4c79b5
4c79b5
?>