Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

acp_database.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 53.24 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * This file is part of the phpBB Forum Software package.
 0005  *
 0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 0007  * @license GNU General Public License, version 2 (GPL-2.0)
 0008  *
 0009  * For full copyright and license information, please see
 0010  * the docs/CREDITS.txt file.
 0011  *
 0012  */
 0013   
 0014  /**
 0015  * @ignore
 0016  */
 0017  if (!defined('IN_PHPBB'))
 0018  {
 0019      exit;
 0020  }
 0021   
 0022  class acp_database
 0023  {
 0024      var $db_tools;
 0025      var $u_action;
 0026   
 0027      function main($id, $mode)
 0028      {
 0029          global $cache, $db, $user, $auth, $template, $table_prefix;
 0030          global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx;
 0031   
 0032          $this->db_tools = new \phpbb\db\tools($db);
 0033   
 0034          $user->add_lang('acp/database');
 0035   
 0036          $this->tpl_name = 'acp_database';
 0037          $this->page_title = 'ACP_DATABASE';
 0038   
 0039          $action    = request_var('action', '');
 0040          $submit = (isset($_POST['submit'])) ? true : false;
 0041   
 0042          $template->assign_vars(array(
 0043              'MODE'    => $mode
 0044          ));
 0045   
 0046          switch ($mode)
 0047          {
 0048              case 'backup':
 0049   
 0050                  $this->page_title = 'ACP_BACKUP';
 0051   
 0052                  switch ($action)
 0053                  {
 0054                      case 'download':
 0055                          $type    = request_var('type', '');
 0056                          $table    = array_intersect($this->db_tools->sql_list_tables(), request_var('table', array('')));
 0057                          $format    = request_var('method', '');
 0058                          $where    = request_var('where', '');
 0059   
 0060                          if (!sizeof($table))
 0061                          {
 0062                              trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
 0063                          }
 0064   
 0065                          $store = $download = $structure = $schema_data = false;
 0066   
 0067                          if ($where == 'store_and_download' || $where == 'store')
 0068                          {
 0069                              $store = true;
 0070                          }
 0071   
 0072                          if ($where == 'store_and_download' || $where == 'download')
 0073                          {
 0074                              $download = true;
 0075                          }
 0076   
 0077                          if ($type == 'full' || $type == 'structure')
 0078                          {
 0079                              $structure = true;
 0080                          }
 0081   
 0082                          if ($type == 'full' || $type == 'data')
 0083                          {
 0084                              $schema_data = true;
 0085                          }
 0086   
 0087                          @set_time_limit(1200);
 0088                          @set_time_limit(0);
 0089   
 0090                          $time = time();
 0091   
 0092                          $filename = 'backup_' . $time . '_' . unique_id();
 0093                          switch ($db->get_sql_layer())
 0094                          {
 0095                              case 'mysqli':
 0096                              case 'mysql4':
 0097                              case 'mysql':
 0098                                  $extractor = new mysql_extractor($format, $filename, $time, $download, $store);
 0099                              break;
 0100   
 0101                              case 'sqlite':
 0102                                  $extractor = new sqlite_extractor($format, $filename, $time, $download, $store);
 0103                              break;
 0104   
 0105                              case 'sqlite3':
 0106                                  $extractor = new sqlite3_extractor($format, $filename, $time, $download, $store);
 0107                              break;
 0108   
 0109                              case 'postgres':
 0110                                  $extractor = new postgres_extractor($format, $filename, $time, $download, $store);
 0111                              break;
 0112   
 0113                              case 'oracle':
 0114                                  $extractor = new oracle_extractor($format, $filename, $time, $download, $store);
 0115                              break;
 0116   
 0117                              case 'mssql':
 0118                              case 'mssql_odbc':
 0119                              case 'mssqlnative':
 0120                                  $extractor = new mssql_extractor($format, $filename, $time, $download, $store);
 0121                              break;
 0122                          }
 0123   
 0124                          $extractor->write_start($table_prefix);
 0125   
 0126                          foreach ($table as $table_name)
 0127                          {
 0128                              // Get the table structure
 0129                              if ($structure)
 0130                              {
 0131                                  $extractor->write_table($table_name);
 0132                              }
 0133                              else
 0134                              {
 0135                                  // We might wanna empty out all that junk :D
 0136                                  switch ($db->get_sql_layer())
 0137                                  {
 0138                                      case 'sqlite':
 0139                                      case 'sqlite3':
 0140                                          $extractor->flush('DELETE FROM ' . $table_name . ";\n");
 0141                                      break;
 0142   
 0143                                      case 'mssql':
 0144                                      case 'mssql_odbc':
 0145                                      case 'mssqlnative':
 0146                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
 0147                                      break;
 0148   
 0149                                      case 'oracle':
 0150                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
 0151                                      break;
 0152   
 0153                                      default:
 0154                                          $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
 0155                                      break;
 0156                                  }
 0157                              }
 0158   
 0159                              // Data
 0160                              if ($schema_data)
 0161                              {
 0162                                  $extractor->write_data($table_name);
 0163                              }
 0164                          }
 0165   
 0166                          $extractor->write_end();
 0167   
 0168                          add_log('admin', 'LOG_DB_BACKUP');
 0169   
 0170                          if ($download == true)
 0171                          {
 0172                              exit;
 0173                          }
 0174   
 0175                          trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action));
 0176                      break;
 0177   
 0178                      default:
 0179                          $tables = $this->db_tools->sql_list_tables();
 0180                          asort($tables);
 0181                          foreach ($tables as $table_name)
 0182                          {
 0183                              if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0)
 0184                              {
 0185                                  $template->assign_block_vars('tables', array(
 0186                                      'TABLE'    => $table_name
 0187                                  ));
 0188                              }
 0189                          }
 0190                          unset($tables);
 0191   
 0192                          $template->assign_vars(array(
 0193                              'U_ACTION'    => $this->u_action . '&amp;action=download'
 0194                          ));
 0195   
 0196                          $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2');
 0197   
 0198                          foreach ($available_methods as $type => $module)
 0199                          {
 0200                              if (!@extension_loaded($module))
 0201                              {
 0202                                  continue;
 0203                              }
 0204   
 0205                              $template->assign_block_vars('methods', array(
 0206                                  'TYPE'    => $type
 0207                              ));
 0208                          }
 0209   
 0210                          $template->assign_block_vars('methods', array(
 0211                              'TYPE'    => 'text'
 0212                          ));
 0213                      break;
 0214                  }
 0215              break;
 0216   
 0217              case 'restore':
 0218   
 0219                  $this->page_title = 'ACP_RESTORE';
 0220   
 0221                  switch ($action)
 0222                  {
 0223                      case 'submit':
 0224                          $delete = request_var('delete', '');
 0225                          $file = request_var('file', '');
 0226                          $download = request_var('download', '');
 0227   
 0228                          if (!preg_match('#^backup_\d{10,}_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
 0229                          {
 0230                              trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 0231                          }
 0232   
 0233                          $file_name = $phpbb_root_path . 'store/' . $matches[0];
 0234   
 0235                          if (!file_exists($file_name) || !is_readable($file_name))
 0236                          {
 0237                              trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
 0238                          }
 0239   
 0240                          if ($delete)
 0241                          {
 0242                              if (confirm_box(true))
 0243                              {
 0244                                  unlink($file_name);
 0245                                  add_log('admin', 'LOG_DB_DELETE');
 0246                                  trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
 0247                              }
 0248                              else
 0249                              {
 0250                                  confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file)));
 0251                              }
 0252                          }
 0253                          else if ($download || confirm_box(true))
 0254                          {
 0255                              if ($download)
 0256                              {
 0257                                  $name = $matches[0];
 0258   
 0259                                  switch ($matches[1])
 0260                                  {
 0261                                      case 'sql':
 0262                                          $mimetype = 'text/x-sql';
 0263                                      break;
 0264                                      case 'sql.bz2':
 0265                                          $mimetype = 'application/x-bzip2';
 0266                                      break;
 0267                                      case 'sql.gz':
 0268                                          $mimetype = 'application/x-gzip';
 0269                                      break;
 0270                                  }
 0271   
 0272                                  header('Cache-Control: private, no-cache');
 0273                                  header("Content-Type: $mimetype; name=\"$name\"");
 0274                                  header("Content-disposition: attachment; filename=$name");
 0275   
 0276                                  @set_time_limit(0);
 0277   
 0278                                  $fp = @fopen($file_name, 'rb');
 0279   
 0280                                  if ($fp !== false)
 0281                                  {
 0282                                      while (!feof($fp))
 0283                                      {
 0284                                          echo fread($fp, 8192);
 0285                                      }
 0286                                      fclose($fp);
 0287                                  }
 0288   
 0289                                  flush();
 0290                                  exit;
 0291                              }
 0292   
 0293                              switch ($matches[1])
 0294                              {
 0295                                  case 'sql':
 0296                                      $fp = fopen($file_name, 'rb');
 0297                                      $read = 'fread';
 0298                                      $seek = 'fseek';
 0299                                      $eof = 'feof';
 0300                                      $close = 'fclose';
 0301                                      $fgetd = 'fgetd';
 0302                                  break;
 0303   
 0304                                  case 'sql.bz2':
 0305                                      $fp = bzopen($file_name, 'r');
 0306                                      $read = 'bzread';
 0307                                      $seek = '';
 0308                                      $eof = 'feof';
 0309                                      $close = 'bzclose';
 0310                                      $fgetd = 'fgetd_seekless';
 0311                                  break;
 0312   
 0313                                  case 'sql.gz':
 0314                                      $fp = gzopen($file_name, 'rb');
 0315                                      $read = 'gzread';
 0316                                      $seek = 'gzseek';
 0317                                      $eof = 'gzeof';
 0318                                      $close = 'gzclose';
 0319                                      $fgetd = 'fgetd';
 0320                                  break;
 0321                              }
 0322   
 0323                              switch ($db->get_sql_layer())
 0324                              {
 0325                                  case 'mysql':
 0326                                  case 'mysql4':
 0327                                  case 'mysqli':
 0328                                  case 'sqlite':
 0329                                  case 'sqlite3':
 0330                                      while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false)
 0331                                      {
 0332                                          $db->sql_query($sql);
 0333                                      }
 0334                                  break;
 0335   
 0336                                  case 'postgres':
 0337                                      $delim = ";\n";
 0338                                      while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false)
 0339                                      {
 0340                                          $query = trim($sql);
 0341   
 0342                                          if (substr($query, 0, 13) == 'CREATE DOMAIN')
 0343                                          {
 0344                                              list(, , $domain) = explode(' ', $query);
 0345                                              $sql = "SELECT domain_name
 0346                                                  FROM information_schema.domains
 0347                                                  WHERE domain_name = '$domain';";
 0348                                              $result = $db->sql_query($sql);
 0349                                              if (!$db->sql_fetchrow($result))
 0350                                              {
 0351                                                  $db->sql_query($query);
 0352                                              }
 0353                                              $db->sql_freeresult($result);
 0354                                          }
 0355                                          else
 0356                                          {
 0357                                              $db->sql_query($query);
 0358                                          }
 0359   
 0360                                          if (substr($query, 0, 4) == 'COPY')
 0361                                          {
 0362                                              while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.')
 0363                                              {
 0364                                                  if ($sub === false)
 0365                                                  {
 0366                                                      trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING);
 0367                                                  }
 0368                                                  pg_put_line($db->get_db_connect_id(), $sub . "\n");
 0369                                              }
 0370                                              pg_put_line($db->get_db_connect_id(), "\\.\n");
 0371                                              pg_end_copy($db->get_db_connect_id());
 0372                                          }
 0373                                      }
 0374                                  break;
 0375   
 0376                                  case 'oracle':
 0377                                      while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false)
 0378                                      {
 0379                                          $db->sql_query($sql);
 0380                                      }
 0381                                  break;
 0382   
 0383                                  case 'mssql':
 0384                                  case 'mssql_odbc':
 0385                                  case 'mssqlnative':
 0386                                      while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false)
 0387                                      {
 0388                                          $db->sql_query($sql);
 0389                                      }
 0390                                  break;
 0391                              }
 0392   
 0393                              $close($fp);
 0394   
 0395                              // Purge the cache due to updated data
 0396                              $cache->purge();
 0397   
 0398                              add_log('admin', 'LOG_DB_RESTORE');
 0399                              trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action));
 0400                              break;
 0401                          }
 0402                          else if (!$download)
 0403                          {
 0404                              confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file)));
 0405                          }
 0406   
 0407                      default:
 0408                          $methods = array('sql');
 0409                          $available_methods = array('sql.gz' => 'zlib', 'sql.bz2' => 'bz2');
 0410   
 0411                          foreach ($available_methods as $type => $module)
 0412                          {
 0413                              if (!@extension_loaded($module))
 0414                              {
 0415                                  continue;
 0416                              }
 0417                              $methods[] = $type;
 0418                          }
 0419   
 0420                          $dir = $phpbb_root_path . 'store/';
 0421                          $dh = @opendir($dir);
 0422   
 0423                          $backup_files = array();
 0424   
 0425                          if ($dh)
 0426                          {
 0427                              while (($file = readdir($dh)) !== false)
 0428                              {
 0429                                  if (preg_match('#^backup_(\d{10,})_[a-z\d]{16}\.(sql(?:\.(?:gz|bz2))?)$#', $file, $matches))
 0430                                  {
 0431                                      if (in_array($matches[2], $methods))
 0432                                      {
 0433                                          $backup_files[(int) $matches[1]] = $file;
 0434                                      }
 0435                                  }
 0436                              }
 0437                              closedir($dh);
 0438                          }
 0439   
 0440                          if (!empty($backup_files))
 0441                          {
 0442                              krsort($backup_files);
 0443   
 0444                              foreach ($backup_files as $name => $file)
 0445                              {
 0446                                  $template->assign_block_vars('files', array(
 0447                                      'FILE'        => $file,
 0448                                      'NAME'        => $user->format_date($name, 'd-m-Y H:i:s', true),
 0449                                      'SUPPORTED'    => true,
 0450                                  ));
 0451                              }
 0452                          }
 0453   
 0454                          $template->assign_vars(array(
 0455                              'U_ACTION'    => $this->u_action . '&amp;action=submit'
 0456                          ));
 0457                      break;
 0458                  }
 0459              break;
 0460          }
 0461      }
 0462  }
 0463   
 0464  class base_extractor
 0465  {
 0466      var $fh;
 0467      var $fp;
 0468      var $write;
 0469      var $close;
 0470      var $store;
 0471      var $download;
 0472      var $time;
 0473      var $format;
 0474      var $run_comp = false;
 0475   
 0476      function base_extractor($format, $filename, $time, $download = false, $store = false)
 0477      {
 0478          global $request;
 0479   
 0480          $this->download = $download;
 0481          $this->store = $store;
 0482          $this->time = $time;
 0483          $this->format = $format;
 0484   
 0485          switch ($format)
 0486          {
 0487              case 'text':
 0488                  $ext = '.sql';
 0489                  $open = 'fopen';
 0490                  $this->write = 'fwrite';
 0491                  $this->close = 'fclose';
 0492                  $mimetype = 'text/x-sql';
 0493              break;
 0494              case 'bzip2':
 0495                  $ext = '.sql.bz2';
 0496                  $open = 'bzopen';
 0497                  $this->write = 'bzwrite';
 0498                  $this->close = 'bzclose';
 0499                  $mimetype = 'application/x-bzip2';
 0500              break;
 0501              case 'gzip':
 0502                  $ext = '.sql.gz';
 0503                  $open = 'gzopen';
 0504                  $this->write = 'gzwrite';
 0505                  $this->close = 'gzclose';
 0506                  $mimetype = 'application/x-gzip';
 0507              break;
 0508          }
 0509   
 0510          if ($download == true)
 0511          {
 0512              $name = $filename . $ext;
 0513              header('Cache-Control: private, no-cache');
 0514              header("Content-Type: $mimetype; name=\"$name\"");
 0515              header("Content-disposition: attachment; filename=$name");
 0516   
 0517              switch ($format)
 0518              {
 0519                  case 'bzip2':
 0520                      ob_start();
 0521                  break;
 0522   
 0523                  case 'gzip':
 0524                      if (strpos($request->header('Accept-Encoding'), 'gzip') !== false && strpos(strtolower($request->header('User-Agent')), 'msie') === false)
 0525                      {
 0526                          ob_start('ob_gzhandler');
 0527                      }
 0528                      else
 0529                      {
 0530                          $this->run_comp = true;
 0531                      }
 0532                  break;
 0533              }
 0534          }
 0535   
 0536          if ($store == true)
 0537          {
 0538              global $phpbb_root_path;
 0539              $file = $phpbb_root_path . 'store/' . $filename . $ext;
 0540   
 0541              $this->fp = $open($file, 'w');
 0542   
 0543              if (!$this->fp)
 0544              {
 0545                  trigger_error('FILE_WRITE_FAIL', E_USER_ERROR);
 0546              }
 0547          }
 0548      }
 0549   
 0550      function write_end()
 0551      {
 0552          static $close;
 0553   
 0554          if ($this->store)
 0555          {
 0556              if ($close === null)
 0557              {
 0558                  $close = $this->close;
 0559              }
 0560              $close($this->fp);
 0561          }
 0562   
 0563          // bzip2 must be written all the way at the end
 0564          if ($this->download && $this->format === 'bzip2')
 0565          {
 0566              $c = ob_get_clean();
 0567              echo bzcompress($c);
 0568          }
 0569      }
 0570   
 0571      function flush($data)
 0572      {
 0573          static $write;
 0574          if ($this->store === true)
 0575          {
 0576              if ($write === null)
 0577              {
 0578                  $write = $this->write;
 0579              }
 0580              $write($this->fp, $data);
 0581          }
 0582   
 0583          if ($this->download === true)
 0584          {
 0585              if ($this->format === 'bzip2' || $this->format === 'text' || ($this->format === 'gzip' && !$this->run_comp))
 0586              {
 0587                  echo $data;
 0588              }
 0589   
 0590              // we can write the gzip data as soon as we get it
 0591              if ($this->format === 'gzip')
 0592              {
 0593                  if ($this->run_comp)
 0594                  {
 0595                      echo gzencode($data);
 0596                  }
 0597                  else
 0598                  {
 0599                      ob_flush();
 0600                      flush();
 0601                  }
 0602              }
 0603          }
 0604      }
 0605  }
 0606   
 0607  class mysql_extractor extends base_extractor
 0608  {
 0609      function write_start($table_prefix)
 0610      {
 0611          $sql_data = "#\n";
 0612          $sql_data .= "# phpBB Backup Script\n";
 0613          $sql_data .= "# Dump of tables for $table_prefix\n";
 0614          $sql_data .= "# DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 0615          $sql_data .= "#\n";
 0616          $this->flush($sql_data);
 0617      }
 0618   
 0619      function write_table($table_name)
 0620      {
 0621          global $db;
 0622          static $new_extract;
 0623   
 0624          if ($new_extract === null)
 0625          {
 0626              if ($db->get_sql_layer() === 'mysqli' || version_compare($db->sql_server_info(true), '3.23.20', '>='))
 0627              {
 0628                  $new_extract = true;
 0629              }
 0630              else
 0631              {
 0632                  $new_extract = false;
 0633              }
 0634          }
 0635   
 0636          if ($new_extract)
 0637          {
 0638              $this->new_write_table($table_name);
 0639          }
 0640          else
 0641          {
 0642              $this->old_write_table($table_name);
 0643          }
 0644      }
 0645   
 0646      function write_data($table_name)
 0647      {
 0648          global $db;
 0649          if ($db->get_sql_layer() === 'mysqli')
 0650          {
 0651              $this->write_data_mysqli($table_name);
 0652          }
 0653          else
 0654          {
 0655              $this->write_data_mysql($table_name);
 0656          }
 0657      }
 0658   
 0659      function write_data_mysqli($table_name)
 0660      {
 0661          global $db;
 0662          $sql = "SELECT *
 0663              FROM $table_name";
 0664          $result = mysqli_query($db->get_db_connect_id(), $sql, MYSQLI_USE_RESULT);
 0665          if ($result != false)
 0666          {
 0667              $fields_cnt = mysqli_num_fields($result);
 0668   
 0669              // Get field information
 0670              $field = mysqli_fetch_fields($result);
 0671              $field_set = array();
 0672   
 0673              for ($j = 0; $j < $fields_cnt; $j++)
 0674              {
 0675                  $field_set[] = $field[$j]->name;
 0676              }
 0677   
 0678              $search            = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
 0679              $replace        = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
 0680              $fields            = implode(', ', $field_set);
 0681              $sql_data        = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
 0682              $first_set        = true;
 0683              $query_len        = 0;
 0684              $max_len        = get_usable_memory();
 0685   
 0686              while ($row = mysqli_fetch_row($result))
 0687              {
 0688                  $values    = array();
 0689                  if ($first_set)
 0690                  {
 0691                      $query = $sql_data . '(';
 0692                  }
 0693                  else
 0694                  {
 0695                      $query  .= ',(';
 0696                  }
 0697   
 0698                  for ($j = 0; $j < $fields_cnt; $j++)
 0699                  {
 0700                      if (!isset($row[$j]) || is_null($row[$j]))
 0701                      {
 0702                          $values[$j] = 'NULL';
 0703                      }
 0704                      else if (($field[$j]->flags & 32768) && !($field[$j]->flags & 1024))
 0705                      {
 0706                          $values[$j] = $row[$j];
 0707                      }
 0708                      else
 0709                      {
 0710                          $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
 0711                      }
 0712                  }
 0713                  $query .= implode(', ', $values) . ')';
 0714   
 0715                  $query_len += strlen($query);
 0716                  if ($query_len > $max_len)
 0717                  {
 0718                      $this->flush($query . ";\n\n");
 0719                      $query = '';
 0720                      $query_len = 0;
 0721                      $first_set = true;
 0722                  }
 0723                  else
 0724                  {
 0725                      $first_set = false;
 0726                  }
 0727              }
 0728              mysqli_free_result($result);
 0729   
 0730              // check to make sure we have nothing left to flush
 0731              if (!$first_set && $query)
 0732              {
 0733                  $this->flush($query . ";\n\n");
 0734              }
 0735          }
 0736      }
 0737   
 0738      function write_data_mysql($table_name)
 0739      {
 0740          global $db;
 0741          $sql = "SELECT *
 0742              FROM $table_name";
 0743          $result = mysql_unbuffered_query($sql, $db->get_db_connect_id());
 0744   
 0745          if ($result != false)
 0746          {
 0747              $fields_cnt = mysql_num_fields($result);
 0748   
 0749              // Get field information
 0750              $field = array();
 0751              for ($i = 0; $i < $fields_cnt; $i++)
 0752              {
 0753                  $field[] = mysql_fetch_field($result, $i);
 0754              }
 0755              $field_set = array();
 0756   
 0757              for ($j = 0; $j < $fields_cnt; $j++)
 0758              {
 0759                  $field_set[] = $field[$j]->name;
 0760              }
 0761   
 0762              $search            = array("\\", "'", "\x00", "\x0a", "\x0d", "\x1a", '"');
 0763              $replace        = array("\\\\", "\\'", '\0', '\n', '\r', '\Z', '\\"');
 0764              $fields            = implode(', ', $field_set);
 0765              $sql_data        = 'INSERT INTO ' . $table_name . ' (' . $fields . ') VALUES ';
 0766              $first_set        = true;
 0767              $query_len        = 0;
 0768              $max_len        = get_usable_memory();
 0769   
 0770              while ($row = mysql_fetch_row($result))
 0771              {
 0772                  $values = array();
 0773                  if ($first_set)
 0774                  {
 0775                      $query = $sql_data . '(';
 0776                  }
 0777                  else
 0778                  {
 0779                      $query  .= ',(';
 0780                  }
 0781   
 0782                  for ($j = 0; $j < $fields_cnt; $j++)
 0783                  {
 0784                      if (!isset($row[$j]) || is_null($row[$j]))
 0785                      {
 0786                          $values[$j] = 'NULL';
 0787                      }
 0788                      else if ($field[$j]->numeric && ($field[$j]->type !== 'timestamp'))
 0789                      {
 0790                          $values[$j] = $row[$j];
 0791                      }
 0792                      else
 0793                      {
 0794                          $values[$j] = "'" . str_replace($search, $replace, $row[$j]) . "'";
 0795                      }
 0796                  }
 0797                  $query .= implode(', ', $values) . ')';
 0798   
 0799                  $query_len += strlen($query);
 0800                  if ($query_len > $max_len)
 0801                  {
 0802                      $this->flush($query . ";\n\n");
 0803                      $query = '';
 0804                      $query_len = 0;
 0805                      $first_set = true;
 0806                  }
 0807                  else
 0808                  {
 0809                      $first_set = false;
 0810                  }
 0811              }
 0812              mysql_free_result($result);
 0813   
 0814              // check to make sure we have nothing left to flush
 0815              if (!$first_set && $query)
 0816              {
 0817                  $this->flush($query . ";\n\n");
 0818              }
 0819          }
 0820      }
 0821   
 0822      function new_write_table($table_name)
 0823      {
 0824          global $db;
 0825   
 0826          $sql = 'SHOW CREATE TABLE ' . $table_name;
 0827          $result = $db->sql_query($sql);
 0828          $row = $db->sql_fetchrow($result);
 0829   
 0830          $sql_data = '# Table: ' . $table_name . "\n";
 0831          $sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
 0832          $this->flush($sql_data . $row['Create Table'] . ";\n\n");
 0833   
 0834          $db->sql_freeresult($result);
 0835      }
 0836   
 0837      function old_write_table($table_name)
 0838      {
 0839          global $db;
 0840   
 0841          $sql_data = '# Table: ' . $table_name . "\n";
 0842          $sql_data .= "DROP TABLE IF EXISTS $table_name;\n";
 0843          $sql_data .= "CREATE TABLE $table_name(\n";
 0844          $rows = array();
 0845   
 0846          $sql = "SHOW FIELDS
 0847              FROM $table_name";
 0848          $result = $db->sql_query($sql);
 0849   
 0850          while ($row = $db->sql_fetchrow($result))
 0851          {
 0852              $line = '   ' . $row['Field'] . ' ' . $row['Type'];
 0853   
 0854              if (!is_null($row['Default']))
 0855              {
 0856                  $line .= " DEFAULT '{$row['Default']}'";
 0857              }
 0858   
 0859              if ($row['Null'] != 'YES')
 0860              {
 0861                  $line .= ' NOT NULL';
 0862              }
 0863   
 0864              if ($row['Extra'] != '')
 0865              {
 0866                  $line .= ' ' . $row['Extra'];
 0867              }
 0868   
 0869              $rows[] = $line;
 0870          }
 0871          $db->sql_freeresult($result);
 0872   
 0873          $sql = "SHOW KEYS
 0874              FROM $table_name";
 0875   
 0876          $result = $db->sql_query($sql);
 0877   
 0878          $index = array();
 0879          while ($row = $db->sql_fetchrow($result))
 0880          {
 0881              $kname = $row['Key_name'];
 0882   
 0883              if ($kname != 'PRIMARY')
 0884              {
 0885                  if ($row['Non_unique'] == 0)
 0886                  {
 0887                      $kname = "UNIQUE|$kname";
 0888                  }
 0889              }
 0890   
 0891              if ($row['Sub_part'])
 0892              {
 0893                  $row['Column_name'] .= '(' . $row['Sub_part'] . ')';
 0894              }
 0895              $index[$kname][] = $row['Column_name'];
 0896          }
 0897          $db->sql_freeresult($result);
 0898   
 0899          foreach ($index as $key => $columns)
 0900          {
 0901              $line = '   ';
 0902   
 0903              if ($key == 'PRIMARY')
 0904              {
 0905                  $line .= 'PRIMARY KEY (' . implode(', ', $columns) . ')';
 0906              }
 0907              else if (strpos($key, 'UNIQUE') === 0)
 0908              {
 0909                  $line .= 'UNIQUE ' . substr($key, 7) . ' (' . implode(', ', $columns) . ')';
 0910              }
 0911              else if (strpos($key, 'FULLTEXT') === 0)
 0912              {
 0913                  $line .= 'FULLTEXT ' . substr($key, 9) . ' (' . implode(', ', $columns) . ')';
 0914              }
 0915              else
 0916              {
 0917                  $line .= "KEY $key (" . implode(', ', $columns) . ')';
 0918              }
 0919   
 0920              $rows[] = $line;
 0921          }
 0922   
 0923          $sql_data .= implode(",\n", $rows);
 0924          $sql_data .= "\n);\n\n";
 0925   
 0926          $this->flush($sql_data);
 0927      }
 0928  }
 0929   
 0930  class sqlite_extractor extends base_extractor
 0931  {
 0932      function write_start($prefix)
 0933      {
 0934          $sql_data = "--\n";
 0935          $sql_data .= "-- phpBB Backup Script\n";
 0936          $sql_data .= "-- Dump of tables for $prefix\n";
 0937          $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 0938          $sql_data .= "--\n";
 0939          $sql_data .= "BEGIN TRANSACTION;\n";
 0940          $this->flush($sql_data);
 0941      }
 0942   
 0943      function write_table($table_name)
 0944      {
 0945          global $db;
 0946          $sql_data = '-- Table: ' . $table_name . "\n";
 0947          $sql_data .= "DROP TABLE $table_name;\n";
 0948   
 0949          $sql = "SELECT sql
 0950              FROM sqlite_master
 0951              WHERE type = 'table'
 0952                  AND name = '" . $db->sql_escape($table_name) . "'
 0953              ORDER BY type DESC, name;";
 0954          $result = $db->sql_query($sql);
 0955          $row = $db->sql_fetchrow($result);
 0956          $db->sql_freeresult($result);
 0957   
 0958          // Create Table
 0959          $sql_data .= $row['sql'] . ";\n";
 0960   
 0961          $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
 0962   
 0963          $ar = array();
 0964          while ($row = $db->sql_fetchrow($result))
 0965          {
 0966              $ar[] = $row;
 0967          }
 0968          $db->sql_freeresult($result);
 0969   
 0970          foreach ($ar as $value)
 0971          {
 0972              if (strpos($value['name'], 'autoindex') !== false)
 0973              {
 0974                  continue;
 0975              }
 0976   
 0977              $result = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($value['name']) . "');");
 0978   
 0979              $fields = array();
 0980              while ($row = $db->sql_fetchrow($result))
 0981              {
 0982                  $fields[] = $row['name'];
 0983              }
 0984              $db->sql_freeresult($result);
 0985   
 0986              $sql_data .= 'CREATE ' . ($value['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $value['name'] . ' on ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
 0987          }
 0988   
 0989          $this->flush($sql_data . "\n");
 0990      }
 0991   
 0992      function write_data($table_name)
 0993      {
 0994          global $db;
 0995   
 0996          $col_types = sqlite_fetch_column_types($db->get_db_connect_id(), $table_name);
 0997   
 0998          $sql = "SELECT *
 0999              FROM $table_name";
 1000          $result = sqlite_unbuffered_query($db->get_db_connect_id(), $sql);
 1001          $rows = sqlite_fetch_all($result, SQLITE_ASSOC);
 1002          $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
 1003          foreach ($rows as $row)
 1004          {
 1005              foreach ($row as $column_name => $column_data)
 1006              {
 1007                  if (is_null($column_data))
 1008                  {
 1009                      $row[$column_name] = 'NULL';
 1010                  }
 1011                  else if ($column_data == '')
 1012                  {
 1013                      $row[$column_name] = "''";
 1014                  }
 1015                  else if (strpos($col_types[$column_name], 'text') !== false || strpos($col_types[$column_name], 'char') !== false || strpos($col_types[$column_name], 'blob') !== false)
 1016                  {
 1017                      $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
 1018                  }
 1019              }
 1020              $this->flush($sql_insert . implode(', ', $row) . ");\n");
 1021          }
 1022      }
 1023   
 1024      function write_end()
 1025      {
 1026          $this->flush("COMMIT;\n");
 1027          parent::write_end();
 1028      }
 1029  }
 1030   
 1031  class sqlite3_extractor extends base_extractor
 1032  {
 1033      function write_start($prefix)
 1034      {
 1035          $sql_data = "--\n";
 1036          $sql_data .= "-- phpBB Backup Script\n";
 1037          $sql_data .= "-- Dump of tables for $prefix\n";
 1038          $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 1039          $sql_data .= "--\n";
 1040          $sql_data .= "BEGIN TRANSACTION;\n";
 1041          $this->flush($sql_data);
 1042      }
 1043   
 1044      function write_table($table_name)
 1045      {
 1046          global $db;
 1047          $sql_data = '-- Table: ' . $table_name . "\n";
 1048          $sql_data .= "DROP TABLE $table_name;\n";
 1049   
 1050          $sql = "SELECT sql
 1051              FROM sqlite_master
 1052              WHERE type = 'table'
 1053                  AND name = '" . $db->sql_escape($table_name) . "'
 1054              ORDER BY name ASC;";
 1055          $result = $db->sql_query($sql);
 1056          $row = $db->sql_fetchrow($result);
 1057          $db->sql_freeresult($result);
 1058   
 1059          // Create Table
 1060          $sql_data .= $row['sql'] . ";\n";
 1061   
 1062          $result = $db->sql_query("PRAGMA index_list('" . $db->sql_escape($table_name) . "');");
 1063   
 1064          while ($row = $db->sql_fetchrow($result))
 1065          {
 1066              if (strpos($row['name'], 'autoindex') !== false)
 1067              {
 1068                  continue;
 1069              }
 1070   
 1071              $result2 = $db->sql_query("PRAGMA index_info('" . $db->sql_escape($row['name']) . "');");
 1072   
 1073              $fields = array();
 1074              while ($row2 = $db->sql_fetchrow($result2))
 1075              {
 1076                  $fields[] = $row2['name'];
 1077              }
 1078              $db->sql_freeresult($result2);
 1079   
 1080              $sql_data .= 'CREATE ' . ($row['unique'] ? 'UNIQUE ' : '') . 'INDEX ' . $row['name'] . ' ON ' . $table_name . ' (' . implode(', ', $fields) . ");\n";
 1081          }
 1082          $db->sql_freeresult($result);
 1083   
 1084          $this->flush($sql_data . "\n");
 1085      }
 1086   
 1087      function write_data($table_name)
 1088      {
 1089          global $db;
 1090   
 1091          $result = $db->sql_query("PRAGMA table_info('" . $db->sql_escape($table_name) . "');");
 1092   
 1093          $col_types = array();
 1094          while ($row = $db->sql_fetchrow($result))
 1095          {
 1096              $col_types[$row['name']] = $row['type'];
 1097          }
 1098          $db->sql_freeresult($result);
 1099   
 1100          $sql_insert = 'INSERT INTO ' . $table_name . ' (' . implode(', ', array_keys($col_types)) . ') VALUES (';
 1101   
 1102          $sql = "SELECT *
 1103              FROM $table_name";
 1104          $result = $db->sql_query($sql);
 1105   
 1106          while ($row = $db->sql_fetchrow($result))
 1107          {
 1108              foreach ($row as $column_name => $column_data)
 1109              {
 1110                  if (is_null($column_data))
 1111                  {
 1112                      $row[$column_name] = 'NULL';
 1113                  }
 1114                  else if ($column_data === '')
 1115                  {
 1116                      $row[$column_name] = "''";
 1117                  }
 1118                  else if (stripos($col_types[$column_name], 'text') !== false || stripos($col_types[$column_name], 'char') !== false || stripos($col_types[$column_name], 'blob') !== false)
 1119                  {
 1120                      $row[$column_name] = sanitize_data_generic(str_replace("'", "''", $column_data));
 1121                  }
 1122              }
 1123              $this->flush($sql_insert . implode(', ', $row) . ");\n");
 1124          }
 1125      }
 1126   
 1127      function write_end()
 1128      {
 1129          $this->flush("COMMIT;\n");
 1130          parent::write_end();
 1131      }
 1132  }
 1133   
 1134  class postgres_extractor extends base_extractor
 1135  {
 1136      function write_start($prefix)
 1137      {
 1138          $sql_data = "--\n";
 1139          $sql_data .= "-- phpBB Backup Script\n";
 1140          $sql_data .= "-- Dump of tables for $prefix\n";
 1141          $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 1142          $sql_data .= "--\n";
 1143          $sql_data .= "BEGIN TRANSACTION;\n";
 1144          $this->flush($sql_data);
 1145      }
 1146   
 1147      function write_table($table_name)
 1148      {
 1149          global $db;
 1150          static $domains_created = array();
 1151   
 1152          $sql = "SELECT a.domain_name, a.data_type, a.character_maximum_length, a.domain_default
 1153              FROM INFORMATION_SCHEMA.domains a, INFORMATION_SCHEMA.column_domain_usage b
 1154              WHERE a.domain_name = b.domain_name
 1155                  AND b.table_name = '{$table_name}'";
 1156          $result = $db->sql_query($sql);
 1157          while ($row = $db->sql_fetchrow($result))
 1158          {
 1159              if (empty($domains_created[$row['domain_name']]))
 1160              {
 1161                  $domains_created[$row['domain_name']] = true;
 1162                  //$sql_data = "DROP DOMAIN {$row['domain_name']};\n";
 1163                  $sql_data = "CREATE DOMAIN {$row['domain_name']} as {$row['data_type']}";
 1164                  if (!empty($row['character_maximum_length']))
 1165                  {
 1166                      $sql_data .= '(' . $row['character_maximum_length'] . ')';
 1167                  }
 1168                  $sql_data .= ' NOT NULL';
 1169                  if (!empty($row['domain_default']))
 1170                  {
 1171                      $sql_data .= ' DEFAULT ' . $row['domain_default'];
 1172                  }
 1173                  $this->flush($sql_data . ";\n");
 1174              }
 1175          }
 1176   
 1177          $sql_data = '-- Table: ' . $table_name . "\n";
 1178          $sql_data .= "DROP TABLE $table_name;\n";
 1179          // PGSQL does not "tightly" bind sequences and tables, we must guess...
 1180          $sql = "SELECT relname
 1181              FROM pg_class
 1182              WHERE relkind = 'S'
 1183                  AND relname = '{$table_name}_seq'";
 1184          $result = $db->sql_query($sql);
 1185          // We don't even care about storing the results. We already know the answer if we get rows back.
 1186          if ($db->sql_fetchrow($result))
 1187          {
 1188              $sql_data .= "DROP SEQUENCE {$table_name}_seq;\n";
 1189              $sql_data .= "CREATE SEQUENCE {$table_name}_seq;\n";
 1190          }
 1191          $db->sql_freeresult($result);
 1192   
 1193          $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
 1194              FROM pg_class c, pg_attribute a, pg_type t
 1195              WHERE c.relname = '" . $db->sql_escape($table_name) . "'
 1196                  AND a.attnum > 0
 1197                  AND a.attrelid = c.oid
 1198                  AND a.atttypid = t.oid
 1199              ORDER BY a.attnum";
 1200          $result = $db->sql_query($field_query);
 1201   
 1202          $sql_data .= "CREATE TABLE $table_name(\n";
 1203          $lines = array();
 1204          while ($row = $db->sql_fetchrow($result))
 1205          {
 1206              // Get the data from the table
 1207              $sql_get_default = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
 1208                  FROM pg_attrdef d, pg_class c
 1209                  WHERE (c.relname = '" . $db->sql_escape($table_name) . "')
 1210                      AND (c.oid = d.adrelid)
 1211                      AND d.adnum = " . $row['attnum'];
 1212              $def_res = $db->sql_query($sql_get_default);
 1213              $def_row = $db->sql_fetchrow($def_res);
 1214              $db->sql_freeresult($def_res);
 1215   
 1216              if (empty($def_row))
 1217              {
 1218                  unset($row['rowdefault']);
 1219              }
 1220              else
 1221              {
 1222                  $row['rowdefault'] = $def_row['rowdefault'];
 1223              }
 1224   
 1225              if ($row['type'] == 'bpchar')
 1226              {
 1227                  // Internally stored as bpchar, but isn't accepted in a CREATE TABLE statement.
 1228                  $row['type'] = 'char';
 1229              }
 1230   
 1231              $line = '  ' . $row['field'] . ' ' . $row['type'];
 1232   
 1233              if (strpos($row['type'], 'char') !== false)
 1234              {
 1235                  if ($row['lengthvar'] > 0)
 1236                  {
 1237                      $line .= '(' . ($row['lengthvar'] - 4) . ')';
 1238                  }
 1239              }
 1240   
 1241              if (strpos($row['type'], 'numeric') !== false)
 1242              {
 1243                  $line .= '(';
 1244                  $line .= sprintf("%s,%s", (($row['lengthvar'] >> 16) & 0xffff), (($row['lengthvar'] - 4) & 0xffff));
 1245                  $line .= ')';
 1246              }
 1247   
 1248              if (isset($row['rowdefault']))
 1249              {
 1250                  $line .= ' DEFAULT ' . $row['rowdefault'];
 1251              }
 1252   
 1253              if ($row['notnull'] == 't')
 1254              {
 1255                  $line .= ' NOT NULL';
 1256              }
 1257   
 1258              $lines[] = $line;
 1259          }
 1260          $db->sql_freeresult($result);
 1261   
 1262          // Get the listing of primary keys.
 1263          $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
 1264              FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
 1265              WHERE (bc.oid = i.indrelid)
 1266                  AND (ic.oid = i.indexrelid)
 1267                  AND (ia.attrelid = i.indexrelid)
 1268                  AND    (ta.attrelid = bc.oid)
 1269                  AND (bc.relname = '" . $db->sql_escape($table_name) . "')
 1270                  AND (ta.attrelid = i.indrelid)
 1271                  AND (ta.attnum = i.indkey[ia.attnum-1])
 1272              ORDER BY index_name, tab_name, column_name";
 1273   
 1274          $result = $db->sql_query($sql_pri_keys);
 1275   
 1276          $index_create = $index_rows = $primary_key = array();
 1277   
 1278          // We do this in two steps. It makes placing the comma easier
 1279          while ($row = $db->sql_fetchrow($result))
 1280          {
 1281              if ($row['primary_key'] == 't')
 1282              {
 1283                  $primary_key[] = $row['column_name'];
 1284                  $primary_key_name = $row['index_name'];
 1285              }
 1286              else
 1287              {
 1288                  // We have to store this all this info because it is possible to have a multi-column key...
 1289                  // we can loop through it again and build the statement
 1290                  $index_rows[$row['index_name']]['table'] = $table_name;
 1291                  $index_rows[$row['index_name']]['unique'] = ($row['unique_key'] == 't') ? true : false;
 1292                  $index_rows[$row['index_name']]['column_names'][] = $row['column_name'];
 1293              }
 1294          }
 1295          $db->sql_freeresult($result);
 1296   
 1297          if (!empty($index_rows))
 1298          {
 1299              foreach ($index_rows as $idx_name => $props)
 1300              {
 1301                  $index_create[] = 'CREATE ' . ($props['unique'] ? 'UNIQUE ' : '') . "INDEX $idx_name ON $table_name (" . implode(', ', $props['column_names']) . ");";
 1302              }
 1303          }
 1304   
 1305          if (!empty($primary_key))
 1306          {
 1307              $lines[] = "  CONSTRAINT $primary_key_name PRIMARY KEY (" . implode(', ', $primary_key) . ")";
 1308          }
 1309   
 1310          // Generate constraint clauses for CHECK constraints
 1311          $sql_checks = "SELECT conname as index_name, consrc
 1312              FROM pg_constraint, pg_class bc
 1313              WHERE conrelid = bc.oid
 1314                  AND bc.relname = '" . $db->sql_escape($table_name) . "'
 1315                  AND NOT EXISTS (
 1316                      SELECT *
 1317                          FROM pg_constraint as c, pg_inherits as i
 1318                          WHERE i.inhrelid = pg_constraint.conrelid
 1319                              AND c.conname = pg_constraint.conname
 1320                              AND c.consrc = pg_constraint.consrc
 1321                              AND c.conrelid = i.inhparent
 1322                  )";
 1323          $result = $db->sql_query($sql_checks);
 1324   
 1325          // Add the constraints to the sql file.
 1326          while ($row = $db->sql_fetchrow($result))
 1327          {
 1328              if (!is_null($row['consrc']))
 1329              {
 1330                  $lines[] = '  CONSTRAINT ' . $row['index_name'] . ' CHECK ' . $row['consrc'];
 1331              }
 1332          }
 1333          $db->sql_freeresult($result);
 1334   
 1335          $sql_data .= implode(", \n", $lines);
 1336          $sql_data .= "\n);\n";
 1337   
 1338          if (!empty($index_create))
 1339          {
 1340              $sql_data .= implode("\n", $index_create) . "\n\n";
 1341          }
 1342          $this->flush($sql_data);
 1343      }
 1344   
 1345      function write_data($table_name)
 1346      {
 1347          global $db;
 1348          // Grab all of the data from current table.
 1349          $sql = "SELECT *
 1350              FROM $table_name";
 1351          $result = $db->sql_query($sql);
 1352   
 1353          $i_num_fields = pg_num_fields($result);
 1354          $seq = '';
 1355   
 1356          for ($i = 0; $i < $i_num_fields; $i++)
 1357          {
 1358              $ary_type[] = pg_field_type($result, $i);
 1359              $ary_name[] = pg_field_name($result, $i);
 1360   
 1361              $sql = "SELECT pg_get_expr(d.adbin, d.adrelid) as rowdefault
 1362                  FROM pg_attrdef d, pg_class c
 1363                  WHERE (c.relname = '{$table_name}')
 1364                      AND (c.oid = d.adrelid)
 1365                      AND d.adnum = " . strval($i + 1);
 1366              $result2 = $db->sql_query($sql);
 1367              if ($row = $db->sql_fetchrow($result2))
 1368              {
 1369                  // Determine if we must reset the sequences
 1370                  if (strpos($row['rowdefault'], "nextval('") === 0)
 1371                  {
 1372                      $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";
 1373                  }
 1374              }
 1375          }
 1376   
 1377          $this->flush("COPY $table_name (" . implode(', ', $ary_name) . ') FROM stdin;' . "\n");
 1378          while ($row = $db->sql_fetchrow($result))
 1379          {
 1380              $schema_vals = array();
 1381   
 1382              // Build the SQL statement to recreate the data.
 1383              for ($i = 0; $i < $i_num_fields; $i++)
 1384              {
 1385                  $str_val = $row[$ary_name[$i]];
 1386   
 1387                  if (preg_match('#char|text|bool|bytea#i', $ary_type[$i]))
 1388                  {
 1389                      $str_val = str_replace(array("\n", "\t", "\r", "\b", "\f", "\v"), array('\n', '\t', '\r', '\b', '\f', '\v'), addslashes($str_val));
 1390                      $str_empty = '';
 1391                  }
 1392                  else
 1393                  {
 1394                      $str_empty = '\N';
 1395                  }
 1396   
 1397                  if (empty($str_val) && $str_val !== '0')
 1398                  {
 1399                      $str_val = $str_empty;
 1400                  }
 1401   
 1402                  $schema_vals[] = $str_val;
 1403              }
 1404   
 1405              // Take the ordered fields and their associated data and build it
 1406              // into a valid sql statement to recreate that field in the data.
 1407              $this->flush(implode("\t", $schema_vals) . "\n");
 1408          }
 1409          $db->sql_freeresult($result);
 1410          $this->flush("\\.\n");
 1411   
 1412          // Write out the sequence statements
 1413          $this->flush($seq);
 1414      }
 1415   
 1416      function write_end()
 1417      {
 1418          $this->flush("COMMIT;\n");
 1419          parent::write_end();
 1420      }
 1421  }
 1422   
 1423  class mssql_extractor extends base_extractor
 1424  {
 1425      function write_end()
 1426      {
 1427          $this->flush("COMMIT\nGO\n");
 1428          parent::write_end();
 1429      }
 1430   
 1431      function write_start($prefix)
 1432      {
 1433          $sql_data = "--\n";
 1434          $sql_data .= "-- phpBB Backup Script\n";
 1435          $sql_data .= "-- Dump of tables for $prefix\n";
 1436          $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 1437          $sql_data .= "--\n";
 1438          $sql_data .= "BEGIN TRANSACTION\n";
 1439          $sql_data .= "GO\n";
 1440          $this->flush($sql_data);
 1441      }
 1442   
 1443      function write_table($table_name)
 1444      {
 1445          global $db;
 1446          $sql_data = '-- Table: ' . $table_name . "\n";
 1447          $sql_data .= "IF OBJECT_ID(N'$table_name', N'U') IS NOT NULL\n";
 1448          $sql_data .= "DROP TABLE $table_name;\n";
 1449          $sql_data .= "GO\n";
 1450          $sql_data .= "\nCREATE TABLE [$table_name] (\n";
 1451          $rows = array();
 1452   
 1453          $text_flag = false;
 1454   
 1455          $sql = "SELECT COLUMN_NAME, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, 'IsIdentity') as IS_IDENTITY
 1456              FROM INFORMATION_SCHEMA.COLUMNS
 1457              WHERE TABLE_NAME = '$table_name'";
 1458          $result = $db->sql_query($sql);
 1459   
 1460          while ($row = $db->sql_fetchrow($result))
 1461          {
 1462              $line = "\t[{$row['COLUMN_NAME']}] [{$row['DATA_TYPE']}]";
 1463   
 1464              if ($row['DATA_TYPE'] == 'text')
 1465              {
 1466                  $text_flag = true;
 1467              }
 1468   
 1469              if ($row['IS_IDENTITY'])
 1470              {
 1471                  $line .= ' IDENTITY (1 , 1)';
 1472              }
 1473   
 1474              if ($row['CHARACTER_MAXIMUM_LENGTH'] && $row['DATA_TYPE'] !== 'text')
 1475              {
 1476                  $line .= ' (' . $row['CHARACTER_MAXIMUM_LENGTH'] . ')';
 1477              }
 1478   
 1479              if ($row['IS_NULLABLE'] == 'YES')
 1480              {
 1481                  $line .= ' NULL';
 1482              }
 1483              else
 1484              {
 1485                  $line .= ' NOT NULL';
 1486              }
 1487   
 1488              if ($row['COLUMN_DEFAULT'])
 1489              {
 1490                  $line .= ' DEFAULT ' . $row['COLUMN_DEFAULT'];
 1491              }
 1492   
 1493              $rows[] = $line;
 1494          }
 1495          $db->sql_freeresult($result);
 1496   
 1497          $sql_data .= implode(",\n", $rows);
 1498          $sql_data .= "\n) ON [PRIMARY]";
 1499   
 1500          if ($text_flag)
 1501          {
 1502              $sql_data .= " TEXTIMAGE_ON [PRIMARY]";
 1503          }
 1504   
 1505          $sql_data .= "\nGO\n\n";
 1506          $rows = array();
 1507   
 1508          $sql = "SELECT CONSTRAINT_NAME, COLUMN_NAME
 1509              FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
 1510              WHERE TABLE_NAME = '$table_name'";
 1511          $result = $db->sql_query($sql);
 1512          while ($row = $db->sql_fetchrow($result))
 1513          {
 1514              if (!sizeof($rows))
 1515              {
 1516                  $sql_data .= "ALTER TABLE [$table_name] WITH NOCHECK ADD\n";
 1517                  $sql_data .= "\tCONSTRAINT [{$row['CONSTRAINT_NAME']}] PRIMARY KEY  CLUSTERED \n\t(\n";
 1518              }
 1519              $rows[] = "\t\t[{$row['COLUMN_NAME']}]";
 1520          }
 1521          if (sizeof($rows))
 1522          {
 1523              $sql_data .= implode(",\n", $rows);
 1524              $sql_data .= "\n\t)  ON [PRIMARY] \nGO\n";
 1525          }
 1526          $db->sql_freeresult($result);
 1527   
 1528          $index = array();
 1529          $sql = "EXEC sp_statistics '$table_name'";
 1530          $result = $db->sql_query($sql);
 1531          while ($row = $db->sql_fetchrow($result))
 1532          {
 1533              if ($row['TYPE'] == 3)
 1534              {
 1535                  $index[$row['INDEX_NAME']][] = '[' . $row['COLUMN_NAME'] . ']';
 1536              }
 1537          }
 1538          $db->sql_freeresult($result);
 1539   
 1540          foreach ($index as $index_name => $column_name)
 1541          {
 1542              $index[$index_name] = implode(', ', $column_name);
 1543          }
 1544   
 1545          foreach ($index as $index_name => $columns)
 1546          {
 1547              $sql_data .= "\nCREATE  INDEX [$index_name] ON [$table_name]($columns) ON [PRIMARY]\nGO\n";
 1548          }
 1549          $this->flush($sql_data);
 1550      }
 1551   
 1552      function write_data($table_name)
 1553      {
 1554          global $db;
 1555   
 1556          if ($db->get_sql_layer() === 'mssql')
 1557          {
 1558              $this->write_data_mssql($table_name);
 1559          }
 1560          else if($db->get_sql_layer() === 'mssqlnative')
 1561          {
 1562              $this->write_data_mssqlnative($table_name);
 1563          }
 1564          else
 1565          {
 1566              $this->write_data_odbc($table_name);
 1567          }
 1568      }
 1569   
 1570      function write_data_mssql($table_name)
 1571      {
 1572          global $db;
 1573          $ary_type = $ary_name = array();
 1574          $ident_set = false;
 1575          $sql_data = '';
 1576   
 1577          // Grab all of the data from current table.
 1578          $sql = "SELECT *
 1579              FROM $table_name";
 1580          $result = $db->sql_query($sql);
 1581   
 1582          $retrieved_data = mssql_num_rows($result);
 1583   
 1584          $i_num_fields = mssql_num_fields($result);
 1585   
 1586          for ($i = 0; $i < $i_num_fields; $i++)
 1587          {
 1588              $ary_type[$i] = mssql_field_type($result, $i);
 1589              $ary_name[$i] = mssql_field_name($result, $i);
 1590          }
 1591   
 1592          if ($retrieved_data)
 1593          {
 1594              $sql = "SELECT 1 as has_identity
 1595                  FROM INFORMATION_SCHEMA.COLUMNS
 1596                  WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
 1597              $result2 = $db->sql_query($sql);
 1598              $row2 = $db->sql_fetchrow($result2);
 1599              if (!empty($row2['has_identity']))
 1600              {
 1601                  $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
 1602                  $ident_set = true;
 1603              }
 1604              $db->sql_freeresult($result2);
 1605          }
 1606   
 1607          while ($row = $db->sql_fetchrow($result))
 1608          {
 1609              $schema_vals = $schema_fields = array();
 1610   
 1611              // Build the SQL statement to recreate the data.
 1612              for ($i = 0; $i < $i_num_fields; $i++)
 1613              {
 1614                  $str_val = $row[$ary_name[$i]];
 1615   
 1616                  if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
 1617                  {
 1618                      $str_quote = '';
 1619                      $str_empty = "''";
 1620                      $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
 1621                  }
 1622                  else if (preg_match('#date|timestamp#i', $ary_type[$i]))
 1623                  {
 1624                      if (empty($str_val))
 1625                      {
 1626                          $str_quote = '';
 1627                      }
 1628                      else
 1629                      {
 1630                          $str_quote = "'";
 1631                      }
 1632                  }
 1633                  else
 1634                  {
 1635                      $str_quote = '';
 1636                      $str_empty = 'NULL';
 1637                  }
 1638   
 1639                  if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
 1640                  {
 1641                      $str_val = $str_empty;
 1642                  }
 1643   
 1644                  $schema_vals[$i] = $str_quote . $str_val . $str_quote;
 1645                  $schema_fields[$i] = $ary_name[$i];
 1646              }
 1647   
 1648              // Take the ordered fields and their associated data and build it
 1649              // into a valid sql statement to recreate that field in the data.
 1650              $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
 1651   
 1652              $this->flush($sql_data);
 1653              $sql_data = '';
 1654          }
 1655          $db->sql_freeresult($result);
 1656   
 1657          if ($retrieved_data && $ident_set)
 1658          {
 1659              $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
 1660          }
 1661          $this->flush($sql_data);
 1662      }
 1663   
 1664      function write_data_mssqlnative($table_name)
 1665      {
 1666          global $db;
 1667          $ary_type = $ary_name = array();
 1668          $ident_set = false;
 1669          $sql_data = '';
 1670   
 1671          // Grab all of the data from current table.
 1672          $sql = "SELECT * FROM $table_name";
 1673          $db->mssqlnative_set_query_options(array('Scrollable' => SQLSRV_CURSOR_STATIC));
 1674          $result = $db->sql_query($sql);
 1675   
 1676          $retrieved_data = $db->mssqlnative_num_rows($result);
 1677   
 1678          if (!$retrieved_data)
 1679          {
 1680              $db->sql_freeresult($result);
 1681              return;
 1682          }
 1683   
 1684          $sql = "SELECT COLUMN_NAME, DATA_TYPE
 1685              FROM INFORMATION_SCHEMA.COLUMNS
 1686              WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_NAME = '" . $db->sql_escape($table_name) . "'";
 1687          $result_fields = $db->sql_query($sql);
 1688   
 1689          $i_num_fields = 0;
 1690          while ($row = $db->sql_fetchrow($result_fields))
 1691          {
 1692              $ary_type[$i_num_fields] = $row['DATA_TYPE'];
 1693              $ary_name[$i_num_fields] = $row['COLUMN_NAME'];
 1694              $i_num_fields++;
 1695          }
 1696          $db->sql_freeresult($result_fields);
 1697   
 1698          $sql = "SELECT 1 as has_identity
 1699              FROM INFORMATION_SCHEMA.COLUMNS
 1700              WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
 1701          $result2 = $db->sql_query($sql);
 1702          $row2 = $db->sql_fetchrow($result2);
 1703   
 1704          if (!empty($row2['has_identity']))
 1705          {
 1706              $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
 1707              $ident_set = true;
 1708          }
 1709          $db->sql_freeresult($result2);
 1710   
 1711          while ($row = $db->sql_fetchrow($result))
 1712          {
 1713              $schema_vals = $schema_fields = array();
 1714   
 1715              // Build the SQL statement to recreate the data.
 1716              for ($i = 0; $i < $i_num_fields; $i++)
 1717              {
 1718                  $str_val = $row[$ary_name[$i]];
 1719   
 1720                  // defaults to type number - better quote just to be safe, so check for is_int too
 1721                  if (is_int($ary_type[$i]) || preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
 1722                  {
 1723                      $str_quote = '';
 1724                      $str_empty = "''";
 1725                      $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
 1726                  }
 1727                  else if (preg_match('#date|timestamp#i', $ary_type[$i]))
 1728                  {
 1729                      if (empty($str_val))
 1730                      {
 1731                          $str_quote = '';
 1732                      }
 1733                      else
 1734                      {
 1735                          $str_quote = "'";
 1736                      }
 1737                  }
 1738                  else
 1739                  {
 1740                      $str_quote = '';
 1741                      $str_empty = 'NULL';
 1742                  }
 1743   
 1744                  if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
 1745                  {
 1746                      $str_val = $str_empty;
 1747                  }
 1748   
 1749                  $schema_vals[$i] = $str_quote . $str_val . $str_quote;
 1750                  $schema_fields[$i] = $ary_name[$i];
 1751              }
 1752   
 1753              // Take the ordered fields and their associated data and build it
 1754              // into a valid sql statement to recreate that field in the data.
 1755              $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
 1756   
 1757              $this->flush($sql_data);
 1758              $sql_data = '';
 1759          }
 1760          $db->sql_freeresult($result);
 1761   
 1762          if ($ident_set)
 1763          {
 1764              $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
 1765          }
 1766          $this->flush($sql_data);
 1767      }
 1768   
 1769      function write_data_odbc($table_name)
 1770      {
 1771          global $db;
 1772          $ary_type = $ary_name = array();
 1773          $ident_set = false;
 1774          $sql_data = '';
 1775   
 1776          // Grab all of the data from current table.
 1777          $sql = "SELECT *
 1778              FROM $table_name";
 1779          $result = $db->sql_query($sql);
 1780   
 1781          $retrieved_data = odbc_num_rows($result);
 1782   
 1783          if ($retrieved_data)
 1784          {
 1785              $sql = "SELECT 1 as has_identity
 1786                  FROM INFORMATION_SCHEMA.COLUMNS
 1787                  WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
 1788              $result2 = $db->sql_query($sql);
 1789              $row2 = $db->sql_fetchrow($result2);
 1790              if (!empty($row2['has_identity']))
 1791              {
 1792                  $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
 1793                  $ident_set = true;
 1794              }
 1795              $db->sql_freeresult($result2);
 1796          }
 1797   
 1798          $i_num_fields = odbc_num_fields($result);
 1799   
 1800          for ($i = 0; $i < $i_num_fields; $i++)
 1801          {
 1802              $ary_type[$i] = odbc_field_type($result, $i + 1);
 1803              $ary_name[$i] = odbc_field_name($result, $i + 1);
 1804          }
 1805   
 1806          while ($row = $db->sql_fetchrow($result))
 1807          {
 1808              $schema_vals = $schema_fields = array();
 1809   
 1810              // Build the SQL statement to recreate the data.
 1811              for ($i = 0; $i < $i_num_fields; $i++)
 1812              {
 1813                  $str_val = $row[$ary_name[$i]];
 1814   
 1815                  if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
 1816                  {
 1817                      $str_quote = '';
 1818                      $str_empty = "''";
 1819                      $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
 1820                  }
 1821                  else if (preg_match('#date|timestamp#i', $ary_type[$i]))
 1822                  {
 1823                      if (empty($str_val))
 1824                      {
 1825                          $str_quote = '';
 1826                      }
 1827                      else
 1828                      {
 1829                          $str_quote = "'";
 1830                      }
 1831                  }
 1832                  else
 1833                  {
 1834                      $str_quote = '';
 1835                      $str_empty = 'NULL';
 1836                  }
 1837   
 1838                  if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
 1839                  {
 1840                      $str_val = $str_empty;
 1841                  }
 1842   
 1843                  $schema_vals[$i] = $str_quote . $str_val . $str_quote;
 1844                  $schema_fields[$i] = $ary_name[$i];
 1845              }
 1846   
 1847              // Take the ordered fields and their associated data and build it
 1848              // into a valid sql statement to recreate that field in the data.
 1849              $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
 1850   
 1851              $this->flush($sql_data);
 1852   
 1853              $sql_data = '';
 1854   
 1855          }
 1856          $db->sql_freeresult($result);
 1857   
 1858          if ($retrieved_data && $ident_set)
 1859          {
 1860              $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
 1861          }
 1862          $this->flush($sql_data);
 1863      }
 1864   
 1865  }
 1866   
 1867  class oracle_extractor extends base_extractor
 1868  {
 1869      function write_table($table_name)
 1870      {
 1871          global $db;
 1872          $sql_data = '-- Table: ' . $table_name . "\n";
 1873          $sql_data .= "DROP TABLE $table_name\n/\n";
 1874          $sql_data .= "\nCREATE TABLE $table_name (\n";
 1875   
 1876          $sql = "SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_LENGTH, NULLABLE, DATA_DEFAULT
 1877              FROM ALL_TAB_COLS
 1878              WHERE table_name = '{$table_name}'";
 1879          $result = $db->sql_query($sql);
 1880   
 1881          $rows = array();
 1882          while ($row = $db->sql_fetchrow($result))
 1883          {
 1884              $line = '  "' . $row['column_name'] . '" ' . $row['data_type'];
 1885   
 1886              if ($row['data_type'] !== 'CLOB')
 1887              {
 1888                  if ($row['data_type'] !== 'VARCHAR2' && $row['data_type'] !== 'CHAR')
 1889                  {
 1890                      $line .= '(' . $row['data_precision'] . ')';
 1891                  }
 1892                  else
 1893                  {
 1894                      $line .= '(' . $row['data_length'] . ')';
 1895                  }
 1896              }
 1897   
 1898              if (!empty($row['data_default']))
 1899              {
 1900                  $line .= ' DEFAULT ' . $row['data_default'];
 1901              }
 1902   
 1903              if ($row['nullable'] == 'N')
 1904              {
 1905                  $line .= ' NOT NULL';
 1906              }
 1907              $rows[] = $line;
 1908          }
 1909          $db->sql_freeresult($result);
 1910   
 1911          $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
 1912              FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
 1913              WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
 1914                  AND B.CONSTRAINT_TYPE = 'P'
 1915                  AND A.TABLE_NAME = '{$table_name}'";
 1916          $result = $db->sql_query($sql);
 1917   
 1918          $primary_key = array();
 1919          $contraint_name = '';
 1920          while ($row = $db->sql_fetchrow($result))
 1921          {
 1922              $constraint_name = '"' . $row['constraint_name'] . '"';
 1923              $primary_key[] = '"' . $row['column_name'] . '"';
 1924          }
 1925          $db->sql_freeresult($result);
 1926   
 1927          if (sizeof($primary_key))
 1928          {
 1929              $rows[] = "  CONSTRAINT {$constraint_name} PRIMARY KEY (" . implode(', ', $primary_key) . ')';
 1930          }
 1931   
 1932          $sql = "SELECT A.CONSTRAINT_NAME, A.COLUMN_NAME
 1933              FROM USER_CONS_COLUMNS A, USER_CONSTRAINTS B
 1934              WHERE A.CONSTRAINT_NAME = B.CONSTRAINT_NAME
 1935                  AND B.CONSTRAINT_TYPE = 'U'
 1936                  AND A.TABLE_NAME = '{$table_name}'";
 1937          $result = $db->sql_query($sql);
 1938   
 1939          $unique = array();
 1940          $contraint_name = '';
 1941          while ($row = $db->sql_fetchrow($result))
 1942          {
 1943              $constraint_name = '"' . $row['constraint_name'] . '"';
 1944              $unique[] = '"' . $row['column_name'] . '"';
 1945          }
 1946          $db->sql_freeresult($result);
 1947   
 1948          if (sizeof($unique))
 1949          {
 1950              $rows[] = "  CONSTRAINT {$constraint_name} UNIQUE (" . implode(', ', $unique) . ')';
 1951          }
 1952   
 1953          $sql_data .= implode(",\n", $rows);
 1954          $sql_data .= "\n)\n/\n";
 1955   
 1956          $sql = "SELECT A.REFERENCED_NAME, C.*
 1957              FROM USER_DEPENDENCIES A, USER_TRIGGERS B, USER_SEQUENCES C
 1958              WHERE A.REFERENCED_TYPE = 'SEQUENCE'
 1959                  AND A.NAME = B.TRIGGER_NAME
 1960                  AND B.TABLE_NAME = '{$table_name}'
 1961                  AND C.SEQUENCE_NAME = A.REFERENCED_NAME";
 1962          $result = $db->sql_query($sql);
 1963   
 1964          $type = request_var('type', '');
 1965   
 1966          while ($row = $db->sql_fetchrow($result))
 1967          {
 1968              $sql_data .= "\nDROP SEQUENCE \"{$row['referenced_name']}\"\n/\n";
 1969              $sql_data .= "\nCREATE SEQUENCE \"{$row['referenced_name']}\"";
 1970   
 1971              if ($type == 'full')
 1972              {
 1973                  $sql_data .= ' START WITH ' . $row['last_number'];
 1974              }
 1975   
 1976              $sql_data .= "\n/\n";
 1977          }
 1978          $db->sql_freeresult($result);
 1979   
 1980          $sql = "SELECT DESCRIPTION, WHEN_CLAUSE, TRIGGER_BODY
 1981              FROM USER_TRIGGERS
 1982              WHERE TABLE_NAME = '{$table_name}'";
 1983          $result = $db->sql_query($sql);
 1984          while ($row = $db->sql_fetchrow($result))
 1985          {
 1986              $sql_data .= "\nCREATE OR REPLACE TRIGGER {$row['description']}WHEN ({$row['when_clause']})\n{$row['trigger_body']}\n/\n";
 1987          }
 1988          $db->sql_freeresult($result);
 1989   
 1990          $sql = "SELECT A.INDEX_NAME, B.COLUMN_NAME
 1991              FROM USER_INDEXES A, USER_IND_COLUMNS B
 1992              WHERE A.UNIQUENESS = 'NONUNIQUE'
 1993                  AND A.INDEX_NAME = B.INDEX_NAME
 1994                  AND B.TABLE_NAME = '{$table_name}'";
 1995          $result = $db->sql_query($sql);
 1996   
 1997          $index = array();
 1998   
 1999          while ($row = $db->sql_fetchrow($result))
 2000          {
 2001              $index[$row['index_name']][] = $row['column_name'];
 2002          }
 2003   
 2004          foreach ($index as $index_name => $column_names)
 2005          {
 2006              $sql_data .= "\nCREATE INDEX $index_name ON $table_name(" . implode(', ', $column_names) . ")\n/\n";
 2007          }
 2008          $db->sql_freeresult($result);
 2009          $this->flush($sql_data);
 2010      }
 2011   
 2012      function write_data($table_name)
 2013      {
 2014          global $db;
 2015          $ary_type = $ary_name = array();
 2016   
 2017          // Grab all of the data from current table.
 2018          $sql = "SELECT *
 2019              FROM $table_name";
 2020          $result = $db->sql_query($sql);
 2021   
 2022          $i_num_fields = ocinumcols($result);
 2023   
 2024          for ($i = 0; $i < $i_num_fields; $i++)
 2025          {
 2026              $ary_type[$i] = ocicolumntype($result, $i + 1);
 2027              $ary_name[$i] = ocicolumnname($result, $i + 1);
 2028          }
 2029   
 2030          $sql_data = '';
 2031   
 2032          while ($row = $db->sql_fetchrow($result))
 2033          {
 2034              $schema_vals = $schema_fields = array();
 2035   
 2036              // Build the SQL statement to recreate the data.
 2037              for ($i = 0; $i < $i_num_fields; $i++)
 2038              {
 2039                  // Oracle uses uppercase - we use lowercase
 2040                  $str_val = $row[strtolower($ary_name[$i])];
 2041   
 2042                  if (preg_match('#char|text|bool|raw|clob#i', $ary_type[$i]))
 2043                  {
 2044                      $str_quote = '';
 2045                      $str_empty = "''";
 2046                      $str_val = sanitize_data_oracle($str_val);
 2047                  }
 2048                  else if (preg_match('#date|timestamp#i', $ary_type[$i]))
 2049                  {
 2050                      if (empty($str_val))
 2051                      {
 2052                          $str_quote = '';
 2053                      }
 2054                      else
 2055                      {
 2056                          $str_quote = "'";
 2057                      }
 2058                  }
 2059                  else
 2060                  {
 2061                      $str_quote = '';
 2062                      $str_empty = 'NULL';
 2063                  }
 2064   
 2065                  if (empty($str_val) && $str_val !== '0')
 2066                  {
 2067                      $str_val = $str_empty;
 2068                  }
 2069   
 2070                  $schema_vals[$i] = $str_quote . $str_val . $str_quote;
 2071                  $schema_fields[$i] = '"' . $ary_name[$i] . '"';
 2072              }
 2073   
 2074              // Take the ordered fields and their associated data and build it
 2075              // into a valid sql statement to recreate that field in the data.
 2076              $sql_data = "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ")\n/\n";
 2077   
 2078              $this->flush($sql_data);
 2079          }
 2080          $db->sql_freeresult($result);
 2081      }
 2082   
 2083      function write_start($prefix)
 2084      {
 2085          $sql_data = "--\n";
 2086          $sql_data .= "-- phpBB Backup Script\n";
 2087          $sql_data .= "-- Dump of tables for $prefix\n";
 2088          $sql_data .= "-- DATE : " . gmdate("d-m-Y H:i:s", $this->time) . " GMT\n";
 2089          $sql_data .= "--\n";
 2090          $this->flush($sql_data);
 2091      }
 2092  }
 2093   
 2094  // 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)
 2095  function get_usable_memory()
 2096  {
 2097      $val = trim(@ini_get('memory_limit'));
 2098   
 2099      if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs))
 2100      {
 2101          $memory_limit = (int) $regs[1];
 2102          switch ($regs[2])
 2103          {
 2104   
 2105              case 'k':
 2106              case 'K':
 2107                  $memory_limit *= 1024;
 2108              break;
 2109   
 2110              case 'm':
 2111              case 'M':
 2112                  $memory_limit *= 1048576;
 2113              break;
 2114   
 2115              case 'g':
 2116              case 'G':
 2117                  $memory_limit *= 1073741824;
 2118              break;
 2119          }
 2120   
 2121          // how much memory PHP requires at the start of export (it is really a little less)
 2122          if ($memory_limit > 6100000)
 2123          {
 2124              $memory_limit -= 6100000;
 2125          }
 2126   
 2127          // allow us to consume half of the total memory available
 2128          $memory_limit /= 2;
 2129      }
 2130      else
 2131      {
 2132          // set the buffer to 1M if we have no clue how much memory PHP will give us :P
 2133          $memory_limit = 1048576;
 2134      }
 2135   
 2136      return $memory_limit;
 2137  }
 2138   
 2139  function sanitize_data_mssql($text)
 2140  {
 2141      $data = preg_split('/[\n\t\r\b\f]/', $text);
 2142      preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
 2143   
 2144      $val = array();
 2145   
 2146      foreach ($data as $value)
 2147      {
 2148          if (strlen($value))
 2149          {
 2150              $val[] = "'" . $value . "'";
 2151          }
 2152          if (sizeof($matches[0]))
 2153          {
 2154              $val[] = 'char(' . ord(array_shift($matches[0])) . ')';
 2155          }
 2156      }
 2157   
 2158      return implode('+', $val);
 2159  }
 2160   
 2161  function sanitize_data_oracle($text)
 2162  {
 2163  //    $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text);
 2164  //    preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches);
 2165      $data = preg_split('/[\0\b\f\'\/]/', $text);
 2166      preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches);
 2167   
 2168      $val = array();
 2169   
 2170      foreach ($data as $value)
 2171      {
 2172          if (strlen($value))
 2173          {
 2174              $val[] = "'" . $value . "'";
 2175          }
 2176          if (sizeof($matches[0]))
 2177          {
 2178              $val[] = 'chr(' . ord(array_shift($matches[0])) . ')';
 2179          }
 2180      }
 2181   
 2182      return implode('||', $val);
 2183  }
 2184   
 2185  function sanitize_data_generic($text)
 2186  {
 2187      $data = preg_split('/[\n\t\r\b\f]/', $text);
 2188      preg_match_all('/[\n\t\r\b\f]/', $text, $matches);
 2189   
 2190      $val = array();
 2191   
 2192      foreach ($data as $value)
 2193      {
 2194          if (strlen($value))
 2195          {
 2196              $val[] = "'" . $value . "'";
 2197          }
 2198          if (sizeof($matches[0]))
 2199          {
 2200              $val[] = "'" . array_shift($matches[0]) . "'";
 2201          }
 2202      }
 2203   
 2204      return implode('||', $val);
 2205  }
 2206   
 2207  // modified from PHP.net
 2208  function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
 2209  {
 2210      $record = '';
 2211      $delim_len = strlen($delim);
 2212   
 2213      while (!$eof($fp))
 2214      {
 2215          $pos = strpos($record, $delim);
 2216          if ($pos === false)
 2217          {
 2218              $record .= $read($fp, $buffer);
 2219              if ($eof($fp) && ($pos = strpos($record, $delim)) !== false)
 2220              {
 2221                  $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
 2222                  return substr($record, 0, $pos);
 2223              }
 2224          }
 2225          else
 2226          {
 2227              $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR);
 2228              return substr($record, 0, $pos);
 2229          }
 2230      }
 2231   
 2232      return false;
 2233  }
 2234   
 2235  function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192)
 2236  {
 2237      static $array = array();
 2238      static $record = '';
 2239   
 2240      if (!sizeof($array))
 2241      {
 2242          while (!$eof($fp))
 2243          {
 2244              if (strpos($record, $delim) !== false)
 2245              {
 2246                  $array = explode($delim, $record);
 2247                  $record = array_pop($array);
 2248                  break;
 2249              }
 2250              else
 2251              {
 2252                  $record .= $read($fp, $buffer);
 2253              }
 2254          }
 2255          if ($eof($fp) && strpos($record, $delim) !== false)
 2256          {
 2257              $array = explode($delim, $record);
 2258              $record = array_pop($array);
 2259          }
 2260      }
 2261   
 2262      if (sizeof($array))
 2263      {
 2264          return array_shift($array);
 2265      }
 2266   
 2267      return false;
 2268  }
 2269