Exemple #1
0
function fs_db_install(&$fsdb)
{
    $fsdb->hide_errors();
    $version_table = fs_version_table();
    $hits_table = fs_hits_table();
    $useragents_table = fs_useragents_table();
    $sql = "\n\t\tCREATE TABLE IF NOT EXISTS {$hits_table}\n\t\t(\n\t\t\t`id` INTEGER PRIMARY KEY AUTO_INCREMENT " . fs_comment('Primary key') . ",\n\t\t\t`site_id` INTEGER default 1 " . fs_comment('Source site ID, defaults to site 0') . ",\n\t\t\t`ip` VARCHAR(40) NOT NULL DEFAULT 'unknown' " . fs_comment('IP Address of hit source') . ",\n\t\t\t`timestamp` DATETIME NOT NULL " . fs_comment('Hit timestamp') . ",\n\t\t\t`url_id` INTEGER " . fs_comment('Hit URL ID') . ",\n\t\t\t`referer_id` INTEGER " . fs_comment('Referer URL id') . ",\n\t\t\t`useragent_id` INTEGER " . fs_comment('UserAgent ID') . ",\n\t\t\t`session_id` VARCHAR(30) " . fs_comment('Client session ID') . ",\n\t\t\t`user_id` INTEGER default NULL " . fs_comment('User ID in the enclosing system, NULL for unknown user') . ",\n\t\t\t`country_code` INT(4) default NULL " . fs_comment('Country code of IP address or NULL if unknown') . ",\n\t\t\t`excluded_by_user` TINYINT(1) DEFAULT 0 " . fs_comment('1 if user explicitly excluded record, 0 otherwise') . ",\n\t\t\t`excluded_ip` TINYINT(1) DEFAULT 0 " . fs_comment('1 if the ip is in the excluded ips table, 0 otherwise') . ",\n\t\t\t`excluded_user` TINYINT(1) DEFAULT 0 " . fs_comment('1 if the user id is in the excluded users table, 0 otherwise') . ",\n\t\t\tINDEX (`site_id`)\n\t\t)\n\t\t" . fs_comment('Hits table') . fs_engine("InnoDB");
    if ($fsdb->query($sql) === FALSE) {
        $fsdb->debug();
        return false;
    }
    $r = $fsdb->query("CREATE TABLE IF NOT EXISTS `{$useragents_table}`\n\t\t(\n\t\t\tid INTEGER PRIMARY KEY AUTO_INCREMENT " . fs_comment('Primary key') . ", \n\t\t\tuseragent TEXT " . fs_comment('Useragent string') . ",\n\t\t\tmd5 CHAR(32) NOT NULL,\n\t\t\tmatch_bots INTEGER DEFAULT 0 " . fs_comment('Number of matching bots (useragent wildcards), if 0 the useragent is not exluded') . ",\n\t\t\tUNIQUE(`md5`)\n\t\t) " . fs_comment('User-Agents table') . fs_engine("InnoDB"));
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    $urls_table = fs_urls_table();
    $r = $fsdb->query("CREATE TABLE IF NOT EXISTS {$urls_table}\n\t\t(\n\t\t\t`id` INTEGER PRIMARY KEY AUTO_INCREMENT " . fs_comment('Primary key') . ",\n\t\t\t`url` TEXT,\n\t\t\t`site_id` INT NULL,\n\t\t\t`md5` CHAR(32) NOT NULL,\n\t\t\t`host` VARCHAR( 40 ) NULL DEFAULT NULL, \n\t\t\t`search_engine_id` SMALLINT NULL DEFAULT NULL " . fs_comment('Search engine ID') . ",\n\t\t\t`search_terms` VARCHAR( 255 ) NULL DEFAULT NULL " . fs_comment('Search terms') . ",\n\t\t\t`title` VARCHAR( 255 ) NULL DEFAULT NULL " . fs_comment('Optional title, or NULL for unkown') . ",\n\t\t\t`type` INT NULL DEFAULT NULL " . fs_comment('Optional type, or NULL for unkown') . ",\n\t\t\t`add_time` DATETIME NOT NULL " . fs_comment('Time this url was added') . ",\n\t\t\tUNIQUE(`md5`),\n\t\t\tINDEX (`search_engine_id`),\n\t\t\tINDEX (`host`),\n\t\t\tINDEX (`type`)\n\t\t) " . fs_comment('Referers table') . fs_engine("InnoDB"));
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    $excluded_ip_table = fs_excluded_ips_table();
    $r = $fsdb->query("CREATE TABLE IF NOT EXISTS {$excluded_ip_table}\n\t\t(\n\t\t\tid INTEGER PRIMARY KEY AUTO_INCREMENT " . fs_comment('Primary key') . ",\n\t\t\tip VARCHAR(16) NOT NULL\n\t\t) " . fs_comment('List of excluded ips') . fs_engine("InnoDB"));
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    $bots_table = fs_bots_table();
    $r = $fsdb->query("CREATE TABLE IF NOT EXISTS {$bots_table}\n\t\t(\n\t\t\tid INTEGER PRIMARY KEY AUTO_INCREMENT " . fs_comment('Primary key') . ",\n\t\t\twildcard VARCHAR(100) NOT NULL " . fs_comment('Bots wildcard') . "\n\t\t) " . fs_comment('Bots table') . fs_engine("InnoDB"));
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    if (!fs_create_options_table($fsdb)) {
        return false;
    }
    if (!fs_create_sites_table($fsdb)) {
        return false;
    }
    if (!fs_create_archive_tables($fsdb)) {
        return false;
    }
    if (!fs_create_users_table($fsdb)) {
        return false;
    }
    if (!fs_create_pending_data_table($fsdb)) {
        return false;
    }
    if (!fs_create_url_metadata($fsdb)) {
        return false;
    }
    $r = $fsdb->query("CREATE TABLE IF NOT EXISTS `{$version_table}`\n\t(\n\t\t\tversion INTEGER NOT NULL PRIMARY KEY\n\t)" . fs_comment('FireStats datbase schema version') . fs_engine("InnoDB"));
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    $r = $fsdb->query("INSERT INTO `{$version_table}` (`version`) VALUES('" . FS_REQUIRED_DB_VERSION . "')");
    if ($r === FALSE) {
        $fsdb->debug();
        return false;
    }
    return true;
}
Exemple #2
0
function fs_db_upgrade_11(&$fsdb, $db_version)
{
    $r = fs_create_users_table($fsdb);
    if ($r === FALSE) {
        echo fs_db_error();
        return false;
    }
    $options = fs_options_table();
    $referers = fs_table_prefix() . 'firestats_referers';
    // deprecated table, function no longer exists.
    $urls = fs_urls_table();
    $hits = fs_hits_table();
    $archive_pages = fs_archive_pages();
    $archive_ranges = fs_archive_ranges();
    $user_id_missing = fs_column_not_exists($fsdb, $options, 'user_id');
    $sqls = array(fs_index_exists($fsdb, $options, 'option_key'), "ALTER TABLE `{$options}` DROP INDEX `option_key`", fs_column_exists($fsdb, $options, 'id'), "ALTER TABLE `{$options}` DROP `id`", $user_id_missing, "ALTER TABLE `{$options}` ADD `user_id` INT NOT NULL FIRST", fs_index_not_exists($fsdb, $options, 'user_id_option_key_unique'), "ALTER TABLE `{$options}` ADD UNIQUE `user_id_option_key_unique` ( `user_id`,`option_key`)", fs_column_exists($fsdb, $referers, 'referer'), "ALTER TABLE `{$referers}` CHANGE `referer` `url` TEXT NULL DEFAULT NULL", fs_column_not_exists($fsdb, $referers, 'site_id'), "ALTER TABLE `{$referers}` ADD `site_id` INT NULL AFTER `url`", fs_column_not_exists($fsdb, $urls, 'site_id'), "ALTER TABLE `{$urls}` ADD `site_id` INT NULL AFTER `url`", fs_column_not_exists($fsdb, $urls, 'new_url_id'), "ALTER TABLE `{$urls}` ADD `new_url_id` INT NULL", fs_column_not_exists($fsdb, $referers, 'title'), "ALTER TABLE `{$referers}` ADD `title` VARCHAR( 255 ) NULL DEFAULT NULL", fs_column_not_exists($fsdb, $referers, 'type'), "ALTER TABLE `{$referers}` ADD `type` INT NULL DEFAULT NULL", fs_index_not_exists($fsdb, $referers, 'type'), "ALTER TABLE `{$referers}` ADD INDEX `type` (`type`)", fs_column_not_exists($fsdb, $referers, 'add_time'), "ALTER TABLE `{$referers}` ADD `add_time` DATETIME NOT NULL");
    if (!fs_apply_db_upgrade($fsdb, $sqls)) {
        return false;
    }
    // if created user id, change the following options to system options.
    if ($user_id_missing) {
        $system_options = array('firestats_id', 'first_run_time', 'archive_method', 'botlist_last_version_check_time', 'botlist_last_version_info_on_server', 'botlist_version_check_enabled', 'botlist_version_hash', 'firestats_last_version_check_time', 'firestats_last_version_info_on_server', 'firestats_version_check_enabled', 'ip-to-country-db_last_version_check_time', 'ip-to-country-db_last_version_info_on_server', 'ip-to-country-db_version_check_enabled', 'archive_method', 'archive_older_than', 'auto_bots_list_update', 'last_sent_sysinfo', 'user_agreed_to_send_system_information', 'last_version_check_time');
        foreach ($system_options as $opt) {
            $sql = "UPDATE `{$options}` SET `user_id` = '-1' WHERE `option_key`= '{$opt}'";
            if (false === $fsdb->query($sql)) {
                echo fs_db_error();
                return false;
            }
        }
    }
    if (!fs_create_pending_data_table($fsdb)) {
        return false;
    }
    if (!fs_create_url_metadata($fsdb)) {
        return false;
    }
    $fsdb->query("START TRANSACTION");
    if (fs_mysql_newer_than("4.1.0")) {
        // pupulate current urls table with site ids based on urls in the hits table.
        $sql = "UPDATE `{$urls}` u,\n\t\t\t\t   (SELECT DISTINCT(u.id) url_id,h.site_id FROM `{$urls}` u,`{$hits}` h WHERE u.id = h.url_id ORDER BY `timestamp` DESC) k \n\t\t\t\tSET u.site_id = k.site_id \n\t\t\t\tWHERE u.id = k.url_id";
        $r = $fsdb->query($sql);
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
        // pupulate current urls table with site ids based on urls in the archive pages table.
        // this step is not needed for mysql < 4.1.0 because we only support archving for mysql > 4.1.14
        $sql = "UPDATE `{$urls}` u,(SELECT site_id, url_id, max(range_start) from `{$archive_pages}` p, `{$archive_ranges}` r WHERE p.range_id = r.range_id GROUP BY url_id) k \n\t\t\t\tSET u.site_id = k.site_id WHERE u.id = k.url_id";
        $r = $fsdb->query($sql);
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
    } else {
        // mysql 4.0 does not support nested update-selects. need to update them one by one.
        // get site ids of urls
        $sql = "SELECT DISTINCT(u.id) url_id,h.site_id FROM `{$urls}` u,`{$hits}` h WHERE u.id = h.url_id ORDER BY `timestamp` DESC";
        $res = $fsdb->get_results($sql);
        if ($res === FALSE) {
            echo fs_db_error(true);
            return false;
        }
        // pupulate current urls table with site ids.
        foreach ($res as $u) {
            $sql = "UPDATE `{$urls}` u SET u.site_id = '{$u->site_id}' WHERE u.id = {$u->url_id}";
            $r = $fsdb->query($sql);
            if ($r === FALSE) {
                echo fs_db_error(true);
                return false;
            }
        }
    }
    // insert all urls in urls table into referrers table, along with their corrosponding site_id
    $sql = "INSERT IGNORE INTO `{$referers}` (`url`,`md5`) SELECT url,MD5(url) FROM `{$urls}`";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // set the site id in the referrers table for urls that were in the urls table.
    $sql = "UPDATE `{$referers}` r, `{$urls}` u SET r.site_id = u.site_id WHERE u.md5 = r.md5";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // update host column of referrers table (lines inserted from urls table does not contain them).
    $sql = "UPDATE `{$referers}` SET `host`=substring_index(substring_index(`url`,'/',3),'/',-1) WHERE `url` REGEXP 'http://.*'";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // populate new_url_id row in urls table based on the url id in the referrers table
    $sql = "UPDATE `{$urls}` u,`{$referers}` r SET `new_url_id`= r.id WHERE MD5(u.url) = r.md5";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // update add_time for existing urls.
    if (fs_mysql_newer_than("4.1.0")) {
        // set add_time to urls in the urls table
        $select = "SELECT id,MIN(`timestamp`) `timestamp` FROM (SELECT url_id AS id, MIN(`timestamp`) `timestamp` FROM `{$hits}` GROUP BY `url_id` UNION SELECT `referer_id` AS `id`, MIN(`timestamp`) `timestamp` FROM `{$hits}` GROUP BY `referer_id`) `u`  GROUP BY id";
        $sql = "UPDATE `{$referers}`,({$select}) k SET `add_time` = k.`timestamp` WHERE {$referers}.id = k.id";
        $r = $fsdb->query($sql);
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
        $select = "SELECT id,MIN(`timestamp`) `timestamp` FROM (SELECT url_id AS id, MIN(`timestamp`) `timestamp` FROM `{$hits}` GROUP BY `url_id` UNION SELECT `referer_id` AS `id`, MIN(`timestamp`) `timestamp` FROM `{$hits}` GROUP BY `referer_id`) `u`  GROUP BY id";
        $sql = "UPDATE `{$referers}`,({$select}) k SET `add_time` = k.`timestamp` WHERE {$referers}.id = k.id";
        $r = $fsdb->query($sql);
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
    } else {
        $sql = "SELECT referer_id id, MIN(timestamp) `timestamp` FROM `{$hits}` GROUP BY referer_id LIMIT 10";
        $res = $fsdb->get_results($sql);
        if ($res === FALSE) {
            echo fs_db_error(true);
            return false;
        }
        foreach ($res as $ref) {
            $r = $fsdb->query("UPDATE {$referers} r set r.add_time = '{$ref->timestamp}' WHERE r.id = '{$ref->id}'");
            if ($r === FALSE) {
                echo fs_db_error(true);
                return false;
            }
        }
    }
    // if unique index 'ip' exists in hits table, drop it
    if (fs_index_exists($fsdb, $hits, 'ip')) {
        // drop unique index.
        // in fact, some tests shows that we don't really need it from the performance pov, and I really don't understand why we need
        // it from the uniqueness pov.
        $r = $fsdb->query("ALTER TABLE `{$hits}` DROP INDEX `ip`");
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
    }
    // update hits table with new url ids.
    $sql = "UPDATE `{$hits}` h,`{$urls}` u SET h.url_id = u.new_url_id WHERE h.url_id = u.id";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // if unique index exists in archive pages table, drop it
    if (fs_index_exists($fsdb, $archive_pages, 'index')) {
        // drop unique index for the duration of the update.
        $r = $fsdb->query("ALTER TABLE `{$archive_pages}` DROP INDEX `index`");
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
    }
    // update pages archive table table with new url ids.
    $sql = "UPDATE `{$archive_pages}` h,`{$urls}` u SET h.url_id = u.new_url_id WHERE h.url_id = u.id";
    $r = $fsdb->query($sql);
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    // re-establish unique index
    $r = $fsdb->query("ALTER TABLE `{$archive_pages}` ADD UNIQUE `index` ( `range_id` , `site_id` , `url_id` )");
    if ($r === FALSE) {
        echo fs_db_error(true);
        return false;
    }
    $fsdb->query("COMMIT");
    if (fs_table_exists($fsdb, $referers)) {
        $r = $fsdb->query("DROP TABLE `{$urls}");
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
        $r = $fsdb->query("RENAME TABLE `{$referers}` TO `{$urls}`");
        if ($r === FALSE) {
            echo fs_db_error(true);
            return false;
        }
    }
    fs_add_pending_maintanence_job('recalculate_search_engine_terms');
    if (!fs_update_db_version($fsdb, 11)) {
        return false;
    }
    return true;
}