Collection::insertMany()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * Ember Db - An embeddable document database for php.
4
 * Copyright (C) 2016 Alexander During
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 * @link      http://github.com/alexanderduring/php-ember-db
20
 * @copyright Copyright (C) 2016 Alexander During
21
 * @license   http://www.gnu.org/licenses GNU General Public License v3.0
22
 */
23
24
declare(strict_types=1);
25
26
namespace EmberDb\Collection;
27
28
use EmberDb\Document;
29
use EmberDb\Exception;
30
use EmberDb\Filter\Filter;
31
use EmberDb\Logger;
32
33
class Collection
34
{
35
    /** @var MetaData */
36
    private $metaData;
37
38
    /** @var string */
39
    private $name;
40
41
    /** @var string */
42
    private $path;
43
44
45
46
    public function __construct(string $name, string $path)
47
    {
48
        $this->name = $name;
49
        $this->path = $path;
50
        $this->metaData = new MetaData($path . '/' . $name . 'meta.edb');
51
    }
52
53
54
55
    public function insert(Document $document)
56
    {
57
        $this->insertEntries(array($document));
58
    }
59
60
61
62
    public function insertMany($documents)
63
    {
64
        $this->insertEntries($documents);
65
    }
66
67
68
69
    public function find(Filter $filter): array
70
    {
71
        $documents = [];
72
73
        $entries = $this->readEntries($filter);
74
        foreach ($entries as $entry) {
75
            $documents[] = new Document($entry);
76
        }
77
78
        return $documents;
79
    }
80
81
82
83
    public function remove()
84
    {
85
        $filePath = $this->getCollectionFilePath();
86
        if (file_exists($filePath)) {
87
            unlink($filePath);
88
        }
89
    }
90
91
92
93
    private function readEntries(Filter $filter)
94
    {
95
        $entries = array();
96
97
        try {
98
            // Open file for reading
99
            $collectionFilePath = $this->getCollectionFilePath();
100
            $file = fopen($collectionFilePath, 'r');
101
102
            $lockAquired = $this->aquireReadLock($file);
103
            if (!$lockAquired) {
104
                throw new Exception('Lock wait timeout.');
105
            }
106
            Logger::log("Read lock aquired on $collectionFilePath.\n");
107
108
            // Read file line by line
109
            while (($buffer = fgets($file)) !== false) {
110
                $entry = json_decode(trim($buffer), true);
111
                // Match entry against filter
112
                if ($filter->matchesEntry($entry)) {
113
                    $entries[] = $entry;
114
                }
115
            }
116
117
            // Close file
118
            fclose($file);
119
120
        } catch (Exception $exception) {
121
            Logger::log($exception->getMessage());
122
        }
123
124
125
        return $entries;
126
    }
127
128
129
130
    private function insertEntries($documents)
131
    {
132
        // Open or create file for writing
133
        $collectionFilePath = $this->getCollectionFilePath();
134
        $collectionFileHandle = fopen($collectionFilePath, 'a');
135
136
        // Add entries to end of file
137
        foreach ($documents as $document) {
138
            $document->setId($this->createId());
139
            fwrite($collectionFileHandle, json_encode($document)."\n");
140
        }
141
142
        // Close file
143
        fclose($collectionFileHandle);
144
    }
145
146
147
148
    private function removeEntries(array $filterArray)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
Unused Code introduced by
The parameter $filterArray is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
149
    {
150
        // Do the same like readEntries does, but copy all non matching
151
        // entries into new file and remove the old one.
152
    }
153
154
155
156
157
    private function getCollectionFilePath()
158
    {
159
        return $this->path . '/' . $this->name . '.edb';
160
    }
161
162
163
164
    private function createId(): string
165
    {
166
        return $id = time() . '-' . mt_rand(1000, 9999);
0 ignored issues
show
Unused Code introduced by
$id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
167
    }
168
169
170
171
    private function aquireReadLock($file)
172
    {
173
        $lockAquired = flock($file, LOCK_SH | LOCK_NB);
174
175
        if (!$lockAquired) {
176
            $deadline = time() + 1 * 60; // 1 minute
177
            while (!$lockAquired && time() < $deadline) {
178
                sleep(1);
179
                $lockAquired = flock($file, LOCK_SH | LOCK_NB);
180
            }
181
        }
182
183
        return $lockAquired;
184
    }
185
}
186