/[refeed]/trunk/library/RF/InstallController.class.php
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/library/RF/InstallController.class.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Wed Jul 5 00:27:49 2006 UTC (17 years, 10 months ago) by dpavlin
File size: 47130 byte(s)
make working copy of trunk
1 <?php
2 // vim: ts=4 foldcolumn=4 foldmethod=marker
3 /**
4 * RF_Install_Controller class found here.
5 *
6 * This file is part of Reblog,
7 * a derivative work of Feed On Feeds.
8 *
9 * Distributed under the Gnu Public License.
10 *
11 * @package Refeed
12 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
13 * @author Michal Migurski <mike@stamen.com>
14 * @author Michael Frumin <mfrumin@eyebeam.org>
15 * @copyright ©2004 Michael Frumin, Michal Migurski
16 * @link http://reblog.org Reblog
17 * @link http://feedonfeeds.com Feed On Feeds
18 * @version $Revision: 1.10 $
19 */
20
21 /**
22 * RF_Install_Controller handles all installation functionality, including
23 * table creation and upgrades from existing Feed On Feeds or ReFeed data.
24 */
25 class RF_Install_Controller
26 {
27 /**
28 * Reference to operative controller object.
29 * @var RF_Controller
30 */
31 var $controller;
32
33 /**
34 * Descriptions of all DB tables for installation existence check
35 * @var array
36 */
37 var $tables = array();
38
39 /**
40 * @param RF_Controller $controller -
41 *
42 * @uses RF_Install_Controller::$controller Assigned on instantiation, from {@link RF_Controller $controller}.
43 * @uses RF_Install_Controller::$tables Assigned on instantiation, from results of {@link RF_Install_Controller::describeAllTables() describeAllTables()}.
44 */
45 function RF_Install_Controller(&$controller)
46 {
47 if(strtolower(get_class($controller)) != strtolower('RF_Controller'))
48 die("RF_Install_Controller must be instantiated with an RF_Controller.");
49
50 $this->controller =& $controller;
51 $this->tables = $this->describeAllTables();
52 }
53
54 /**
55 * Check whether Aefeed is installed, based on presence of a writeable cache directory.
56 *
57 * @return boolean Return value of {@link RF_Install_Controller::writeableCache() RF_Install_Controller::writeableCache()}
58 *
59 * @uses RF_Install_Controller::writeableCache()
60 */
61 function refeedInstalled()
62 {
63 return $this->writeableCache() /*&& $this->isRefeed2()*/;
64 }
65
66 /**
67 * Installs newest Refeed tables.
68 *
69 * @param string $upgrade Upgrade, or no?
70 * - "yes": Yes, upgrade existing Feed On Feeds or legacy Refeed to latest + greatest.
71 * - "no": Don't.
72 * @return boolean True on success, false otherwise.
73 *
74 * @uses RF_Install_Controller::writeableCache()
75 * @uses RF_Install_Controller::printNote()
76 * @uses RF_Install_Controller::printFreakout()
77 * @uses RF_Install_Controller::printMumble()
78 * @uses RF_Install_Controller::isRefeed2()
79 * @uses RF_Install_Controller::isRefeed1()
80 * @uses RF_Install_Controller::upgradeFromRefeed1()
81 * @uses RF_Install_Controller::isRecess()
82 * @uses RF_Install_Controller::upgradeFromRecess()
83 * @uses RF_Install_Controller::upgradeFromFeedOnFeeds()
84 * @uses RF_Install_Controller::createTables()
85 */
86 function installRefeed($upgrade)
87 {
88 if($this->writeableCache()) {
89 $this->printNote("Your cache directory exists, and is writeable.");
90
91 } else {
92 $this->printFreakout("Your cache directory does not exist, or is not writeable.");
93 return false;
94
95 }
96
97 if($this->isRefeed2()) {
98 $this->printNote("You already have a complete Refeed 2.x database, silly goose.");
99 return true;
100
101 } else {
102 if($upgrade != 'no' && $this->isRefeed2alpha()) {
103 $this->printMumble("You seem to have Refeed 2.0 alpha installed.");
104
105 if(empty($upgrade)) {
106 $this->printFreakout("Do you want to upgrade your Refeed 2.0 alpha database?");
107 print('<p><a href="install.php?upgrade=yes">Yes, upgrade</a> / <a href="install.php?upgrade=no">No, just a clean install</a></p>');
108
109 } elseif($upgrade == 'yes' && $this->upgradeFromRefeed2alpha()) {
110 $this->printNote("Upgraded your Refeed 2.0 alpha database.");
111 return true;
112
113 }
114
115 } elseif($upgrade != 'no' && $this->isRefeed1()) {
116 $this->printMumble("You seem to have Refeed 1.x installed.");
117
118 if(empty($upgrade)) {
119 $this->printFreakout("Do you want to upgrade your Refeed 1.x database? This may take some time, if you are subscribed to a lot of feeds.");
120 print('<p><a href="install.php?upgrade=yes">Yes, upgrade</a> / <a href="install.php?upgrade=no">No, just a clean install</a></p>');
121
122 } elseif($upgrade == 'yes' && $this->upgradeFromRefeed1()) {
123 $this->printNote("Upgraded your Refeed 1.x database.");
124 return true;
125
126 }
127
128 } elseif($upgrade != 'no' && $this->isRecess()) {
129 $this->printMumble("You seem to have ReceSS installed.");
130
131 if(empty($upgrade)) {
132 $this->printFreakout("Do you want to upgrade your ReceSS database? This may take some time, if you are subscribed to a lot of feeds.");
133 print('<p><a href="install.php?upgrade=yes">Yes, upgrade</a> / <a href="install.php?upgrade=no">No, just a clean install</a></p>');
134
135 } elseif($upgrade == 'yes' && $this->upgradeFromRecess()) {
136 $this->printNote("Upgraded your ReceSS database.");
137 return true;
138
139 }
140
141 } elseif($upgrade != 'no' && $this->isFeedOnFeeds()) {
142 $this->printMumble("You seem to have Feed On Feeds installed.");
143
144 if(empty($upgrade)) {
145 $this->printFreakout("Do you want to upgrade your Feed On Feeds database? This may take some time, if you are subscribed to a lot of feeds.");
146 print('<p><a href="install.php?upgrade=yes">Yes, upgrade</a> / <a href="install.php?upgrade=no">No, just a clean install</a></p>');
147
148 } elseif($upgrade == 'yes' && $this->upgradeFromFeedOnFeeds()) {
149 $this->printNote("Upgraded your Feed On Feeds database.");
150 return true;
151
152 }
153
154 } elseif($this->createTables()) {
155 $this->printNote("Installed your Refeed Tables.");
156 return true;
157
158 }
159 }
160
161 return false;
162 }
163
164 /**
165 * Print a note about installation progress to the client.
166 * @param string $string Note to print.
167 */
168 function printNote($string)
169 {
170 printf('<p>%s</p>', htmlspecialchars($string));
171 }
172
173 /**
174 * Print a bold, red warning about installation progress to the client.
175 * @param string $string Warning to print.
176 */
177 function printFreakout($string)
178 {
179 printf('<p style="color: red; font-weight: bold;">%s</p>', htmlspecialchars($string));
180 }
181
182 /**
183 * Print a subtle note about installation progress to the client.
184 * @param string $string Note to print.
185 */
186 function printMumble($string)
187 {
188 printf('<p style="color: gray;">%s</p>', htmlspecialchars($string));
189 }
190
191 /**
192 * Check for existence of writeable cache directory.
193 * Create one if possible.
194 *
195 * @return boolean True on success, false otherwise.
196 *
197 * @uses RF_Install_Controller::printFreakout()
198 */
199 function writeableCache()
200 {
201 $cache = get_configured_cache_dir();
202
203 if(!file_exists($cache)) {
204 $status = @mkdir($cache, 0755);
205
206 if(!$status) {
207 $this->printFreakout("Can't create directory {$cache}. You will need to create it yourself, and make it writeable by your PHP process. Then, reload this page.");
208 return false;
209 }
210 }
211
212 if(!is_writable($cache)) {
213 $this->printFreakout("The directory {$cache} exists, but is not writable. You will need to make it writeable by your PHP process. Then, reload this page.");
214 return false;
215 }
216
217 return true;
218 }
219
220 /**
221 * Get table descriptions for {@link http://feedonfeeds.com Feed On Feeds} tables.
222 *
223 * @return array Associative array with column/type listings for two tables:
224 * - "item_table" - items
225 * - "feed_table" - feeds
226 */
227 function tablesInFeedOnFeeds()
228 {
229 $item_table = array(
230 'id' => 'int',
231 'feed_id' => 'int',
232 'timestamp' => 'timestamp',
233 'link' => 'text',
234 'title' => 'varchar',
235 'content' => 'text',
236 'dcdate' => 'text',
237 'dccreator' => 'text',
238 'dcsubject' => 'text',
239 'read' => 'tinyint'
240 );
241
242 $feed_table = array(
243 'id' => 'int',
244 'url' => 'varchar',
245 'title' => 'varchar',
246 'link' => 'varchar',
247 'description' => 'varchar'
248 );
249
250 return compact('item_table', 'feed_table');
251 }
252
253 /**
254 * Check whether there is an active installation of {@link http://feedonfeeds.com Feed On Feeds} in the current database.
255 *
256 * @return boolean True if tables matching {@link RF_Install_Controller::tablesInFeedOnFeeds() tablesInFeedOnFeeds} are found, false otherwise.
257 *
258 * @uses RF_Install_Controller::tablesInFeedOnFeeds()
259 * @uses RF_Install_Controller::$tables Searched for {@link http://feedonfeeds.com Feed On Feeds} tables.
260 */
261 function isFeedOnFeeds()
262 {
263 extract($this->tablesInFeedOnFeeds());
264
265 return (in_array($item_table, $this->tables)
266 && in_array($feed_table, $this->tables));
267 }
268
269 /**
270 * Upgrade existing {@link http://feedonfeeds.com Feed On Feeds} tables to fresh new Refeed tables.
271 * @todo This method is currently empty.
272 */
273 function upgradeFromFeedOnFeeds()
274 {
275 // stub
276
277 /*
278 print_note("Upgrading database from Feed On Feeds.");
279
280 $temp_item_table = REF_ITEM_TABLE . "__TMP";
281 $query1 = sprintf('ALTER TABLE %s RENAME TO %s',
282 REF_ITEM_TABLE,
283 $temp_item_table);
284
285 $temp_feed_table = REF_FEED_TABLE . "__TMP";
286 $query2 = sprintf('ALTER TABLE %s RENAME TO %s',
287 REF_FEED_TABLE,
288 $temp_feed_table);
289
290 if(!(ref_do_query($query1, null, 1) && ref_do_query($query2, null, 1)))
291 trigger_error("Can't rename tables. MySQL says: " . mysql_error(), INSTALL_FATAL);
292
293 do_create_tables();
294
295 ref_do_query(sprintf('INSERT INTO %s
296 (id, url, title, link, description)
297 SELECT id, url, title, link, description
298 FROM %s',
299 REF_FEED_TABLE,
300 $temp_feed_table));
301
302 ref_do_query(sprintf('INSERT INTO %s
303 (id, feed_id, published)
304 SELECT id, id, NULL
305 FROM %s',
306 REF_FEED_SELECT_TABLE,
307 REF_FEED_TABLE));
308
309 ref_do_query(sprintf('INSERT INTO %s
310 (id, feed_id, guid, `timestamp`, link, title, content, dcdate, dccreator, dcsubject)
311 SELECT i.id, i.feed_id, CONCAT("%s", MD5(CONCAT(f.url,i.link,i.title,i.content))), i.`timestamp`, i.link, i.title, i.content, i.dcdate, i.dccreator, i.dcsubject
312 FROM %s i
313 INNER JOIN %s f
314 ON i.feed_id = f.id',
315 REF_ITEM_TABLE,
316 REF_GUID_TAG_PREFIX,
317 $temp_item_table,
318 REF_FEED_TABLE));
319
320
321 ref_do_query(sprintf('INSERT INTO %s
322 (id, item_id, feed_id, `read`, published, link, title, content, `timestamp`)
323 SELECT id, id, feed_id, IF(`read` is NULL, NULL, 1), IF(`read` is NULL or `read` = 1, NULL, 1), NULL, NULL, NULL, `timestamp`
324 FROM %s',
325 REF_ITEM_SELECT_TABLE,
326 $temp_item_table));
327
328 $query1 = sprintf('DROP TABLE %s', $temp_feed_table);
329 $query2 = sprintf('DROP TABLE %s', $temp_item_table);
330
331 if(!(ref_do_query($query1, null, 1) && ref_do_query($query2, null, 1)))
332 trigger_error("Can't drop tables. MySQL says: " . mysql_error(), INSTALL_WARN);
333
334 return true;
335 */
336 }
337
338 /**
339 *
340 */
341 /**
342 * Get table descriptions for ReceSS (early version of Reblog) tables.
343 *
344 * @return array Associative array with column/type listings for two tables:
345 * - "item_table" - items
346 * - "feed_table" - feeds
347 */
348 function tablesInRecess()
349 {
350 $item_table = array(
351 'id' => 'int',
352 'feed_id' => 'int',
353 'timestamp' => 'timestamp',
354 'link' => 'text',
355 'title' => 'varchar',
356 'content' => 'text',
357 'dcdate' => 'text',
358 'dccreator' => 'text',
359 'dcsubject' => 'text',
360 'read' => 'tinyint',
361 'dcidentifier' => 'varchar',
362 'reblog_link' => 'text'
363 );
364
365 $feed_table = array(
366 'id' => 'int',
367 'url' => 'varchar',
368 'title' => 'varchar',
369 'link' => 'varchar',
370 'description' => 'varchar'
371 );
372
373 return compact('item_table', 'feed_table');
374 }
375
376 /**
377 * Check whether there is an active installation of ReceSS (early version of Reblog) in the current database.
378 *
379 * @return boolean True if tables matching {@link RF_Install_Controller::tablesInRecess() tablesInRecess} are found, false otherwise.
380 *
381 * @uses RF_Install_Controller::tablesInRecess()
382 * @uses RF_Install_Controller::$tables Searched for ReceSS (early version of Reblog) tables.
383 */
384 function isRecess()
385 {
386 extract($this->tablesInRecess());
387
388 return (in_array($item_table, $this->tables)
389 && in_array($feed_table, $this->tables));
390 }
391
392 /**
393 * Upgrade existing ReceSS (early version of Reblog) tables to fresh new Refeed tables.
394 * @todo This method is currently empty.
395 */
396 function upgradeFromRecess()
397 {
398 // stub
399
400 /*
401 print_note("Upgrading your database from ReceSS.");
402
403 $temp_item_table = REF_ITEM_TABLE . "__TMP";
404 $query1 = sprintf('ALTER TABLE %s RENAME TO %s',
405 REF_ITEM_TABLE,
406 $temp_item_table);
407
408 $temp_feed_table = REF_FEED_TABLE . "__TMP";
409 $query2 = sprintf('ALTER TABLE %s RENAME TO %s',
410 REF_FEED_TABLE,
411 $temp_feed_table);
412
413 if(!(ref_do_query($query1, null, 1) && ref_do_query($query2, null, 1)))
414 trigger_error("Can't rename tables. MySQL says: " . mysql_error(), INSTALL_FATAL);
415
416 do_create_tables();
417
418 ref_do_query(sprintf('INSERT INTO %s
419 (id, url, title, link, description)
420 SELECT id, url, title, link, description
421 FROM %s',
422 REF_FEED_TABLE,
423 $temp_feed_table));
424
425 ref_do_query(sprintf('INSERT INTO %s
426 (id, feed_id, published)
427 SELECT id, id, NULL
428 FROM %s',
429 REF_FEED_SELECT_TABLE,
430 REF_FEED_TABLE));
431
432 ref_do_query(sprintf('INSERT INTO %s
433 (id, feed_id, guid, `timestamp`, link, title, content, dcdate, dccreator, dcsubject)
434 SELECT id, feed_id, CONCAT("%s", dcidentifier), `timestamp`, link, title, content, dcdate, dccreator, dcsubject
435 FROM %s',
436 REF_ITEM_TABLE,
437 REF_GUID_TAG_PREFIX,
438 $temp_item_table));
439
440
441 ref_do_query(sprintf('INSERT INTO %s
442 (id, item_id, feed_id, `read`, published, link, title, content, `timestamp`)
443 SELECT id, id, feed_id, IF(`read` is NULL, NULL, 1), IF(`read` is NULL or `read` = 1, NULL, 1), IF(link = reblog_link, NULL, reblog_link), NULL, NULL, `timestamp`
444 FROM %s',
445 REF_ITEM_SELECT_TABLE,
446 $temp_item_table));
447
448 $query1 = sprintf('DROP TABLE %s', $temp_feed_table);
449 $query2 = sprintf('DROP TABLE %s', $temp_item_table);
450
451 if(!(ref_do_query($query1, null, 1) && ref_do_query($query2, null, 1)))
452 trigger_error("Can't drop tables. MySQL says: " . mysql_error(), INSTALL_WARN);
453
454 return true;
455 */
456 }
457
458 /**
459 * Get table descriptions for Refeed 1.x tables.
460 *
461 * @return array Associative array with column/type listings for two tables:
462 * - "item_table" - items
463 * - "feed_table" - feeds
464 * - "item_select_table" - items user data
465 * - "feed_select_table" - feeds user data
466 */
467 function tablesInRefeed1()
468 {
469 $item_table = array(
470 'id' => 'int',
471 'feed_id' => 'int',
472 'guid' => 'varchar',
473 'timestamp' => 'timestamp',
474 'link' => 'text',
475 'title' => 'text',
476 'content' => 'text',
477 'dcdate' => 'varchar',
478 'dccreator' => 'varchar',
479 'dcsubject' => 'varchar',
480 'xml' => 'text'
481 );
482
483 $feed_table = array(
484 'id' => 'int',
485 'url' => 'text',
486 'title' => 'varchar',
487 'link' => 'varchar',
488 'description' => 'varchar',
489 'xml' => 'text',
490 'timestamp' => 'timestamp'
491 );
492
493 $item_select_table = array(
494 'id' => 'int',
495 'item_id' => 'int',
496 'feed_id' => 'int',
497 'read' => 'tinyint',
498 'public' => 'tinyint',
499 'link' => 'text',
500 'title' => 'text',
501 'content' => 'text',
502 'comment' => 'text',
503 'subjects' => 'varchar',
504 'timestamp' => 'timestamp'
505 );
506
507 $feed_select_table = array(
508 'id' => 'int',
509 'feed_id' => 'int',
510 'public' => 'tinyint',
511 'timestamp' => 'timestamp'
512 );
513
514 return compact('item_table', 'feed_table', 'item_select_table', 'feed_select_table');
515 }
516
517 /**
518 * Check whether there is an active installation of Refeed 1.x in the current database.
519 *
520 * @return boolean True if tables matching {@link RF_Install_Controller::tablesInRefeed1() tablesInRefeed1} are found, false otherwise.
521 *
522 * @uses RF_Install_Controller::tablesInRefeed1()
523 * @uses RF_Install_Controller::$tables Searched for Refeed 1.x tables.
524 */
525 function isRefeed1()
526 {
527 extract($this->tablesInRefeed1());
528
529 return (in_array($item_table, $this->tables)
530 && in_array($feed_table, $this->tables)
531 && in_array($item_select_table, $this->tables)
532 && in_array($feed_select_table, $this->tables));
533 }
534
535 /**
536 * Upgrade existing Refeed 1.x tables to fresh new Refeed tables.
537 *
538 * @return boolean True if upgrade was successful, false otherwise.
539 *
540 * @uses RF_Controller::getReadHandle()
541 * @uses RF_Install_Controller::createTables()
542 * @uses RF_Install_Controller::tablesInRefeed2()
543 * @uses RF_Install_Controller::tablesInRefeed1()
544 * @uses RF_Install_Controller::printMumble()
545 * @uses RF_Controller::writeToDatabase()
546 * @uses RF_Controller::readFromDatabase()
547 * @uses ref_iso86012unix_timestamp()
548 * @uses RF_Install_Controller::$tables Searched for Refeed 1.x & 2.x tables.
549 */
550 function upgradeFromRefeed1()
551 {
552 $dbhr =& $this->controller->getReadHandle();
553
554 $this->createTables();
555
556 $refeed2 = $this->tablesInRefeed2();
557
558 $refeed2_items_tablename = $dbhr->quoteIdentifier(array_search($refeed2['items_table'], $this->tables));
559 $refeed2_feeds_tablename = $dbhr->quoteIdentifier(array_search($refeed2['feeds_table'], $this->tables));
560 $refeed2_items_userdata_tablename = $dbhr->quoteIdentifier(array_search($refeed2['items_userdata_table'], $this->tables));
561 $refeed2_feeds_userdata_tablename = $dbhr->quoteIdentifier(array_search($refeed2['feeds_userdata_table'], $this->tables));
562
563 $refeed1 = $this->tablesInRefeed1();
564
565 $refeed1_item_tablename = $dbhr->quoteIdentifier(array_search($refeed1['item_table'], $this->tables));
566 $refeed1_feed_tablename = $dbhr->quoteIdentifier(array_search($refeed1['feed_table'], $this->tables));
567 $refeed1_item_select_tablename = $dbhr->quoteIdentifier(array_search($refeed1['item_select_table'], $this->tables));
568 $refeed1_feed_select_tablename = $dbhr->quoteIdentifier(array_search($refeed1['feed_select_table'], $this->tables));
569
570
571
572 $this->printMumble("Populating new {$refeed2_feeds_tablename} table from Refeed 1.x {$refeed1_feed_tablename} table.");
573
574 $this->controller->writeToDatabase("
575 INSERT INTO {$refeed2_feeds_tablename}
576 (id, url, title, link, description, `timestamp`, xml)
577 SELECT id, url, title, link, description, `timestamp`, xml
578 FROM {$refeed1_feed_tablename}");
579
580
581
582 $this->printMumble("Populating new {$refeed2_feeds_userdata_tablename} table from Refeed 1.x {$refeed1_feed_tablename} table.");
583
584 $this->controller->writeToDatabase("
585 INSERT INTO {$refeed2_feeds_userdata_tablename}
586 (feed_id, user_id, label, value_numeric)
587 SELECT id, 1, 'subscribed', 1
588 FROM {$refeed1_feed_tablename}");
589
590 $this->controller->writeToDatabase("
591 INSERT INTO {$refeed2_feeds_userdata_tablename}
592 (feed_id, user_id, label, value_numeric, `timestamp`)
593 SELECT feed_id, 1, 'published', 1, `timestamp`
594 FROM {$refeed1_feed_select_tablename}
595 WHERE public = 1");
596
597
598
599 $this->printMumble("Populating new {$refeed2_items_tablename} table from Refeed 1.x {$refeed1_item_tablename} table.");
600
601 $this->controller->writeToDatabase("
602 INSERT INTO {$refeed2_items_tablename}
603 (id, feed_id, guid, link, title, content, author, category, modified, `timestamp`)
604 SELECT id, feed_id, guid, link, title, content, dccreator, dcsubject, NOW(), `timestamp`
605 FROM {$refeed1_item_tablename}");
606
607 $result = $this->controller->readFromDatabase("SELECT id, dcdate FROM {$refeed1_item_tablename}");
608
609 while($item_modified = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
610 $item_modified['modified'] = date('Y-m-d H:i:s', ref_iso86012unix_timestamp($item_modified['dcdate']));
611
612 $this->controller->writeToDatabase("
613 UPDATE {$refeed2_items_tablename}
614 SET modified = '{$item_modified['modified']}', `timestamp` = `timestamp`
615 WHERE id = {$item_modified['id']}");
616 }
617
618
619
620 $this->printMumble("Populating new {$refeed2_items_userdata_tablename} table from Refeed 1.x {$refeed1_item_select_tablename} table.");
621
622 $this->controller->writeToDatabase("
623 INSERT INTO {$refeed2_items_userdata_tablename}
624 (item_id, user_id, label, value_numeric, `timestamp`)
625 SELECT item_id, 1, 'read', IFNULL(`read`, 0), `timestamp`
626 FROM {$refeed1_item_select_tablename}");
627
628 $this->controller->writeToDatabase("
629 INSERT INTO {$refeed2_items_userdata_tablename}
630 (item_id, user_id, label, value_numeric, `timestamp`)
631 SELECT item_id, 1, 'published', public, `timestamp`
632 FROM {$refeed1_item_select_tablename}
633 WHERE public = 1");
634
635 $this->controller->writeToDatabase("
636 INSERT INTO {$refeed2_items_userdata_tablename}
637 (item_id, user_id, label, value_numeric, `timestamp`)
638 SELECT item_id, 1, 'title', title, `timestamp`
639 FROM {$refeed1_item_select_tablename}
640 WHERE title IS NOT NULL");
641
642 $this->controller->writeToDatabase("
643 INSERT INTO {$refeed2_items_userdata_tablename}
644 (item_id, user_id, label, value_numeric, `timestamp`)
645 SELECT item_id, 1, 'content', content, `timestamp`
646 FROM {$refeed1_item_select_tablename}
647 WHERE content IS NOT NULL");
648
649 $this->controller->writeToDatabase("
650 INSERT INTO {$refeed2_items_userdata_tablename}
651 (item_id, user_id, label, value_numeric, `timestamp`)
652 SELECT item_id, 1, 'link', link, `timestamp`
653 FROM {$refeed1_item_select_tablename}
654 WHERE link IS NOT NULL");
655
656 $this->controller->writeToDatabase("
657 INSERT INTO {$refeed2_items_userdata_tablename}
658 (item_id, user_id, label, value_numeric, `timestamp`)
659 SELECT item_id, 1, 'comment', comment, `timestamp`
660 FROM {$refeed1_item_select_tablename}
661 WHERE comment IS NOT NULL");
662
663 $this->controller->writeToDatabase("
664 INSERT INTO {$refeed2_items_userdata_tablename}
665 (item_id, user_id, label, value_numeric, `timestamp`)
666 SELECT item_id, 1, 'tags', subjects, `timestamp`
667 FROM {$refeed1_item_select_tablename}
668 WHERE subjects IS NOT NULL");
669
670 return true;
671 }
672
673 /**
674 * Get table descriptions for Refeed 2.0 Alpha tables.
675 *
676 * @return array Associative array with column/type listings for two tables:
677 * - "feeds_table" - items
678 * - "items_table" - feeds
679 * - "feeds_userdata_table" - feeds userdata
680 * - "items_userdata_table" - items userdata
681 *
682 * @uses RF_Install_Controller::tablesInRefeed2()
683 */
684 function tablesInRefeed2alpha()
685 {
686 $tables = $this->tablesInRefeed2();
687
688 // not too many changes were made
689 unset($tables['items_table']['xml']);
690 unset($tables['items_table']['insert_timestamp']);
691 unset($tables['feeds_table']['insert_timestamp']);
692
693 return $tables;
694 }
695
696 /**
697 * Check whether there is an active installation of Refeed 2.0 alpha in the current database.
698 *
699 * @return boolean True if tables matching {@link RF_Install_Controller::tablesInRefeed2alpha() tablesInRefeed2alpha} are found, false otherwise.
700 *
701 * @uses RF_Install_Controller::tablesInRefeed2alpha()
702 * @uses RF_Feed::tableName()
703 * @uses RF_Item::tableName()
704 * @uses RF_Feed::userdataTableName()
705 * @uses RF_Item::userdataTableName()
706 * @uses RF_Install_Controller::$tables Searched for Refeed 2.0 alpha tables.
707 */
708 function isRefeed2alpha()
709 {
710 extract($this->tablesInRefeed2alpha());
711
712 return ($this->tables[RF_Feed::tableName()] == $feeds_table
713 && $this->tables[RF_Item::tableName()] == $items_table
714 && $this->tables[RF_Feed::userdataTableName()] == $feeds_userdata_table
715 && $this->tables[RF_Item::userdataTableName()] == $items_userdata_table);
716 }
717
718 /**
719 * Upgrade existing Refeed 2.0 alpha tables to fresh new Refeed tables.
720 *
721 * @return boolean True if upgrade was successful, false otherwise.
722 *
723 * @uses RF_Controller::getReadHandle()
724 * @uses RF_Install_Controller::tablesInRefeed2alpha()
725 * @uses RF_Install_Controller::printMumble()
726 * @uses RF_Controller::writeToDatabase()
727 * @uses RF_Install_Controller::$tables Searched for Refeed 2.0 alpha tables.
728 */
729 function upgradeFromRefeed2alpha()
730 {
731 $dbhr =& $this->controller->getReadHandle();
732
733 $refeed2a = $this->tablesInRefeed2alpha();
734
735 $refeed2a_items_tablename = $dbhr->quoteIdentifier(array_search($refeed2a['items_table'], $this->tables));
736 $refeed2a_feeds_tablename = $dbhr->quoteIdentifier(array_search($refeed2a['feeds_table'], $this->tables));
737 $refeed2a_items_userdata_tablename = $dbhr->quoteIdentifier(array_search($refeed2a['items_userdata_table'], $this->tables));
738 $refeed2a_feeds_userdata_tablename = $dbhr->quoteIdentifier(array_search($refeed2a['feeds_userdata_table'], $this->tables));
739
740
741 $this->printMumble("Updating table {$refeed2a_items_tablename}.");
742
743 $this->controller->writeToDatabase("
744 ALTER TABLE {$refeed2a_items_tablename}
745 ADD COLUMN `xml` TEXT AFTER `modified`");
746
747 $this->controller->writeToDatabase("
748 ALTER TABLE {$refeed2a_items_tablename}
749 ADD COLUMN `insert_timestamp` TIMESTAMP(14) AFTER `timestamp`");
750
751 $this->controller->writeToDatabase("
752 UPDATE {$refeed2a_items_tablename}
753 SET `insert_timestamp` = `timestamp`");
754
755
756 $this->printMumble("Updating table {$refeed2a_items_tablename}.");
757
758 $this->controller->writeToDatabase("
759 ALTER TABLE {$refeed2a_feeds_tablename}
760 ADD COLUMN `insert_timestamp` TIMESTAMP(14) AFTER `timestamp`");
761
762 $this->controller->writeToDatabase("
763 UPDATE {$refeed2a_feeds_tablename}
764 SET `insert_timestamp` = `timestamp`");
765
766
767 return true;
768 }
769
770 /**
771 * Get table descriptions for Refeed 2.x tables.
772 *
773 * @return array Associative array with column/type listings for two tables:
774 * - "feeds_table" - items
775 * - "items_table" - feeds
776 * - "feeds_userdata_table" - feeds userdata
777 * - "items_userdata_table" - items userdata
778 */
779 function tablesInRefeed2()
780 {
781 $feeds_table = array(
782 'id' => 'int unsigned',
783 'url' => 'text',
784 'title' => 'varchar',
785 'link' => 'varchar',
786 'description' => 'varchar',
787 'timestamp' => 'timestamp',
788 'insert_timestamp' => 'timestamp',
789 'xml' => 'text'
790 );
791
792 $feeds_userdata_table = array(
793 'feed_id' => 'int unsigned',
794 'user_id' => 'int unsigned',
795 'label' => 'varchar',
796 'value_numeric' => 'int',
797 'value_short' => 'varchar',
798 'value_long' => 'text',
799 'timestamp' => 'timestamp'
800 );
801
802 $items_table = array(
803 'id' => 'int unsigned',
804 'feed_id' => 'int unsigned',
805 'guid' => 'varchar',
806 'link' => 'text',
807 'title' => 'text',
808 'content' => 'text',
809 'author' => 'varchar',
810 'category' => 'text',
811 'modified' => 'datetime',
812 'timestamp' => 'timestamp',
813 'insert_timestamp' => 'timestamp',
814 'xml' => 'text'
815 );
816
817 $items_userdata_table = array(
818 'item_id' => 'int unsigned',
819 'user_id' => 'int unsigned',
820 'label' => 'varchar',
821 'value_numeric' => 'int',
822 'value_short' => 'varchar',
823 'value_long' => 'text',
824 'timestamp' => 'timestamp'
825 );
826
827 return compact('feeds_table', 'items_table', 'feeds_userdata_table', 'items_userdata_table');
828 }
829
830 /**
831 * Check whether there is an active installation of Refeed 2.x in the current database.
832 *
833 * @return boolean True if tables matching {@link RF_Install_Controller::tablesInRefeed2() tablesInRefeed2} are found, false otherwise.
834 *
835 * @uses RF_Install_Controller::tablesInRefeed2()
836 * @uses RF_Feed::tableName()
837 * @uses RF_Item::tableName()
838 * @uses RF_Feed::userdataTableName()
839 * @uses RF_Item::userdataTableName()
840 * @uses RF_Install_Controller::$tables Searched for Refeed 2.x tables.
841 */
842 function isRefeed2()
843 {
844 extract($this->tablesInRefeed2());
845
846 return ($this->tables[RF_Feed::tableName()] == $feeds_table
847 && $this->tables[RF_Item::tableName()] == $items_table
848 && $this->tables[RF_Feed::userdataTableName()] == $feeds_userdata_table
849 && $this->tables[RF_Item::userdataTableName()] == $items_userdata_table);
850 }
851
852 /**
853 * Create Refeed 2.x database tables.
854 *
855 * @return boolean True if tables were created, false otherwise.
856 *
857 * @uses RF_Controller::getReadHandle()
858 * @uses RF_Feed::tableName()
859 * @uses RF_Item::tableName()
860 * @uses RF_Feed::userdataTableName()
861 * @uses RF_Item::userdataTableName()
862 * @uses RF_Controller::writeToDatabase()
863 * @uses RF_Install_Controller::printMumble()
864 * @uses RF_Install_Controller::describeTable()
865 * @uses RF_Install_Controller::describeAllTables()
866 * @uses RF_Install_Controller::$tables Assigned after new table creation, from results of {@link RF_Install_Controller::describeAllTables() describeAllTables()}.
867 */
868 function createTables()
869 {
870 $dbhr =& $this->controller->getReadHandle();
871
872 $feeds_tablename = $dbhr->quoteIdentifier(RF_Feed::tableName());
873 $items_tablename = $dbhr->quoteIdentifier(RF_Item::tableName());
874 $feeds_userdata_tablename = $dbhr->quoteIdentifier(RF_Feed::userdataTableName());
875 $items_userdata_tablename = $dbhr->quoteIdentifier(RF_Item::userdataTableName());
876
877 if($this->describeTable(RF_Feed::tableName())) {
878 die("Sorry, table {$feeds_tablename} already exists - change feeds table name in your configuration file or move the existing table!");
879 return false;
880 }
881
882 if($this->describeTable(RF_Item::tableName())) {
883 die("Sorry, table {$items_tablename} already exists - change items table name in your configuration file or move the existing table!");
884 return false;
885 }
886
887 if($this->describeTable(RF_Feed::userdataTableName())) {
888 die("Sorry, table {$feeds_userdata_tablename} already exists - change feeds userdata table name in your configuration file or move the existing table!");
889 return false;
890 }
891
892 if($this->describeTable(RF_Item::userdataTableName())) {
893 die("Sorry, table {$items_userdata_tablename} already exists - change items userdata table name in your configuration file or move the existing table!");
894 return false;
895 }
896
897 $this->printMumble("Creating table {$feeds_tablename}.");
898
899 $this->controller->writeToDatabase("
900 CREATE TABLE {$feeds_tablename} (
901
902 # internal to Reblog
903 id INT UNSIGNED NOT NULL AUTO_INCREMENT,
904 url TEXT NOT NULL DEFAULT '',
905
906 # http://feedparser.org/docs/reference-feed-title.html
907 title VARCHAR(255) NOT NULL DEFAULT '',
908
909 # http://feedparser.org/docs/reference-feed-link.html
910 link VARCHAR(255) DEFAULT NULL,
911
912 # http://feedparser.org/docs/reference-feed-tagline.html
913 description VARCHAR(255) DEFAULT NULL,
914
915 # internal to Reblog
916 xml TEXT DEFAULT NULL,
917
918 # the first timestamp is kept up-to-date on every UPDATE,
919 # the second is only set on INSERT.
920 `timestamp` TIMESTAMP(14) NOT NULL,
921 insert_timestamp TIMESTAMP(14),
922
923 PRIMARY KEY (id),
924 FULLTEXT(url, title, link, description)
925
926 ) TYPE=MyISAM
927 ");
928
929 $this->printMumble("Creating table {$items_tablename}.");
930
931 $this->controller->writeToDatabase("
932 CREATE TABLE {$items_tablename} (
933
934 # internal to Reblog
935 id INT UNSIGNED NOT NULL AUTO_INCREMENT,
936 feed_id INT UNSIGNED NOT NULL DEFAULT 0,
937
938 # http://feedparser.org/docs/reference-entry-id.html
939 guid VARCHAR(255) NOT NULL DEFAULT '',
940
941 # http://feedparser.org/docs/reference-entry-link.html
942 link TEXT,
943
944 # http://feedparser.org/docs/reference-entry-title.html
945 title TEXT,
946
947 # http://feedparser.org/docs/reference-entry-summary.html
948 content TEXT,
949
950 # http://feedparser.org/docs/reference-entry-author.html
951 author VARCHAR(255),
952
953 # http://feedparser.org/docs/reference-entry-category.html
954 category TEXT,
955
956 # http://feedparser.org/docs/reference-entry-modified.html
957 modified DATETIME,
958
959 # internal to Reblog
960 xml TEXT,
961
962 # the first timestamp is kept up-to-date on every UPDATE,
963 # the second is only set on INSERT.
964 `timestamp` TIMESTAMP(14) NOT NULL,
965 insert_timestamp TIMESTAMP(14),
966
967 PRIMARY KEY (id),
968 UNIQUE KEY feed_id_guid (feed_id, guid),
969 FULLTEXT(link, title, content, author, category)
970
971 ) TYPE=MyISAM
972 ");
973
974 $this->printMumble("Creating table {$feeds_userdata_tablename}.");
975
976 $this->controller->writeToDatabase("
977 CREATE TABLE {$feeds_userdata_tablename} (
978
979 # key columns
980 feed_id INT UNSIGNED NOT NULL DEFAULT 0,
981 user_id INT UNSIGNED NOT NULL DEFAULT 0,
982 label VARCHAR(64) NOT NULL DEFAULT '',
983
984 # value columns - application code figures out how
985 # to interpret these, based on `label` column above
986 value_numeric INT,
987 value_short VARCHAR(255),
988 value_long TEXT,
989
990 `timestamp` TIMESTAMP(14) NOT NULL,
991
992 INDEX user_feed (user_id, feed_id),
993 INDEX user_label (user_id, label),
994 INDEX user_label_feed (user_id, feed_id, label),
995 INDEX user_label_numeric (user_id, label, value_numeric),
996 INDEX user_label_short (user_id, label, value_short)
997
998 ) TYPE=InnoDB
999 ");
1000
1001 $this->printMumble("Creating table {$items_userdata_tablename}.");
1002
1003 $this->controller->writeToDatabase("
1004 CREATE TABLE {$items_userdata_tablename} (
1005
1006 # key columns
1007 item_id INT UNSIGNED NOT NULL DEFAULT 0,
1008 user_id INT UNSIGNED NOT NULL DEFAULT 0,
1009 label VARCHAR(64) NOT NULL DEFAULT '',
1010
1011 # value columns - application code figures out how
1012 # to interpret these, based on `label` column above
1013 value_numeric INT,
1014 value_short VARCHAR(255),
1015 value_long TEXT,
1016
1017 # for kicks
1018 `timestamp` TIMESTAMP(14) NOT NULL,
1019
1020 INDEX user_item (user_id, item_id),
1021 INDEX user_label (user_id, label),
1022 INDEX user_label_item (user_id, item_id, label),
1023 INDEX user_label_numeric (user_id, label, value_numeric),
1024 INDEX user_label_short (user_id, label, value_short)
1025
1026 ) TYPE=InnoDB
1027 ");
1028
1029 $this->tables = $this->describeAllTables();
1030 return true;
1031 }
1032
1033 /**
1034 * Describe all current database tables.
1035 *
1036 * @return array Array of table description arrays, with column name keys and column type values.
1037 *
1038 * @uses RF_Controller::readFromDatabase()
1039 */
1040 function describeAllTables()
1041 {
1042 $result_tables = $this->controller->readFromDatabase("SHOW TABLES");
1043
1044 $tables = array();
1045
1046 while($table = $result_tables->fetchRow()) {
1047
1048 $table = $table[0];
1049 $tables[$table] = array();
1050 $result_columns = $this->controller->readFromDatabase("SHOW COLUMNS FROM `{$table}`");
1051
1052 while($column = $result_columns->fetchRow(DB_FETCHMODE_ASSOC))
1053 $tables[$table][$column['Field']] = strtolower(preg_replace('#\(\d+\)#', '', $column['Type']));
1054 }
1055
1056 return $tables;
1057 }
1058
1059 /**
1060 * Describe one current database table.
1061 *
1062 * @param string $table Name of table to describe.
1063 *
1064 * @return array Table description array, with column name keys and column type values.
1065 *
1066 * @uses RF_Controller::readFromDatabase()
1067 */
1068 function describeTable($table)
1069 {
1070 $result = $this->controller->readFromDatabase("SHOW TABLES LIKE '{$table}'");
1071
1072 $columns = array();
1073
1074 if($result->numRows()) {
1075 $result = $this->controller->readFromDatabase("SHOW COLUMNS FROM `{$table}`");
1076
1077 while($col = $result->fetchRow(DB_FETCHMODE_ASSOC))
1078 $columns[$col['Field']] = strtolower(preg_replace('#\(\d+\)#', '', $col['Type']));
1079 }
1080
1081 return empty($columns)
1082 ? false
1083 : $columns;
1084 }
1085 }
1086
1087 ?>

  ViewVC Help
Powered by ViewVC 1.1.26