Add updated_at column to accounts
[gamestick-pjgsapi.git] / src / ProfileDb.php
1 <?php
2 require_once 'Profile.php';
3
4 /**
5  * Functions to work with player profiles
6  */
7 class ProfileDb
8 {
9     protected PDO $db;
10
11     public function __construct()
12     {
13         $dbFile = static::getDbFilePath();
14         $this->db = new PDO(
15             'sqlite:' . $dbFile,
16             '', '',
17             [
18                 PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
19                 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
20             ]
21         );
22         $this->createTablesIfNeeded();
23     }
24
25     public static function getDbFilePath()
26     {
27         return dirname(__FILE__, 2) . '/data/profiles.sqlite3';
28     }
29
30     public function getProfileByHardwareId(string $hwId): ?Profile
31     {
32         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE hwId = :id');
33         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
34         $stmt->execute([':id' => $hwId]);
35         $row = $stmt->fetch();
36         return $row === false ? null : $row;
37     }
38
39     public function getProfileBySessionId(string $sessionId): ?Profile
40     {
41         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE sessionId = :id');
42         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
43         $stmt->execute([':id' => $sessionId]);
44         $row = $stmt->fetch();
45         return $row === false ? null : $row;
46     }
47
48     public function getProfileByVerificationCode(string $code): ?Profile
49     {
50         $stmt = $this->db->prepare('SELECT * FROM gamesticks WHERE verificationCode = :code');
51         $stmt->setFetchMode(PDO::FETCH_CLASS, 'Profile');
52         $stmt->execute([':code' => $code]);
53         $row = $stmt->fetch();
54         return $row === false ? null : $row;
55     }
56
57     public function createProfile(string $hwId): Profile
58     {
59         $stmt = $this->db->prepare(
60             <<<SQL
61             INSERT INTO gamesticks
62             (hwId, sessionId, verificationCode, created_at, updated_at)
63             VALUES (:hwId, :sessionId, :verificationCode, :created_at, :updated_at)
64 SQL
65         );
66         $stmt->execute(
67             [
68                 ':hwId'             => $hwId,
69                 ':sessionId'        => 's' . str_replace(':', '', $hwId),
70                 ':verificationCode' => date('His'),
71                 ':created_at'       => date('c'),
72                 ':updated_at'       => date('c'),
73             ]
74         );
75         return $this->getProfileByHardwareId($hwId);
76     }
77
78     public function updateProfile(string $hwId, array $values): ?Profile
79     {
80         $params = [
81             ':hwId'       => $hwId,
82             ':updated_at' => date('c'),
83         ];
84
85         $sql = 'UPDATE gamesticks SET';
86         $sqlParts = [
87             ' updated_at = :updated_at'
88         ];
89         foreach ($values as $column => $value) {
90             $sqlParts[] = ' ' . $column . '= :' . $column;
91             $params[':' . $column] = $value;
92         }
93         $sql .= implode(', ', $sqlParts) . ' WHERE hwId = :hwId';
94
95         $stmt = $this->db->prepare($sql);
96         $stmt->execute($params);
97
98         return $this->getProfileByHardwareId($hwId);
99     }
100
101     protected function createTablesIfNeeded()
102     {
103         $res = $this->db->query(
104             'SELECT name FROM sqlite_master WHERE type = "table" AND name = "gamesticks"'
105         )->fetch();
106         if ($res !== false) {
107             return;
108         }
109
110         $this->db->exec(
111             <<<SQL
112         CREATE TABLE gamesticks (
113             id INTEGER PRIMARY KEY AUTOINCREMENT,
114             hwId TEXT NOT NULL,
115             sessionId TEXT,
116             verificationCode TEXT DEFAULT NULL,
117             gamerTag TEXT DEFAULT NULL,
118             founderFlag INTEGER DEFAULT 0 NOT NULL,
119             founderName TEXT DEFAULT NULL,
120             minAge INTEGER DEFAULT 3 NOT NULL,
121             avatar TEXT DEFAULT NULL,
122
123             created_at TEXT DEFAULT CURRENT_TIMESTAMP,
124             updated_at TEXT DEFAULT CURRENT_TIMESTAMP
125         )
126 SQL
127         );
128     }
129 }
130 ?>