Пример #1
0
 /**
  * LOAD
  * Begins the processing for replace logic
  * @param mysql  $conn			The db connection object
  * @param array  $list			Key value pair of 'search' and 'replace' arrays
  * @param array  $tables		The tables we want to look at
  * @param array  $fullsearch    Search every column reguardless of its data type
  * @return array Collection of information gathered during the run.
  */
 public static function load($conn, $list = array(), $tables = array(), $fullsearch = false)
 {
     $report = array('scan_tables' => 0, 'scan_rows' => 0, 'scan_cells' => 0, 'updt_tables' => 0, 'updt_rows' => 0, 'updt_cells' => 0, 'errsql' => array(), 'errser' => array(), 'errkey' => array(), 'errsql_sum' => 0, 'errser_sum' => 0, 'errkey_sum' => 0, 'time' => '', 'err_all' => 0);
     $walk_function = create_function('&$str', '$str = "`$str`";');
     $profile_start = DUPX_Util::get_microtime();
     if (is_array($tables) && !empty($tables)) {
         foreach ($tables as $table) {
             $report['scan_tables']++;
             $columns = array();
             // Get a list of columns in this table
             $fields = mysqli_query($conn, 'DESCRIBE ' . $table);
             while ($column = mysqli_fetch_array($fields)) {
                 $columns[$column['Field']] = $column['Key'] == 'PRI' ? true : false;
             }
             // Count the number of rows we have in the table if large we'll split into blocks
             $row_count = mysqli_query($conn, "SELECT COUNT(*) FROM `{$table}`");
             $rows_result = mysqli_fetch_array($row_count);
             @mysqli_free_result($row_count);
             $row_count = $rows_result[0];
             if ($row_count == 0) {
                 DUPX_Log::Info("{$table}^ ({$row_count})");
                 continue;
             }
             $page_size = 25000;
             $offset = $page_size + 1;
             $pages = ceil($row_count / $page_size);
             // Grab the columns of the table.  Only grab text based columns because
             // they are the only data types that should allow any type of search/replace logic
             $colList = '*';
             $colMsg = '*';
             if (!$fullsearch) {
                 $colList = self::getTextColumns($conn, $table);
                 if ($colList != null && is_array($colList)) {
                     array_walk($colList, $walk_function);
                     $colList = implode(',', $colList);
                 }
                 $colMsg = empty($colList) ? '*' : '~';
             }
             if (empty($colList)) {
                 DUPX_Log::Info("{$table}^ ({$row_count})");
                 continue;
             } else {
                 DUPX_Log::Info("{$table}{$colMsg} ({$row_count})");
             }
             //Paged Records
             for ($page = 0; $page < $pages; $page++) {
                 $current_row = 0;
                 $start = $page * $page_size;
                 $end = $start + $page_size;
                 $sql = sprintf("SELECT {$colList} FROM `%s` LIMIT %d, %d", $table, $start, $offset);
                 $data = mysqli_query($conn, $sql);
                 if (!$data) {
                     $report['errsql'][] = mysqli_error($conn);
                 }
                 $scan_count = $row_count < $end ? $row_count : $end;
                 DUPX_Log::Info("\tScan => {$start} of {$scan_count}", 2);
                 //Loops every row
                 while ($row = mysqli_fetch_array($data)) {
                     $report['scan_rows']++;
                     $current_row++;
                     $upd_col = array();
                     $upd_sql = array();
                     $where_sql = array();
                     $upd = false;
                     $serial_err = 0;
                     //Loops every cell
                     foreach ($columns as $column => $primary_key) {
                         $report['scan_cells']++;
                         $edited_data = $data_to_fix = $row[$column];
                         $base64coverted = false;
                         $txt_found = false;
                         //Only replacing string values
                         if (!empty($row[$column]) && !is_numeric($row[$column])) {
                             //Base 64 detection
                             if (base64_decode($row[$column], true)) {
                                 $decoded = base64_decode($row[$column], true);
                                 if (self::is_serialized($decoded)) {
                                     $edited_data = $decoded;
                                     $base64coverted = true;
                                 }
                             }
                             //Skip table cell if match not found
                             foreach ($list as $item) {
                                 if (strpos($edited_data, $item['search']) !== false) {
                                     $txt_found = true;
                                     break;
                                 }
                             }
                             if (!$txt_found) {
                                 continue;
                             }
                             //Replace logic - level 1: simple check on any string or serlized strings
                             foreach ($list as $item) {
                                 $edited_data = self::recursive_unserialize_replace($item['search'], $item['replace'], $edited_data);
                             }
                             //Replace logic - level 2: repair serilized strings that have become broken
                             $serial_check = self::fix_serial_string($edited_data);
                             if ($serial_check['fixed']) {
                                 $edited_data = $serial_check['data'];
                             } elseif ($serial_check['tried'] && !$serial_check['fixed']) {
                                 $serial_err++;
                             }
                         }
                         //Change was made
                         if ($edited_data != $data_to_fix || $serial_err > 0) {
                             $report['updt_cells']++;
                             //Base 64 encode
                             if ($base64coverted) {
                                 $edited_data = base64_encode($edited_data);
                             }
                             $upd_col[] = $column;
                             $upd_sql[] = $column . ' = "' . mysqli_real_escape_string($conn, $edited_data) . '"';
                             $upd = true;
                         }
                         if ($primary_key) {
                             $where_sql[] = $column . ' = "' . mysqli_real_escape_string($conn, $data_to_fix) . '"';
                         }
                     }
                     //PERFORM ROW UPDATE
                     if ($upd && !empty($where_sql)) {
                         $sql = "UPDATE `{$table}` SET " . implode(', ', $upd_sql) . ' WHERE ' . implode(' AND ', array_filter($where_sql));
                         $result = mysqli_query($conn, $sql) or $report['errsql'][] = mysqli_error($conn);
                         //DEBUG ONLY:
                         DUPX_Log::Info("\t{$sql}\n", 3);
                         if ($result) {
                             if ($serial_err > 0) {
                                 $report['errser'][] = "SELECT " . implode(', ', $upd_col) . " FROM `{$table}`  WHERE " . implode(' AND ', array_filter($where_sql)) . ';';
                             }
                             $report['updt_rows']++;
                         }
                     } elseif ($upd) {
                         $report['errkey'][] = sprintf("Row [%s] on Table [%s] requires a manual update.", $current_row, $table);
                     }
                 }
                 DUPX_Util::fcgi_flush();
                 @mysqli_free_result($data);
             }
             if ($upd) {
                 $report['updt_tables']++;
             }
         }
     }
     $profile_end = DUPX_Util::get_microtime();
     $report['time'] = DUPX_Util::elapsed_time($profile_end, $profile_start);
     $report['errsql_sum'] = empty($report['errsql']) ? 0 : count($report['errsql']);
     $report['errser_sum'] = empty($report['errser']) ? 0 : count($report['errser']);
     $report['errkey_sum'] = empty($report['errkey']) ? 0 : count($report['errkey']);
     $report['err_all'] = $report['errsql_sum'] + $report['errser_sum'] + $report['errkey_sum'];
     return $report;
 }
