-
Notifications
You must be signed in to change notification settings - Fork 13
/
web.php
121 lines (98 loc) · 2.92 KB
/
web.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php declare(strict_types=1);
/**
* Copyright (c) 2020-2023, Jos de Ruijter <[email protected]>
*/
/**
* Class for handling database related tasks (for the web). This is a stripped
* down class based on "db.php". For comments see aforementioned file.
*/
class db
{
private static string $database = '%CHANGEME%';
private static SQLite3 $db;
private function __construct() {}
public static function connect(): void
{
try {
self::$db = new SQLite3(self::$database, SQLITE3_OPEN_READONLY);
} catch (Exception $e) {
out::put('critical', 'sqlite fail: '.$e->getMessage());
}
/**
* Set up the SQLite connection:
* - Prevent all changes to database files ("query_only = ON").
*/
$pragmas = [
'busy_timeout' => '0',
'query_only' => 'ON',
'temp_store' => 'MEMORY'];
foreach ($pragmas as $pragma => $value) {
self::query_exec('PRAGMA '.$pragma.' = '.$value);
}
self::query_exec('BEGIN TRANSACTION');
}
public static function disconnect(): void
{
self::query_exec('COMMIT');
self::$db->close();
}
private static function fail(): never
{
out::put(self::$db->lastErrorCode(), self::$db->lastErrorMsg());
}
public static function query(string $query): SQLite3Result
{
if (($results = self::$db->query($query)) === false) {
self::fail();
}
return $results;
}
public static function query_exec(string $query): void
{
self::$db->exec($query) or self::fail();
}
public static function query_single_col(string $query): float|int|string|null
{
if (($result = self::$db->querySingle($query)) === false) {
self::fail();
}
return $result;
}
public static function query_single_row(string $query): ?array
{
if (($result = self::$db->querySingle($query, true)) === false) {
self::fail();
}
if (empty($result) || count(array_filter($result, 'is_null')) === count($result)) {
return null;
}
return $result;
}
}
/**
* Class for handling output messages (for the web). This is a stripped down
* class based on "out.php". For comments see aforementioned file.
*/
class out
{
private static string $stylesheet = 'sss.css';
private function __construct() {}
public static function put(int|string $type, string $message): never
{
/**
* Code 5 = SQLITE_BUSY, code 6 = SQLITE_LOCKED.
*/
if ($type === 5 || $type === 6) {
$message = 'Statistics are currently being updated, this may take a minute.';
}
if (!file_exists(self::$stylesheet)) {
header('Content-Type: text/plain');
exit($message."\n");
}
exit('<!DOCTYPE html>'."\n\n".'<html lang="en"><head><meta charset="utf-8"><title>seriously?</title><link rel="stylesheet" href="'.htmlspecialchars(self::$stylesheet, ENT_QUOTES | ENT_HTML5, 'UTF-8').'"></head><body><div id="container"><div id="error">'.htmlspecialchars($message, ENT_QUOTES | ENT_HTML5, 'UTF-8').'</div></div></body></html>'."\n");
}
public static function set_stylesheet(string $stylesheet): void
{
self::$stylesheet = $stylesheet;
}
}