Location: PHPKode > scripts > GreenLight SQLTool > greenlight-sqltool/dumpdb.php
<?php
require_once("DB.php");
//edit these lines with your connection details
if (@$HTTP_POST_VARS["dumpToFile"]) {
  header("Content-type: application/sql");
  header("Content-Disposition: attachment; filename=\"$dbname.sql\"");
} else {
  header("Content-type: text/plain");
  header("Content-Disposition: inline; filename=\"$dbname.sql\"");
}

// Fetch connection/dump parameters, with appropriate defaults
$dbpasswd = @$HTTP_POST_VARS["dbpasswd"];
$dbhost = (! empty($HTTP_POST_VARS["dbhost"])) ? $HTTP_POST_VARS["dbhost"]
    : "localhost";
$dbname = @$HTTP_POST_VARS["dbname"];
$dbuser = @$HTTP_POST_VARS["dbuser"];
$dbtype = (! empty($HTTP_POST_VARS["dbtype"])) ? $HTTP_POST_VARS["dbtype"]
    : (function_exists("mssql_connect") ? "mssql" : "mysql");
$targetType = (! empty($HTTP_POST_VARS["targetType"]))
     ? $HTTP_POST_VARS["targetType"] : $dbtype;
$dumpTablesPattern = @$HTTP_POST_VARS["dumpTablesPattern"];
$addReconnect = @$HTTP_POST_VARS["addReconnect"];
$reconnectInverval = max(5, @$HTTP_POST_VARS["reconnectInterval"]);
$addDropTables = @$HTTP_POST_VARS["addDropTables"];
$addFulltextIndex = @$HTTP_POST_VARS["addFulltextIndex"];

// Establish connection
$db = DB::connect(
    array(
      "phptype" => $dbtype,
      "hostspec" => $dbhost,
      "username" => $dbuser,
      "password" => $dbpasswd,
      "database" => $dbname),
    array(
      "autofree" => true
    ));

if (DB::isError($db)) {
  die("SQL error: ".$db->getDebugInfo()."\n");
}
$db->setFetchMode(DB_FETCHMODE_ASSOC);
if ($targetType==$dbtype) {
  $tdb = $db;
} else {
  $tdb = DB::factory($targetType);
}
// PEAR DB library Bug workaround
// DB::mysql::quoteSmart() does not work without a connection
$qdb = ($targetType=="mysql" ? $db : $tdb);

$prepSql = array();
$postSql = array();
if ($targetType=="mssql") {
  $prepSql[] = "SET DATEFORMAT ymd";
  $prepSql[] = "SET ANSI_NULLS ON";
  $prepSql[] = "SET ANSI_NULL_DFLT_ON ON";
  $prepSql[] = "SET ANSI_PADDING ON";
  //  $postSql[] = "COMMIT TRAN";
}
if ($dbtype=="mssql") {
  $db->query("SET DATEFORMAT ymd");
}

function printQuery($query) {
  // This function outputs a single query
  // It automatically inserts 'RECONNECT' every $reconnectInterval queries,
  // and ensures every batch of queries starts with $prepSql and ends with
  // $postSql
  global $prepSql, $postSql, $targetType, $addReconnect, $reconnectInterval;
  static $countQueries;
  if ($query=="END") {
    // We've reached the end of the dump
    print "\n";
    if (count($postSql) >0) {
      print join(";\n", $postSql).";\n";
    }
    return;
  }
  if (@$addReconnect && $countQueries+count($postSql)>=$reconnectInterval) {
    // We should issue a RECONNECT command
    print "\n";
    if (count($postSql) >0) {
      print join(";\n", $postSql).";\n";
    }
    print "RECONNECT;\n";
    $countQueries = 0;
  }
  if (empty($countQueries) && count($prepSql) >0) {
    // Either we just RECONNECTed or we're just starting: either way, do Prep
    print join(";\n", $prepSql).";\n\n";
    $countQueries = count($prepSql);
  }
  // Print the query
  $countQueries++;
  print "$query;\n";
}

function mapType($colType) {
  global $targetType, $dbtype;
  $colType = strtoupper($colType);
  if ($targetType=="mssql") {
    switch($colType) {
      case "MEDIUMINT":
        return "INT";
      case "TIMESTAMP":
        return ($dbtype=="mysql" ? "DATETIME" : "TIMESTAMP");
      case "DATE":
      case "TIME":
      case "YEAR":
        return "DATETIME";
      case "BLOB":
      case "TINYBLOB":
      case "MEDIUMBLOB":
      case "LONGBLOB":
        return "TEXT";
      case "TEXT":
      case "TINYTEXT":
      case "MEDIUMTEXT":
      case "LONGTEXT":
        return "TEXT";
      case "ENUM":
      case "STRING":
      case "CHAR":
        return "VARCHAR";
    }
  } elseif ($targetType=="mysql") {
    switch($colType) {
      case "BIT":
        return "TINYINT";
      case "MONEY":
        return "BIGINT";
      case "SMALLMONEY":
        return "INT";
      case "SMALLDATETIME":
        return "DATETIME";
      case "NTEXT":
        return "TEXT";
      case "BINARY":
      case "VARBINARY":
        return "BLOB";
      case "IMAGE":
        return "LONGBLOB";
      case "STRING":
      case "CHAR":
        return "VARCHAR";
    }
  }
  return $colType;
}


