diff options
Diffstat (limited to 'visitors.php')
| -rw-r--r-- | visitors.php | 65 | 
1 files changed, 51 insertions, 14 deletions
| diff --git a/visitors.php b/visitors.php index e6c106a..47992d0 100644 --- a/visitors.php +++ b/visitors.php @@ -77,6 +77,8 @@ $config['db'] = 'visitors.csv';  /* --- END OF CONFIG, CODE BELOW, PROBABLY DON'T EDIT PAST THIS POINT --- */ +/* DATABASES */ +  // db_row: ['id' => int (only for list_rows), 'name' => string, 'message' => string, 'email' => ?string, 'website' => ?string, 'timestamp' => string (or DateTimeInterface for list_rows)]  // message is pre-escaped at insert time.  // timestamp is DateTimeInterface::ISO8601_EXPANDED format. @@ -99,12 +101,14 @@ abstract class Database {      return $this->_delete_row($id);    } +  abstract public function __construct(string $file); +    abstract protected function _append_row(array $db_row);    abstract protected function _list_rows(): array;    abstract protected function _delete_row(int $id): bool;  } -// notes: `id` is not stable +// sigh, refactor later, it wont be a perf issue for any realistic number of entries.  abstract class FileDatabase extends Database {    protected string $file;    protected array $data; @@ -119,29 +123,24 @@ abstract class FileDatabase extends Database {    }    protected function _append_row(array $db_row) { -    array_unshift($this->data, $db_row); +    array_unshift($this->data, array(...$db_row, 'id' => max(array_map(fn($a) => $a['id'], $this->data))));      $this->save();    }    protected function _list_rows(): array {      $data = $this->data; -    foreach($data as $id => &$row) { -      $row['id'] = $id; -    } -      return $data;    }    protected function _delete_row(int $id): bool { -    if (!isset($this->data[$id])) -      return false; - -    unset($this->data[$id]); -    $this->data = array_values($this->data); -    $this->save(); - -    return true; +    foreach(array_keys($this->data) as $key) +      if ($this->data[$key]['id'] === $id) { +        unset($this->data[$key]); +        $this->save(); +        return true; +      } +    return false;    }    abstract protected function save(); @@ -191,3 +190,41 @@ final class CsvDatabase extends FileDatabase {      return array_map(fn($s) => array_combine(self::KEY_ORDER, str_getcsv($s)), file($file));    }  } + +final class SqliteDatabase extends Database { +  private Sqlite3 $handle; + +  public function __construct(string $file) { +    $this->handle = new Sqlite3($file); +    if (!$this->handle->querySingle('SELECT count(*) FROM sqlite_master')) +      $this->handle->exec('CREATE TABLE visitors (id INTEGER PRIMARY KEY, name TEXT NOT NULL, message TEXT NOT NULL, email TEXT, website TEXT, timestamp TEXT NOT NULL)'); +  } + +  protected function _append_row(array $db_row) { +    $stmt = $this->handle->prepare('INSERT INTO visitors (name, message, email, website, timestamp) VALUES (:name, :message, :email, :website, :timestamp)'); +    foreach($db_row as $key => $value) +      $stmt->bindValue($key, $value); +    $stmt->execute(); +  } +  protected function _list_rows(): array { +    $rows = array(); + +    $res = $this->handle->query('SELECT * FROM visitors ORDER BY id DESC'); +    while ($row = $res->fetchArray(SQLITE3_ASSOC)) +      $rows[] = $row; + +    return $rows; +  } +  protected function _delete_row(int $id): bool { +    $stmt = $this->handle->prepare('SELECT count(*) FROM visitors WHERE id=:id'); +    $stmt->bindValue('id', $id); +    if (!$stmt->execute()->fetchArray(SQLITE3_NUM)[0]) +      return false;; + +    $stmt = $this->handle->prepare('DELETE FROM visitors WHERE id=:id'); +    $stmt->bindValue('id', $id); +    $stmt->execute(); + +    return true; +  } +} | 
