Completed
Push — master ( 322d21...4a7f1b )
by Richard
05:35
created

DB::source_file_table()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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