Completed
Push — master ( 9971b9...3d6cb8 )
by Richard
06:14
created

IndexDB::source_table()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
nc 1
cc 1
eloc 2
nop 0
crap 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\Schema as S;
19
use Doctrine\DBAL\Types\Type;
20
use Doctrine\DBAL\Schema\Synchronizer\SingleDatabaseSynchronizer;
21
22
class IndexDB extends DB implements Insert, Query {
23
//    use CachesReferences;
24
25
    // Implementation of Insert interface.
26
27
    /**
28
     * @inheritdoc
29
     */
30 53
    public function name($name, $type) {
31 53
        assert('is_string($name)');
32 53
        assert('\\Lechimp\\Dicto\\Variables\\Variable::is_type($type)');
33
34 53
        $name_id = $this->get_int_id($name, $this->name_table(), "name");
35 53
        if ($name_id !== null) {
36 2
            return $name_id;
37
        }
38
39 53
        $this->builder()
40 53
            ->insert($this->name_table())
41 53
            ->values(array
42
                ( "name" => "?"
43 53
                , "type" => "?"
44 53
                ))
45 53
            ->setParameter(0, $name)
46 53
            ->setParameter(1, $type)
47 53
            ->execute();
48 53
        return (int)$this->connection->lastInsertId();
49
    }
50
51
    /**
52
     * Store a filename or just get its id if the file is already stored.
53
     *
54
     * @param   string      $path
55
     * @return  int
56
     */
57 54
    public function file($path) {
58 54
        assert('is_string($path)');
59
60 54
        $file_id = $this->get_int_id($path, $this->file_table(), "path");
61 54
        if ($file_id !== null) {
62 52
            return $file_id;
63
        }
64
65 54
        $this->builder()
66 54
            ->insert($this->file_table())
67 54
            ->values(array
68
                ( "path" => "?"
69 54
                ))
70 54
            ->setParameter(0, $path)
71 54
            ->execute();
72 54
        return (int)$this->connection->lastInsertId();
73
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78 53
    public function source($path, $content) {
79 53
        assert('is_string($content)');
80
81 53
        $file_id = $this->file($path);
82
83 53
        $stmt = $this->builder()
84 53
            ->insert($this->source_table())
85 53
            ->values(array
86
                ( "file" => "?"
87 53
                , "line" => "?"
88 53
                , "source" => "?"
89 53
                ))
90 53
            ->setParameter(0, $file_id);
91 53
        $line = 1;
92 53
        foreach (explode("\n", $content) as $source) {
93 1
            $stmt
94 53
                ->setParameter(1, $line)
95 53
                ->setParameter(2, $source)
96 53
                ->execute();
97 53
            $line++;
98 53
        }
99 53
        return $file_id;
100
    }
101
102
    /**
103
     * @inheritdoc
104
     */
105 50
    public function definition($name, $type, $file, $start_line, $end_line) {
106 50
        assert('is_int($start_line)');
107 50
        assert('is_int($end_line)');
108
109 50
        $name_id = $this->name($name, $type);
110 50
        $file_id = $this->file($file);
111
112 50
        $this->builder()
113 50
            ->insert($this->definition_table())
114 50
            ->values(array
115
                ( "name" => "?"
116 50
                , "file" => "?"
117 50
                , "start_line" => "?"
118 50
                , "end_line" => "?"
119 50
                ))
120 50
            ->setParameter(0, $name_id)
121 50
            ->setParameter(1, $file_id)
122 50
            ->setParameter(2, $start_line)
123 50
            ->setParameter(3, $end_line)
124 50
            ->execute();
125 50
        return $name_id;
126
    }
127
128
    /**
129
     * @inheritdoc
130
     */
131 29
    public function relation($name_left_id, $name_right_id, $which, $file, $line) {
132 29
        assert('is_int($name_left_id)');
133 29
        assert('is_int($name_right_id)');
134 29
        assert('is_string($which)');
135 29
        assert('is_int($line)');
136
137 29
        $file_id = $this->get_int_id($file, $this->file_table(), "path");
138
139 29
        assert('is_int($file_id)');
140
141 29
        $this->builder()
142 29
            ->insert($this->relation_table())
143 29
            ->values(array
144
                ( "name_left" => "?"
145 29
                , "name_right" => "?"
146 29
                , "which" => "?"
147 29
                , "file" => "?"
148 29
                , "line" => "?"
149 29
                ))
150 29
            ->setParameter(0, $name_left_id)
151 29
            ->setParameter(1, $name_right_id)
152 29
            ->setParameter(2, $which)
153 29
            ->setParameter(3, $file_id)
154 29
            ->setParameter(4, $line)
155 29
            ->execute();
156 29
    }
157
158
    /**
159
     * Get the numeric id for the stringy id in table by using id_column
160
     * as column name.
161
     *
162
     * @param   string  $id
163
     * @param   string  $table
164
     * @param   string  $id_colum
0 ignored issues
show
Documentation introduced by
There is no parameter named $id_colum. Did you maybe mean $id_column?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
165
     * @return  int|null
166
     */
167 56
    protected function get_int_id($id, $table, $id_column) {
168 56
        $res = $this->builder()
169 56
            ->select("id")
170 56
            ->from($table)
171 56
            ->where($this->builder()->expr()->andX
172 56
                ( "$id_column = ?"
173 56
                ))
174 56
            ->setParameter(0, $id)
175 56
            ->execute()
176 56
            ->fetch();
177 56
        if ($res) {
178 54
            return (int)$res["id"];
179
        }
180
        else {
181 56
            return null;
182
        }
183
    }
184
185
    // Naming
186
187 57
    public function name_table() {
188 57
        return "names";
189
    }
190
191 57 View Code Duplication
    public function init_name_table(S\Schema $schema) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
192 57
        $name_table = $schema->createTable($this->name_table());
193 57
        $name_table->addColumn
194 57
            ("id", "integer"
195 57
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
196 57
            );
197 57
        $name_table->addColumn
198 57
            ( "name", "string"
199 57
            , array("notnull" => true)
200 57
            );
201
        // TODO: insert namespace column here
202 57
        $name_table->addColumn
203 57
            ( "type", "integer"
204 57
            , array("notnull" => true, "unsigned" => true)
205 57
            );
206 57
        $name_table->setPrimaryKey(array("id"));
207 57
        $name_table->addUniqueIndex(array("name"));
208 57
        return $name_table;
209
    }
210
211 57
    public function file_table() {
212 57
        return "files";
213
    }
214
215 57
    public function init_file_table(S\Schema $schema) {
216 57
        $file_table = $schema->createTable($this->file_table());
217 57
        $file_table->addColumn
218 57
            ("id", "integer"
219 57
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
220 57
            );
221 57
        $file_table->addColumn
222 57
            ( "path", "string"
223 57
            , array("notnull" => true)
224 57
            );
225 57
        $file_table->setPrimaryKey(array("id"));
226 57
        return $file_table;
227
    }
228
229 57
    public function source_table() {
230 57
        return "source";
231
    }
232
233 57 View Code Duplication
    public function init_source_table(S\Schema $schema, S\Table $file_table) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234 57
        $source_table = $schema->createTable($this->source_table());
235 57
        $source_table->addColumn
236 57
            ( "file", "integer"
237 57
            , array("notnull" => true)
238 57
            );
239 57
        $source_table->addColumn
240 57
            ( "line", "integer"
241 57
            , array("notnull" => true, "unsigned" => true)
242 57
            );
243 57
        $source_table->addColumn
244 57
            ( "source", "string"
245 57
            , array("notnull" => true)
246 57
            );
247 57
        $source_table->setPrimaryKey(array("file", "line"));
248 57
        $source_table->addForeignKeyConstraint
249 57
            ( $file_table
250 57
            , array("file")
251 57
            , array("id")
252 57
            );
253 57
        return $source_table;
254
    }
