Example #1
0
 function Backup(&$binfo, $flags = 0)
 {
     global $ADEI_ROOTDIR;
     global $BACKUP_DB;
     if (is_array($dbinfo)) {
         $dbinfo =& $binfo;
     } else {
         $dbinfo = $BACKUP_DB;
         $dbinfo['database'] = $binfo;
     }
     $lock = new LOCK("backup." . $this->srvid);
     $lock->Lock(LOCK::BLOCK);
     try {
         $zeus = new ZEUS($dbinfo);
     } catch (ADEIException $e) {
         if ($flags & READER::BACKUP_FULL) {
             $tmpinfo = $dbinfo;
             unset($tmpinfo['database']);
             $zeus = new ZEUS($tmpinfo);
             $dblist = $zeus->db->ShowDatabases();
             foreach ($dblist as $row) {
                 if (strtolower($row[0]) == strtolower($dbinfo['database'])) {
                     throw new ADEIException(translate("Broken or invalid database is specified for backup"));
                 }
             }
             if (strtolower($dbinfo['driver']) == "mysql" && strtolower($this->server['driver']) == "mysql") {
                 $cli = Database::GetConnectionString($this->server);
                 $srv = Database::GetConnectionString($dbinfo);
                 $zeus->db->CreateDatabase($dbinfo['database']);
                 @system("mysqldump --compact {$cli} | mysql {$srv}", $res);
                 if ($res) {
                     throw new ADEIException(translate("The initialization of the backup database is failed."));
                 }
                 $zeus = new ZEUS($dbinfo);
             } elseif (strtolower($dbinfo['driver']) == "mysql") {
                 $sql = file_get_contents("{$ADEI_ROOTDIR}/sql/zeus71.sql");
                 $zeus->db->CreateDatabase($dbinfo['database']);
                 $zeus = new ZEUS($dbinfo);
                 $zeus->db->Query($sql);
             } else {
                 throw new ADEIException(translate("The initial backup database should setup manualy. The auto mode is only works for the MySQL at the moment"));
             }
         } else {
             throw $e;
         }
     }
     $src_list = $this->GetGroupList(REQUEST::NEED_INFO | REQUEST::NEED_ITEMINFO);
     if ($this->char_mode && !$zeus->char_mode) {
         $pack = 1;
     } else {
         $pack = 0;
     }
     $zeus->db->Query("SET SQL_MODE=NO_AUTO_VALUE_ON_ZERO");
     if ($flags & READER::BACKUP_FULL) {
         $tables = array("config", "blocks", "groups", "items", "g2id", "marker", "masks", "messages", "loginfo", "opc");
         $blobs = array("config" => array(3), "items" => array(3), "masks" => array(3));
         if ($this->opts->Get("lclb_is_varchar", false)) {
             unset($blobs["config"]);
         }
         foreach ($tables as $table) {
             $src = $this->db->Prepare("SELECT * FROM {$table}");
             $src->execute();
             $width = $src->columnCount();
             $full_query = "TRUNCATE TABLE {$table};";
             if ($pack) {
                 $cur_blobs = $blobs[$table];
             } else {
                 $cur_blobs = false;
             }
             if ($width > 1) {
                 $query = "?" . str_repeat(", ?", $width - 1);
             } else {
                 $query = "?";
             }
             $dst = $zeus->db->Prepare("INSERT INTO {$table} VALUES ({$query})");
             $row = array();
             for ($i = 0; $i < $width; $i++) {
                 $row[$i] = false;
                 if ($cur_blobs && in_array($i, $cur_blobs)) {
                     $src->bindColumn($i + 1, $row[$i], PDO::PARAM_LOB);
                     $dst->bindParam($i + 1, $row[$i], PDO::PARAM_LOB);
                 } else {
                     $src->bindColumn($i + 1, $row[$i]);
                     $dst->bindParam($i + 1, $row[$i]);
                 }
             }
             $zeus->db->Query($full_query);
             while ($src->fetch(PDO::FETCH_BOUND)) {
                 if ($cur_blobs) {
                     foreach ($cur_blobs as $i) {
                         $row[$i] = pack("H*", $row[$i]);
                     }
                 }
                 $dst->execute();
             }
             /*
             	    $rows = $src->fetchAll(PDO::FETCH_NUM);
             	    foreach ($rows as $row) {
             		$query = "INSERT INTO $table VALUES(";
             		foreach ($row as $i=>$value) {
             		    if (($cur_blobs)&&(in_array($i, $cur_blobs))) {
             #			echo "Value($table, $i): " . $value . "!\n";
             //			$value = pack("H*", $value);
             		        if ($i) $query .= ", 0x$value";
             			else $query .= "0x$value";
             		    } else {
             		        if ($i) $query .= ", \"$value\"";
             			else $query .= "\"$value\"";
             		    }
             		}
             		$full_query .= "$query); ";
             	    }
             //	    echo $full_query . "\n";
             
             	    $zeus->db->Query($full_query);
             */
         }
         $stmt = $zeus->db->Query("SHOW TABLES LIKE 'log%'");
         $log_tables_result = $stmt->fetchAll(PDO::FETCH_NUM);
         // loginfo additional
         $log_tables = array();
         foreach ($log_tables_result as $i => $table) {
             $log_tables[$i] = $table[0];
         }
         //print_r($log_tables);
         foreach ($src_list as &$grp) {
             $table = "log" . $grp['gid'];
             if (!in_array($table, $log_tables)) {
                 $zeus->db->Query("CREATE TABLE {$table} (lid bigint(20) NOT NULL auto_increment PRIMARY KEY, ts double NOT NULL, data BLOB, INDEX(ts))");
             }
         }
     }
     $dst_list = $zeus->GetGroupList(REQUEST::NEED_INFO | REQUEST::NEED_ITEMINFO);
     if (sizeof($src_list) != sizeof($dst_list) || sizeof($src_list['items']) != sizeof($dst_list['items'])) {
         // or compare names (items by content not lenght, 'name', 'comment')
         throw new ADEIException(translate("The configuration of the current backup not in sync with the data source"));
     }
     /*$tables = array(
         	"messagelog" => "lid", 
     	"syslog" => "lid"
         );*/
     $tables = array("messagelog" => "lid");
     $blobs = array();
     $list = $this->req->GetGroups();
     foreach ($list as $greq) {
         $grp = $greq->CreateGroup($this);
         /*	
         	// Support limited backup if time limiting options are set
         	if ($dst_list[$grp->gid]['__internal__']['last']) $from = $dst_list[$grp->gid]['__internal__']['last'];
         	else $from = false;
         
         	if ($src_list[$grp->gid]['__internal__']['last']) $to = $src_list[$grp->gid]['__internal__']['last'];
         	else $to = false;
         
         	if (($to === false)||(($from !== false)&&(abs(round($from) - round($to))<2))) continue;
         
         	if (($from !== false)&&($from > $to))
         	    throw new ADEIException(translate("The backup had newer data than the source does"));
         */
         $stmt = $zeus->db->Query("SELECT MAX(lid), MAX(ts) FROM " . $grp->table);
         $row = $stmt->fetch(PDO::FETCH_NUM);
         if ($row && isset($row[0])) {
             $first_lid = $row[0];
             $first_ts = $row[1];
         } else {
             $first_lid = false;
         }
         if ($first_lid !== false) {
             $stmt = $this->db->Query("SELECT MAX(lid) AS lid FROM " . $grp->table);
             $row = $stmt->fetch(PDO::FETCH_BOTH);
             // FETCH_NUM looks to be corrupted with MSSQL/ODBC
             if ($row && isset($row['lid'])) {
                 $remote_last_lid = $row['lid'];
             } else {
                 $remote_last_lid = false;
             }
             if ($remote_last_lid && $remote_last_lid < $first_lid) {
                 $stmt = $this->db->Query("SELECT MIN(lid) AS lid FROM " . $grp->table . " WHERE ts > " . $first_ts);
                 $row = $stmt->fetch(PDO::FETCH_NUM);
                 if ($row && isset($row['lid'])) {
                     $diff_lid = $first_lid + 1 - $row['lid'];
                 } else {
                     return;
                 }
             } else {
                 $diff_lid = false;
             }
         }
         try {
             if ($first_lid === false) {
                 $src = $this->db->Prepare("SELECT lid,ts,data FROM " . $grp->table . " ORDER by lid ASC");
             } else {
                 if ($diff_lid === false) {
                     $src = $this->db->Prepare("SELECT lid,ts,data FROM " . $grp->table . " WHERE lid > " . $first_lid . " ORDER by lid ASC");
                 } else {
                     $src = $this->db->Prepare("SELECT (lid + {$diff_lid}) AS lid, ts, data FROM " . $grp->table . " WHERE ts > " . $first_ts . " ORDER by lid ASC");
                 }
             }
             /*
             	    if ($from === false) {
             	        $src = $this->db->Prepare("SELECT lid,ts,data FROM " . $grp->table . " ORDER by lid ASC");
             	    } else {
             	        $src = $this->db->Prepare("SELECT lid,ts,data FROM " . $grp->table . " WHERE ts > " . $from . " ORDER by lid ASC");
             	    }
             */
             if (!$src->execute()) {
                 $einfo = $dst->errorInfo();
                 throw new ADEIException("Failure while backing up group " . $grp->gid . ". SQL Error: " . $einfo[0] . ", Driver Error: " . $einfo[1] . ", Message: " . $einfo[2]);
             }
             $src->bindColumn(1, $lid);
             $src->bindColumn(2, $ts);
             $src->bindColumn(3, $data, PDO::PARAM_LOB);
             $dst = $zeus->db->Prepare("INSERT INTO " . $grp->table . " (lid,ts,data) VALUES (?, ?, ?)");
             $dst->bindParam(1, $lid);
             $dst->bindParam(2, $ts);
             $dst->bindParam(3, $data, PDO::PARAM_LOB);
             while ($src->fetch(PDO::FETCH_BOUND)) {
                 //		echo "$lid, $ts\n";
                 if ($pack) {
                     $data = pack("H*", $data);
                 }
                 if (!$dst->execute()) {
                     $einfo = $dst->errorInfo();
                     throw new ADEIException("Failure while backing up group " . $grp->gid . ", item " . $lid . "(" . date("r", ceil($this->ExportUnixTime($ts))) . ") SQL Error: " . $einfo[0] . ", Driver Error: " . $einfo[1] . ", Message: " . $einfo[2]);
                 }
             }
         } catch (PDOException $e) {
             throw new ADEIException(translate("SQL request is failed with error") . ": " . $e->getMessage(), $e->getCode());
         }
     }
     foreach ($tables as $table => $id) {
         if ($pack) {
             $cur_blobs = $blobs[$table];
         } else {
             $cur_blobs = false;
         }
         $stmt = $zeus->db->Query("SELECT MAX({$id}) FROM " . $table);
         $row = $stmt->fetch(PDO::FETCH_NUM);
         if ($row && isset($row[0])) {
             $first_lid = $row[0];
         } else {
             $first_lid = false;
         }
         if ($first_lid === false) {
             $src = $this->db->Prepare("SELECT * FROM {$table} ORDER BY {$id} ASC");
         } else {
             $src = $this->db->Prepare("SELECT * FROM {$table} WHERE {$id} > {$first_lid} ORDER BY {$id} ASC");
         }
         $src->execute();
         while ($row = $src->fetch(PDO::FETCH_NUM)) {
             $query = "INSERT INTO {$table} VALUES(";
             foreach ($row as $i => $value) {
                 if ($cur_blobs && in_array($i, $cur_blobs)) {
                     if ($i) {
                         $query .= ", 0x{$value}";
                     } else {
                         $query .= "0x{$value}";
                     }
                 } else {
                     if ($i) {
                         $query .= ", \"{$value}\"";
                     } else {
                         $query .= "\"{$value}\"";
                     }
                 }
             }
             $zeus->db->Query("{$query})");
         }
     }
     $lock->UnLock();
     unset($lock);
 }