Пример #2
0
        //Check to make sure the connection is alive
        if (!empty($err)) {
            if (!mysqli_ping($dbh)) {
                mysqli_close($dbh);
                $dbh = DUPX_Util::db_connect($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpass'], $_POST['dbname'], $_POST['dbport']);
                // Reset session setup
                @mysqli_query($dbh, "SET wait_timeout = {$GLOBALS['DB_MAX_TIME']}");
                DUPX_Util::mysql_set_charset($dbh, $_POST['dbcharset'], $_POST['dbcollate']);
            }
            DUPX_Log::Info("**ERROR** database error write '{$err}' - [sql=" . substr($sql_result_file_data[$counter], 0, 75) . "...]");
            $dbquery_errs++;
            //Buffer data to browser to keep connection open
        } else {
            if ($fcgi_buffer_count++ > $fcgi_buffer_pool) {
                $fcgi_buffer_count = 0;
                DUPX_Util::fcgi_flush();
            }
            $dbquery_rows++;
        }
    }
    $counter++;
}
@mysqli_commit($dbh);
@mysqli_autocommit($dbh, true);
DUPX_Log::Info("ERRORS FOUND:\t{$dbquery_errs}");
DUPX_Log::Info("DROP TABLE:\t{$drop_log}");
DUPX_Log::Info("QUERIES RAN:\t{$dbquery_rows}\n");
$dbtable_count = 0;
if ($result = mysqli_query($dbh, "SHOW TABLES")) {
    while ($row = mysqli_fetch_array($result, MYSQLI_NUM)) {
        $table_rows = DUPX_Util::table_row_count($dbh, $row[0]);