function typeDefault($colType) {
  global $targetType, $dbtype, $qdb;
  switch($colType) {
    case "INT":
    case "TINYINT":
    case "SMALLINT":
    case "MEDIUMINT":
    case "BIGINT":
    case "FLOAT":
    case "DOUBLE":
    case "DECIMAL":
    case "NUMERIC":
    case "BIT":
    case "MONEY":
    case "SMALLMONEY":
      return $qdb->quoteSmart(0);
    case "DATETIME":
    case "SMALLDATETIME":
      return $targetType=="mssql" ? "CURRENT_TIMESTAMP" : "";
    case "VARCHAR":
    case "CHAR":
    case "TEXT":
    case "NATIONAL CHAR":
    case "NATIONAL VARCHAR":
    case "NATIONAL TEXT":
    case "BINARY":
    case "VARBINARY":
    case "IMAGE":
    case "TINYBLOB":
    case "TINYTEXT":
    case "BLOB":
    case "TEXT":
    case "MEDIUMBLOB":
    case "MEDIUMTEXT":
    case "LONGBLOB":
    case "LONGTEXT":
    case "ENUM":
      return  $qdb->quoteSmart("");
    default:
      return "";
  }
}

// Get list of tables
switch($dbtype) {
  case "mssql":
    $dbres = $db->query("EXEC sp_tables @table_type=\"'TABLE'\"");
    if (DB::isError($dbres)) {
       die("SQL error: ".$dbres->getDebugInfo()."\n");
    }
    $tblNames = array();
    while($dbres->fetchInto($tblrec)) {
      if ($tblrec["TABLE_NAME"] != "dtproperties") {
        $tblNames[] = $tblrec["TABLE_NAME"];
      }
    }
    break;
  case "mysql":
    $tblNames = $db->getCol("SHOW TABLES");
    if (DB::isError($tblNames)) {
       die("SQL error: ".$tblNames->getDebugInfo()."\n");
    }
    break;
  default:
    die("Unknown database type $dbtype");
}


