phpbb\convert\convertor::convert_data PHP Method

convert_data() public method

The function which does the actual work (or dispatches it to the relevant places)
public convert_data ( $converter )
    function convert_data($converter)
    {
        global $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache, $auth;
        global $convert, $convert_row, $message_parser, $skip_rows, $language;
        global $request, $phpbb_dispatcher;
        $phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx);
        extract($phpbb_config_php_file->get_all());
        require_once $phpbb_root_path . 'includes/constants.' . $phpEx;
        require_once $phpbb_root_path . 'includes/functions_convert.' . $phpEx;
        $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
        /** @var \phpbb\db\driver\driver_interface $db */
        $db = new $dbms();
        $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
        unset($dbpasswd);
        // We need to fill the config to let internal functions correctly work
        $config = new \phpbb\config\db($db, new \phpbb\cache\driver\dummy(), CONFIG_TABLE);
        // Override a couple of config variables for the duration
        $config['max_quote_depth'] = 0;
        // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
        $config['max_post_chars'] = $config['min_post_chars'] = 0;
        // Set up a user as well. We _should_ have enough of a database here at this point to do this
        // and it helps for any core code we call
        $user->session_begin();
        $user->page = $user->extract_current_page($phpbb_root_path);
        $convert->options = array();
        if (isset($config['convert_progress'])) {
            $convert->options = unserialize($config['convert_progress']);
            $convert->options = array_merge($convert->options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
        }
        // This information should have already been checked once, but do it again for safety
        if (empty($convert->options) || empty($convert->options['tag']) || !isset($convert->options['dbms']) || !isset($convert->options['dbhost']) || !isset($convert->options['dbport']) || !isset($convert->options['dbuser']) || !isset($convert->options['dbpasswd']) || !isset($convert->options['dbname']) || !isset($convert->options['table_prefix'])) {
            $this->error($user->lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
        }
        $this->template->assign_var('S_CONV_IN_PROGRESS', true);
        // Make some short variables accessible, for easier referencing
        $convert->convertor_tag = basename($convert->options['tag']);
        $convert->src_dbms = $convert->options['dbms'];
        $convert->src_dbhost = $convert->options['dbhost'];
        $convert->src_dbport = $convert->options['dbport'];
        $convert->src_dbuser = $convert->options['dbuser'];
        $convert->src_dbpasswd = $convert->options['dbpasswd'];
        $convert->src_dbname = $convert->options['dbname'];
        $convert->src_table_prefix = $convert->options['table_prefix'];
        // initiate database connection to old db if old and new db differ
        global $src_db, $same_db;
        $src_db = $same_db = null;
        if ($convert->src_dbms != $dbms || $convert->src_dbhost != $dbhost || $convert->src_dbport != $dbport || $convert->src_dbname != $dbname || $convert->src_dbuser != $dbuser) {
            $dbms = $convert->src_dbms;
            /** @var \phpbb\db\driver\driver $src_db */
            $src_db = new $dbms();
            $src_db->sql_connect($convert->src_dbhost, $convert->src_dbuser, htmlspecialchars_decode($convert->src_dbpasswd), $convert->src_dbname, $convert->src_dbport, false, true);
            $same_db = false;
        } else {
            $src_db = $db;
            $same_db = true;
        }
        $convert->mysql_convert = false;
        switch ($src_db->sql_layer) {
            case 'sqlite3':
                $convert->src_truncate_statement = 'DELETE FROM ';
                break;
                // Thanks MySQL, for silently converting...
            // Thanks MySQL, for silently converting...
            case 'mysql':
            case 'mysql4':
                if (version_compare($src_db->sql_server_info(true, false), '4.1.3', '>=')) {
                    $convert->mysql_convert = true;
                }
                $convert->src_truncate_statement = 'TRUNCATE TABLE ';
                break;
            case 'mysqli':
                $convert->mysql_convert = true;
                $convert->src_truncate_statement = 'TRUNCATE TABLE ';
                break;
            default:
                $convert->src_truncate_statement = 'TRUNCATE TABLE ';
                break;
        }
        if ($convert->mysql_convert && !$same_db) {
            $src_db->sql_query("SET NAMES 'binary'");
        }
        switch ($db->get_sql_layer()) {
            case 'sqlite3':
                $convert->truncate_statement = 'DELETE FROM ';
                break;
            default:
                $convert->truncate_statement = 'TRUNCATE TABLE ';
                break;
        }
        $get_info = false;
        // check security implications of direct inclusion
        if (!file_exists('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx)) {
            $this->error($user->lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
        }
        if (file_exists('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx)) {
            include_once './convertors/functions_' . $convert->convertor_tag . '.' . $phpEx;
        }
        $get_info = true;
        include './convertors/convert_' . $convert->convertor_tag . '.' . $phpEx;
        // Map some variables...
        $convert->convertor_data = $convertor_data;
        $convert->tables = $tables;
        $convert->config_schema = $config_schema;
        // Now include the real data
        $get_info = false;
        include './convertors/convert_' . $convert->convertor_tag . '.' . $phpEx;
        $convert->convertor_data = $convertor_data;
        $convert->tables = $tables;
        $convert->config_schema = $config_schema;
        $convert->convertor = $convertor;
        // The test_file is a file that should be present in the location of the old board.
        if (!file_exists($convert->options['forum_path'] . '/' . $test_file)) {
            $this->error(sprintf($user->lang['COULD_NOT_FIND_PATH'], $convert->options['forum_path']), __LINE__, __FILE__);
        }
        $search_type = $config['search_type'];
        // For conversions we are a bit less strict and set to a search backend we know exist...
        if (!class_exists($search_type)) {
            $search_type = '\\phpbb\\search\\fulltext_native';
            $config->set('search_type', $search_type);
        }
        if (!class_exists($search_type)) {
            trigger_error('NO_SUCH_SEARCH_MODULE');
        }
        $error = false;
        $convert->fulltext_search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
        if ($error) {
            trigger_error($error);
        }
        include_once $phpbb_root_path . 'includes/message_parser.' . $phpEx;
        $message_parser = new \parse_message();
        $jump = $request->variable('jump', 0);
        $final_jump = $request->variable('final_jump', 0);
        $sync_batch = $request->variable('sync_batch', -1);
        $last_statement = $request->variable('last', 0);
        // We are running sync...
        if ($sync_batch >= 0) {
            $this->sync_forums($converter, $sync_batch);
            return;
        }
        if ($jump) {
            $this->jump($converter, $jump, $last_statement);
            return;
        }
        if ($final_jump) {
            $this->final_jump($final_jump);
            return;
        }
        $current_table = $request->variable('current_table', 0);
        $old_current_table = min(-1, $current_table - 1);
        $skip_rows = $request->variable('skip_rows', 0);
        if (!$current_table && !$skip_rows) {
            if (!$request->variable('confirm', false)) {
                // If avatars / ranks / smilies folders are specified make sure they are writable
                $bad_folders = array();
                $local_paths = array('avatar_path' => path($config['avatar_path']), 'avatar_gallery_path' => path($config['avatar_gallery_path']), 'icons_path' => path($config['icons_path']), 'ranks_path' => path($config['ranks_path']), 'smilies_path' => path($config['smilies_path']));
                foreach ($local_paths as $folder => $local_path) {
                    if (isset($convert->convertor[$folder])) {
                        if (empty($convert->convertor['test_file'])) {
                            // test_file is mandantory at the moment so this should never be reached, but just in case...
                            $this->error($user->lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
                        }
                        if (!$local_path || !$this->filesystem->is_writable($phpbb_root_path . $local_path)) {
                            if (!$local_path) {
                                $bad_folders[] = sprintf($user->lang['CONFIG_PHPBB_EMPTY'], $folder);
                            } else {
                                $bad_folders[] = $local_path;
                            }
                        }
                    }
                }
                if (sizeof($bad_folders)) {
                    $msg = sizeof($bad_folders) == 1 ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
                    sort($bad_folders);
                    $this->error(sprintf($msg, implode('<br />', $bad_folders)), __LINE__, __FILE__, true);
                    $this->template->assign_vars(array('L_SUBMIT' => $user->lang['INSTALL_TEST'], 'U_ACTION' => $this->controller_helper->route('phpbb_convert_convert', array('converter' => $converter))));
                    return;
                }
                // Grab all the tables used in convertor
                $missing_tables = $tables_list = $aliases = array();
                foreach ($convert->convertor['schema'] as $schema) {
                    // Skip those not used (because of addons/plugins not detected)
                    if (!$schema['target']) {
                        continue;
                    }
                    foreach ($schema as $key => $val) {
                        // we're dealing with an array like:
                        // array('forum_status',			'forums.forum_status',				'is_item_locked')
                        if (is_int($key) && !empty($val[1])) {
                            $temp_data = $val[1];
                            if (!is_array($temp_data)) {
                                $temp_data = array($temp_data);
                            }
                            foreach ($temp_data as $value) {
                                if (preg_match('/([a-z0-9_]+)\\.([a-z0-9_]+)\\)* ?A?S? ?([a-z0-9_]*?)\\.?([a-z0-9_]*)$/i', $value, $m)) {
                                    $table = $convert->src_table_prefix . $m[1];
                                    $tables_list[$table] = $table;
                                    if (!empty($m[3])) {
                                        $aliases[] = $convert->src_table_prefix . $m[3];
                                    }
                                }
                            }
                        } else {
                            if ($key == 'left_join') {
                                // Convert the value if it wasn't an array already.
                                if (!is_array($val)) {
                                    $val = array($val);
                                }
                                for ($j = 0, $size = sizeof($val); $j < $size; ++$j) {
                                    if (preg_match('/LEFT JOIN ([a-z0-9_]+) AS ([a-z0-9_]+)/i', $val[$j], $m)) {
                                        $table = $convert->src_table_prefix . $m[1];
                                        $tables_list[$table] = $table;
                                        if (!empty($m[2])) {
                                            $aliases[] = $convert->src_table_prefix . $m[2];
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                // Remove aliased tables from $tables_list
                foreach ($aliases as $alias) {
                    unset($tables_list[$alias]);
                }
                // Check if the tables that we need exist
                $src_db->sql_return_on_error(true);
                foreach ($tables_list as $table => $null) {
                    $sql = 'SELECT 1 FROM ' . $table;
                    $_result = $src_db->sql_query_limit($sql, 1);
                    if (!$_result) {
                        $missing_tables[] = $table;
                    }
                    $src_db->sql_freeresult($_result);
                }
                $src_db->sql_return_on_error(false);
                // Throw an error if some tables are missing
                // We used to do some guessing here, but since we have a suggestion of possible values earlier, I don't see it adding anything here to do it again
                if (sizeof($missing_tables) == sizeof($tables_list)) {
                    $this->error($user->lang['NO_TABLES_FOUND'] . ' ' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
                } else {
                    if (sizeof($missing_tables)) {
                        $this->error(sprintf($user->lang['TABLES_MISSING'], implode($user->lang['COMMA_SEPARATOR'], $missing_tables)) . '<br /><br />' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
                    }
                }
                $url = $this->save_convert_progress($converter, 'confirm=1');
                $msg = $user->lang['PRE_CONVERT_COMPLETE'];
                if ($convert->convertor_data['author_notes']) {
                    $msg .= '</p><p>' . sprintf($user->lang['AUTHOR_NOTES'], $convert->convertor_data['author_notes']);
                }
                $this->template->assign_vars(array('L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], 'BODY' => $msg, 'U_ACTION' => $url));
                return;
            }
            // if (!$request->variable('confirm', false)))
            $this->template->assign_block_vars('checks', array('S_LEGEND' => true, 'LEGEND' => $user->lang['STARTING_CONVERT']));
            // Convert the config table and load the settings of the old board
            if (!empty($convert->config_schema)) {
                restore_config($convert->config_schema);
                // Override a couple of config variables for the duration
                $config['max_quote_depth'] = 0;
                // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
                $config['max_post_chars'] = $config['min_post_chars'] = 0;
            }
            $this->template->assign_block_vars('checks', array('TITLE' => $user->lang['CONFIG_CONVERT'], 'RESULT' => $user->lang['DONE']));
            // Now process queries and execute functions that have to be executed prior to the conversion
            if (!empty($convert->convertor['execute_first'])) {
                // @codingStandardsIgnoreStart
                eval($convert->convertor['execute_first']);
                // @codingStandardsIgnoreEnd
            }
            if (!empty($convert->convertor['query_first'])) {
                if (!is_array($convert->convertor['query_first'])) {
                    $convert->convertor['query_first'] = array('target', array($convert->convertor['query_first']));
                } else {
                    if (!is_array($convert->convertor['query_first'][0])) {
                        $convert->convertor['query_first'] = array(array($convert->convertor['query_first'][0], $convert->convertor['query_first'][1]));
                    }
                }
                foreach ($convert->convertor['query_first'] as $query_first) {
                    if ($query_first[0] == 'src') {
                        if ($convert->mysql_convert && $same_db) {
                            $src_db->sql_query("SET NAMES 'binary'");
                        }
                        $src_db->sql_query($query_first[1]);
                        if ($convert->mysql_convert && $same_db) {
                            $src_db->sql_query("SET NAMES 'utf8'");
                        }
                    } else {
                        $db->sql_query($query_first[1]);
                    }
                }
            }
            $this->template->assign_block_vars('checks', array('TITLE' => $user->lang['PREPROCESS_STEP'], 'RESULT' => $user->lang['DONE']));
        }
        // if (!$current_table && !$skip_rows)
        $this->template->assign_block_vars('checks', array('S_LEGEND' => true, 'LEGEND' => $user->lang['FILLING_TABLES']));
        // This loop takes one target table and processes it
        while ($current_table < sizeof($convert->convertor['schema'])) {
            $schema = $convert->convertor['schema'][$current_table];
            // The target table isn't set, this can be because a module (for example the attachement mod) is taking care of this.
            if (empty($schema['target'])) {
                $current_table++;
                continue;
            }
            $this->template->assign_block_vars('checks', array('TITLE' => sprintf($user->lang['FILLING_TABLE'], $schema['target'])));
            // This is only the case when we first start working on the tables.
            if (!$skip_rows) {
                // process execute_first and query_first for this table...
                if (!empty($schema['execute_first'])) {
                    // @codingStandardsIgnoreStart
                    eval($schema['execute_first']);
                    // @codingStandardsIgnoreEnd
                }
                if (!empty($schema['query_first'])) {
                    if (!is_array($schema['query_first'])) {
                        $schema['query_first'] = array('target', array($schema['query_first']));
                    } else {
                        if (!is_array($schema['query_first'][0])) {
                            $schema['query_first'] = array(array($schema['query_first'][0], $schema['query_first'][1]));
                        }
                    }
                    foreach ($schema['query_first'] as $query_first) {
                        if ($query_first[0] == 'src') {
                            if ($convert->mysql_convert && $same_db) {
                                $src_db->sql_query("SET NAMES 'binary'");
                            }
                            $src_db->sql_query($query_first[1]);
                            if ($convert->mysql_convert && $same_db) {
                                $src_db->sql_query("SET NAMES 'utf8'");
                            }
                        } else {
                            $db->sql_query($query_first[1]);
                        }
                    }
                }
                if (!empty($schema['autoincrement'])) {
                    switch ($db->get_sql_layer()) {
                        case 'postgres':
                            $db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
                            break;
                        case 'oracle':
                            $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
                            $row = $db->sql_fetchrow($result);
                            $db->sql_freeresult($result);
                            $largest_id = (int) $row['max_id'];
                            if ($largest_id) {
                                $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
                                $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
                            }
                            break;
                    }
                }
            }
            // Process execute_always for this table
            // This is for code which needs to be executed on every pass of this table if
            // it gets split because of time restrictions
            if (!empty($schema['execute_always'])) {
                // @codingStandardsIgnoreStart
                eval($schema['execute_always']);
                // @codingStandardsIgnoreEnd
            }
            //
            // Set up some variables
            //
            // $waiting_rows	holds rows for multirows insertion (MySQL only)
            // $src_tables		holds unique tables with aliases to select from
            // $src_fields		will quickly refer source fields (or aliases) corresponding to the current index
            // $select_fields	holds the names of the fields to retrieve
            //
            $sql_data = array('source_fields' => array(), 'target_fields' => array(), 'source_tables' => array(), 'select_fields' => array());
            // This statement is building the keys for later insertion.
            $insert_query = $this->build_insert_query($schema, $sql_data, $current_table);
            // If no source table is affected, we skip the table
            if (empty($sql_data['source_tables'])) {
                $skip_rows = 0;
                $current_table++;
                continue;
            }
            $distinct = !empty($schema['distinct']) ? 'DISTINCT ' : '';
            $sql = 'SELECT ' . $distinct . implode(', ', $sql_data['select_fields']) . " \nFROM " . implode(', ', $sql_data['source_tables']);
            // Where
            $sql .= !empty($schema['where']) ? "\nWHERE (" . $schema['where'] . ')' : '';
            // Group By
            if (!empty($schema['group_by'])) {
                $schema['group_by'] = array($schema['group_by']);
                foreach ($sql_data['select_fields'] as $select) {
                    $alias = strpos(strtolower($select), ' as ');
                    $select = $alias ? substr($select, 0, $alias) : $select;
                    if (!in_array($select, $schema['group_by'])) {
                        $schema['group_by'][] = $select;
                    }
                }
            }
            $sql .= !empty($schema['group_by']) ? "\nGROUP BY " . implode(', ', $schema['group_by']) : '';
            // Having
            $sql .= !empty($schema['having']) ? "\nHAVING " . $schema['having'] : '';
            // Order By
            if (empty($schema['order_by']) && !empty($schema['primary'])) {
                $schema['order_by'] = $schema['primary'];
            }
            $sql .= !empty($schema['order_by']) ? "\nORDER BY " . $schema['order_by'] : '';
            // Counting basically holds the amount of rows processed.
            $counting = -1;
            $batch_time = 0;
            while ($counting === -1 || $counting >= $convert->batch_size && still_on_time()) {
                $old_current_table = $current_table;
                $rows = '';
                $waiting_rows = array();
                if (!empty($batch_time)) {
                    $mtime = explode(' ', microtime());
                    $mtime = $mtime[0] + $mtime[1];
                    $rows = ceil($counting / ($mtime - $batch_time)) . " rows/s ({$counting} rows) | ";
                }
                $this->template->assign_block_vars('checks', array('TITLE' => "skip_rows = {$skip_rows}", 'RESULT' => $rows . (defined('DEBUG') && function_exists('memory_get_usage') ? ceil(memory_get_usage() / 1024) . ' ' . $user->lang['KIB'] : '')));
                $mtime = explode(' ', microtime());
                $batch_time = $mtime[0] + $mtime[1];
                if ($convert->mysql_convert && $same_db) {
                    $src_db->sql_query("SET NAMES 'binary'");
                }
                // Take skip rows into account and only fetch batch_size amount of rows
                $___result = $src_db->sql_query_limit($sql, $convert->batch_size, $skip_rows);
                if ($convert->mysql_convert && $same_db) {
                    $src_db->sql_query("SET NAMES 'utf8'");
                }
                // This loop processes each row
                $counting = 0;
                $convert->row = $convert_row = array();
                if (!empty($schema['autoincrement'])) {
                    switch ($db->get_sql_layer()) {
                        case 'mssql_odbc':
                        case 'mssqlnative':
                            $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' ON');
                            break;
                    }
                }
                // Now handle the rows until time is over or no more rows to process...
                while ($counting === 0 || still_on_time()) {
                    $convert_row = $src_db->sql_fetchrow($___result);
                    if (!$convert_row) {
                        // move to the next batch or table
                        break;
                    }
                    // With this we are able to always save the last state
                    $convert->row = $convert_row;
                    // Increment the counting variable, it stores the number of rows we have processed
                    $counting++;
                    $insert_values = array();
                    $sql_flag = $this->process_row($schema, $sql_data, $insert_values);
                    if ($sql_flag === true) {
                        switch ($db->get_sql_layer()) {
                            // If MySQL, we'll wait to have num_wait_rows rows to submit at once
                            case 'mysql':
                            case 'mysql4':
                            case 'mysqli':
                                $waiting_rows[] = '(' . implode(', ', $insert_values) . ')';
                                if (sizeof($waiting_rows) >= $convert->num_wait_rows) {
                                    $errored = false;
                                    $db->sql_return_on_error(true);
                                    if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) {
                                        $errored = true;
                                    }
                                    $db->sql_return_on_error(false);
                                    if ($errored) {
                                        $db->sql_return_on_error(true);
                                        // Because it errored out we will try to insert the rows one by one... most of the time this
                                        // is caused by duplicate entries - but we also do not want to miss one...
                                        foreach ($waiting_rows as $waiting_sql) {
                                            if (!$db->sql_query($insert_query . $waiting_sql)) {
                                                $this->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                                            }
                                        }
                                        $db->sql_return_on_error(false);
                                    }
                                    $waiting_rows = array();
                                }
                                break;
                            default:
                                $insert_sql = $insert_query . '(' . implode(', ', $insert_values) . ')';
                                $db->sql_return_on_error(true);
                                if (!$db->sql_query($insert_sql)) {
                                    $this->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                                }
                                $db->sql_return_on_error(false);
                                $waiting_rows = array();
                                break;
                        }
                    }
                    $skip_rows++;
                }
                $src_db->sql_freeresult($___result);
                // We might still have some rows waiting
                if (sizeof($waiting_rows)) {
                    $errored = false;
                    $db->sql_return_on_error(true);
                    if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) {
                        $errored = true;
                    }
                    $db->sql_return_on_error(false);
                    if ($errored) {
                        $db->sql_return_on_error(true);
                        // Because it errored out we will try to insert the rows one by one... most of the time this
                        // is caused by duplicate entries - but we also do not want to miss one...
                        foreach ($waiting_rows as $waiting_sql) {
                            $db->sql_query($insert_query . $waiting_sql);
                            $this->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                        }
                        $db->sql_return_on_error(false);
                    }
                    $waiting_rows = array();
                }
                if (!empty($schema['autoincrement'])) {
                    switch ($db->get_sql_layer()) {
                        case 'mssql_odbc':
                        case 'mssqlnative':
                            $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' OFF');
                            break;
                        case 'postgres':
                            $db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
                            break;
                        case 'oracle':
                            $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
                            $row = $db->sql_fetchrow($result);
                            $db->sql_freeresult($result);
                            $largest_id = (int) $row['max_id'];
                            if ($largest_id) {
                                $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
                                $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
                            }
                            break;
                    }
                }
            }
            // When we reach this point, either the current table has been processed or we're running out of time.
            if (still_on_time() && $counting < $convert->batch_size) {
                $skip_rows = 0;
                $current_table++;
            } else {
                /*
                				if (still_on_time() && $counting < $convert->batch_size)
                				{
                					$skip_rows = 0;
                					$current_table++;
                				}*/
                // Looks like we ran out of time.
                $url = $this->save_convert_progress($converter, 'current_table=' . $current_table . '&amp;skip_rows=' . $skip_rows);
                $current_table++;
                //				$percentage = ($skip_rows == 0) ? 0 : floor(100 / ($total_rows / $skip_rows));
                $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $current_table, sizeof($convert->convertor['schema']));
                $this->template->assign_vars(array('BODY' => $msg, 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], 'U_ACTION' => $url));
                $this->meta_refresh($url);
                return;
            }
        }
        // Process execute_last then we'll be done
        $url = $this->save_convert_progress($converter, 'jump=1');
        $this->template->assign_vars(array('L_SUBMIT' => $user->lang['FINAL_STEP'], 'U_ACTION' => $url));
        $this->meta_refresh($url);
        return;
    }