Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
15 / 15 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
SQL | |
100.00% |
15 / 15 |
|
100.00% |
6 / 6 |
14 | |
100.00% |
1 / 1 |
explain | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
random | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
dbList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
tableList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
systemTableList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
viewList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
triggerList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
functionList | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
procedureList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
sequenceList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
columnList | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
typeList | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
fkList | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
indexList | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 |
1 | <?php declare(strict_types=1); |
2 | /** |
3 | * Query |
4 | * |
5 | * SQL Query Builder / Database Abstraction Layer |
6 | * |
7 | * PHP version 8.1 |
8 | * |
9 | * @package Query |
10 | * @author Timothy J. Warren <tim@timshome.page> |
11 | * @copyright 2012 - 2023 Timothy J. Warren |
12 | * @license http://www.opensource.org/licenses/mit-license.html MIT License |
13 | * @link https://git.timshomepage.net/aviat/Query |
14 | * @version 4.0.0 |
15 | */ |
16 | |
17 | namespace Query\Drivers\Pgsql; |
18 | |
19 | use Query\Drivers\AbstractSQL; |
20 | |
21 | /** |
22 | * PostgreSQL specific SQL |
23 | */ |
24 | class SQL extends AbstractSQL |
25 | { |
26 | /** |
27 | * Get the query plan for the sql query |
28 | */ |
29 | public function explain(string $sql): string |
30 | { |
31 | return "EXPLAIN VERBOSE {$sql}"; |
32 | } |
33 | |
34 | /** |
35 | * Random ordering keyword |
36 | */ |
37 | public function random(): string |
38 | { |
39 | return ' RANDOM()'; |
40 | } |
41 | |
42 | /** |
43 | * Returns sql to list other databases |
44 | */ |
45 | public function dbList(): string |
46 | { |
47 | return <<<'SQL' |
48 | SELECT "datname" FROM "pg_database" |
49 | WHERE "datname" NOT IN ('template0','template1') |
50 | ORDER BY "datname" ASC |
51 | SQL; |
52 | } |
53 | |
54 | /** |
55 | * Returns sql to list tables |
56 | */ |
57 | public function tableList(): string |
58 | { |
59 | return <<<'SQL' |
60 | SELECT "table_name" |
61 | FROM "information_schema"."tables" |
62 | WHERE "table_type" = 'BASE TABLE' |
63 | AND "table_schema" NOT IN |
64 | ('pg_catalog', 'information_schema'); |
65 | SQL; |
66 | } |
67 | |
68 | /** |
69 | * Returns sql to list system tables |
70 | */ |
71 | public function systemTableList(): string |
72 | { |
73 | return <<<'SQL' |
74 | SELECT "table_name" |
75 | FROM "information_schema"."tables" |
76 | WHERE "table_type" = 'BASE TABLE' |
77 | AND "table_schema" IN |
78 | ('pg_catalog', 'information_schema'); |
79 | SQL; |
80 | } |
81 | |
82 | /** |
83 | * Returns sql to list views |
84 | */ |
85 | public function viewList(): string |
86 | { |
87 | return <<<'SQL' |
88 | SELECT "viewname" FROM "pg_views" |
89 | WHERE "schemaname" NOT IN |
90 | ('pg_catalog', 'information_schema') |
91 | AND "viewname" !~ '^pg_' |
92 | ORDER BY "viewname" ASC |
93 | SQL; |
94 | } |
95 | |
96 | /** |
97 | * Returns sql to list triggers |
98 | */ |
99 | public function triggerList(): string |
100 | { |
101 | return <<<'SQL' |
102 | SELECT * |
103 | FROM "information_schema"."triggers" |
104 | WHERE "trigger_schema" NOT IN |
105 | ('pg_catalog', 'information_schema') |
106 | SQL; |
107 | } |
108 | |
109 | /** |
110 | * Return sql to list functions |
111 | */ |
112 | public function functionList(): ?string |
113 | { |
114 | return NULL; |
115 | } |
116 | |
117 | /** |
118 | * Return sql to list stored procedures |
119 | */ |
120 | public function procedureList(): string |
121 | { |
122 | return <<<'SQL' |
123 | SELECT "routine_name" |
124 | FROM "information_schema"."routines" |
125 | WHERE "specific_schema" NOT IN |
126 | ('pg_catalog', 'information_schema') |
127 | AND "type_udt_name" != 'trigger'; |
128 | SQL; |
129 | } |
130 | |
131 | /** |
132 | * Return sql to list sequences |
133 | */ |
134 | public function sequenceList(): string |
135 | { |
136 | return <<<'SQL' |
137 | SELECT "c"."relname" |
138 | FROM "pg_class" "c" |
139 | WHERE "c"."relkind" = 'S' |
140 | ORDER BY "relname" ASC |
141 | SQL; |
142 | } |
143 | |
144 | /** |
145 | * Return sql to list columns of the specified table |
146 | */ |
147 | public function columnList(string $table): string |
148 | { |
149 | return <<<SQL |
150 | SELECT ordinal_position, |
151 | column_name, |
152 | data_type, |
153 | column_default, |
154 | is_nullable, |
155 | character_maximum_length, |
156 | numeric_precision |
157 | FROM information_schema.columns |
158 | WHERE table_name = '{$table}' |
159 | ORDER BY ordinal_position; |
160 | SQL; |
161 | } |
162 | |
163 | /** |
164 | * SQL to show list of field types |
165 | */ |
166 | public function typeList(): string |
167 | { |
168 | return <<<'SQL' |
169 | SELECT "typname" FROM "pg_catalog"."pg_type" |
170 | WHERE "typname" !~ '^pg_|_' |
171 | AND "typtype" = 'b' |
172 | ORDER BY "typname" |
173 | SQL; |
174 | } |
175 | |
176 | /** |
177 | * Get the list of foreign keys for the current |
178 | * table |
179 | */ |
180 | public function fkList(string $table): string |
181 | { |
182 | return <<<SQL |
183 | SELECT |
184 | "att2"."attname" AS "child_column", |
185 | "cl"."relname" AS "parent_table", |
186 | "att"."attname" AS "parent_column", |
187 | "con"."update" AS "update", |
188 | "con"."update" AS "delete" |
189 | FROM |
190 | (SELECT |
191 | unnest(con1.conkey) AS "parent", |
192 | unnest(con1.confkey) AS "child", |
193 | "con1"."confrelid", |
194 | "con1"."conrelid", |
195 | "con1"."confupdtype" as "update", |
196 | "con1"."confdeltype" as "delete" |
197 | FROM "pg_class" "cl" |
198 | JOIN "pg_namespace" "ns" ON "cl"."relnamespace" = "ns"."oid" |
199 | JOIN "pg_constraint" "con1" ON "con1"."conrelid" = "cl"."oid" |
200 | WHERE "cl"."relname" = '{$table}' |
201 | AND "ns"."nspname" = 'public' |
202 | AND "con1"."contype" = 'f' |
203 | ) |
204 | "con" |
205 | JOIN "pg_attribute" "att" ON |
206 | "att"."attrelid" = "con"."confrelid" |
207 | AND "att"."attnum" = "con"."child" |
208 | JOIN "pg_class" "cl" ON |
209 | "cl"."oid" = "con"."confrelid" |
210 | JOIN "pg_attribute" "att2" ON |
211 | "att2"."attrelid" = "con"."conrelid" |
212 | AND "att2"."attnum" = "con"."parent" |
213 | SQL; |
214 | } |
215 | |
216 | /** |
217 | * Get the list of indexes for the current table |
218 | */ |
219 | public function indexList(string $table): string |
220 | { |
221 | return <<<SQL |
222 | SELECT |
223 | t.relname AS table_name, |
224 | i.relname AS index_name, |
225 | array_to_string(array_agg(a.attname), ', ') AS column_names |
226 | FROM |
227 | pg_class t, |
228 | pg_class i, |
229 | pg_index ix, |
230 | pg_attribute a |
231 | WHERE |
232 | t.oid = ix.indrelid |
233 | AND i.oid = ix.indexrelid |
234 | AND a.attrelid = t.oid |
235 | AND a.attnum = ANY(ix.indkey) |
236 | AND t.relkind = 'r' |
237 | AND t.relname = '{$table}' |
238 | GROUP BY |
239 | t.relname, |
240 | i.relname |
241 | ORDER BY |
242 | t.relname, |
243 | i.relname; |
244 | SQL; |
245 | } |
246 | } |