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 SqliteOutputter extends DatabaseOutputter {
34 : private $filename;
35 : private $db;
36 :
37 :
38 :
39 :
40 : public function __construct($filename)
41 : {
42 0 : $this->filename = $filename;
43 0 : }
44 :
45 :
46 :
47 :
48 :
49 : public function __destruct()
50 : {
51 0 : if ($this->db) sqlite_close($this->db);
52 0 : }
53 :
54 :
55 :
56 :
57 :
58 :
59 : protected function connect()
60 : {
61 0 : $this->db = @sqlite_open($this->filename);
62 0 : if ($this->db == false) return false;
63 0 : return true;
64 : }
65 :
66 :
67 :
68 :
69 :
70 : protected function query($query)
71 : {
72 0 : $query = str_ireplace('TRUNCATE', 'DELETE FROM', $query);
73 :
74 0 : $return = sqlite_query($query, $this->db, SQLITE_BOTH, $error);
75 0 : if ($return === false) {
76 0 : echo "<p>Error in query <em>{$query}</em>. SQLite reported the following: <em>{$error}</em></p>";
77 0 : }
78 0 : return $return;
79 : }
80 :
81 :
82 :
83 :
84 :
85 :
86 : protected function sql_safen($input)
87 : {
88 0 : if ($input === null) {
89 0 : return 'NULL';
90 0 : } else if (is_integer($input)) {
91 0 : return $input;
92 : } else {
93 0 : return "'" . sqlite_escape_string($input) . "'";
94 : }
95 : }
96 :
97 :
98 :
99 :
100 :
101 : protected function fetch_row($res)
102 : {
103 0 : return sqlite_fetch_array($res, SQLITE_NUM);
104 : }
105 :
106 :
107 :
108 :
109 :
110 : protected function fetch_assoc($res)
111 : {
112 0 : return sqlite_fetch_array($res, SQLITE_ASSOC);
113 : }
114 :
115 :
116 :
117 :
118 :
119 :
120 : protected function affected_rows($res)
121 : {
122 0 : if ($res) return 1;
123 0 : return 0;
124 : }
125 :
126 :
127 :
128 :
129 :
130 : protected function insert_id()
131 : {
132 0 : return sqlite_last_insert_rowid($this->db);
133 : }
134 :
135 :
136 :
137 :
138 :
139 : protected function do_multiple_insert($table, $data)
140 : {
141 0 : foreach ($data as $row) {
142 0 : $this->do_insert($table, $row);
143 0 : }
144 0 : }
145 :
146 :
147 :
148 :
149 :
150 : protected function get_table_list()
151 : {
152 : $q = "SELECT name FROM sqlite_master
153 : WHERE type='table'
154 0 : ORDER BY name";
155 0 : $res = $this->query ($q);
156 :
157 0 : $tables = array();
158 0 : while ($row = $this->fetch_row($res)) {
159 0 : $tables[] = $row[0];
160 0 : }
161 :
162 0 : return $tables;
163 : }
164 :
165 :
166 :
167 :
168 :
169 :
170 :
171 :
172 :
173 :
174 :
175 :
176 :
177 :
178 : protected function get_sql_type($internal_type_name)
179 : {
180 : switch ($internal_type_name) {
181 0 : case 'serial': return 'INTEGER';
182 0 : case 'smallnum': return 'INTEGER';
183 0 : case 'largenum': return 'INTEGER';
184 0 : case 'string': return 'TEXT';
185 0 : case 'text': return 'TEXT';
186 0 : default:
187 0 : throw new Exception ("Undefined type '{$internal_type_name}' specified");
188 : break;
189 0 : }
190 : }
191 :
192 :
193 :
194 :
195 :
196 :
197 :
198 :
199 : public function check_layout($layout_filename)
200 : {
201 :
202 :
203 :
204 :
205 0 : if ($this->db) sqlite_close($this->db);
206 :
207 0 : $fp = @fopen($this->filename, 'wb');
208 0 : if ($fp) {
209 0 : ftruncate($fp, 0);
210 0 : fclose($fp);
211 0 : }
212 :
213 0 : $this->db = @sqlite_open($this->filename);
214 0 : if ($this->db == false) {
215 0 : throw new Exception('Failed to reconnect to db');
216 : }
217 :
218 0 : parent::check_layout($layout_filename);
219 0 : }
220 :
221 :
222 :
223 :
224 :
225 :
226 :
227 :
228 :
229 :
230 :
231 :
232 :
233 :
234 : protected function get_column_details($table_name)
235 : {
236 :
237 :
238 :
239 :
240 :
241 0 : return;
242 :
243 : $columns = array();
244 : while ($row = $this->fetch_assoc($res)) {
245 : if ($row['Null'] == 'YES') {
246 : $row['NotNull'] = false;
247 : } else {
248 : $row['NotNull'] = true;
249 : }
250 :
251 :
252 : $row['Type'] = preg_replace('/\(.+\)/', '', $row['Type']);
253 : $row['Type'] = strtolower($row['Type']);
254 : switch ($row['Type']) {
255 : case 'smallint unsigned': $row['Type'] = 'smallnum'; break;
256 : case 'smallint': $row['Type'] = 'smallnum'; break;
257 : case 'int unsigned': $row['Type'] = 'largenum'; break;
258 : case 'int': $row['Type'] = 'largenum'; break;
259 : case 'varchar': $row['Type'] = 'string'; break;
260 : case 'mediumtext': $row['Type'] = 'text'; break;
261 : }
262 :
263 :
264 : if (strcasecmp('bigint unsigned', $row['Type']) == 0
265 : and $row['NotNull']
266 : and stripos('auto_increment', $row['Extra']) !== false) {
267 : $row['Type'] = 'serial';
268 : }
269 :
270 : unset ($row['Extra'], $row['Default']);
271 : $columns[] = $row;
272 : }
273 :
274 : return $columns;
275 : }
276 :
277 :
278 :
279 :
280 :
281 : protected function get_alter_column_query($table, $column_name, $new_type, $not_null)
282 : {
283 0 : $new_type = $this->get_sql_type($new_type);
284 :
285 0 : $q = "ALTER TABLE {$table} MODIFY COLUMN {$column_name} {$new_type}";
286 0 : return $q;
287 : }
288 :
289 :
290 :
291 :
292 :
293 : protected function create_table($table_name, $dest_table)
294 : {
295 0 : $q = "CREATE TABLE {$table_name} (\n";
296 0 : foreach ($dest_table['Columns'] as $col_name => $col_def) {
297 0 : $dest_sql = $this->get_sql_type($col_def['Type']);
298 0 : if ($col_def['NotNull']) $dest_sql .= ' not null';
299 :
300 0 : $q .= " {$col_name} {$dest_sql},\n";
301 0 : }
302 0 : $q .= " PRIMARY KEY ({$dest_table['PK']})\n";
303 0 : $q .= ")";
304 0 : echo "<b>Query:\n{$q}</b>\n";
305 :
306 0 : $res = $this->query ($q);
307 0 : if ($res) echo 'Affected rows: ', $this->affected_rows($res), "\n";
308 0 : }
309 :
310 :
311 :
312 :
313 :
314 : protected function start_transaction()
315 : {
316 0 : $this->query ('BEGIN TRANSACTION');
317 0 : }
318 :
319 :
320 :
321 :
322 :
323 : protected function commit_transaction()
324 : {
325 0 : $this->query ('COMMIT TRANSACTION');
326 0 : }
327 :
328 :
329 :
330 :
331 :
332 : protected function rollback_transaction()
333 : {
334 0 : $this->query ('ROLLBACK TRANSACTION');
335 0 : }
336 :
337 :
338 : }
339 :
340 :
341 : ?>
|