Issues (16)

src/PostgresConnection.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Umbrellio\Postgres;
6
7
use DateTimeInterface;
8
use Doctrine\DBAL\Types\Type;
9
use Illuminate\Database\PostgresConnection as BasePostgresConnection;
10
use Illuminate\Support\Traits\Macroable;
11
use PDO;
12
use Umbrellio\Postgres\Extensions\AbstractExtension;
13
use Umbrellio\Postgres\Extensions\Exceptions\ExtensionInvalidException;
14
use Umbrellio\Postgres\Helpers\PostgresTextSanitizer;
15
use Umbrellio\Postgres\Schema\Builder;
16
use Umbrellio\Postgres\Schema\Grammars\PostgresGrammar;
17
use Umbrellio\Postgres\Schema\Types\NumericType;
18
use Umbrellio\Postgres\Schema\Types\TsRangeType;
19
use Umbrellio\Postgres\Schema\Types\TsTzRangeType;
20
21
class PostgresConnection extends BasePostgresConnection
22
{
23
    use Macroable;
24
25
    public $name;
26
27
    private static $extensions = [];
28
29
    private $initialTypes = [
30
        TsRangeType::TYPE_NAME => TsRangeType::class,
31
        TsTzRangeType::TYPE_NAME => TsTzRangeType::class,
32
        NumericType::TYPE_NAME => NumericType::class,
33
    ];
34
35
    /**
36
     * @param AbstractExtension|string $extension
37
     * @codeCoverageIgnore
38
     */
39
    final public static function registerExtension(string $extension): void
40
    {
41
        if (! is_subclass_of($extension, AbstractExtension::class)) {
42
            throw new ExtensionInvalidException(sprintf(
43
                'Class %s must be implemented from %s',
44
                $extension,
45
                AbstractExtension::class
46
            ));
47
        }
48
        self::$extensions[$extension::getName()] = $extension;
49
    }
50
51 27
    public function getSchemaBuilder()
52
    {
53 27
        if ($this->schemaGrammar === null) {
54 27
            $this->schemaGrammar = $this->getDefaultSchemaGrammar();
55
        }
56 27
        return new Builder($this);
57
    }
58
59 29
    public function useDefaultPostProcessor(): void
60
    {
61 29
        parent::useDefaultPostProcessor();
62
63 29
        $this->registerExtensions();
64 29
        $this->registerInitialTypes();
65
    }
66
67 27
    public function bindValues($statement, $bindings)
68
    {
69 27
        if ($this->getPdo()->getAttribute(PDO::ATTR_EMULATE_PREPARES)) {
70 8
            foreach ($bindings as $key => $value) {
71 8
                $parameter = is_string($key) ? $key : $key + 1;
72
73
                switch (true) {
74 8
                    case is_bool($value):
75 2
                        $dataType = PDO::PARAM_BOOL;
76 2
                        break;
77
78 6
                    case $value === null:
79 1
                        $dataType = PDO::PARAM_NULL;
80 1
                        break;
81
82
                    default:
83 5
                        $dataType = PDO::PARAM_STR;
84
                }
85
86 8
                $statement->bindValue($parameter, $value, $dataType);
87
            }
88
        } else {
89 19
            parent::bindValues($statement, $bindings);
90
        }
91
    }
92
93 27
    public function prepareBindings(array $bindings)
94
    {
95 27
        if ($this->getPdo()->getAttribute(PDO::ATTR_EMULATE_PREPARES)) {
96 8
            $grammar = $this->getQueryGrammar();
97
98 8
            foreach ($bindings as $key => $value) {
99 8
                if ($value instanceof DateTimeInterface) {
100 1
                    $bindings[$key] = $value->format($grammar->getDateFormat());
101
                }
102 8
                if (is_string($value)) {
103 2
                    $bindings[$key] = PostgresTextSanitizer::sanitize($value);
104
                }
105
            }
106
107 8
            return $bindings;
108
        }
109
110 19
        return parent::prepareBindings($bindings);
111
    }
112
113 27
    protected function getDefaultSchemaGrammar()
114
    {
115 27
        return new PostgresGrammar($this);
116
    }
117
118 29
    private function registerInitialTypes(): void
119
    {
120 29
        foreach ($this->initialTypes as $type => $typeClass) {
121 29
            if (! Type::hasType($type)) {
122 1
                Type::addType($type, $typeClass);
123
            }
124
        }
125
    }
126
127
    /**
128
     * @codeCoverageIgnore
129
     */
130
    private function registerExtensions(): void
131
    {
132
        collect(self::$extensions)->each(function ($extension) {
0 ignored issues
show
self::extensions of type array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
        collect(/** @scrutinizer ignore-type */ self::$extensions)->each(function ($extension) {
Loading history...
133
            /** @var AbstractExtension $extension */
134
            $extension::register();
135
            foreach ($extension::getTypes() as $type => $typeClass) {
136
                if (! Type::hasType($type)) {
137
                    Type::addType($type, $typeClass);
138
                }
139
            }
140
        });
141
    }
142
}
143