exec('PRAGMA cache_size = 32000'); // Enable WAL mode $db->exec('PRAGMA journal_mode = WAL'); // Move temp store to memory $db->exec('PRAGMA temp_store = MEMORY'); return $db; } /** * Return a connection to the auth database. */ function db_auth() { return $GLOBALS['db_auth'] ??= db_open(DBP . '/auth.db'); } /** * Return a connection to the live database. */ function db_live() { return $GLOBALS['db_live'] ??= db_open(DBP . '/live.db'); } /** * Return a connection to the fights database. */ function db_fights() { return $GLOBALS['db_fights'] ??= db_open(DBP . '/fights.db'); } /** * Return a connection to the blueprints database. */ function db_blueprints() { return $GLOBALS['db_blueprints'] ??= db_open(DBP . '/blueprints.db'); } /** * Take a SQLite3 database connection, a query string, and an array of parameters. Prepare the query and * bind the parameters with proper type casting. Then execute the query and return the result. */ function db_query(SQLite3 $db, string $query, array $params = []): SQLite3Result|false { $p = strpos($query, '?') !== false; // are generic placeholders? $stmt = $db->prepare($query); if (!empty($params)) { foreach ($params as $k => $v) $stmt->bindValue($p ? $k + 1 : $k, $v, getSQLiteType($v)); } $start = microtime(true); $r = $stmt->execute(); db_log($query, microtime(true) - $start); return $r; } /** * Take a SQLite3 database connection and a query string. Execute the query and return the result. */ function db_exec($db, $query) { $start = microtime(true); $r = $db->exec($query); db_log($query, microtime(true) - $start); return $r; } /** * Take a SQLite3 database connection, a column name, and a value. Execute a SELECT query to see if the value * exists in the column. Return true if the value exists, false otherwise. */ function db_exists(SQLite3 $db, string $table, string $column, mixed $value, bool $caseInsensitive = true): bool { if ($caseInsensitive) { $query = "SELECT 1 FROM $table WHERE $column = :v COLLATE NOCASE LIMIT 1"; } else { $query = "SELECT 1 FROM $table WHERE $column = :v LIMIT 1"; } $result = db_query($db, $query, [':v' => $value]); return $result->fetchArray(SQLITE3_NUM) !== false; } /** * Return the appropriate SQLite type casting for the value. */ function getSQLiteType($value): int { return match (true) { is_int($value) => SQLITE3_INTEGER, is_float($value) => SQLITE3_FLOAT, is_null($value) => SQLITE3_NULL, default => SQLITE3_TEXT }; } /** * Log the given query string to the db debug log. */ function db_log($query, $timeTaken = 0) { $GLOBALS['queries']++; $GLOBALS['query_time'] += $timeTaken; if (env('debug', false)) $GLOBALS['query_log'][] = [$query, $timeTaken]; }