Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
PDOAccess
0.00% covered (danger)
0.00%
0 / 70
0.00% covered (danger)
0.00%
0 / 13
1190
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
20
 __call
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 postConnect
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 loadAccessor
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 connect
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0
 getConnection
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 query
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 exec
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 prepare
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 beginTransaction
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 commit
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 rollBack
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 inTransaction
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace BO\Zmsdldb;
4
5abstract class PDOAccess extends AbstractAccess
6{
7    /**
8     * @SuppressWarnings(PHPMD.LongVariable)
9     */
10    protected $accessorClassName = [];
11
12    protected $accessorNamesPlural = [
13        'Authority' => 'Authorities',
14        'Borough' => 'Boroughs',
15        'Link' => 'Links',
16        'Location' => 'Locations',
17        'Office' => 'Offices',
18        'Service' => 'Services',
19        'Setting' => 'Settings',
20        'Topic' => 'Topics'
21    ];
22
23    protected $pdo;
24
25    protected string $engine = 'SQLite';
26
27
28    public function __construct(array $options)
29    {
30        try {
31            $parts = explode("\\", static::class);
32            $this->engine = str_replace('Access', '', end($parts));
33
34            $accessorNameKeys = array_keys($this->accessorNamesPlural);
35            $accessorClassName = array_flip($this->accessorNamesPlural);
36
37            $this->accessorClassName = array_merge(
38                $accessorClassName,
39                array_combine($accessorNameKeys, $accessorNameKeys)
40            );
41            $this->accessorNamesPlural = array_merge(
42                $this->accessorNamesPlural,
43                array_flip($this->accessorNamesPlural)
44            );
45
46            if (isset($options['pdoConnection']) && $options['pdoConnection'] instanceof \PDO) {
47                $this->pdo = $options['pdoConnection'];
48            } else {
49                $this->connect($options);
50            }
51            $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
52            $this->postConnect();
53        } catch (\Exception $e) {
54            throw $e;
55        }
56    }
57
58    #[\Override]
59    public function __call($method, $args = [])
60    {
61        try {
62            return parent::__call($method, $args);
63        } catch (\Exception $e) {
64            if ('loadFromPath' != $method && preg_match('/load(?P<accessor>[A-Za-z_0-9]+)/', $method, $matches)) {
65                $locale = $args[0] ?? 'de';
66                $instance = $this->loadAccessor($matches['accessor'], $locale);
67
68                return $instance;
69            }
70        }
71    }
72
73    /**
74     * @return void
75     */
76    protected function postConnect()
77    {
78    }
79
80    public function loadAccessor(string $name, string $locale = 'de')
81    {
82        if (isset($this->accessorClassName[$name])) {
83            if (null === $this->accessInstance[$locale][$this->accessorClassName[$name]]) {
84                $accessorClass = __NAMESPACE__ . '\\' . $this->engine . '\\' . $this->accessorClassName[$name];
85
86                $instance = new $accessorClass($this, $locale);
87                $this->accessInstance[$locale][$name] = $instance;
88                $this->accessInstance[$locale][$this->accessorNamesPlural[$name]] = $instance;
89            }
90            return $this->accessInstance[$locale][$name];
91        }
92        throw new \Exception('Invalid accessor');
93    }
94
95    abstract protected function connect(array $options): void;
96
97    /** @psalm-api */
98    public function getConnection()
99    {
100        return $this->pdo;
101    }
102
103    /**
104     * parameters see https://www.php.net/manual/de/pdo.query.php
105     */
106
107    public function query(...$args)
108    {
109        try {
110            return $this->pdo->query(...$args);
111        } catch (\Exception $e) {
112            throw $e;
113        }
114    }
115
116    /**
117     * parameters see https://www.php.net/manual/de/pdo.exec.php
118     */
119    public function exec(string ...$args)
120    {
121        try {
122            return $this->pdo->exec(...$args);
123        } catch (\Exception $e) {
124            throw $e;
125        }
126    }
127
128    /**
129     * parameters see https://www.php.net/manual/de/pdo.prepare.php
130     */
131    public function prepare(string ...$args)
132    {
133        try {
134            return $this->pdo->prepare(...$args);
135        } catch (\Exception $e) {
136            throw $e;
137        }
138    }
139
140    protected $transactionCount = 0;
141
142    public function beginTransaction()
143    {
144        try {
145            $this->transactionCount++;
146            if ($this->inTransaction()) {
147                return true;
148            }
149            return $this->pdo->beginTransaction();
150        } catch (\Exception $e) {
151            throw $e;
152        }
153    }
154
155    public function commit()
156    {
157        try {
158            $this->transactionCount--;
159            if ($this->transactionCount == 0 && $this->inTransaction()) {
160                return $this->pdo->commit();
161            } elseif (!$this->inTransaction()) {
162                trigger_error(__METHOD__ . ' no transaction started');
163            }
164            return true;
165        } catch (\Exception $e) {
166            throw $e;
167        }
168    }
169
170    public function rollBack()
171    {
172        try {
173            $this->transactionCount--;
174            if ($this->transactionCount == 0 && $this->inTransaction()) {
175                return $this->pdo->rollBack();
176            } elseif (!$this->inTransaction()) {
177                trigger_error(__METHOD__ . ' no transaction started');
178            }
179            return true;
180        } catch (\Exception $e) {
181            throw $e;
182        }
183    }
184
185    public function inTransaction()
186    {
187        try {
188            return $this->pdo->inTransaction();
189        } catch (\Exception $e) {
190            throw $e;
191        }
192    }
193}