255
256 57
    public function definition_table() {
257 57
        return "definitions";
258
    }
259
260 57
    public function init_definition_table(S\Schema $schema, S\Table $name_table, S\Table $source_table) {
261 57
        $definition_table = $schema->createTable($this->definition_table());
262 57
        $definition_table->addColumn
263 57
            ( "name", "integer"
264 57
            , array("notnull" => true)
265 57
            );
266 57
        $definition_table->addColumn
267 57
            ( "file", "integer"
268 57
            , array("notnull" => true)
269 57
            );
270 57
        $definition_table->addColumn
271 57
            ( "start_line", "integer"
272 57
            , array("notnull" => true)
273 57
            );
274 57
        $definition_table->addColumn
275 57
            ( "end_line", "integer"
276 57
            , array("notnull" => true)
277 57
            );
278 57
        $definition_table->setPrimaryKey(array("name"));
279 57
        $definition_table->addForeignKeyConstraint
280 57
            ( $name_table
281 57
            , array("name")
282 57
            , array("id")
283 57
            );
284 57
        $definition_table->addForeignKeyConstraint
285 57
            ( $source_table
286 57
            , array("file", "start_line")
287 57
            , array("file", "line")
288 57
            );
289 57
        $definition_table->addForeignKeyConstraint
290 57
            ( $source_table
291 57
            , array("file", "end_line")
292 57
            , array("file", "line")
293 57
            );
294 57
        return $definition_table;
295
    }
