Completed
Push — master ( 389cae...29b40e )
by Richard
06:27
created

DB::relation()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 23

Duplication

Lines 25
Ratio 100 %

Code Coverage

Tests 24
CRAP Score 1

Importance

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