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: throw new Nette\NotImplementedException;
68: }
69:
70:
71:
72: 73: 74:
75: public function applyLimit(&$sql, $limit, $offset)
76: {
77: if ($limit >= 0)
78: $sql .= ' LIMIT ' . (int) $limit;
79:
80: if ($offset > 0)
81: $sql .= ' OFFSET ' . (int) $offset;
82: }
83:
84:
85:
86: 87: 88:
89: public function normalizeRow($row, $statement)
90: {
91: return $row;
92: }
93:
94:
95:
96:
97:
98:
99:
100: 101: 102:
103: public function getTables()
104: {
105: return $this->connection->query("
106: SELECT table_name as name, CAST(table_type = 'VIEW' AS INTEGER) as view
107: FROM information_schema.tables
108: WHERE table_schema = current_schema()
109: ")->fetchAll();
110: }
111:
112:
113:
114: 115: 116:
117: public function getColumns($table)
118: {
119: $primary = (int) $this->connection->query("
120: SELECT indkey
121: FROM pg_class
122: LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid AND pg_index.indisprimary
123: WHERE pg_class.relname = {$this->connection->quote($table)}
124: ")->fetchColumn(0);
125:
126: $columns = array();
127: foreach ($this->connection->query("
128: SELECT *
129: FROM information_schema.columns
130: WHERE table_name = {$this->connection->quote($table)} AND table_schema = current_schema()
131: ORDER BY ordinal_position
132: ") as $row) {
133: $size = (int) max($row['character_maximum_length'], $row['numeric_precision']);
134: $columns[] = array(
135: 'name' => $row['column_name'],
136: 'table' => $table,
137: 'nativetype' => strtoupper($row['udt_name']),
138: 'size' => $size ? $size : NULL,
139: 'nullable' => $row['is_nullable'] === 'YES',
140: 'default' => $row['column_default'],
141: 'autoincrement' => (int) $row['ordinal_position'] === $primary && substr($row['column_default'], 0, 7) === 'nextval',
142: 'primary' => (int) $row['ordinal_position'] === $primary,
143: 'vendor' => (array) $row,
144: );
145: }
146: return $columns;
147: }
148:
149:
150:
151: 152: 153:
154: public function getIndexes($table)
155: {
156: $columns = array();
157: foreach ($this->connection->query("
158: SELECT ordinal_position, column_name
159: FROM information_schema.columns
160: WHERE table_name = {$this->connection->quote($table)} AND table_schema = current_schema()
161: ORDER BY ordinal_position
162: ") as $row) {
163: $columns[$row['ordinal_position']] = $row['column_name'];
164: }
165:
166: $indexes = array();
167: foreach ($this->connection->query("
168: SELECT pg_class2.relname, indisunique, indisprimary, indkey
169: FROM pg_class
170: LEFT JOIN pg_index on pg_class.oid = pg_index.indrelid
171: INNER JOIN pg_class as pg_class2 on pg_class2.oid = pg_index.indexrelid
172: WHERE pg_class.relname = {$this->connection->quote($table)}
173: ") as $row) {
174: $indexes[$row['relname']]['name'] = $row['relname'];
175: $indexes[$row['relname']]['unique'] = $row['indisunique'] === 't';
176: $indexes[$row['relname']]['primary'] = $row['indisprimary'] === 't';
177: foreach (explode(' ', $row['indkey']) as $index) {
178: $indexes[$row['relname']]['columns'][] = $columns[$index];
179: }
180: }
181: return array_values($indexes);
182: }
183:
184:
185:
186: 187: 188:
189: public function getForeignKeys($table)
190: {
191: throw new NotImplementedException;
192: }
193:
194:
195:
196: 197: 198:
199: public function isSupported($item)
200: {
201: return $item === self::META;
202: }
203:
204: }
205: