Completed
Push — master ( 6f7e0c...868d3a )
by Richard
06:00
created

DB::init_sqlite_regexp()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0438

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 10
ccs 7
cts 9
cp 0.7778
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
crap 2.0438
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 licence along with the code.
9
 */
10
11
namespace Lechimp\Dicto\App;
12
13
use Lechimp\Dicto\Analysis\Consts;
14
use Lechimp\Dicto\Analysis\Query;
15
use Lechimp\Dicto\Indexer\Insert;
16
use Doctrine\DBAL\Connection;
17
use Doctrine\DBAL\Schema;
18
use Doctrine\DBAL\Types\Type;
19
use Doctrine\DBAL\Schema\Synchronizer\SingleDatabaseSynchronizer;
20
21
class DB implements Insert, Query {
22
    /**
23
     * @var Connection
24
     */
25
    protected $connection;
26
27 52
    public function __construct(Connection $connection) {
28 52
        $this->connection = $connection;
29 52
    }
30
31
    /**
32
     * @return \Doctrine\DBAL\Query\Builder
33
     */
34 52
    public function builder() {
35 52
        return $this->connection->createQueryBuilder();
36
    }
37
38
    // Implementation of Insert interface.
39
40
    /**
41
     * @inheritdoc
42
     */
43 51
    public function entity($type, $name, $file, $start_line, $end_line, $source) {
44 51
        assert('in_array($type, \\Lechimp\\Dicto\\Analysis\\Consts::$ENTITY_TYPES)');
45 51
        assert('is_string($name)');
46 51
        assert('is_string($file)');
47 51
        assert('is_int($start_line)');
48 51
        assert('is_int($end_line)');
49 51
        assert('is_string($source)');
50 51
        $this->builder()
51 51
            ->insert($this->entity_table())
52 51
            ->values(array
53
                ( "type" => "?"
54 51
                , "name" => "?"
55 51
                , "file" => "?"
56 51
                , "start_line" => "?"
57 51
                , "end_line" => "?"
58 51
                , "source" => "?"
59 51
                ))
60 51
            ->setParameter(0, $type)
61 51
            ->setParameter(1, $name)
62 51
            ->setParameter(2, $file)
63 51
            ->setParameter(3, $start_line)
64 51
            ->setParameter(4, $end_line)
65 51
            ->setParameter(5, $source)
66 51
            ->execute();
67 51
        return (int)$this->connection->lastInsertId();
68
    }
69
70
    /**
71
     * @inheritdoc
72
     */
73 40
    public function reference($type, $name, $file, $line) {
74 40
        assert('in_array($type, \\Lechimp\\Dicto\\Analysis\\Consts::$ENTITY_TYPES)');
75 40
        assert('is_string($name)');
76 40
        assert('is_string($file)');
77 40
        assert('is_int($line)');
78 40
        $this->builder()
79 40
            ->insert($this->reference_table())
80 40
            ->values(array
81
                ( "type" => "?"
82 40
                , "name" => "?"
83 40
                , "file" => "?"
84 40
                , "line" => "?"
85 40
                ))
86 40
            ->setParameter(0, $type)
87 40
            ->setParameter(1, $name)
88 40
            ->setParameter(2, $file)
89 40
            ->setParameter(3, $line)
90 40
            ->execute();
91 40
        return (int)$this->connection->lastInsertId();
92
    }
93
94
    /**
95
     * @inheritdoc
96
     */
97 23 View Code Duplication
    public function dependency($dependent_id, $dependency_id, $file, $line, $source_line) {
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...
98 23
        assert('is_int($dependent_id)');
99 23
        assert('is_int($dependency_id)');
100 23
        assert('is_string($file)');
101 23
        assert('is_int($line)');
102 23
        assert('is_string($source_line)');
103 23
        $this->builder()
104 23
            ->insert($this->dependencies_table())
105 23
            ->values(array
106
                ( "dependent_id" => "?"
107 23
                , "dependency_id" => "?"
108 23
                , "file" => "?"
109 23
                , "line" => "?"
110 23
                , "source_line" => "?"
111 23
                ))
112 23
            ->setParameter(0, $dependent_id)
113 23
            ->setParameter(1, $dependency_id)
114 23
            ->setParameter(2, $file)
115 23
            ->setParameter(3, $line)
116 23
            ->setParameter(4, $source_line)
117 23
            ->execute();
118 23
    }
119
120
    /**
121
     * @inheritdoc
122
     */
123 8 View Code Duplication
    public function invocation($invoker_id, $invokee_id, $file, $line, $source_line) {
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...
124 8
        assert('is_int($invoker_id)');
125 8
        assert('is_int($invokee_id)');
126 8
        assert('is_string($file)');
127 8
        assert('is_int($line)');
128 8
        assert('is_string($source_line)');
129 8
        $this->builder()
130 8
            ->insert($this->invocations_table())
131 8
            ->values(array
132
                ( "invoker_id" => "?"
133 8
                , "invokee_id" => "?"
134 8
                , "file" => "?"
135 8
                , "line" => "?"
136 8
                , "source_line" => "?"
137 8
                ))
138 8
            ->setParameter(0, $invoker_id)
139 8
            ->setParameter(1, $invokee_id)
140 8
            ->setParameter(2, $file)
141 8
            ->setParameter(3, $line)
142 8
            ->setParameter(4, $source_line)
143 8
            ->execute();
144 8
    }
145
146
    // Naming
147
148 52
    public function entity_table() {
149 52
        return "entities";
150
    } 
151
152 52
    public function reference_table() {
153 52
        return "refs";
154
    }
155
156 52
    public function dependencies_table() {
157 52
        return "dependencies";
158
    }
159
160 52
    public function invocations_table() {
161 52
        return "invocations";
162
    }
163
164
    /**
165
     * Initialize REGEXP for sqlite.
166
     */
167 47
    public function init_sqlite_regexp() {
168 47
        $pdo = $this->connection->getWrappedConnection();
169 47
        if (!($pdo instanceof \Doctrine\DBAL\Driver\PDOConnection)) {
170
            throw new \RuntimeException(
171
                "Expected wrapped connection to be PDOConnection.");
172
        }
173 47
        $pdo->sqliteCreateFunction("regexp", function($pattern, $data) {
0 ignored issues
show
Bug introduced by
The method sqliteCreateFunction() does not seem to exist on object<Doctrine\DBAL\Driver\PDOConnection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
174 24
            return preg_match("%$pattern%", $data) > 0;
175 47
        });
176 47
    }
177
178
    // Creation of database.
179
180 47
    public function maybe_init_database_schema() {
181 47
        $res = $this->builder()
182 47
            ->select("COUNT(*)")
183 47
            ->from("sqlite_master")
184 47
            ->where("type = 'table'")
185 47
            ->execute()
186 47
            ->fetchColumn();
187 47
        if ($res == 0) {
188 47
            $this->init_database_schema();
189 47
        }
190 47
    }
191
192 52
    public function init_database_schema() {
193 52
        $schema = new Schema\Schema();
194
195 52
        $entity_table = $schema->createTable($this->entity_table());
196 52
        $entity_table->addColumn
197 52
            ("id", "integer"
198 52
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
199 52
            );
200 52
        $entity_table->addColumn
201 52
            ("type", "string"
202 52
            , array("notnull" => true)
203 52
            );
204 52
        $entity_table->addColumn
205 52
            ("name", "string"
206 52
            , array("notnull" => true)
207 52
            );
208 52
        $entity_table->addColumn
209 52
            ("file", "string"
210 52
            , array("notnull" => true)
211 52
            );
212 52
        $entity_table->addColumn
213 52
            ("start_line", "integer"
214 52
            , array("notnull" => true, "unsigned" => true)
215 52
            );
216 52
        $entity_table->addColumn
217 52
            ("end_line", "integer"
218 52
            , array("notnull" => true, "unsigned" => true)
219 52
            );
220 52
        $entity_table->addColumn
221 52
            ("source", "text"
222 52
            , array("notnull" => true)
223 52
            );
224 52
        $entity_table->setPrimaryKey(array("id"));
225
226 52
        $reference_table = $schema->createTable($this->reference_table());
227 52
        $reference_table->addColumn
228 52
            ( "id", "integer"
229 52
            , array("notnull" => true, "unsigned" => true, "autoincrement" => true)
230 52
            );
231 52
        $reference_table->addColumn
232 52
            ("type", "string"
233 52
            , array("notnull" => true)
234 52
            );
235 52
        $reference_table->addColumn
236 52
            ("name", "string"
237 52
            , array("notnull" => true)
238 52
            );
239 52
        $reference_table->addColumn
240 52
            ("file", "string"
241 52
            , array("notnull" => true)
242 52
            );
243 52
        $reference_table->addColumn
244 52
            ("line", "integer"
245 52
            , array("notnull" => true, "unsigned" => true)
246 52
            );
247 52
        $reference_table->setPrimaryKey(array("id"));
248
249 52
        $dependencies_table = $schema->createTable($this->dependencies_table());
250 52
        $dependencies_table->addColumn
251 52
            ( "dependent_id", "integer"
252 52
            , array("notnull" => true, "unsigned" => true)
253 52
            );
254 52
        $dependencies_table->addColumn
255 52
            ( "dependency_id", "integer"
256 52
            , array("notnull" => true, "unsigned" => true)
257 52
            );
258 52
        $dependencies_table->addColumn
259 52
            ("file", "string"
260 52
            , array("notnull" => true)
261 52
            );
262 52
        $dependencies_table->addColumn
263 52
            ("line", "integer"
264 52
            , array("notnull" => true, "unsigned" => true)
265 52
            );
266 52
        $dependencies_table->addColumn
267 52
            ("source_line", "text"
268 52
            , array("notnull" => true)
269 52
            );
270 52
        $dependencies_table->addForeignKeyConstraint
271 52
            ( $entity_table
272 52
            , array("dependent_id")
273 52
            , array("id")
274 52
            );
275 52
        $dependencies_table->addForeignKeyConstraint
276 52
            ( $reference_table
277 52
            , array("dependency_id")
278 52
            , array("id")
279 52
            );
280
281 52
        $invocations_table = $schema->createTable($this->invocations_table());
282 52
        $invocations_table->addColumn
283 52
            ( "invoker_id", "integer"
284 52
            , array("notnull" => true, "unsigned" => true)
285 52
            );
286 52
        $invocations_table->addColumn
287 52
            ( "invokee_id", "integer"
288 52
            , array("notnull" => true, "unsigned" => true)
289 52
            );
290 52
        $invocations_table->addColumn
291 52
            ("file", "string"
292 52
            , array("notnull" => true)
293 52
            );
294 52
        $invocations_table->addColumn
295 52
            ("line", "integer"
296 52
            , array("notnull" => true, "unsigned" => true)
297 52
            );
298 52
        $invocations_table->addColumn
299 52
            ("source_line", "text"
300 52
            , array("notnull" => true)
301 52
            );
302 52
        $invocations_table->addForeignKeyConstraint
303 52
            ( $entity_table
304 52
            , array("invoker_id")
305 52
            , array("id")
306 52
            );
307 52
        $invocations_table->addForeignKeyConstraint
308 52
            ( $reference_table
309 52
            , array("invokee_id")
310 52
            , array("id")
311 52
            );
312
313 52
        $sync = new SingleDatabaseSynchronizer($this->connection);
314 52
        $sync->createSchema($schema);
315 52
    }
316
}
317