Completed
Push — master ( 84f79f...bf95a2 )
by Felix
02:59
created

SqLiteStorage::garbageCollection()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 9.4285
cc 3
eloc 6
nc 2
nop 0
crap 3
1
<?php
2
/**
3
 * PhPsst.
4
 *
5
 * @copyright Copyright (c) 2016 Felix Sandström
6
 * @license   MIT
7
 */
8
9
namespace PhPsst\Storage;
10
11
use PhPsst\Password;
12
use PhPsst\PhPsstException;
13
use SQLite3;
14
15
/**
16
 * @group failing
17
 */
18
class SqLiteStorage extends Storage
19
{
20
    /**
21
     * @var int
22
     */
23
    protected $gcProbability;
24
25
    /**
26
     * @var SQLite3
27
     */
28
    protected $db;
29
30
    /**
31
     * FileStorage constructor.
32
     * @param SQLite3 $db
33
     * @param int $gcProbability
34
     */
35 2
    public function __construct(SQLite3 $db, $gcProbability)
36
    {
37 2
        if ($gcProbability < 0) {
38 1
            throw new \LogicException('Invalid value for gcProbability');
39
        }
40 1
        $this->gcProbability = $gcProbability;
41
42 1
        $this->db = $db;
43 1
        $this->db->enableExceptions(true);
44
        $sql = <<<'SQL'
45
CREATE TABLE IF NOT EXISTS `phPsst` (
46
  id VARCHAR(13) PRIMARY KEY NOT NULL,
47
  password TEXT NOT NULL,
48
  ttl INT NOT NULL,
49
  views INT NOT NULL
50
);
51 1
SQL;
52 1
        $this->db->exec($sql);
53 1
    }
54
55
    /**
56
     * @param Password $password
57
     * @param bool $allowOverwrite
58
     */
59 7
    public function store(Password $password, $allowOverwrite = false)
60
    {
61 7
        if ($this->get($password->getId())) {
62 2
            if (!$allowOverwrite) {
63 1
                throw new PhPsstException('The ID already exists', PhPsstException::ID_IS_ALREADY_TAKEN);
64
            } else {
65 1
                $this->delete($password);
66
            }
67 1
        }
68
69 7
        $stmt = $this->db->prepare('INSERT INTO phPsst VALUES (:id, :password, :ttl, :views)');
70 7
        $stmt->bindValue(':id', $password->getId(), SQLITE3_TEXT);
71 7
        $stmt->bindValue(':password', $password->getPassword(), SQLITE3_TEXT);
72 7
        $stmt->bindValue(':ttl', $password->getTtl(), SQLITE3_INTEGER);
73 7
        $stmt->bindValue(':views', $password->getViews(), SQLITE3_INTEGER);
74 7
        $stmt->execute();
75
76 7
        $this->garbageCollection();
77 7
    }
78
79
    /**
80
     * @param $key
81
     * @return Password|null
82
     */
83 4
    public function get($key)
84
    {
85 4
        $password = null;
86
87 4
        $stmt = $this->db->prepare('SELECT * FROM phPsst WHERE ID = :id');
88 4
        $stmt->bindValue(':id', $key, SQLITE3_TEXT);
89 4
        $result = $stmt->execute();
90 4
        if (($row = $result->fetchArray())) {
91 4
            $password = new Password($row['id'], $row['password'], $row['ttl'], $row['views']);
92 4
            if (($row['ttl'] < time())) {
93 1
                $this->delete($password);
94 1
                $password = null;
95 1
            }
96 4
        }
97
98 4
        return $password;
99
    }
100
101
    /**
102
     * @param Password $password
103
     */
104 2
    public function delete(Password $password)
105
    {
106 2
        $stmt = $this->db->prepare('DELETE FROM phPsst WHERE ID = :id');
107 2
        $stmt->bindValue(':id', $password->getId(), SQLITE3_TEXT);
108 2
        $stmt->execute();
109
110 2
        $this->garbageCollection();
111 2
    }
112
113
    /**
114
     */
115 7
    protected function garbageCollection()
116
    {
117 7
        if (!$this->gcProbability || rand(1, $this->gcProbability) !== 1) {
118 3
            return;
119
        }
120
121 4
        $stmt = $this->db->prepare('DELETE FROM phPsst WHERE ttl < :time');
122 4
        $stmt->bindValue(':time', time(), SQLITE3_INTEGER);
123 4
        $stmt->execute();
124 4
    }
125
}
126