• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ICanBoogie / ActiveRecord / 11642569649

02 Nov 2024 12:10PM UTC coverage: 83.671% (-0.4%) from 84.036%
11642569649

push

github

olvlvl
Add ConnectionTelemetry

30 of 41 new or added lines in 4 files covered. (73.17%)

5 existing lines in 3 files now uncovered.

1404 of 1678 relevant lines covered (83.67%)

21.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.54
/lib/ActiveRecord/Driver/TableRendererForPostgreSQL.php
1
<?php
2

3
namespace ICanBoogie\ActiveRecord\Driver;
4

5
use ICanBoogie\ActiveRecord\Schema;
6
use ICanBoogie\ActiveRecord\Schema\BelongsTo;
7
use ICanBoogie\ActiveRecord\Schema\Binary;
8
use ICanBoogie\ActiveRecord\Schema\Blob;
9
use ICanBoogie\ActiveRecord\Schema\Boolean;
10
use ICanBoogie\ActiveRecord\Schema\Column;
11
use ICanBoogie\ActiveRecord\Schema\Date;
12
use ICanBoogie\ActiveRecord\Schema\DateTime;
13
use ICanBoogie\ActiveRecord\Schema\Integer;
14
use ICanBoogie\ActiveRecord\Schema\Serial;
15
use ICanBoogie\ActiveRecord\Schema\Text;
16
use ICanBoogie\ActiveRecord\Schema\Time;
17

18
use InvalidArgumentException;
19

20
use function implode;
21
use function in_array;
22
use function is_array;
23
use function PHPUnit\Framework\matches;
24

25
/**
26
 * @see https://www.sqlite.org/lang_createtable.html
27
 */
28
class TableRendererForPostgreSQL extends TableRenderer
29
{
30
    protected function render_column_defs(Schema $schema): array
31
    {
32
        $render = [];
5✔
33

34
        foreach ($schema->columns as $name => $column) {
5✔
35
            $type = $this->render_type_name($column);
5✔
36
            $constraint = $this->render_column_constraint($column);
5✔
37

38
            $render[] = "$name $type $constraint";
5✔
39
        }
40

41
        return $render;
5✔
42
    }
43

44
    protected function render_type_name(Column $column): string
45
    {
46
        return match ($column::class) {
5✔
47
            Serial::class => match ($column->size) {
2✔
UNCOV
48
                Integer::SIZE_SMALL => "SMALLSERIAL",
×
49
                Integer::SIZE_REGULAR => "SERIAL",
2✔
UNCOV
50
                Integer::SIZE_BIG => "BIGSERIAL",
×
51
                default => throw new InvalidArgumentException("Serial size {$column->size} is not supported by PostgreSQL")
2✔
52
            },
2✔
53
            BelongsTo::class, Integer::class => match ($column->size) {
2✔
UNCOV
54
                Integer::SIZE_SMALL => "SMALLINT",
×
55
                Integer::SIZE_REGULAR => "INTEGER",
2✔
56
                Integer::SIZE_BIG => "BIGINT",
1✔
57
                default => throw new InvalidArgumentException("Integer size {$column->size} is not supported by PostgreSQL")
2✔
58
            },
2✔
59

60
            // https://www.postgresql.org/docs/current/datatype-bit.html
61
            Binary::class => $column->fixed
1✔
62
                ? "BIT($column->size)"
1✔
63
                : "BIT VARYING($column->size)",
1✔
64

65
            // https://www.postgresql.org/docs/current/datatype-character.html
66
            Text::class => "TEXT",
1✔
67
            // https://www.postgresql.org/docs/current/datatype-binary.html
68
            Blob::class => "BYTEA",
1✔
69

70
            // https://www.postgresql.org/docs/current/datatype-datetime.html
71
            DateTime::class => "TIMESTAMP",
1✔
72

73
            default => parent::render_type_name($column)
5✔
74
        };
5✔
75
    }
76

77
    private function render_column_constraint(Column $column): string
78
    {
79
        $constraint = '';
5✔
80

81
        if ($column instanceof Integer && !$column instanceof Boolean && !$column instanceof Serial) {
5✔
82
            $constraint .= $column->unsigned ? " UNSIGNED" : '';
2✔
83
        }
84

85
        $constraint .= $column->null ? " NULL" : " NOT NULL";
5✔
86
        $constraint .= $column->default !== null ? " DEFAULT " . $this->format_default($column->default) : '';
5✔
87
        $constraint .= $column->unique ? " UNIQUE" : '';
5✔
88
        $constraint .= $column->collate ? " COLLATE $column->collate" : '';
5✔
89

90
        // foreign-key-clause goes here
91

92
        return ltrim($constraint);
5✔
93
    }
94

95
    private function format_default(string $default): string
96
    {
97
        if (in_array($default, [ DateTime::CURRENT_TIMESTAMP, Date::CURRENT_DATE, Time::CURRENT_TIME ])) {
1✔
98
            return "($default)";
1✔
99
        }
100

101
        return $default;
×
102
    }
103

104
    protected function render_table_constraints(Schema $schema): array
105
    {
106
        $constraints = [];
5✔
107

108
        //
109
        // PRIMARY KEY
110
        //
111
        $primary = $schema->primary;
5✔
112

113
        if (is_array($primary)) {
5✔
114
            $primary = implode(', ', $primary);
1✔
115
            $constraints[] = "PRIMARY KEY ($primary)";
1✔
116
        } elseif (is_string($primary)) {
4✔
117
            $constraints[] = "PRIMARY KEY ($primary)";
1✔
118
        }
119

120
        //
121
        // UNIQUE
122
        //
123
        foreach ($schema->indexes as $index) {
5✔
124
            if (!$index->unique || $index->name) {
3✔
125
                continue;
3✔
126
            }
127

128
            $indexed_columns = is_array($index->columns)
1✔
129
                ? implode(', ', $index->columns)
×
130
                : $index->columns;
1✔
131
            $constraints[] = "UNIQUE ($indexed_columns)";
1✔
132
        }
133

134
        return $constraints;
5✔
135
    }
136

137
    protected function render_create_index(Schema $schema, string $prefixed_table_name): string
138
    {
139
        $create_index = '';
5✔
140

141
        foreach ($schema->indexes as $index) {
5✔
142
            $name = $index->name;
3✔
143

144
            // Unnamed UNIQUE indexes have been added during render_table_constraints()
145
            if ($index->unique && !$name) {
3✔
146
                continue;
1✔
147
            }
148

149
            $unique = $index->unique ? 'UNIQUE ' : '';
3✔
150
            $columns = $index->columns;
3✔
151
            if (!$name) {
3✔
152
                $name = is_array($columns) ? implode('_', $columns) : $columns;
2✔
153
            }
154
            $columns = $this->render_column_list($columns);
3✔
155
            $create_index .= "CREATE {$unique}INDEX $name ON $prefixed_table_name ($columns);\n";
3✔
156
        }
157

158
        return rtrim($create_index, "\n");
5✔
159
    }
160

161
    /**
162
     * @param string|string[] $columns
163
     */
164
    private function render_column_list(string|array $columns): string
165
    {
166
        return is_array($columns) ? implode(', ', $columns) : $columns;
3✔
167
    }
168

169
    protected function render_table_options(): array
170
    {
171
        return [];
5✔
172
    }
173
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc