1 : <?php
2 :
3 :
4 :
5 :
6 :
7 :
8 :
9 :
10 :
11 :
12 :
13 :
14 :
15 :
16 :
17 :
18 :
19 :
20 :
21 :
22 :
23 :
24 :
25 :
26 :
27 :
28 :
29 :
30 :
31 :
32 :
33 : class PostgresqlOutputter extends DatabaseOutputter {
34 : private $username;
35 : private $password;
36 : private $server;
37 : private $database;
38 : private $db;
39 :
40 :
41 :
42 :
43 : public function __construct($username, $password, $server, $database)
44 : {
45 0 : $this->username = $username;
46 0 : $this->password = $password;
47 0 : $this->server = $server;
48 0 : $this->database = $database;
49 0 : }
50 :
51 :
52 :
53 :
54 :
55 : public function __destruct()
56 : {
57 0 : if ($this->db) pg_close ($this->db);
58 0 : }
59 :
60 :
61 :
62 :
63 :
64 :
65 : protected function connect()
66 : {
67 0 : $connect = '';
68 0 : if (isset($this->server)) $connect .= "host='{$this->server}' ";
69 0 : if (isset($this->username)) $connect .= "user='{$this->username}' ";
70 0 : if (isset($this->password)) $connect .= "password='{$this->password}' ";
71 0 : if (isset($this->database)) $connect .= "dbname='{$this->database}' ";
72 :
73 0 : $this->db = pg_connect($connect);
74 0 : if ($this->db == false) return false;
75 0 : return true;
76 : }
77 :
78 :
79 :
80 :
81 :
82 : protected function query($query)
83 : {
84 :
85 :
86 :
87 0 : if (strncasecmp('CREATE', $query, 6) == 0 or strncasecmp('ALTER', $query, 5) == 0) {
88 0 : $query = str_replace('unsigned', '', $query);
89 0 : $query = str_replace('mediumtext', 'text', $query);
90 0 : }
91 :
92 0 : $return = @pg_query ($query);
93 0 : if ($return === false) {
94 0 : echo "<p>Error in query:<br><em>{$query}</em><br><br>PostgreSQL reported the following:<br><em>" . pg_last_error() . "</em></p>";
95 0 : }
96 0 : return $return;
97 : }
98 :
99 :
100 :
101 :
102 :
103 :
104 : protected function sql_safen($input)
105 : {
106 0 : if ($input === null) {
107 0 : return 'NULL';
108 0 : } else if (is_integer($input)) {
109 0 : return $input;
110 : } else {
111 0 : return "'" . pg_escape_string($input) . "'";
112 : }
113 : }
114 :
115 :
116 :
117 :
118 :
119 : protected function fetch_row($res)
120 : {
121 0 : return pg_fetch_row ($res);
122 : }
123 :
124 :
125 :
126 :
127 :
128 : protected function fetch_assoc($res)
129 : {
130 0 : return pg_fetch_assoc ($res);
131 : }
132 :
133 :
134 :
135 :
136 :
137 : protected function affected_rows($res)
138 : {
139 0 : return pg_affected_rows($res);
140 : }
141 :
142 :
143 :
144 :
145 :
146 : protected function insert_id()
147 : {
148 0 : $res = $this->query ('SELECT LASTVAL()');
149 0 : $row = $this->fetch_row ($res);
150 0 : return $row[0];
151 : }
152 :
153 :
154 :
155 :
156 :
157 :
158 : protected function get_table_list()
159 : {
160 : $q = "SELECT c.relname AS name
161 : FROM pg_catalog.pg_class AS c
162 : LEFT JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
163 : WHERE c.relkind IN ('r','')
164 : AND n.nspname <> 'pg_catalog'
165 : AND n.nspname !~ '^pg_toast'
166 : AND pg_catalog.pg_table_is_visible(c.oid)
167 0 : ORDER BY 1";
168 0 : $res = $this->query ($q);
169 :
170 0 : $tables = array();
171 0 : while ($row = $this->fetch_assoc($res)) {
172 0 : $tables[] = $row['name'];
173 0 : }
174 :
175 0 : return $tables;
176 : }
177 :
178 :
179 :
180 :
181 :
182 :
183 :
184 :
185 :
186 :
187 :
188 :
189 :
190 :
191 : protected function get_sql_type($internal_type_name)
192 : {
193 : switch ($internal_type_name) {
194 0 : case 'serial': return 'serial';
195 0 : case 'smallnum': return 'smallint';
196 0 : case 'largenum': return 'integer';
197 0 : case 'string': return 'character varying(255)';
198 0 : case 'text': return 'text';
199 0 : default:
200 0 : throw new Exception ("Undefined type '{$internal_type_name}' specified");
201 : break;
202 0 : }
203 : }
204 :
205 :
206 :
207 :
208 :
209 :
210 :
211 :
212 :
213 :
214 :
215 :
216 :
217 :
218 :
219 : protected function get_column_details($table_name)
220 : {
221 :
222 : $q = "SELECT c.oid, n.nspname, c.relname
223 : FROM pg_catalog.pg_class c
224 : LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
225 0 : WHERE c.relname ~ '^({$table_name})$'
226 : AND pg_catalog.pg_table_is_visible(c.oid)
227 0 : ORDER BY 2, 3";
228 0 : $res = $this->query ($q);
229 0 : $row = $this->fetch_assoc ($res);
230 :
231 : $q = "SELECT a.attname,
232 : pg_catalog.format_type(a.atttypid, a.atttypmod),
233 : (
234 : SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
235 : FROM pg_catalog.pg_attrdef d
236 : WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef
237 : ) as extra,
238 : a.attnotnull, a.attnum
239 : FROM pg_catalog.pg_attribute a
240 0 : WHERE a.attrelid = '{$row['oid']}' AND a.attnum > 0 AND NOT a.attisdropped
241 0 : ORDER BY a.attnum";
242 0 : $res = $this->query ($q);
243 :
244 0 : $columns = array();
245 0 : while ($row = $this->fetch_assoc ($res)) {
246 0 : $item = array();
247 :
248 0 : $item['Field'] = $row['attname'];
249 0 : $item['Type'] = $row['format_type'];
250 0 : if ($row['attnotnull'] == 't') {
251 0 : $item['NotNull'] = true;
252 0 : } else {
253 0 : $item['NotNull'] = false;
254 : }
255 :
256 :
257 0 : $row['format_type'] = preg_replace('/\(.+\)/', '', $row['format_type']);
258 0 : $row['format_type'] = strtolower($row['format_type']);
259 0 : switch ($row['format_type']) {
260 0 : case 'smallint': $item['Type'] = 'smallnum'; break;
261 0 : case 'integer': $item['Type'] = 'largenum'; break;
262 0 : case 'character varying': $item['Type'] = 'string'; break;
263 0 : case 'text': $item['Type'] = 'text'; break;
264 0 : }
265 :
266 0 : if (strpos($row['extra'], 'nextval') !== false) {
267 0 : $item['Key'] = 'PRI';
268 0 : $item['Type'] = 'serial';
269 0 : $item['NotNull'] = true;
270 0 : }
271 :
272 0 : $columns[] = $item;
273 0 : }
274 :
275 0 : return $columns;
276 : }
277 :
278 :
279 :
280 :
281 :
282 : protected function get_alter_column_query($table, $column_name, $new_type, $not_null)
283 : {
284 0 : $new_type = $this->get_sql_type($new_type);
285 :
286 0 : echo "NOT NULL: $not_null\n";
287 :
288 0 : $q = "ALTER TABLE {$table} ALTER COLUMN {$column_name} TYPE {$new_type}";
289 0 : $q .= ";\n";
290 :
291 0 : if (! $not_null) {
292 0 : $q .= "ALTER TABLE {$table} ALTER COLUMN {$column_name} SET NOT NULL";
293 0 : } else {
294 0 : $q .= "ALTER TABLE {$table} ALTER COLUMN {$column_name} DROP NOT NULL";
295 : }
296 0 : return $q;
297 : }
298 :
299 :
300 :
301 :
302 :
303 : protected function create_table($table_name, $dest_table)
304 : {
305 0 : $q = "CREATE TABLE {$table_name} (\n";
306 0 : foreach ($dest_table['Columns'] as $col_name => $col_def) {
307 0 : $dest_sql = $this->get_sql_type($col_def['Type']);
308 0 : if ($col_def['NotNull']) $dest_sql .= ' not null';
309 :
310 0 : $q .= " {$col_name} {$dest_sql},\n";
311 0 : }
312 0 : $q .= " PRIMARY KEY ({$dest_table['PK']})\n";
313 0 : $q .= ")";
314 0 : echo "<b>Query:\n{$q}</b>\n";
315 :
316 0 : $res = $this->query ($q);
317 0 : if ($res) echo 'Affected rows: ', $this->affected_rows($res), "\n";
318 0 : }
319 :
320 :
321 :
322 :
323 :
324 : protected function start_transaction()
325 : {
326 0 : $this->query ('BEGIN');
327 0 : }
328 :
329 :
330 :
331 :
332 :
333 : protected function commit_transaction()
334 : {
335 0 : $this->query ('COMMIT');
336 0 : }
337 :
338 :
339 :
340 :
341 :
342 : protected function rollback_transaction()
343 : {
344 0 : $this->query ('ROLLBACK');
345 0 : }
346 :
347 :
348 : }
349 :
350 :
351 : ?>
|