1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20:
21: class PgSqlDriver extends Object implements ISupplementalDriver
22: {
23:
24: private $connection;
25:
26:
27:
28: public function __construct(Connection $connection, array $options)
29: {
30: $this->connection = $connection;
31: }
32:
33:
34:
35:
36:
37:
38:
39: 40: 41:
42: public function delimite($name)
43: {
44:
45: return '"' . str_replace('"', '""', $name) . '"';
46: }
47:
48:
49:
50: 51: 52:
53: public function formatBool($value)
54: {
55: return $value ? 'TRUE' : 'FALSE';
56: }
57:
58:
59:
60: 61: 62:
63: public function formatDateTime(DateTime $value)
64: {
65: return $value->format("'Y-m-d H:i:s'");
66: }
67:
68:
69:
70: 71: 72:
73: public function formatLike($value, $pos)
74: {
75: $value = strtr($value, array("'" => "''", '\\' => '\\\\', '%' => '\\\\%', '_' => '\\\\_'));
76: return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
77: }
78:
79:
80:
81: 82: 83:
84: public function applyLimit(&$sql, $limit, $offset)
85: {
86: if ($limit >= 0)
87: $sql .= ' LIMIT ' . (int) $limit;
88:
89: if ($offset > 0)
90: $sql .= ' OFFSET ' . (int) $offset;
91: }
92:
93:
94:
95: 96: 97:
98: public function normalizeRow($row, $statement)
99: {
100: return $row;
101: }
102:
103:
104:
105:
106:
107:
108:
109: 110: 111:
112: public function getTables()
113: {
114: $tables = array();
115: foreach ($this->connection->query("
116: SELECT
117: table_name AS name,
118: table_type = 'VIEW' AS view
119: FROM
120: information_schema.tables
121: WHERE
122: table_schema = current_schema()
123: ") as $row) {
124: $tables[] = (array) $row;
125: }
126:
127: return $tables;
128: }
129:
130:
131:
132: 133: 134:
135: public function getColumns($table)
136: {
137: $columns = array();
138: foreach ($this->connection->query("
139: SELECT
140: c.column_name AS name,
141: c.table_name AS table,
142: upper(c.udt_name) AS nativetype,
143: greatest(c.character_maximum_length, c.numeric_precision) AS size,
144: FALSE AS unsigned,
145: c.is_nullable = 'YES' AS nullable,
146: c.column_default AS default,
147: coalesce(tc.constraint_type = 'PRIMARY KEY', FALSE) AND strpos(c.column_default, 'nextval') = 1 AS autoincrement,
148: coalesce(tc.constraint_type = 'PRIMARY KEY', FALSE) AS primary,
149: substring(c.column_default from 'nextval[(]''\"?([^''\"]+)') AS sequence
150: FROM
151: information_schema.columns AS c
152: LEFT JOIN information_schema.constraint_column_usage AS ccu USING(table_catalog, table_schema, table_name, column_name)
153: LEFT JOIN information_schema.table_constraints AS tc USING(constraint_catalog, constraint_schema, constraint_name)
154: WHERE
155: c.table_name = {$this->connection->quote($table)}
156: AND
157: c.table_schema = current_schema()
158: AND
159: (tc.constraint_type IS NULL OR tc.constraint_type = 'PRIMARY KEY')
160: ORDER BY
161: c.ordinal_position
162: ") as $row) {
163: $column = (array) $row;
164: $column['vendor'] = $column;
165: unset($column['sequence']);
166:
167: $columns[] = $column;
168: }
169:
170: return $columns;
171: }
172:
173:
174:
175: 176: 177:
178: public function getIndexes($table)
179: {
180:
181: $indexes = array();
182: foreach ($this->connection->query("
183: SELECT
184: c2.relname AS name,
185: indisunique AS unique,
186: indisprimary AS primary,
187: attname AS column
188: FROM
189: pg_class AS c1
190: JOIN pg_namespace ON c1.relnamespace = pg_namespace.oid
191: JOIN pg_index ON c1.oid = indrelid
192: JOIN pg_class AS c2 ON indexrelid = c2.oid
193: LEFT JOIN pg_attribute ON c1.oid = attrelid AND attnum = ANY(indkey)
194: WHERE
195: nspname = current_schema()
196: AND
197: c1.relkind = 'r'
198: AND
199: c1.relname = {$this->connection->quote($table)}
200: ") as $row) {
201: $indexes[$row['name']]['name'] = $row['name'];
202: $indexes[$row['name']]['unique'] = $row['unique'];
203: $indexes[$row['name']]['primary'] = $row['primary'];
204: $indexes[$row['name']]['columns'][] = $row['column'];
205: }
206:
207: return array_values($indexes);
208: }
209:
210:
211:
212: 213: 214:
215: public function getForeignKeys($table)
216: {
217:
218: $keys = array();
219: foreach ($this->connection->query("
220: SELECT
221: tc.constraint_name AS name,
222: kcu.column_name AS local,
223: ccu.table_name AS table,
224: ccu.column_name AS foreign
225: FROM
226: information_schema.table_constraints AS tc
227: JOIN information_schema.key_column_usage AS kcu USING(constraint_catalog, constraint_schema, constraint_name)
228: JOIN information_schema.constraint_column_usage AS ccu USING(constraint_catalog, constraint_schema, constraint_name)
229: WHERE
230: constraint_type = 'FOREIGN KEY'
231: AND
232: tc.table_name = {$this->connection->quote($table)}
233: ORDER BY
234: kcu.ordinal_position
235: ") as $row) {
236: $keys[] = (array) $row;
237: }
238:
239: return $keys;
240: }
241:
242:
243:
244: 245: 246:
247: public function isSupported($item)
248: {
249: return $item === self::SUPPORT_COLUMNS_META || $item === self::SUPPORT_SEQUENCE;
250: }
251:
252: }
253: