prepare($query); foreach ($params ?? [] as $k => $v) $stmt->bindValue($p ? $k + 1 : $k, $v, $this->getSQLiteType($v)); $start = microtime(true); $r = $stmt->execute(); $this->log($query, microtime(true) - $start); return $r; } public function exec(string $query): bool { $start = microtime(true); $r = parent::exec($query); $this->log($query, microtime(true) - $start); return $r; } public function exists(string $table, string $column, mixed $value, bool $case_insensitive = true): bool { if ($case_insensitive) { $query = "SELECT 1 FROM $table WHERE $column = :v COLLATE NOCASE LIMIT 1"; } else { $query = "SELECT 1 FROM $table WHERE $column = :v LIMIT 1"; } $result = $this->query($query, [':v' => $value]); return $result->fetchArray(SQLITE3_NUM) !== false; } private function log(string $query, float $time_taken): void { $this->count++; $this->query_time += $time_taken; $this->log[] = [$query, $time_taken]; } private function getSQLiteType(mixed $value): int { return match (true) { is_int($value) => SQLITE3_INTEGER, is_float($value) => SQLITE3_FLOAT, is_null($value) => SQLITE3_NULL, default => SQLITE3_TEXT }; } }