Pular para o conteúdo principal

Classe que gera um backup do banco escolhido sem problemas com foreign key

Fiz a classe abaixo para ajudar na geração e restauração de backup.

Ela ordena as tabelas de tal forma a evitar erros de foreign key ao fazer a restauração.



Código:




/**
* Classe criada no dia 14/02/2011 para gerar um backup do banco
* sem o inconveniente de problemas com chave estrangeira ao fazer o restore
* Exemplo:
* //seta o banco que se deseja fazer o backup
* $backup->setBd($_POST['db']);
*       
* // seta quais tabelas se deseja fazer o backup
* $backup->setListaTblEscolhida($_POST["tabelas"]);
*       
* // cria um nome para o backup
* $no_backup = "./".$_POST['db']."_bkp_".date("YmdHi").".sql";
*    
* // manda a classe fazer o backup
* $backup->fazerBackup($no_backup);
*/

class f_Backup{
    private $lista_bd; // lista de bancos de dados
    private $lista_tbl; // lista das tabelas do banco de dados escolhido
    private $lista_tbl_escolhida = array(); // lista das tabelas que a pessoa deseja fazer o backup
    private $lista_tbl_bkp = array(); // lista ordenada do backup das tabelas
    private $lista_foreign_key; // lista de foreing key do banco
    private $no_backup; // nome do arquivo de backup
    private $bd; // banco escolhido para fazer o backup
    private $msg_erro;
    private $erro;
    private $bkp_file;
   
    /**
    * Retorna a mensagem de erro encontrada ao executar alguma tarefa
    * @return Retorna uma string que contém a mensagem de erro
    */
    public function getMsgErro(){
        return trim($this->msg_erro);
    }

    /**
    * Retorna o tipo de erro
    * @return Retorna um integer que representa o tipo de erro (1->ok, 2->atencao, 3->erro grave)
    */
    public function getErro(){
        return $this->erro;
    }
   
    public function getListaBd(){
        $banco = new Banco();
        $SQL = "SHOW DATABASES";
        $this->lista_bd = $banco->Consulta($SQL);
        return $this->lista_bd;
    }   
   
    // Seta o banco escolhido e ja lista as tabelas do banco
    public function setBd($pno_bd){
        if($this->existeListaBd($pno_bd)){
            // seta o banco escolhido
            $this->bd = $pno_bd;
            // carrega a lista de tabelas do banco
            $this->lista_tbl  = $this->getListaTbl($pno_bd);       
            // carrega a lista de tabelas que dependem de outras tabelas
            $this->carregaForeignKey($pno_bd);
        }
    }
   
    // Seta quais tabelas do banco se deseja fazer o backup
    public function setListaTblEscolhida(array $tabelas){
        $qt = count($tabelas);
        if($qt>0){
            for($cont=0;$cont<$qt;$cont++){
                $this->setListaEscolhida($tabelas[$cont]);   
            }           
            return true;
        } else{
            $this->erro=3;
            $this->msg_erro="Nenhuma tabela foi marcada para se fazer o backup!";
            return false;
        }       
    }
   
    // carrega a lista de tabelas escolhidas para constar no backup
    private function setListaEscolhida($pno_tbl){       
        // se nao estiver carrega ela na lista
        if(!$this->existeListaEscolhida($pno_tbl)){
            $qt = count($this->lista_tbl_escolhida);
            $this->lista_tbl_escolhida[$qt]['tbl'] = $pno_tbl;           
            $this->lista_tbl_escolhida[$qt]['referencias'] = $this->getReferencias($pno_tbl);
            $this->lista_tbl_escolhida[$qt]['auto_incremento'] = $this->getAutoIncremento($pno_tbl);
            $estrutura = $this->getSQLCreateTbl($pno_tbl);
            if($this->lista_tbl_escolhida[$qt]['auto_incremento'] > 0){
                $sql .= str_replace("  ", "\t", str_replace("`", "", $estrutura)). " AUTO_INCREMENT=". $this->lista_tbl_escolhida[$qt]['auto_incremento'] .";\r\n\r\n";                }
            else{
                $sql .= str_replace("  ", "\t", str_replace("`", "", $estrutura)).";\r\n\r\n";
            }
            $this->lista_tbl_escolhida[$qt]['estrutura'] = $estrutura;           
           
            // carrega na lista a ser feito o backup a lista de tabelas que a tabela escolhida depende (FK)
            $qt2 = count($this->lista_tbl_escolhida[$qt]['referencias']);
            for($cont=0;$cont<$qt2;$cont++){
                $this->setListaEscolhida($this->lista_tbl_escolhida[$qt]['referencias'][$cont]);
            }
        }
    }
   
