Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

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:51 - Dateigröße: 54.19 KiB


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