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