    // pega o auto incremento da tabela
    private function getAutoIncremento($pno_tbl){
        $result = 0;
        $qt = count($this->lista_tbl)-1;
        for($cont=0;$cont<$qt;$cont++){
            if($this->lista_tbl[$cont]['Name']==$pno_tbl){
                $result = $this->lista_tbl[$cont]['Auto_increment']*1;
                break;               
            }
        }
        return $result;
    }
   
    // carrega a lista ordenada para constar no backup para evitar erro de chave estrangeira ao inserir
    private function montarListaBkpOrdenada(){
        $qt = count($this->lista_tbl_escolhida);
        $feitos = 0;
        $loops = 0;
       
        while($feitos<$qt && $loops<3){
            for($cont=0;$cont<$qt;$cont++){
                // se nao estiver carrega ela na lista
                $ok = 0;
                if(!$this->existeListaTblBkp($this->lista_tbl_escolhida[$cont]['tbl'])){
                    $ok = 1;
                    $qt2 = count($this->lista_tbl_escolhida[$cont]['referencias']);
                    for($cont2=0;$cont2<$qt2;$cont2++){
                        if(!$this->existeListaTblBkp($this->lista_tbl_escolhida[$cont]['referencias'][$cont2])){
                            $ok = 0;
                        }
                    }
                }
                // se pode fazer pois as que ele depende ja foram feitas
                if($ok==1){
                    $feitos++;
                    $qt3 = count($this->lista_tbl_bkp);
                    $this->lista_tbl_bkp[$qt3]['tbl'] = $this->lista_tbl_escolhida[$cont]['tbl'];
                    $this->lista_tbl_bkp[$qt3]['estrutura'] = $this->lista_tbl_escolhida[$cont]['estrutura'];
                    $this->lista_tbl_bkp[$qt3]['auto_incremento'] = $this->lista_tbl_escolhida[$cont]['auto_incremento'];
                }
            }
            $loops++;
        }       
    }
   
    // verifica se determinada tabela existe na lista de tabelas a fazer o backup
    private function existeListaEscolhida($pno_tbl){
        $result = false;
        $qt = count($this->lista_tbl_escolhida);
        // verifica se a tabela ja nao esta na lista
        for($cont=0;$cont<$qt;$cont++){
            if($this->lista_tbl_escolhida[$cont]['tbl']==$pno_tbl){
                $result = true;
            }
        }
        return $result;
    }
   
    // verifica se determinada tabela existe na lista de tabelas ordenada para constar no backup
    private function existeListaTblBkp($pno_tbl){
        $result = false;
        $qt = count($this->lista_tbl_bkp);
        // verifica se a tabela ja nao esta na lista
        for($cont=0;$cont<$qt;$cont++){
            if($this->lista_tbl_bkp[$cont]['tbl']==$pno_tbl){
                $result = true;
            }
        }
        return $result;
    }
   
    // verifica se determinado nome de banco existe na lista de bancos existentes
    private function existeListaBd($pno_bd){
        $result = false;
        $qt = count($this->lista_bd);
        // verifica se a tabela ja nao esta na lista
        for($cont=0;$cont<$qt;$cont++){
            if($lista_bd[$cont][0]==$pno_tbl){
                $result = true;
            }
        }
        return $result;
    }
   
    // Retorna um array com a lista de tabelas que a tabela depende (FK)
    private function getReferencias($pno_tbl){
        $result = array();
        $qt = count($this->lista_foreign_key)-1;
        for($cont=0;$cont<$qt;$cont++){
            if($this->lista_foreign_key[$cont]['tbl']==$pno_tbl){
                $result[] = $this->lista_foreign_key[$cont]['referencia'];
            }
        }
        return $result;
    }
   
    // Retorna as tabelas que dependem de outras tabelas por ter chaves estrangeiras
    public function carregaForeignKey($pno_bd){       
        $banco = new Banco();
        $SQL = "select kcu.table_name as tbl, kcu.referenced_table_name as referencia FROM key_column_usage kcu
        left join table_constraints tc
        on tc.constraint_name = kcu.constraint_name
        where tc.constraint_type = 'FOREIGN KEY'
        and kcu.constraint_schema = '".$pno_bd."' ";
        $this->lista_foreign_key = $banco->Consulta($SQL, $DB_USER, $DB_PASS, $DB_HOST, 'information_schema');
    }   
   
    // Retorna as tabelas do banco desejado
    public function getListaTbl($pno_bd){
        global $DB_USER;
        global $DB_PASS;
        global $DB_HOST;
       
        $banco = new Banco();
        $SQL = "SHOW TABLE STATUS";
        $this->lista_tbl = $banco->Consulta($SQL, $DB_USER, $DB_PASS, $DB_HOST, $pno_bd);
        return $this->lista_tbl;
    }
   
