0

I have a problem while uploading database with key-connection between the tables.

Script works well as far as there is no connection between the tables.

What MySql command do I have to include in my php class to drop all foreign keys ? So I'd be able to drop the tables and then after all tables have been created add the key-connection back onto the tables.

Here it is the class I am using:

<?php
class BackupDB

    {
    private $host = '';
    private $username = '';
    private $passwd = '';
    private $dbName = '';
    private $charset = '';
    function __construct($host, $username, $passwd, $dbName, $charset = 'utf8')
        {
        $this->host = $host;
        $this->username = $username;
        $this->passwd = $passwd;
        $this->dbName = $dbName;
        $this->charset = $charset;
        $this->initializeDatabase();
        }

    protected
    function initializeDatabase()
        {
        $conn = mysql_connect($this->host, $this->username, $this->passwd);
        mysql_select_db($this->dbName, $conn);
        if (!mysql_set_charset($this->charset, $conn))
            {
            mysql_query('SET NAMES ' . $this->charset);
            }
        }

    /**
     * Backup the whole database or just some tables
     * Use '*' for whole database or 'table1 table2 table3...'
     * @param string $tables
     */
    public

    function backupTables($tables = '*', $outputDir = '.')
        {
        try
            {
            /**
             * Tables to export
             */
            if ($tables == '*')
                {
                $tables = array();
                $result = mysql_query('SHOW TABLES');
                while ($row = mysql_fetch_row($result))
                    {
                    $tables[] = $row[0];
                    }
                }
            else
                {
                $tables = is_array($tables) ? $tables : explode(',', $tables);
                }

            $sql = 'CREATE DATABASE IF NOT EXISTS ' . $this->dbName . ";\n\n";
            $sql.= 'USE ' . $this->dbName . ";\n\n";
            /**
             * Iterate tables
             */
            foreach($tables as $table)
                {
                echo "Backing up " . $table . " table...";
                $result = mysql_query('SELECT * FROM ' . $table);
                $numFields = mysql_num_fields($result);
                $sql.= 'DROP TABLE IF EXISTS ' . $table . ';';
                $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE ' . $table));
                $sql.= "\n\n" . $row2[1] . ";\n\n";
                for ($i = 0; $i < $numFields; $i++)
                    {
                    while ($row = mysql_fetch_row($result))
                        {
                        $sql.= 'INSERT INTO ' . $table . ' VALUES(';
                        for ($j = 0; $j < $numFields; $j++)
                            {
                            $row[$j] = addslashes($row[$j]);
                            $row[$j] = str_replace("\n", "\\n", $row[$j]);
                            if (isset($row[$j]))
                                {
                                $sql.= '"' . $row[$j] . '"';
                                }
                            else
                                {
                                $sql.= '""';
                                }

                            if ($j < ($numFields - 1))
                                {
                                $sql.= ',';
                                }
                            }

                        $sql.= ");\n";
                        }
                    }

                $sql.= "\n\n\n";
                echo " OK" . "<br />";
                }
            }

        catch(Exception $e)
            {
            var_dump($e->getMessage());
            return false;
            }

        return $this->saveFile($sql, $outputDir);
        }

    /**
     * Save SQL to file
     * @param string $sql
     */
    protected
    function saveFile(&$sql, $outputDir = '.')
        {
        if (!$sql) return false;
        try
            {
            $outputfilename = $outputDir . '/db-backup-' . $this->dbName . '-' . date("d.m.Y_H.i.s") . '.sql';
            $result = mysql_query('INSERT INTO backuplog (backup) VALUES ("' . $outputfilename . '")');
            $handle = fopen($outputfilename, 'w+');
            fwrite($handle, $sql);
            fclose($handle);
            echo '<span class="message">Zapisano ' . $outputfilename . ' link do bazy. </span>';
            echo '<span class="message">Właśnie pobrano kopie zapasową. Dziękujemy Serdecznie. Życzymy miłego dnia.</span>';
            }

        catch(Exception $e)
            {
            $result = mysql_query('DELETE FROM backuplog WHERE backup ="' . $outputfilename . '"');
            var_dump($e->getMessage());
            echo '<span class="error">Notacja.Udało się pobrać bazedanych... ale #NIE zaladowano linku do formularza, aby odzyskać dane trzeba ręcznie wpisać nazwę folderu/orazpliku.sql</span>';
            echo '<span class="error">UWAGA! Wystąpił błąd podczas zapisywania danych w bazie... Zadanie nie ukończone.</span>';
            return false;
            }

        return true;
        } //end f
    public

    function loadDB($filename)
        {

        // $result=exec('mysql --user='.$this->user.' --password='.$this->pass .'<DatabaseBackUp/'.$filename);
        // mysql -u user_name -p <file_to_read_from.sql

        $templine = '';

        // Read in entire file

        $lines = file($filename);

        // Loop through each line

        foreach($lines as $line)
            {

            // Skip it if it's a comment

            if (substr($line, 0, 2) == '--' || $line == '') continue;

            // Add this line to the current segment

            $templine.= $line;

            // If it has a semicolon at the end, it's the end of the query

            if (substr(trim($line) , -1, 1) == ';')
                {

                // Perform the query

                if (!mysql_query($templine))
                    {
                    echo "Błąd ładownia pliku.sql";
                    return false;
                    } //echo $templine //TEST!

                // Reset temp variable to empty

                $templine = '';
                }
            }

        return true;
        } //end function
    } //End calss
