]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - scripts/upgrade.php
Merge branch 'nummedout' 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     updateSchemaCore();
37     updateSchemaPlugins();
38
39     // These replace old "fixup_*" scripts
40
41     fixupNoticeRendered();
42     fixupNoticeConversation();
43     initConversation();
44     initInbox();
45     fixupGroupURI();
46
47     initLocalGroup();
48     initNoticeReshare();
49     
50     initFaveURI();
51     initSubscriptionURI();
52     initGroupMemberURI();
53 }
54
55 function tableDefs()
56 {
57         $schema = array();
58         require INSTALLDIR.'/db/core.php';
59         return $schema;
60 }
61
62 function updateSchemaCore()
63 {
64     printfnq("Upgrading core schema...");
65
66     $schema = Schema::get();
67     $schemaUpdater = new SchemaUpdater($schema);
68     foreach (tableDefs() as $table => $def) {
69         $schemaUpdater->register($table, $def);
70     }
71     $schemaUpdater->checkSchema();
72
73     printfnq("DONE.\n");
74 }
75
76 function updateSchemaPlugins()
77 {
78     printfnq("Upgrading plugin schema...");
79
80     Event::handle('CheckSchema');
81
82     printfnq("DONE.\n");
83 }
84
85 function fixupNoticeRendered()
86 {
87     printfnq("Ensuring all notices have rendered HTML...");
88
89     $notice = new Notice();
90
91     $notice->whereAdd('rendered IS NULL');
92     $notice->find();
93
94     while ($notice->fetch()) {
95         $original = clone($notice);
96         $notice->rendered = common_render_content($notice->content, $notice);
97         $notice->update($original);
98     }
99
100     printfnq("DONE.\n");
101 }
102
103 function fixupNoticeConversation()
104 {
105     printfnq("Ensuring all notices have a conversation ID...");
106
107     $notice = new Notice();
108     $notice->whereAdd('conversation is null');
109     $notice->orderBy('id'); // try to get originals before replies
110     $notice->find();
111
112     while ($notice->fetch()) {
113         try {
114             $cid = null;
115     
116             $orig = clone($notice);
117     
118             if (empty($notice->reply_to)) {
119                 $notice->conversation = $notice->id;
120             } else {
121                 $reply = Notice::staticGet('id', $notice->reply_to);
122
123                 if (empty($reply)) {
124                     $notice->conversation = $notice->id;
125                 } else if (empty($reply->conversation)) {
126                     $notice->conversation = $notice->id;
127                 } else {
128                     $notice->conversation = $reply->conversation;
129                 }
130         
131                 unset($reply);
132                 $reply = null;
133             }
134
135             $result = $notice->update($orig);
136
137             $orig = null;
138             unset($orig);
139         } catch (Exception $e) {
140             printv("Error setting conversation: " . $e->getMessage());
141         }
142     }
143
144     printfnq("DONE.\n");
145 }
146
147 function fixupGroupURI()
148 {
149     printfnq("Ensuring all groups have an URI...");
150
151     $group = new User_group();
152     $group->whereAdd('uri IS NULL');
153
154     if ($group->find()) {
155         while ($group->fetch()) {
156             $orig = User_group::staticGet('id', $group->id);
157             $group->uri = $group->getUri();
158             $group->update($orig);
159         }
160     }
161
162     printfnq("DONE.\n");
163 }
164
165 function initConversation()
166 {
167     printfnq("Ensuring all conversations have a row in conversation table...");
168
169     $notice = new Notice();
170     $notice->query('select distinct notice.conversation from notice '.
171                    'where notice.conversation is not null '.
172                    'and not exists (select conversation.id from conversation where id = notice.conversation)');
173
174     while ($notice->fetch()) {
175
176         $id = $notice->conversation;
177
178         $uri = common_local_url('conversation', array('id' => $id));
179
180         // @fixme db_dataobject won't save our value for an autoincrement
181         // so we're bypassing the insert wrappers
182         $conv = new Conversation();
183         $sql = "insert into conversation (id,uri,created) values(%d,'%s','%s')";
184         $sql = sprintf($sql,
185                        $id,
186                        $conv->escape($uri),
187                        $conv->escape(common_sql_now()));
188         $conv->query($sql);
189     }
190
191     printfnq("DONE.\n");
192 }
193
194 function initInbox()
195 {
196     printfnq("Ensuring all users have an inbox...");
197
198     $user = new User();
199     $user->whereAdd('not exists (select user_id from inbox where user_id = user.id)');
200     $user->orderBy('id');
201
202     if ($user->find()) {
203
204         while ($user->fetch()) {
205
206             try {
207                 $notice = new Notice();
208
209                 $notice->selectAdd();
210                 $notice->selectAdd('id');
211                 $notice->joinAdd(array('profile_id', 'subscription:subscribed'));
212                 $notice->whereAdd('subscription.subscriber = ' . $user->id);
213                 $notice->whereAdd('notice.created >= subscription.created');
214
215                 $ids = array();
216
217                 if ($notice->find()) {
218                     while ($notice->fetch()) {
219                         $ids[] = $notice->id;
220                     }
221                 }
222
223                 $notice = null;
224
225                 $inbox = new Inbox();
226                 $inbox->user_id = $user->id;
227                 $inbox->pack($ids);
228                 $inbox->insert();
229             } catch (Exception $e) {
230                 printv("Error initializing inbox: " . $e->getMessage());
231             }
232         }
233     }
234
235     printfnq("DONE.\n");
236 }
237
238 function initLocalGroup()
239 {
240     printfnq("Ensuring all local user groups have a local_group...");
241
242     $group = new User_group();
243     $group->whereAdd('NOT EXISTS (select group_id from local_group where group_id = user_group.id)');
244     $group->find();
245
246     while ($group->fetch()) {
247         try {
248             // Hack to check for local groups
249             if ($group->getUri() == common_local_url('groupbyid', array('id' => $group->id))) {
250                 $lg = new Local_group();
251
252                 $lg->group_id = $group->id;
253                 $lg->nickname = $group->nickname;
254                 $lg->created  = $group->created; // XXX: common_sql_now() ?
255                 $lg->modified = $group->modified;
256
257                 $lg->insert();
258             }
259         } catch (Exception $e) {
260             printfv("Error initializing local group for {$group->nickname}:" . $e->getMessage());
261         }
262     }
263
264     printfnq("DONE.\n");
265 }
266
267 function initNoticeReshare()
268 {
269     printfnq("Ensuring all reshares have the correct verb and object-type...");
270     
271     $notice = new Notice();
272     $notice->whereAdd('repeat_of is not null');
273     $notice->whereAdd('(verb != "'.ActivityVerb::SHARE.'" OR object_type != "'.ActivityObject::ACTIVITY.'")');
274
275     if ($notice->find()) {
276         while ($notice->fetch()) {
277             try {
278                 $orig = Notice::staticGet('id', $notice->id);
279                 $notice->verb = ActivityVerb::SHARE;
280                 $notice->object_type = ActivityObject::ACTIVITY;
281                 $notice->update($orig);
282             } catch (Exception $e) {
283                 printfv("Error updating verb and object_type for {$notice->id}:" . $e->getMessage());
284             }
285         }
286     }
287
288     printfnq("DONE.\n");
289 }
290
291 function initFaveURI() 
292 {
293     printfnq("Ensuring all faves have a URI...");
294
295     $fave = new Fave();
296     $fave->whereAdd('uri IS NULL');
297
298     if ($fave->find()) {
299         while ($fave->fetch()) {
300             try {
301                 $fave->decache();
302                 $fave->query(sprintf('update fave '.
303                                      'set uri = "%s", '.
304                                      '    modified = "%s" '.
305                                      'where user_id = %d '.
306                                      'and notice_id = %d',
307                                      Fave::newURI($fave->user_id, $fave->notice_id, $fave->modified),
308                                      common_sql_date(strtotime($fave->modified)),
309                                      $fave->user_id,
310                                      $fave->notice_id));
311             } catch (Exception $e) {
312                 common_log(LOG_ERR, "Error updated fave URI: " . $e->getMessage());
313             }
314         }
315     }
316
317     printfnq("DONE.\n");
318 }
319
320 function initSubscriptionURI()
321 {
322     printfnq("Ensuring all subscriptions have a URI...");
323
324     $sub = new Subscription();
325     $sub->whereAdd('uri IS NULL');
326
327     if ($sub->find()) {
328         while ($sub->fetch()) {
329             try {
330                 $sub->decache();
331                 $sub->query(sprintf('update subscription '.
332                                     'set uri = "%s" '.
333                                     'where subscriber = %d '.
334                                     'and subscribed = %d',
335                                     Subscription::newURI($sub->subscriber, $sub->subscribed, $sub->created),
336                                     $sub->subscriber,
337                                     $sub->subscribed));
338             } catch (Exception $e) {
339                 common_log(LOG_ERR, "Error updated subscription URI: " . $e->getMessage());
340             }
341         }
342     }
343
344     printfnq("DONE.\n");
345 }
346
347 function initGroupMemberURI()
348 {
349     printfnq("Ensuring all group memberships have a URI...");
350
351     $mem = new Group_member();
352     $mem->whereAdd('uri IS NULL');
353
354     if ($mem->find()) {
355         while ($mem->fetch()) {
356             try {
357                 $mem->decache();
358                 $mem->query(sprintf('update group_member set uri = "%s" '.
359                                     'where profile_id = %d ' . 
360                                     'and group_id = %d ',
361                                     Group_member::newURI($mem->profile_id, $mem->group_id, $mem->created),
362                                     $mem->profile_id,
363                                     $mem->group_id));
364             } catch (Exception $e) {
365                 common_log(LOG_ERR, "Error updated membership URI: " . $e->getMessage());  
366           }
367         }
368     }
369
370     printfnq("DONE.\n");
371 }
372
373 main();