OSDN Git Service

[add]死因ランキング・人気ランキング表示用コード
authorHabu <habu@users.sourceforge.jp>
Thu, 15 Mar 2018 01:04:53 +0000 (10:04 +0900)
committerHabu <habu@users.sourceforge.jp>
Thu, 15 Mar 2018 01:39:59 +0000 (10:39 +0900)
db_common.inc [new file with mode: 0644]
killer_ranking.php [new file with mode: 0644]
popularity_ranking.php [new file with mode: 0644]

diff --git a/db_common.inc b/db_common.inc
new file mode 100644 (file)
index 0000000..ef5e2bb
--- /dev/null
@@ -0,0 +1,172 @@
+<?php
+class ScoreDB
+{
+    public function __construct() {
+        $this->dbh = new PDO('sqlite:db/score.db');
+        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+    }
+
+    public function get_db_handle() {
+        return $this->dbh;
+    }
+
+    private function update_killers_cache_table()
+    {
+        try {
+            $this->dbh->beginTransaction();
+
+            $this->dbh->exec("DROP TABLE IF EXISTS killers_cache");
+            $this->dbh->exec("CREATE TABLE killers_cache (killer_name TEXT PRIMARY KEY, killer_count_total INTEGER, killer_count_normal INTEGER, killer_count_freeze INTEGER)");
+
+            // 通常状態、麻痺・彫像状態で別々に取得し、それぞれの回数と合計回数を計算しkillers_cacheテーブルに格納する
+            $killers['normal'] = $this->dbh->query("SELECT killer, count(*) AS killer_count FROM scores WHERE killer NOT LIKE '麻痺状態で%' AND killer NOT LIKE '彫像状態で%' GROUP BY killer")->fetchAll(PDO::FETCH_ASSOC);
+            $killers['freeze'] = $this->dbh->query("SELECT killer, count(*) AS killer_count FROM scores WHERE killer LIKE '麻痺状態で%' OR killer LIKE '彫像状態で%' GROUP BY killer")->fetchAll(PDO::FETCH_ASSOC);
+
+            $killer_count = [];
+            foreach ($killers['normal'] as $row) {
+                $killer = self::killer_normalize($row['killer']);
+                $killer_count[$killer]['normal'] = intval($row['killer_count']);
+            }
+
+            foreach ($killers['freeze'] as $row) {
+                $killer = self::killer_normalize($row['killer']);
+                $killer_count[$killer]['freeze'] = intval($row['killer_count']);
+            }
+
+            foreach ($killer_count as $k => $v) {
+                if (!isset($killer_count[$k]['normal'])) {
+                    $killer_count[$k]['normal'] = 0;
+                }
+                if (!isset($killer_count[$k]['freeze'])) {
+                    $killer_count[$k]['freeze'] = 0;
+                }
+            }
+            foreach ($killer_count as $k => $v) {
+                $killer_count[$k]['total'] = $v['normal'] + $v['freeze'];
+            }
+
+            $insert_stmt = $this->dbh->prepare("INSERT INTO killers_cache VALUES(?, ?, ?, ?)");
+            foreach ($killer_count as $k => $v) {
+                $insert_stmt->execute([$k, $v['total'], $v['normal'], $v['freeze']]);
+            }
+
+            $this->dbh->commit();
+
+            return TRUE;
+        } catch (PDOException $e) {
+            $this->dbh->rollBack();
+
+            return FALSE;
+        }
+    }
+
+    public function get_killers_table()
+    {
+        //$this->update_cache_status('killers_cache', 0);
+        if (!$this->get_cache_status('killers_cache')) {
+            $this->update_killers_cache_table();
+            $this->update_cache_status('killers_cache', 1);
+        }
+
+        $killers = $this->dbh->query("SELECT * FROM killers_cache ORDER BY killer_count_total DESC")->fetchAll(PDO::FETCH_ASSOC);
+
+        return $killers;
+    }
+
+    private function update_statistics_tables() {
+        $statistics_list = ['race', 'class', 'personality'];
+
+        try {
+            foreach ($statistics_list as $stat) {
+                $table_name = $stat."_statistics";
+                $this->dbh->exec("DROP TABLE IF EXISTS ".$table_name);
+                $stmt = $this->dbh->query("CREATE TABLE ".$table_name." AS SELECT ".$stat."_id, count(sex=1 or NULL) AS male_count, count(sex=0 or NULL) AS female_count, count(*) AS total_count, count(winner=1 OR NULL) AS winner_count, avg(score) AS average_score, max(score) AS max_score from scores GROUP BY ".$stat."_id");
+            }
+
+            return TRUE;
+        } catch (PDOException $e) {
+            return FALSE;
+        }
+    }
+
+    public function get_statistics_tables() {
+        if (!$this->get_cache_status('statistics_cache')) {
+            $this->update_statistics_tables();
+            $this->update_cache_status('statistics_cache', 1);
+        }
+
+        $stat = [];
+
+        $this->dbh->beginTransaction();
+        $stmt = $this->dbh->query("SELECT race_name AS name, * from race_statistics NATURAL INNER JOIN races ORDER BY total_count DESC");
+        $stat['race'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+        $stmt = $this->dbh->query("SELECT class_name AS name, * from class_statistics NATURAL INNER JOIN classes ORDER BY total_count DESC");
+        $stat['class'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+        $stmt = $this->dbh->query("SELECT personality_name AS name, * from personality_statistics NATURAL INNER JOIN personalities ORDER BY total_count DESC");
+        $stat['personality'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+        $this->dbh->commit();
+
+        return $stat;
+    }
+
+    public function table_exists($table_name)
+    {
+        $stmt = $this->dbh->prepare("SELECT count(*) AS table_exists FROM sqlite_master WHERE type='table' AND name=?");
+        $stmt->execute([$table_name]);
+        $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+        return intval($res[0]['table_exists']) === 1;
+    }
+
+
+    public function get_cache_status($cache_table_name)
+    {
+        if (!$this->table_exists('cache_status_table')) {
+            $this->create_cache_status_table();
+        }
+
+        $stmt = $this->dbh->prepare("SELECT cached FROM cache_status_table WHERE table_name=?");
+        $stmt->execute([$cache_table_name]);
+        $res = $stmt->fetchAll(PDO::FETCH_ASSOC);
+
+        return count($res) === 1 ? intval($res[0]['cached']) : 0;
+    }
+
+    public function update_cache_status($cache_table_name, $status)
+    {
+        if (!$this->table_exists('cache_status_table')) {
+            $this->create_cache_status_table();
+        }
+
+        $stmt = $this->dbh->prepare("INSERT OR REPLACE INTO cache_status_table VALUES(?, ?)");
+        $stmt->execute([$cache_table_name, $status]);
+
+        return $stmt->rowCount();
+    }
+
+    public function create_cache_status_table()
+    {
+        $this->dbh->exec(<<<EOM
+CREATE TABLE cache_status_table
+  (table_name TEXT PRIMARY KEY,
+   cached BOOLEAN)
+EOM
+        );
+    }
+
+    private static function killer_normalize($killer)
+    {
+        if ($killer === "ripe") {
+            return "引退";
+        } else if ($killer === "Seppuku") {
+            return "切腹";
+        }
+
+        $n = str_replace("麻痺状態で", "", $killer);
+        $n = str_replace("彫像状態で", "", $n);
+
+        return $n;
+    }
+
+}
diff --git a/killer_ranking.php b/killer_ranking.php
new file mode 100644 (file)
index 0000000..4618045
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+//ini_set('display_errors', 'On');
+
+ini_set('log_errors', 'On');
+ini_set('error_log', 'errors/'.pathinfo(__FILE__, PATHINFO_FILENAME).'.log');
+
+ini_set('zlib.output_compression', 'On');
+
+include "db_common.inc";
+
+$db = new ScoreDB();
+
+$time_start = microtime(true);
+
+$killers = $db->get_killers_table();
+
+$query_time = microtime(true) - $time_start;
+?>
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
+<title>変愚蛮怒 死因ランキング</title>
+</head>
+
+<body>
+<h1>変愚蛮怒 死因ランキング</h1>
+<small>クエリ時間<?php echo sprintf("%.3f msec", $query_time * 1000) ?></small>
+<hr>
+<table>
+<tr><th>回数(内、彫像・麻痺状態)</th><th>死因</th></tr>
+<?php
+    foreach ($killers as $k) {
+        //$total = $count['knormal'] + $count['freeze'];
+        $freeze = $k['killer_count_freeze'] > 0 ? "(".$k['killer_count_freeze'].")" : "";
+        echo <<<EOM
+<tr><td>{$k['killer_count_total']}$freeze</td><td>{$k['killer_name']}</td></tr>
+
+EOM;
+    }
+?>
+</table>
+</body>
+</html>
diff --git a/popularity_ranking.php b/popularity_ranking.php
new file mode 100644 (file)
index 0000000..bd75859
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+//ini_set('display_errors', 'On');
+
+ini_set('log_errors', 'On');
+ini_set('error_log', 'errors/'.pathinfo(__FILE__, PATHINFO_FILENAME).'.log');
+
+ini_set('zlib.output_compression', 'On');
+
+include "db_common.inc";
+
+function print_popularity_table($stat, $name)
+{
+    echo <<< EOM
+        <table>
+    <tr>
+    <th>#
+    <th>$name
+    <th>計
+    <th>男性
+    <th>女性
+    <th>勝利
+    <th>平均スコア
+    <th>最大スコア
+    </tr>
+EOM;
+
+    $rank = 0;
+    foreach ($stat as $s) {
+        $rank ++;
+        $average_score = floor($s['average_score']);
+        echo <<< EOM
+<tr>
+            <td>$rank</td>
+        <td>{$s['name']}</td>
+        <td>{$s['total_count']}</td>
+        <td>{$s['male_count']}</td>
+        <td>{$s['female_count']}</td>
+        <td>{$s['winner_count']}</td>
+        <td>$average_score</td>
+        <td>{$s['max_score']}</td>
+        </tr>
+EOM;
+    }
+
+    echo "</table>";
+}
+
+
+$db = new ScoreDB();
+
+$time_start = microtime(true);
+
+$statistics = $db->get_statistics_tables();
+
+$query_time = microtime(true) - $time_start;
+?>
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
+<title>変愚蛮怒 人気のある種族・職業・性格</title>
+</head>
+
+<small>クエリ時間<?php echo sprintf("%.3f msec", $query_time * 1000) ?></small>
+<hr>
+<h1>人気のある種族</h1>
+
+<?php
+print_popularity_table($statistics['race'], "種族");
+?>
+
+<hr>
+<h1>人気のある職業</h1>
+
+<?php
+print_popularity_table($statistics['class'], "職業");
+?>
+
+<hr>
+<h1>人気のある性格</h1>
+
+<?php
+print_popularity_table($statistics['personality'], "性格");
+?>