/* USE EXAMPLE

// DOWNLOAD DB FROM SERVER AS SQL FILE TO

$backupDatabase = new BackupDB(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
$status = $backupDatabase->backupTables(TABLES, OUTPUT_DIR) ? 'OK' : 'KO';
echo "<br /><br /><br />Backup result: ".$status;

// RETRIVE DATA FROM SQL FILE TO DATABASE

$backupDatabase->loadDB("Path/to/mysqlfile.sql");
*/
?>

If you know how to extract foreign keys from a database, drop them one after the other, delete all tables and then put the keys back on again, please share your knowledge. Thanks again for looking into it.

Again for those who like to use this script it works fine... if! tables in database are not connected with foreign keys. Let's hope this state will soon change.

Short example of outputed .sql file:

CREATE DATABASE IF NOT EXISTS DATABASEONE;

USE DATABASEONE;

DROP TABLE IF EXISTS st_glowne_st_pages;

CREATE TABLE `st_glowne_st_pages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fk_glowne` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  `fk_pages` varchar(50) COLLATE utf8_polish_ci NOT NULL,
  `kolejnosc` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  KEY `fk_glowne` (`fk_glowne`),
  KEY `fk_pages` (`fk_pages`),
  CONSTRAINT `st_glowne_st_pages_ibfk_1` FOREIGN KEY (`fk_glowne`) REFERENCES `st_glowne` (`name`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `st_glowne_st_pages_ibfk_2` FOREIGN KEY (`fk_pages`) REFERENCES `st_pages` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci;

INSERT INTO st_glowne_st_pages VALUES("1","admin.php","pageadmin.php","1");
INSERT INTO st_glowne_st_pages VALUES("3","index.php","pageindex.php","1");
INSERT INTO st_glowne_st_pages VALUES("4","work.php","pagework.php","1");
INSERT INTO st_glowne_st_pages VALUES("7","register.php","pageregister.php","1");
INSERT INTO st_glowne_st_pages VALUES("8","login.php","pagelogin.php","1");
yivi
  • 42,438
  • 18
  • 116
  • 138
DevWL
  • 17,345
  • 6
  • 90
  • 86

1 Answers1

0

I haven't tried this myself, but apparently you can turn checking off.

SET FOREIGN_KEY_CHECKS = 0;

you'll need to read all the foreign key constraints and also store them in your backup file if you want to recreate them afterwards.

see this answer for some more clues.

you really should consider using sqldump though ...

Community
  • 1
  • 1
Loopo
  • 2,204
  • 2
  • 28
  • 45
  • Well if I could disable FOREIGN_KEY than it could work. This script already reads and store key constrains in mysql file. I will add short example above. Thanks – DevWL Sep 30 '13 at 15:43
  • Problem is that script is not able to drop table with key constrain. – DevWL Sep 30 '13 at 15:51