]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - scripts/upgrade.php
Merge branch '1.0.x' into testing
[quix0rs-gnu-social.git] / scripts / upgrade.php
1 #!/usr/bin/env php
2 <?php
3 /*
4  * StatusNet - a distributed open-source microblogging tool
5  * Copyright (C) 2008-2011 StatusNet, Inc.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
22
23 $shortoptions = 'x::';
24 $longoptions = array('extensions=');
25
26 $helptext = <<<END_OF_UPGRADE_HELP
27 php upgrade.php [options]
28 Upgrade database schema and data to latest software
29
30 END_OF_UPGRADE_HELP;
31
32 require_once INSTALLDIR.'/scripts/commandline.inc';
33
34 function main()
35 {
36     if (Event::handle('StartUpgrade')) {
37         updateSchemaCore();
38         updateSchemaPlugins();
39
40         // These replace old "fixup_*" scripts
41
42         fixupNoticeRendered();
43         fixupNoticeConversation();
44         initConversation();
45         initInbox();
46         fixupGroupURI();
47
48         initLocalGroup();
49         initNoticeReshare();
50     
51         initFaveURI();
52         initSubscriptionURI();
53         initGroupMemberURI();
54
55         Event::handle('EndUpgrade');
56     }
57 }
58
59 function tableDefs()
60 {
61         $schema = array();
62         require INSTALLDIR.'/db/core.php';
63         return $schema;
64 }
65
66 function updateSchemaCore()
67 {
68     printfnq("Upgrading core schema...");
69
70     $schema = Schema::get();
71     $schemaUpdater = new SchemaUpdater($schema);
72     foreach (tableDefs() as $table => $def) {
73         $schemaUpdater->register($table, $def);
74     }
75     $schemaUpdater->checkSchema();
76
77     printfnq("DONE.\n");
78 }
79
80 function updateSchemaPlugins()
81 {
82     printfnq("Upgrading plugin schema...");
83
84     Event::handle('CheckSchema');
85
86     printfnq("DONE.\n");
87 }
88
89 function fixupNoticeRendered()
90 {
91     printfnq("Ensuring all notices have rendered HTML...");
92
93     $notice = new Notice();
94
95     $notice->whereAdd('rendered IS NULL');
96     $notice->find();
97
98     while ($notice->fetch()) {
99         $original = clone($notice);
100         $notice->rendered = common_render_content($notice->content, $notice);
101         $notice->update($original);
102     }
103
104     printfnq("DONE.\n");
105 }
106
107 function fixupNoticeConversation()
108 {
109     printfnq("Ensuring all notices have a conversation ID...");
110
111     $notice = new Notice();
112     $notice->whereAdd('conversation is null');
113     $notice->orderBy('id'); // try to get originals before replies
114     $notice->find();
115
116     while ($notice->fetch()) {
117         try {
118             $cid = null;
119     
120             $orig = clone($notice);
121     
122             if (empty($notice->reply_to)) {
123                 $notice->conversation = $notice->id;
124             } else {
125                 $reply = Notice::staticGet('id', $notice->reply_to);
126
127                 if (empty($reply)) {
128                     $notice->conversation = $notice->id;
129                 } else if (empty($reply->conversation)) {
130                     $notice->conversation = $notice->id;
131                 } else {
132                     $notice->conversation = $reply->conversation;
133                 }
134         
135                 unset($reply);
136                 $reply = null;
137             }
138
139             $result = $notice->update($orig);
140
141             $orig = null;
142             unset($orig);
143         } catch (Exception $e) {
144             printv("Error setting conversation: " . $e->getMessage());
145         }
146     }
147
148     printfnq("DONE.\n");
149 }
150
151 function fixupGroupURI()
152 {
153     printfnq("Ensuring all groups have an URI...");
154
155     $group = new User_group();
156     $group->whereAdd('uri IS NULL');
157
158     if ($group->find()) {
159         while ($group->fetch()) {
160             $orig = User_group::staticGet('id', $group->id);
161             $group->uri = $group->getUri();
162             $group->update($orig);
163         }
164     }
165
166     printfnq("DONE.\n");
167 }
168
169 function initConversation()
170 {
171     printfnq("Ensuring all conversations have a row in conversation table...");
172
173     $notice = new Notice();
174     $notice->query('select distinct notice.conversation from notice '.
175                    'where notice.conversation is not null '.
176                    'and not exists (select conversation.id from conversation where id = notice.conversation)');
177
178     while ($notice->fetch()) {
179
180         $id = $notice->conversation;
181
182         $uri = common_local_url('conversation', array('id' => $id));
183
184         // @fixme db_dataobject won't save our value for an autoincrement
185         // so we're bypassing the insert wrappers
186         $conv = new Conversation();
187         $sql = "insert into conversation (id,uri,created) values(%d,'%s','%s')";
188         $sql = sprintf($sql,
189                        $id,
190                        $conv->escape($uri),
191                        $conv->escape(common_sql_now()));
192         $conv->query($sql);
193     }
194
195     printfnq("DONE.\n");
196 }
197
198 function initInbox()
199 {
200     printfnq("Ensuring all users have an inbox...");
201
202     $user = new User();
203     $user->whereAdd('not exists (select user_id from inbox where user_id = user.id)');
204     $user->orderBy('id');
205
206     if ($user->find()) {
207
208         while ($user->fetch()) {
209
210             try {
211                 $notice = new Notice();
212
213                 $notice->selectAdd();
214                 $notice->selectAdd('id');
215                 $notice->joinAdd(array('profile_id', 'subscription:subscribed'));
216                 $notice->whereAdd('subscription.subscriber = ' . $user->id);
217                 $notice->whereAdd('notice.created >= subscription.created');
218
219                 $ids = array();
220
221                 if ($notice->find()) {
222                     while ($notice->fetch()) {
223                         $ids[] = $notice->id;
224                     }
225                 }
226
227                 $notice = null;
228
229                 $inbox = new Inbox();
230                 $inbox->user_id = $user->id;
231                 $inbox->pack($ids);
232                 $inbox->insert();
233             } catch (Exception $e) {
234                 printv("Error initializing inbox: " . $e->getMessage());
235             }
236         }
237     }
238
239     printfnq("DONE.\n");
240 }
241
242 function initLocalGroup()
243 {
244     printfnq("Ensuring all local user groups have a local_group...");
245
246     $group = new User_group();
247     $group->whereAdd('NOT EXISTS (select group_id from local_group where group_id = user_group.id)');
248     $group->find();
249
250     while ($group->fetch()) {
251         try {
252             // Hack to check for local groups
253             if ($group->getUri() == common_local_url('groupbyid', array('id' => $group->id))) {
254                 $lg = new Local_group();
255
256                 $lg->group_id = $group->id;
257                 $lg->nickname = $group->nickname;
258                 $lg->created  = $group->created; // XXX: common_sql_now() ?
259                 $lg->modified = $group->modified;
260
261                 $lg->insert();
262             }
263         } catch (Exception $e) {
264             printfv("Error initializing local group for {$group->nickname}:" . $e->getMessage());
265         }
266     }
267
268     printfnq("DONE.\n");
269 }
270
271 function initNoticeReshare()
272 {
273     printfnq("Ensuring all reshares have the correct verb and object-type...");
274     
275     $notice = new Notice();
276     $notice->whereAdd('repeat_of is not null');
277     $notice->whereAdd('(verb != "'.ActivityVerb::SHARE.'" OR object_type != "'.ActivityObject::ACTIVITY.'")');
278
279     if ($notice->find()) {
280         while ($notice->fetch()) {
281             try {
282                 $orig = Notice::staticGet('id', $notice->id);
283                 $notice->verb = ActivityVerb::SHARE;
284                 $notice->object_type = ActivityObject::ACTIVITY;
285                 $notice->update($orig);
286             } catch (Exception $e) {
287                 printfv("Error updating verb and object_type for {$notice->id}:" . $e->getMessage());
288             }
289         }
290     }
291
292     printfnq("DONE.\n");
293 }
294
295 function initFaveURI() 
296 {
297     printfnq("Ensuring all faves have a URI...");
298
299     $fave = new Fave();
300     $fave->whereAdd('uri IS NULL');
301
302     if ($fave->find()) {
303         while ($fave->fetch()) {
304             try {
305                 $fave->decache();
306                 $fave->query(sprintf('update fave '.
307                                      'set uri = "%s", '.
308                                      '    modified = "%s" '.
309                                      'where user_id = %d '.
310                                      'and notice_id = %d',
311                                      Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified),
312                                      common_sql_date(strtotime($fave->modified)),
313                                      $fave->user_id,
314                                      $fave->notice_id));
315             } catch (Exception $e) {
316                 common_log(LOG_ERR, "Error updated fave URI: " . $e->getMessage());
317             }
318         }
319     }
320
321     printfnq("DONE.\n");
322 }
323
324 function initSubscriptionURI()
325 {
326     printfnq("Ensuring all subscriptions have a URI...");
327
328     $sub = new Subscription();
329     $sub->whereAdd('uri IS NULL');
330
331     if ($sub->find()) {
332         while ($sub->fetch()) {
333             try {
334                 $sub->decache();
335                 $sub->query(sprintf('update subscription '.
336                                     'set uri = "%s" '.
337                                     'where subscriber = %d '.
338                                     'and subscribed = %d',
339                                     Subscription::newURI($sub->subscriber, $sub->subscribed, $sub->created),
340                                     $sub->subscriber,
341                                     $sub->subscribed));
342             } catch (Exception $e) {
343                 common_log(LOG_ERR, "Error updated subscription URI: " . $e->getMessage());
344             }
345         }
346     }
347
348     printfnq("DONE.\n");
349 }
350
351 function initGroupMemberURI()
352 {
353     printfnq("Ensuring all group memberships have a URI...");
354
355     $mem = new Group_member();
356     $mem->whereAdd('uri IS NULL');
357
358     if ($mem->find()) {
359         while ($mem->fetch()) {
360             try {
361                 $mem->decache();
362                 $mem->query(sprintf('update group_member set uri = "%s" '.
363                                     'where profile_id = %d ' . 
364                                     'and group_id = %d ',
365                                     Group_member::newURI($mem->profile_id, $mem->group_id, $mem->created),
366                                     $mem->profile_id,
367                                     $mem->group_id));
368             } catch (Exception $e) {
369                 common_log(LOG_ERR, "Error updated membership URI: " . $e->getMessage());  
370           }
371         }
372     }
373
374     printfnq("DONE.\n");
375 }
376
377 main();