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