Completed
Push — master ( 4a7f1b...1a5eaf )
by Richard
05:32
created

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