    // Retorna a lista de campos da tabela
    public function getListaCamposTbl($pno_tbl){
        $banco = new Banco();
        $SQL = "SHOW COLUMNS FROM ".$pno_tbl." ";
        $lista = $banco->Consulta($SQL, $DB_USER, $DB_PASS, $DB_HOST, $this->bd);
        $qt = count($lista)-1;
        $result = "";
        for($cont = 0; $cont < $qt; $cont++){
            if($cont>0){
                $result .= ", ".$lista[$cont][0];
            } else{
                $result .= $lista[$cont][0];
            }
        }
        return $result;
    }
   
    // Retorna a estrutura de criacao da tabela
    public function getSQLCreateTbl($pno_tabela){
        global $DB_USER;
        global $DB_PASS;
        global $DB_HOST;
       
        $banco = new Banco();
        $SQL = "SHOW CREATE TABLE ".$pno_tabela;
        $this->lista_tbl = $banco->Consulta($SQL, $DB_USER, $DB_PASS, $DB_HOST, $this->bd);
        return $this->lista_tbl[0][1];
    }
   
    // Texto inicial do backup
    private function getTextIni(){
        $texto = "-- Banco de dados do MySQL: ". $this->bd ."\r\n";
        $texto .= "-- Data backup: ". date("d/m/Y H:i:s")."\r\n";
        return $texto;
    }
   
    // seta o caminho e nome do arquivo
    public function fazerBackup($pno_backup){       
        // monta a lista ordenada de tabelas para constar no backup evitando erros de FK quando for fazer o restore
        $this->montarListaBkpOrdenada();       
       
        // abre o arquivo para iniciar o backup
        $fp = fopen($pno_backup, "a");
       
        // comeca a geracao do texto
        $texto = $this->getTextIni();
       
        // percorre as tabelas
        $qt = count($this->lista_tbl_bkp);
        for($i = 0; $i < $qt; $i++){
            $sql = '';           
           
            // carrega os dados de criacao tabela
            $sql .= "-- Estrutura da tabela ".$this->lista_tbl_bkp[$i]['tbl']."\r\n\r\n";                       
            $sql .= $this->lista_tbl_bkp[$i]['estrutura']."\r\n\r\n";
           
            // carrega as colunas da tabela
            $campos = $this->getListaCamposTbl($this->lista_tbl_bkp[$i]['tbl']);           
           
            // carrega os dados da tabela
            $banco = new Banco();
            $SQL = "SELECT * FROM ".$this->lista_tbl_bkp[$i]['tbl']." ";
            $lista = $banco->Consulta($SQL, $DB_USER, $DB_PASS, $DB_HOST, $this->bd);
           
            // percorre a tabela montando a sql de backup
            $qt_linha = count($lista)-1;
            if($qt_linha>0){
                $qt_coluna = count($lista[0]);               
                for($i2 = 0; $i2 < $qt_linha; $i2++){
                    $valores = array();
                    for($i3 = 0; $i3 < $qt_coluna; $i3++){
                        $valores[] .= "'".addslashes(stripslashes($lista[$i2][$i3].'').'') ."'";
                    }
                    $valor = implode(", ", $valores);
                    if($i2==0){               
                        $sql  .= "INSERT INTO ".$this->lista_tbl_bkp[$i]['tbl']." (".$campos.") VALUES\r\n(".$valor.")";
                    } else{               
                        $sql  .= ",\r\n(".$valor.")";
                    }
                }               
            }
            $sql .= ";\r\n\r\n";
           
            // grava os dados da tabela
            fwrite($fp, $sql);
        }       
       
        // fecha o arquivo
        fclose($fp);
       
        return true;
    }
}
?>

Comentários

Postagens mais visitadas deste blog

Função php que gera número romano

/**  * Funcao que serve para transformar o numero em romano  * @param integer $integer Recebe algum numero inteiro  * @return string Retorna a string do numero romano  */ function fRomano($integer) {     $table = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1);     $return = '';     while($integer > 0) {         foreach($table as $rom=>$arb) {             if($integer >= $arb) {                 $integer -= $arb;                 $return .= $rom;                 break;             }         }     }     return $return; }

Lista de órgãos emissores de RG

Para quem quiser normalizar os órgãos emissores de RG, aí vai uma lista retirada do site da FGV: SSP - Secretaria de Segurança Pública PM - Polícia Militar PC - Policia Civil CNT - Carteira Nacional de Habilitação DIC - Diretoria de Identificação Civil CTPS - Carteira de Trabaho e Previdência Social FGTS - Fundo de Garantia do Tempo de Serviço IFP - Instituto Félix Pacheco IPF - Instituto Pereira Faustino IML - Instituto Médico-Legal MTE - Ministério do Trabalho e Emprego MMA - Ministério da Marinha MAE - Ministério da Aeronáutica MEX - Ministério do Exército POF - Polícia Federal POM - Polícia Militar SES - Carteira de Estrangeiro SJS - Secretaria da Justiça e Segurança SJTS - Secretaria da Justiça do Trabalho e Segurança ZZZ - Outros (inclusive exterior)