Completed
Push — master ( dca6dc...178b4a )
by Richard
06:29
created

IndexDB   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 258
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 98.98%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 16
c 1
b 0
f 0
lcom 1
cbo 6
dl 0
loc 258
ccs 194
cts 196
cp 0.9898
rs 10

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A builder() 0 3 1
A source_file() 0 20 2
A entity() 0 23 1
A reference() 0 20 1
A relation() 0 16 1
A source_file_table() 0 3 1
A entity_table() 0 3 1
A reference_table() 0 3 1
A relations_table() 0 3 1
A init_sqlite_regexp() 0 10 2
A maybe_init_database_schema() 0 11 2
B init_database_schema() 0 95 1
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 *
5
 * Copyright (c) 2016, 2015 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received
8
 * a copy of the license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\App;
12
13
use Lechimp\Dicto\Variables\Variable;
14
use Lechimp\Dicto\Analysis\Query;
15
use Lechimp\Dicto\Analysis\CompilesVars;
16
use Lechimp\Dicto\Indexer\Insert;
17
use Lechimp\Dicto\Indexer\CachesReferences;
18
use Doctrine\DBAL\Connection;
19
use Doctrine\DBAL\Schema;
20
use Doctrine\DBAL\Types\Type;
21
use Doctrine\DBAL\Schema\Synchronizer\SingleDatabaseSynchronizer;
22
23
class IndexDB implements Insert, Query {
24
    use CachesReferences;
25
26
    /**
27
     * @var Connection
28
     */
29
    protected $connection;
30
31 56
    public function __construct(Connection $connection) {
32 56
        $this->connection = $connection;
33 56
    }
34
35
    /**
36
     * @return \Doctrine\DBAL\Query\Builder
37
     */
38 55
    public function builder() {
39 55
        return $this->connection->createQueryBuilder();
40
    }
41
42
    // Implementation of Insert interface.
43
44
    /**
45
     * @inheritdoc
46
     */
47 49
    public function source_file($name, $content) {
48 49
        assert('is_string($name)');
49 49
        assert('is_string($content)');
50 49
        $stmt = $this->builder()
51 49
            ->insert($this->source_file_table())
52 49
            ->values(array
53
                ( "name" => "?"
54 49
                , "line" => "?"
55 49
                , "source" => "?"
56 49
                ))
57 49
            ->setParameter(0, $name);
58 49
        $line = 1;
59 49
        foreach (explode("\n", $content) as $source) {
60
            $stmt
61 49
                ->setParameter(1, $line)
62 49
                ->setParameter(2, $source)
63 49
                ->execute();
64 49
            $line++;
65 49
        }
66 49
    }
67
68
    /**
69
     * @inheritdoc
70
     */
71 52
    public function entity($type, $name, $file, $start_line, $end_line) {
72 52
        assert('\\Lechimp\\Dicto\\Variables\\Variable::is_type($type)');
73 52
        assert('is_string($name)');
74 52
        assert('is_string($file)');
75 52
        assert('is_int($start_line)');
76 52
        assert('is_int($end_line)');
77 52
        $this->builder()
78 52
            ->insert($this->entity_table())
79 52
            ->values(array
80
                ( "type" => "?"
81 52
                , "name" => "?"
82 52
                , "file" => "?"
83 52
                , "start_line" => "?"
84 52
                , "end_line" => "?"
85 52
                ))
86 52
            ->setParameter(0, $type)
87 52
            ->setParameter(1, $name)
88 52
            ->setParameter(2, $file)
89 52
            ->setParameter(3, $start_line)
90 52
            ->setParameter(4, $end_line)
91 52
            ->execute();
92 52
        return (int)$this->connection->lastInsertId();
93 1
    }
94
95
    /**
96
     * @inheritdoc
97
     */
98 40
    public function reference($type, $name, $file, $line) {
99 40
        assert('\\Lechimp\\Dicto\\Variables\\Variable::is_type($type)');
100 40
        assert('is_string($name)');
101 40
        assert('is_string($file)');
102 40
        assert('is_int($line)');
103 40
        $this->builder()
104 40
            ->insert($this->reference_table())
105 40
            ->values(array
106
                ( "type" => "?"
107 40
                , "name" => "?"
108 40
                , "file" => "?"
109 40
                , "line" => "?"
110 40
                ))
111 40
            ->setParameter(0, $type)
112 40
            ->setParameter(1, $name)
113 40
            ->setParameter(2, $file)
114 40
            ->setParameter(3, $line)
115 40
            ->execute();
116 40
        return (int)$this->connection->lastInsertId();
117
    }
118
119
    /**
120
     * @inheritdoc
121
     */
122 30
    public function relation($name, $entity_id, $reference_id) {
123 30
        assert('is_string($name)');
124 30
        assert('is_int($entity_id)');
125 30
        assert('is_int($reference_id)');
126 30
        $this->builder()
127 30
            ->insert($this->relations_table())
128 30
            ->values(array
129
                ( "name" => "?"
130 30
                , "entity_id" => "?"
131 30
                , "reference_id" => "?"
132 30
                ))
133 30
            ->setParameter(0, $name)
134 30
            ->setParameter(1, $entity_id)
135 30
            ->setParameter(2, $reference_id)
136 30
            ->execute();
137 30
    }
138
139
    // Naming
140
141 55
    public function source_file_table() {
142 55
        return "files";
143
    }
144
145 55
    public function entity_table() {
146 55
        return "entities";
147
    } 
148
149 55
    public function reference_table() {
150 55
        return "refs";
151
    }
152
153 55
    public function relations_table() {
154 55
        return "relations";
155
    }
156
157
    /**
158
     * Initialize REGEXP for sqlite.
159
     */
160 50
    public function init_sqlite_regexp() {
161 50
        $pdo = $this->connection->getWrappedConnection();
162 50
        if (!($pdo instanceof \PDO)) {
163
            throw new \RuntimeException(
164
                "Expected wrapped connection to be PDO-object.");
165
        }
166 50
        $pdo->sqliteCreateFunction("regexp", function($pattern, $data) {
167 25
            return preg_match("%$pattern%", $data) > 0;
168 50
        });
169 50
    }
170
171
    // Creation of database.
172
173 49
    public function maybe_init_database_schema() {
174 49
        $res = $this->builder()
175 49
            ->select("COUNT(*)")
176 49
            ->from("sqlite_master")
177 49
            ->where("type = 'table'")
178 49
            ->execute()
179 49
            ->fetchColumn();
180 49
        if ($res == 0) {
181 49
            $this->init_database_schema();
182 49
        }
183 49
    }
184
185 55
    public function init_database_schema() {
186 55
        $schema = new Schema\Schema();
187
188 55
        $file_table = $schema->createTable($this->source_file_table());
189 55
        $file_table->addColumn
190 55
            ( "name", "string"
191 55
            , array("notnull" => true)
192 55
            );
193 55
        $file_table->addColumn
194 55
            ( "line", "integer"
195 55
            , array("notnull" => true, "unsigned" => true)
196 55
            );
197 55
        $file_table->addColumn
198 55
            ( "source", "string"
199 55
            , array("notnull" => true)
200 55
            );
201 55
        $file_table->setPrimaryKey(array("name", "line"));
202
203 55
        $entity_table = $schema->createTable($this->entity_table());
204 55
        $entity_table->addColumn
205 55
            ("id", "integer"
206 55
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
207 55
            );
208 55
        $entity_table->addColumn
209 55
            ("type", "string"
210 55
            , array("notnull" => true)
211 55
            );
212 55
        $entity_table->addColumn
213 55
            ("name", "string"
214 55
            , array("notnull" => true)
215 55
            );
216 55
        $entity_table->addColumn
217 55
            ("file", "string"
218 55
            , array("notnull" => true)
219 55
            );
220 55
        $entity_table->addColumn
221 55
            ("start_line", "integer"
222 55
            , array("notnull" => true, "unsigned" => true)
223 55
            );
224 55
        $entity_table->addColumn
225 55
            ("end_line", "integer"
226 55
            , array("notnull" => true, "unsigned" => true)
227 55
            );
228 55
        $entity_table->setPrimaryKey(array("id"));
229
230 55
        $reference_table = $schema->createTable($this->reference_table());
231 55
        $reference_table->addColumn
232 55
            ( "id", "integer"
233 55
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
234 55
            );
235 55
        $reference_table->addColumn
236 55
            ("type", "string"
237 55
            , array("notnull" => true)
238 55
            );
239 55
        $reference_table->addColumn
240 55
            ("name", "string"
241 55
            , array("notnull" => true)
242 55
            );
243 55
        $reference_table->addColumn
244 55
            ("file", "string"
245 55
            , array("notnull" => true)
246 55
            );
247 55
        $reference_table->addColumn
248 55
            ("line", "integer"
249 55
            , array("notnull" => true, "unsigned" => true)
250 55
            );
251 55
        $reference_table->setPrimaryKey(array("id"));
252
253 55
        $relations_table = $schema->createTable($this->relations_table());
254 55
        $relations_table->addColumn
255 55
            ("name", "string"
256 55
            , array("notnull" => true)
257 55
            );
258 55
        $relations_table->addColumn
259 55
            ( "entity_id", "integer"
260 55
            , array("notnull" => true, "unsigned" => true)
261 55
            );
262 55
        $relations_table->addColumn
263 55
            ( "reference_id", "integer"
264 55
            , array("notnull" => true, "unsigned" => true)
265 55
            );
266 55
        $relations_table->addForeignKeyConstraint
267 55
            ( $entity_table
268 55
            , array("entity_id")
269 55
            , array("id")
270 55
            );
271 55
        $relations_table->addForeignKeyConstraint
272 55
            ( $reference_table
273 55
            , array("reference_id")
274 55
            , array("id")
275 55
            );
276
277 55
        $sync = new SingleDatabaseSynchronizer($this->connection);
278 55
        $sync->createSchema($schema);
279 55
    }
280
}
281