296
297 57
    public function relation_table() {
298 57
        return "relations";
299
    }
300
301 57
    public function init_relation_table(S\Schema $schema, S\Table $name_table, S\Table $source_table) {
302 57
        $relation_table = $schema->createTable($this->relation_table());
303 57
        $relation_table->addColumn
304 57
            ( "name_left", "integer"
305 57
            , array("notnull" => true)
306 57
            );
307 57
        $relation_table->addColumn
308 57
            ( "name_right", "integer"
309 57
            , array("notnull" => true)
310 57
            );
311 57
        $relation_table->addColumn
312 57
            ( "which", "string"
313 57
            , array("notnull" => true)
314 57
            );
315 57
        $relation_table->addColumn
316 57
            ( "file", "integer"
317 57
            , array("notnull" => true)
318 57
            );
319 57
        $relation_table->addColumn
320 57
            ( "line", "integer"
321 57
            , array("notnull" => true)
322 57
            );
323 57
        $relation_table->setPrimaryKey(array("name_left", "name_right", "which"));
324 57
        $relation_table->addForeignKeyConstraint
325 57
            ( $name_table
326 57
            , array("name_left")
327 57
            , array("id")
328 57
            );
329 57
        $relation_table->addForeignKeyConstraint
330 57
            ( $name_table
331 57
            , array("name_right")
332 57
            , array("id")
333 57
            );
334 57
        $relation_table->addForeignKeyConstraint
335 57
            ( $source_table
336 57
            , array("file", "line")
337 57
            , array("file", "line")
338 57
            );
339 57
        return $relation_table;
340
    }
341
342
    // Creation of database.
343
344 57
    public function init_database_schema() {
345 57
        $schema = new S\Schema();
346
347 57
        $name_table = $this->init_name_table($schema);
348 57
        $file_table = $this->init_file_table($schema);
0 ignored issues
show
Unused Code introduced by
$file_table 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...
349 57
        $source_table = $this->init_source_table($schema, $name_table);
350 57
        $this->init_definition_table($schema, $name_table, $source_table);
351 57
        $this->init_relation_table($schema, $name_table, $source_table);
352
353 57
        $sync = new SingleDatabaseSynchronizer($this->connection);
354 57
        $sync->createSchema($schema);
355 57
    }
356
}
357