// Dump each table
$constraintNames=array();
foreach($tblNames as $tblName) {
  // fetch info about table to write the CREATE command for this table
  $tblInfo = $db->tableInfo("$tblName");
  $tblHasIncrementingKey = 0;
  $colDefinitions = array();
  $colList = array();
  $multikeys = array();
  $datefields = array();
  $tblNameQuoted = $tdb->quoteIdentifier($tblName);
  $primaryConstraint = "";
  foreach($tblInfo as $colInfo) {
    // get info about column
    $colName = $colInfo["name"];
    $colList[] = $tdb->quoteIdentifier($colName);
    $colType = mapType($colInfo["type"]);
    $colLength = $colInfo["len"];
    $colAllowsNull = ! preg_match("/not_null/i", $colInfo["flags"]);
    $colIsIncrementing = preg_match("/increment/i", $colInfo["flags"]);
    $tblHasIncrementingKey = $tblHasIncrementingKey || $colIsIncrementing;
    $colIsUnique = false;
    if (preg_match("/primary/i", $colInfo["flags"])) {
      $multikeys["PRIMARY KEY"][] = $colName;
    } elseif (preg_match("/unique/i", $colInfo["flags"])) {
       if (preg_match("/multiple/i", $colInfo["flags"])||$targetType=="mysql"){
         $multikeys["UNIQUE"][] = $colName;
       } else {
         $colIsUnique = true;
       }
    } elseif ((preg_match("/multiple/i", $colInfo["flags"]) || $colIsIncrementing) && $targetType=="mysql") {
      $multikeys["KEY"][] = $colName;
    }
    if (preg_match("/date/i", $colType)) {
      $datefields[] = $colName;
    }
    if ($colIsIncrementing) {
      $colDefault = "";
    } elseif ($colAllowsNull) {
      $colDefault = "NULL";
    } else {
      $colDefault = typeDefault($colType);
    }
    $colDefinitions[] = $tdb->quoteIdentifier($colName)
      . " " . $colType
      . ($colType=="VARCHAR"||$colType=="CHAR" ? "($colLength)" : "")
      . ($colAllowsNull ? " NULL" : " NOT NULL")
      . ($colIsIncrementing ? 
          ($targetType=="mssql"?" IDENTITY":" AUTO_INCREMENT") : "")
      . ($colIsUnique ? " UNIQUE" : "")
      . ($colDefault!="" ? " DEFAULT $colDefault" : "");
  }
  if (count($multikeys)>0) {
    // Add primary- and multiple-key constraints
    foreach($multikeys as $multitype => $multikey) {
      $multiname = join("_", $multikey).(count($multikey)==1?"_constraint":"");
      $postfix = "";
      // Make sure every constraint has a unique name
      while (in_array($multiname.$postfix, $constraintNames)) {
        $postfix++;
      }
      $multiname.=$postfix;
      $constraintNames[] = $multiname;
      if ($multitype=="PRIMARY KEY") {
        $primaryConstraint = $multiname;
      }
      $multiname = $tdb->quoteIdentifier($multiname);
      $multikey2 = array();
      foreach ($multikey as $multikeyfield) {
        $multikey2[] = $tdb->quoteIdentifier($multikeyfield);
      }
      $colDefinitions[] = 
          ($targetType=="mssql" ? "CONSTRAINT $multiname $multitype"
          : "$multitype $multiname") . " (" . join(", ", $multikey2) . ")";
    }
  }
  if ($addDropTables) {
    printQuery("DROP TABLE $tblNameQuoted");
  }
  printQuery("CREATE TABLE $tblNameQuoted (\n  "
      . join(",\n  ", $colDefinitions) . "\n)");
  print "\n";
  // Add fulltext indexes/catalogs
  $fulltext = array();
  $fulltextname = "";
  if ($addFulltextIndex) {
    if ($dbtype == "mysql") {
      foreach($db->getAll("SHOW INDEX FROM $tblName") as $colInfo) {
        if ($colInfo["Index_type"]=="FULLTEXT") {
          $fulltext[] = $colInfo["Column_name"];
          $fulltextname = $colInfo["Key_name"];
        }
      }
    }
  }
  if (count($fulltext)>0) {
    if ($targetType == "mysql") {
      $fulltextQuoted = array();
      foreach($fulltext as $colName) {
        $fulltextQuoted = $tdb->quoteIdentifier($colName);
      }
      printQuery("ALTER TABLE $tblNameQuoted"
         ." ADD FULLTEXT ".$tdb->quoteIdentifier($fulltextname)
         ." (".join(", ", $fulltextQuoted).")");
    } else {
      // MSSQL full text indices are a bit more work
      printQuery("EXEC sp_fulltext_catalog "
          . $qdb->quoteSmart($fulltextname).", "
          . $qdb->quoteSmart('create'));
      printQuery("EXEC sp_fulltext_table "
          . $qdb->quoteSmart($tblName).", "
          . $qdb->quoteSmart('create').", "
          . $qdb->quoteSmart($fulltextname).", "
          . $qdb->quoteSmart($primaryConstraint));
      foreach($fulltext as $colName) {
        printQuery("EXEC sp_fulltext_column "
          . $qdb->quoteSmart($tblName).", "
          . $qdb->quoteSmart('add'));
      }
      printQuery("EXEC sp_fulltext_table "
          . $qdb->quoteSmart($tblName).", "
          . $qdb->quoteSmart('activate'));
      printQuery("EXEC sp_fulltext_table "
          . $qdb->quoteSmart($tblName).", "
          . $qdb->quoteSmart('start_full'));
      printQuery("EXEC sp_fulltext_table "
          . $qdb->quoteSmart($tblName).", "
          . $qdb->quoteSmart('start_background_updateindex'));
    }
  }

  if (empty($dumpTablesPattern) 
       || preg_match("/(?:$dumpTablesPattern)/i", $tblName)) { 
    // Dump the contents of the table (if any)
    $tblres=$db->query("SELECT * FROM $tblName");
    if ($tblres->fetchInto($tblrow)) {
      if ($tblHasIncrementingKey && $targetType=="mssql") {
        printQuery("SET IDENTITY_INSERT $tblNameQuoted ON");
        $prepSql[] = "SET IDENTITY_INSERT $tblNameQuoted ON";
        $postSql[] = "SET IDENTITY_INSERT $tblNameQuoted OFF";
      }
      do {
        if (count($datefields)>0 && $targetType!=$dbtype) {
          if ($targetType=="mysql") {
            // Reformat date fields mssql=>mysql
            foreach ($datefields as $fld) {
              $tblrow[$fld] = strftime("%Y-%m-%d %H:%M:%S",
                  strtotime($tblrow[$fld]));
            }
          } else  {
            // Reformat date fields mysql=>mssql
            foreach ($datefields as $fld) {
              if (preg_match("/^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/",
                  $tblrow[$fld], $match)) {
                $tblrow[$fld] = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
                    $match[1], $match[2], $match[3],
                    $match[4], $match[5], $match[6]);
              }
            }
          }
        }
        $valuesQuoted = array();
        foreach ($tblrow as $i => $value) {
          $valuesQuoted[] = $qdb->quoteSmart($value);
        }
        printQuery("INSERT INTO $tblNameQuoted\n  ("
            .join(", ", $colList) .")\n"
            . "  VALUES (".join(", ", $valuesQuoted).")");
      } while($tblres->fetchInto($tblrow));
      if ($tblHasIncrementingKey && $targetType=="mssql") {
        printQuery("SET IDENTITY_INSERT $tblNameQuoted OFF");
        array_pop($prepSql);
        array_pop($postSql);
      }
      print "\n\n";
    }
    print "\n";
  }

}
printQuery("END");
Return current item: GreenLight SQLTool