]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - db/core.php
Merge activity plugin into mainline
[quix0rs-gnu-social.git] / db / core.php
1 <?php
2
3 /**
4  *
5  * Some notes...
6  *
7  * Drupal docs don't list a bool type, but it might be nice to use rather than 'tinyint'
8  * Note however that we use bitfields and things as well in tinyints, and PG's
9  * "bool" type isn't 100% compatible with 0/1 checks. Just keeping tinyints. :)
10  *
11  * decimal <-> numeric
12  *
13  * MySQL 'timestamp' columns were formerly used for 'modified' files for their
14  * auto-updating properties. This didn't play well with changes to cache usage
15  * in 0.9.x, as we don't know the timestamp value at INSERT time and never
16  * have a chance to load it up again before caching. For now I'm leaving them
17  * in, but we may want to clean them up later.
18  *
19  * Current code should be setting 'created' and 'modified' fields explicitly;
20  * this also avoids mismatches between server and client timezone settings.
21  *
22  *
23  * fulltext indexes?
24  * got one or two things wanting a custom charset setting on a field?
25  *
26  * foreign keys are kinda funky...
27  *     those specified in inline syntax (as all in the original .sql) are NEVER ENFORCED on mysql
28  *     those made with an explicit 'foreign key' WITHIN INNODB and IF there's a proper index, do get enforced
29  *     double-check what we've been doing on postgres?
30  */
31
32 $schema['profile'] = array(
33     'description' => 'local and remote users have profiles',
34     'fields' => array(
35         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
36         'nickname' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'nickname or username'),
37         'fullname' => array('type' => 'varchar', 'length' => 255, 'description' => 'display name'),
38         'profileurl' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL, cached so we dont regenerate'),
39         'homepage' => array('type' => 'varchar', 'length' => 255, 'description' => 'identifying URL'),
40         'bio' => array('type' => 'text', 'description' => 'descriptive biography'),
41         'location' => array('type' => 'varchar', 'length' => 255, 'description' => 'physical location'),
42         'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
43         'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
44         'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
45         'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
46
47         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
48         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
49     ),
50     'primary key' => array('id'),
51     'indexes' => array(
52         'profile_nickname_idx' => array('nickname'),
53     ),
54     'fulltext indexes' => array(
55         'nickname' => array('nickname', 'fullname', 'location', 'bio', 'homepage')
56     ),
57 );
58
59 $schema['avatar'] = array(
60     'fields' => array(
61         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
62         'original' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'uploaded by user or generated?'),
63         'width' => array('type' => 'int', 'not null' => true, 'description' => 'image width'),
64         'height' => array('type' => 'int', 'not null' => true, 'description' => 'image height'),
65         'mediatype' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'file type'),
66         'filename' => array('type' => 'varchar', 'length' => 255, 'description' => 'local filename, if local'),
67         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'avatar location'),
68         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
69         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
70     ),
71     'primary key' => array('profile_id', 'width', 'height'),
72     'unique keys' => array(
73         'avatar_url_key' => array('url'),
74     ),
75     'foreign keys' => array(
76         'avatar_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
77     ),
78     'indexes' => array(
79         'avatar_profile_id_idx' => array('profile_id'),
80     ),
81 );
82
83 $schema['sms_carrier'] = array(
84     'fields' => array(
85         'id' => array('type' => 'int', 'not null' => true, 'description' => 'primary key for SMS carrier'),
86         'name' => array('type' => 'varchar', 'length' => 64, 'description' => 'name of the carrier'),
87         'email_pattern' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'sprintf pattern for making an email address from a phone number'),
88         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
89         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
90     ),
91     'primary key' => array('id'),
92     'unique keys' => array(
93         'sms_carrier_name_key' => array('name'),
94     ),
95 );
96
97 $schema['user'] = array(
98     'description' => 'local users',
99     'fields' => array(
100         'id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
101         'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'nickname or username, duped in profile'),
102         'password' => array('type' => 'varchar', 'length' => 255, 'description' => 'salted password, can be null for OpenID users'),
103         'email' => array('type' => 'varchar', 'length' => 255, 'description' => 'email address for password recovery etc.'),
104         'incomingemail' => array('type' => 'varchar', 'length' => 255, 'description' => 'email address for post-by-email'),
105         'emailnotifysub' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of subscriptions'),
106         'emailnotifyfav' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of favorites'),
107         'emailnotifynudge' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of nudges'),
108         'emailnotifymsg' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of direct messages'),
109         'emailnotifyattn' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of @-replies'),
110         'emailmicroid' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'whether to publish email microid'),
111         'language' => array('type' => 'varchar', 'length' => 50, 'description' => 'preferred language'),
112         'timezone' => array('type' => 'varchar', 'length' => 50, 'description' => 'timezone'),
113         'emailpost' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Post by email'),
114         'sms' => array('type' => 'varchar', 'length' => 64, 'description' => 'sms phone number'),
115         'carrier' => array('type' => 'int', 'description' => 'foreign key to sms_carrier'),
116         'smsnotify' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to send notices to SMS'),
117         'smsreplies' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to send notices to SMS on replies'),
118         'smsemail' => array('type' => 'varchar', 'length' => 255, 'description' => 'built from sms and carrier'),
119         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'),
120         'autosubscribe' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'automatically subscribe to users who subscribe to us'),
121         'subscribe_policy' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can subscribe; 1 = require approval'),
122         'urlshorteningservice' => array('type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'),
123         'inboxed' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'has an inbox been created for this user?'),
124         'private_stream' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'whether to limit all notices to followers only'),
125
126         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
127         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
128     ),
129     'primary key' => array('id'),
130     'unique keys' => array(
131         'user_nickname_key' => array('nickname'),
132         'user_email_key' => array('email'),
133         'user_incomingemail_key' => array('incomingemail'),
134         'user_sms_key' => array('sms'),
135         'user_uri_key' => array('uri'),
136     ),
137     'foreign keys' => array(
138         'user_id_fkey' => array('profile', array('id' => 'id')),
139         'user_carrier_fkey' => array('sms_carrier', array('carrier' => 'id')),
140     ),
141     'indexes' => array(
142         'user_smsemail_idx' => array('smsemail'),
143     ),
144 );
145
146 $schema['remote_profile'] = array(
147     'description' => 'remote people (OMB)',
148     'fields' => array(
149         'id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
150         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'),
151         'postnoticeurl' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL we use for posting notices'),
152         'updateprofileurl' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL we use for updates to this profile'),
153         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
154         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
155     ),
156     'primary key' => array('id'),
157     'unique keys' => array(
158         'remote_profile_uri_key' => array('uri'),
159     ),
160     'foreign keys' => array(
161         'remote_profile_id_fkey' => array('profile', array('id' => 'id')),
162     ),
163 );
164
165 $schema['subscription'] = array(
166     'fields' => array(
167         'subscriber' => array('type' => 'int', 'not null' => true, 'description' => 'profile listening'),
168         'subscribed' => array('type' => 'int', 'not null' => true, 'description' => 'profile being listened to'),
169         'jabber' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver jabber messages'),
170         'sms' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver sms messages'),
171         'token' => array('type' => 'varchar', 'length' => 255, 'description' => 'authorization token'),
172         'secret' => array('type' => 'varchar', 'length' => 255, 'description' => 'token secret'),
173         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
174         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
175     ),
176     'primary key' => array('subscriber', 'subscribed'),
177     'indexes' => array(
178         'subscription_subscriber_idx' => array('subscriber', 'created'),
179         'subscription_subscribed_idx' => array('subscribed', 'created'),
180         'subscription_token_idx' => array('token'),
181     ),
182 );
183
184 $schema['notice'] = array(
185     'fields' => array(
186         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
187         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'who made the update'),
188         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'),
189         'content' => array('type' => 'text', 'description' => 'update content'),
190         'rendered' => array('type' => 'text', 'description' => 'HTML version of the content'),
191         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of any attachment (image, video, bookmark, whatever)'),
192         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
193         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
194         'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'),
195         'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
196         'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
197         'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'),
198         'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
199         'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
200         'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
201         'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
202         'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
203         'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'),
204         'scope' => array('type' => 'int',
205                          'default' => '1',
206                          'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = followers'),
207     ),
208     'primary key' => array('id'),
209     'unique keys' => array(
210         'notice_uri_key' => array('uri'),
211     ),
212     'foreign keys' => array(
213         'notice_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
214         'notice_reply_to_fkey' => array('notice', array('reply_to' => 'id')),
215         'notice_conversation_fkey' => array('conversation', array('conversation' => 'id')), # note... used to refer to notice.id
216         'notice_repeat_of_fkey' => array('notice', array('repeat_of' => 'id')), # @fixme: what about repeats of deleted notices?
217     ),
218     'indexes' => array(
219         'notice_profile_id_idx' => array('profile_id', 'created', 'id'),
220         'notice_conversation_idx' => array('conversation'),
221         'notice_created_idx' => array('created'),
222         'notice_replyto_idx' => array('reply_to'),
223         'notice_repeatof_idx' => array('repeat_of'),
224     ),
225     'fulltext indexes' => array(
226         'content' => array('content'),
227     )
228 );
229
230 $schema['notice_source'] = array(
231     'fields' => array(
232         'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'source code'),
233         'name' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'name of the source'),
234         'url' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'url to link to'),
235         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'date this record was created'),
236         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
237         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
238     ),
239     'primary key' => array('code'),
240 );
241
242 $schema['reply'] = array(
243     'fields' => array(
244         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'),
245         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'profile replied to'),
246         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
247         'replied_id' => array('type' => 'int', 'description' => 'notice replied to (not used, see notice.reply_to)'),
248     ),
249     'primary key' => array('notice_id', 'profile_id'),
250     'foreign keys' => array(
251         'reply_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
252         'reply_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
253     ),
254     'indexes' => array(
255         'reply_notice_id_idx' => array('notice_id'),
256         'reply_profile_id_idx' => array('profile_id'),
257         'reply_replied_id_idx' => array('replied_id'),
258     ),
259 );
260
261 $schema['fave'] = array(
262     'fields' => array(
263         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the favorite'),
264         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who likes this notice'),
265         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
266     ),
267     'primary key' => array('notice_id', 'user_id'),
268     'foreign keys' => array(
269         'fave_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
270         'fave_user_id_fkey' => array('profile', array('user_id' => 'id')), // note: formerly referenced notice.id, but we can now record remote users' favorites
271     ),
272     'indexes' => array(
273         'fave_notice_id_idx' => array('notice_id'),
274         'fave_user_id_idx' => array('user_id', 'modified'),
275         'fave_modified_idx' => array('modified'),
276     ),
277 );
278
279 /* tables for OAuth */
280
281 $schema['consumer'] = array(
282     'description' => 'OAuth consumer record',
283     'fields' => array(
284         'consumer_key' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'unique identifier, root URL'),
285         'consumer_secret' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'secret value'),
286         'seed' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'seed for new tokens by this consumer'),
287
288         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
289         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
290     ),
291     'primary key' => array('consumer_key'),
292 );
293
294 $schema['token'] = array(
295     'description' => 'OAuth token record',
296     'fields' => array(
297         'consumer_key' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'unique identifier, root URL'),
298         'tok' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'identifying value'),
299         'secret' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'secret value'),
300         'type' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'request or access'),
301         'state' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'for requests, 0 = initial, 1 = authorized, 2 = used'),
302         'verifier' => array('type' => 'varchar', 'length' => 255, 'description' => 'verifier string for OAuth 1.0a'),
303         'verified_callback' => array('type' => 'varchar', 'length' => 255, 'description' => 'verified callback URL for OAuth 1.0a'),
304
305         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
306         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
307     ),
308     'primary key' => array('consumer_key', 'tok'),
309     'foreign keys' => array(
310         'token_consumer_key_fkey' => array('consumer', array('consumer_key'=> 'consumer_key')),
311     ),
312 );
313
314 $schema['nonce'] = array(
315     'description' => 'OAuth nonce record',
316     'fields' => array(
317         'consumer_key' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'unique identifier, root URL'),
318         'tok' => array('type' => 'char', 'length' => 32, 'description' => 'buggy old value, ignored'),
319         'nonce' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'nonce'),
320         'ts' => array('type' => 'datetime', 'not null' => true, 'description' => 'timestamp sent'),
321
322         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
323         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
324     ),
325     'primary key' => array('consumer_key', 'ts', 'nonce'),
326 );
327
328 $schema['oauth_application'] = array(
329     'description' => 'OAuth application registration record',
330     'fields' => array(
331         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
332         'owner' => array('type' => 'int', 'not null' => true, 'description' => 'owner of the application'),
333         'consumer_key' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'application consumer key'),
334         'name' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'name of the application'),
335         'description' => array('type' => 'varchar', 'length' => 255, 'description' => 'description of the application'),
336         'icon' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'application icon'),
337         'source_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'application homepage - used for source link'),
338         'organization' => array('type' => 'varchar', 'length' => 255, 'description' => 'name of the organization running the application'),
339         'homepage' => array('type' => 'varchar', 'length' => 255, 'description' => 'homepage for the organization'),
340         'callback_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'url to redirect to after authentication'),
341         'type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'type of app, 1 = browser, 2 = desktop'),
342         'access_type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'default access type, bit 1 = read, bit 2 = write'),
343         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
344         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
345     ),
346     'primary key' => array('id'),
347     'unique keys' => array(
348         'oauth_application_name_key' => array('name'), // in the long run, we should perhaps not force these unique, and use another source id
349     ),
350     'foreign keys' => array(
351         'oauth_application_owner_fkey' => array('profile', array('owner' => 'id')), // Are remote users allowed to create oauth application records?
352         'oauth_application_consumer_key_fkey' => array('consumer', array('consumer_key' => 'consumer_key')),
353     ),
354 );
355
356 $schema['oauth_application_user'] = array(
357     'fields' => array(
358         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'user of the application'),
359         'application_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of the application'),
360         'access_type' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'access type, bit 1 = read, bit 2 = write'),
361         'token' => array('type' => 'varchar', 'length' => 255, 'description' => 'request or access token'),
362         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
363         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
364     ),
365     'primary key' => array('profile_id', 'application_id'),
366     'foreign keys' => array(
367         'oauth_application_user_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
368         'oauth_application_user_application_id_fkey' => array('oauth_application', array('application_id' => 'id')),
369     ),
370 );
371
372 /* These are used by JanRain OpenID library */
373
374 $schema['oid_associations'] = array(
375     'fields' => array(
376         'server_url' => array('type' => 'blob', 'not null' => true),
377         'handle' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'default' => ''), // character set latin1,
378         'secret' => array('type' => 'blob'),
379         'issued' => array('type' => 'int'),
380         'lifetime' => array('type' => 'int'),
381         'assoc_type' => array('type' => 'varchar', 'length' => 64),
382     ),
383     'primary key' => array(array('server_url', 255), 'handle'),
384 );
385
386 $schema['oid_nonces'] = array(
387     'fields' => array(
388         'server_url' => array('type' => 'varchar', 'length' => 2047),
389         'timestamp' => array('type' => 'int'),
390         'salt' => array('type' => 'char', 'length' => 40),
391     ),
392     'unique keys' => array(
393         'oid_nonces_server_url_timestamp_salt_key' => array(array('server_url', 255), 'timestamp', 'salt'),
394     ),
395 );
396
397 $schema['confirm_address'] = array(
398     'fields' => array(
399         'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'),
400         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who requested confirmation'),
401         'address' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'address (email, xmpp, SMS, etc.)'),
402         'address_extra' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'carrier ID, for SMS'),
403         'address_type' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'),
404         'claimed' => array('type' => 'datetime', 'description' => 'date this was claimed for queueing'),
405         'sent' => array('type' => 'datetime', 'description' => 'date this was sent for queueing'),
406         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
407     ),
408     'primary key' => array('code'),
409     'foreign keys' => array(
410         'confirm_address_user_id_fkey' => array('user', array('user_id' => 'id')),
411     ),
412 );
413
414 $schema['remember_me'] = array(
415     'fields' => array(
416         'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'good random code'),
417         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who is logged in'),
418         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
419     ),
420     'primary key' => array('code'),
421     'foreign keys' => array(
422         'remember_me_user_id_fkey' => array('user', array('user_id' => 'id')),
423     ),
424 );
425
426 $schema['queue_item'] = array(
427     'fields' => array(
428         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
429         'frame' => array('type' => 'blob', 'not null' => true, 'description' => 'data: object reference or opaque string'),
430         'transport' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'queue for what? "email", "xmpp", "sms", "irc", ...'), // @fixme 8 chars is too short; bump up.
431         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
432         'claimed' => array('type' => 'datetime', 'description' => 'date this item was claimed'),
433     ),
434     'primary key' => array('id'),
435     'indexes' => array(
436         'queue_item_created_idx' => array('created'),
437     ),
438 );
439
440 $schema['notice_tag'] = array(
441     'description' => 'Hash tags',
442     'fields' => array(
443         'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'),
444         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice tagged'),
445         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
446     ),
447     'primary key' => array('tag', 'notice_id'),
448     'foreign keys' => array(
449         'notice_tag_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
450     ),
451     'indexes' => array(
452         'notice_tag_created_idx' => array('created'),
453         'notice_tag_notice_id_idx' => array('notice_id'),
454     ),
455 );
456
457 /* Synching with foreign services */
458
459 $schema['foreign_service'] = array(
460     'fields' => array(
461         'id' => array('type' => 'int', 'not null' => true, 'description' => 'numeric key for service'),
462         'name' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'name of the service'),
463         'description' => array('type' => 'varchar', 'length' => 255, 'description' => 'description'),
464         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
465         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
466     ),
467     'primary key' => array('id'),
468     'unique keys' => array(
469         'foreign_service_name_key' => array('name'),
470     ),
471 );
472
473 $schema['foreign_user'] = array(
474     'fields' => array(
475         'id' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'unique numeric key on foreign service'),
476         'service' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to service'),
477         'uri' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'identifying URI'),
478         'nickname' => array('type' => 'varchar', 'length' => 255, 'description' => 'nickname on foreign service'),
479         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
480         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
481     ),
482     'primary key' => array('id', 'service'),
483     'foreign keys' => array(
484         'foreign_user_service_fkey' => array('foreign_service', array('service' => 'id')),
485     ),
486     'unique keys' => array(
487         'foreign_user_uri_key' => array('uri'),
488     ),
489 );
490
491 $schema['foreign_link'] = array(
492     'fields' => array(
493         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'link to user on this system, if exists'),
494         'foreign_id' => array('type' => 'int', 'size' => 'big', 'unsigned' => true, 'not null' => true, 'description' => 'link to user on foreign service, if exists'),
495         'service' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to service'),
496         'credentials' => array('type' => 'varchar', 'length' => 255, 'description' => 'authc credentials, typically a password'),
497         'noticesync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies'),
498         'friendsync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 2, 'description' => 'friend synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'),
499         'profilesync' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'profile synchronization, bit 1 = sync outgoing, bit 2 = sync incoming'),
500         'last_noticesync' => array('type' => 'datetime', 'description' => 'last time notices were imported'),
501         'last_friendsync' => array('type' => 'datetime', 'description' => 'last time friends were imported'),
502         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
503         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
504     ),
505     'primary key' => array('user_id', 'foreign_id', 'service'),
506     'foreign keys' => array(
507         'foreign_link_user_id_fkey' => array('user', array('user_id' => 'id')),
508         'foreign_link_foreign_id_fkey' => array('foreign_user', array('foreign_id' => 'id', 'service' => 'service')),
509         'foreign_link_service_fkey' => array('foreign_service', array('service' => 'id')),
510     ),
511     'indexes' => array(
512         'foreign_user_user_id_idx' => array('user_id'),
513     ),
514 );
515
516 $schema['foreign_subscription'] = array(
517     'fields' => array(
518         'service' => array('type' => 'int', 'not null' => true, 'description' => 'service where relationship happens'),
519         'subscriber' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscriber on foreign service'),
520         'subscribed' => array('type' => 'int', 'size' => 'big', 'not null' => true, 'description' => 'subscribed user'),
521         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
522     ),
523     'primary key' => array('service', 'subscriber', 'subscribed'),
524     'foreign keys' => array(
525         'foreign_subscription_service_fkey' => array('foreign_service', array('service' => 'id')),
526         'foreign_subscription_subscriber_fkey' => array('foreign_user', array('subscriber' => 'id', 'service' => 'service')),
527         'foreign_subscription_subscribed_fkey' => array('foreign_user', array('subscribed' => 'id', 'service' => 'service')),
528     ),
529     'indexes' => array(
530         'foreign_subscription_subscriber_idx' => array('service', 'subscriber'),
531         'foreign_subscription_subscribed_idx' => array('service', 'subscribed'),
532     ),
533 );
534
535 $schema['invitation'] = array(
536     'fields' => array(
537         'code' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'random code for an invitation'),
538         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'who sent the invitation'),
539         'address' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'invitation sent to'),
540         'address_type' => array('type' => 'varchar', 'length' => 8, 'not null' => true, 'description' => 'address type ("email", "xmpp", "sms")'),
541         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
542         'registered_user_id' => array('type' => 'int', 'not null' => false, 'description' => 'if the invitation is converted, who the new user is'),
543     ),
544     'primary key' => array('code'),
545     'foreign keys' => array(
546         'invitation_user_id_fkey' => array('user', array('user_id' => 'id')),
547         'invitation_registered_user_id_fkey' => array('user', array('registered_user_id' => 'id')),
548     ),
549     'indexes' => array(
550         'invitation_address_idx' => array('address', 'address_type'),
551         'invitation_user_id_idx' => array('user_id'),
552         'invitation_registered_user_id_idx' => array('registered_user_id'),
553     ),
554 );
555
556 $schema['message'] = array(
557     'fields' => array(
558         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
559         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier'),
560         'from_profile' => array('type' => 'int', 'not null' => true, 'description' => 'who the message is from'),
561         'to_profile' => array('type' => 'int', 'not null' => true, 'description' => 'who the message is to'),
562         'content' => array('type' => 'text', 'description' => 'message content'),
563         'rendered' => array('type' => 'text', 'description' => 'HTML version of the content'),
564         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of any attachment (image, video, bookmark, whatever)'),
565         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
566         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
567         'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
568     ),
569     'primary key' => array('id'),
570     'unique keys' => array(
571         'message_uri_key' => array('uri'),
572     ),
573     'foreign keys' => array(
574         'message_from_profile_fkey' => array('profile', array('from_profile' => 'id')),
575         'message_to_profile_fkey' => array('profile', array('to_profile' => 'id')),
576     ),
577     'indexes' => array(
578         // @fixme these are really terrible indexes, since you can only sort on one of them at a time.
579         // looks like we really need a (to_profile, created) for inbox and a (from_profile, created) for outbox
580         'message_from_idx' => array('from_profile'),
581         'message_to_idx' => array('to_profile'),
582         'message_created_idx' => array('created'),
583     ),
584 );
585
586 $schema['notice_inbox'] = array(
587     'description' => 'Obsolete; old entries here are converted to packed entries in the inbox table since 0.9',
588     'fields' => array(
589         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user receiving the message'),
590         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice received'),
591         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice was created'),
592         'source' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'reason it is in the inbox, 1=subscription'),
593     ),
594     'primary key' => array('user_id', 'notice_id'),
595     'foreign keys' => array(
596         'notice_inbox_user_id_fkey' => array('user', array('user_id' => 'id')),
597         'notice_inbox_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
598     ),
599     'indexes' => array(
600         'notice_inbox_notice_id_idx' => array('notice_id'),
601     ),
602 );
603
604 $schema['profile_tag'] = array(
605     'fields' => array(
606         'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
607         'tagged' => array('type' => 'int', 'not null' => true, 'description' => 'profile tagged'),
608         'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'hash tag associated with this notice'),
609         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was added'),
610     ),
611     'primary key' => array('tagger', 'tagged', 'tag'),
612     'foreign keys' => array(
613         'profile_tag_tagger_fkey' => array('profile', array('tagger' => 'id')),
614         'profile_tag_tagged_fkey' => array('profile', array('tagged' => 'id')),
615         'profile_tag_tag_fkey' => array('profile_list', array('tag' => 'tag')),
616     ),
617     'indexes' => array(
618         'profile_tag_modified_idx' => array('modified'),
619         'profile_tag_tagger_tag_idx' => array('tagger', 'tag'),
620         'profile_tag_tagged_idx' => array('tagged'),
621     ),
622 );
623
624 $schema['profile_list'] = array(
625     'fields' => array(
626         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
627         'tagger' => array('type' => 'int', 'not null' => true, 'description' => 'user making the tag'),
628         'tag' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'people tag'),
629         'description' => array('type' => 'text', 'description' => 'description of the people tag'),
630         'private' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'is this tag private'),
631
632         'created' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was added'),
633         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date the tag was modified'),
634
635         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universal identifier'),
636         'mainpage' => array('type' => 'varchar', 'length' => 255, 'description' => 'page to link to'),
637         'tagged_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of people tagged with this tag by this user'),
638         'subscriber_count' => array('type' => 'int', 'default' => 0, 'description' => 'number of subscribers to this tag'),
639     ),
640     'primary key' => array('tagger', 'tag'),
641     'unique keys' => array(
642       'profile_list_id_key' => array('id')
643     ),
644     'foreign keys' => array(
645         'profile_list_tagger_fkey' => array('profile', array('tagger' => 'id')),
646     ),
647     'indexes' => array(
648         'profile_list_modified_idx' => array('modified'),
649         'profile_list_tag_idx' => array('tag'),
650         'profile_list_tagger_tag_idx' => array('tagger', 'tag'),
651         'profile_list_tagged_count_idx' => array('tagged_count'),
652         'profile_list_subscriber_count_idx' => array('subscriber_count'),
653     ),
654 );
655
656 $schema['profile_tag_inbox'] = array(
657     'description' => 'Many-many table listing notices associated with people tags.',
658     'fields' => array(
659         'profile_tag_id' => array('type' => 'int', 'not null' => true, 'description' => 'people tag receiving the message'),
660         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice received'),
661         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice was created'),
662     ),
663     'primary key' => array('profile_tag_id', 'notice_id'),
664     'foreign keys' => array(
665         'profile_tag_inbox_profile_list_id_fkey' => array('profile_list', array('profile_tag_id' => 'id')),
666         'profile_tag_inbox_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
667     ),
668     'indexes' => array(
669         'profile_tag_inbox_created_idx' => array('created'),
670         'profile_tag_inbox_profile_tag_id_idx' => array('profile_tag_id'),
671     ),
672 );
673
674 $schema['profile_tag_subscription'] = array(
675     'fields' => array(
676         'profile_tag_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile_tag'),
677         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
678
679         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
680         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
681     ),
682     'primary key' => array('profile_tag_id', 'profile_id'),
683     'foreign keys' => array(
684         'profile_tag_subscription_profile_list_id_fkey' => array('profile_list', array('profile_tag_id' => 'id')),
685         'profile_tag_subscription_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
686     ),
687     'indexes' => array(
688         // @fixme probably we want a (profile_id, created) index here?
689         'profile_tag_subscription_profile_id_idx' => array('profile_id'),
690         'profile_tag_subscription_created_idx' => array('created'),
691     ),
692 );
693
694 $schema['profile_block'] = array(
695     'fields' => array(
696         'blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'),
697         'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'),
698         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking'),
699     ),
700     'foreign keys' => array(
701         'profile_block_blocker_fkey' => array('user', array('blocker' => 'id')),
702         'profile_block_blocked_fkey' => array('profile', array('blocked' => 'id')),
703     ),
704     'primary key' => array('blocker', 'blocked'),
705 );
706
707 $schema['user_group'] = array(
708     'fields' => array(
709         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
710
711         'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'),
712         'fullname' => array('type' => 'varchar', 'length' => 255, 'description' => 'display name'),
713         'homepage' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL, cached so we dont regenerate'),
714         'description' => array('type' => 'text', 'description' => 'group description'),
715         'location' => array('type' => 'varchar', 'length' => 255, 'description' => 'related physical location, if any'),
716
717         'original_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'original size logo'),
718         'homepage_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'homepage (profile) size logo'),
719         'stream_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'stream-sized logo'),
720         'mini_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'mini logo'),
721
722         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
723         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
724
725         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universal identifier'),
726         'mainpage' => array('type' => 'varchar', 'length' => 255, 'description' => 'page for group info to link to'),
727         'join_policy' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'),      
728         'force_scope' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always'),
729     ),
730     'primary key' => array('id'),
731     'unique keys' => array(
732         'user_group_uri_key' => array('uri'),
733     ),
734     'indexes' => array(
735         'user_group_nickname_idx' => array('nickname'),
736     ),
737 );
738
739 $schema['group_member'] = array(
740     'fields' => array(
741         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
742         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'),
743         'is_admin' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'is this user an admin?'),
744
745         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
746         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
747     ),
748     'primary key' => array('group_id', 'profile_id'),
749     'foreign keys' => array(
750         'group_member_group_id_fkey' => array('user_group', array('group_id' => 'id')),
751         'group_member_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
752     ),
753     'indexes' => array(
754         // @fixme probably we want a (profile_id, created) index here?
755         'group_member_profile_id_idx' => array('profile_id'),
756         'group_member_created_idx' => array('created'),
757     ),
758 );
759
760 $schema['related_group'] = array(
761     // @fixme description for related_group?
762     'fields' => array(
763         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
764         'related_group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'),
765
766         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
767     ),
768     'primary key' => array('group_id', 'related_group_id'),
769     'foreign keys' => array(
770         'related_group_group_id_fkey' => array('user_group', array('group_id' => 'id')),
771         'related_group_related_group_id_fkey' => array('user_group', array('related_group_id' => 'id')),
772     ),
773 );
774
775 $schema['group_inbox'] = array(
776     'description' => 'Many-many table listing notices posted to a given group, or which groups a given notice was posted to.',
777     'fields' => array(
778         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group receiving the message'),
779         'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice received'),
780         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice was created'),
781     ),
782     'primary key' => array('group_id', 'notice_id'),
783     'foreign keys' => array(
784         'group_inbox_group_id_fkey' => array('user_group', array('group_id' => 'id')),
785         'group_inbox_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
786     ),
787     'indexes' => array(
788         'group_inbox_created_idx' => array('created'),
789         'group_inbox_notice_id_idx' => array('notice_id'),
790     ),
791 );
792
793 $schema['file'] = array(
794     'fields' => array(
795         'id' => array('type' => 'serial', 'not null' => true),
796         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'destination URL after following redirections'),
797         'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'),
798         'size' => array('type' => 'int', 'description' => 'size of resource when available'),
799         'title' => array('type' => 'varchar', 'length' => 255, 'description' => 'title of resource when available'),
800         'date' => array('type' => 'int', 'description' => 'date of resource according to http query'),
801         'protected' => array('type' => 'int', 'description' => 'true when URL is private (needs login)'),
802         'filename' => array('type' => 'varchar', 'length' => 255, 'description' => 'if a local file, name of the file'),
803
804         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
805     ),
806     'primary key' => array('id'),
807     'unique keys' => array(
808         'file_url_key' => array('url'),
809     ),
810 );
811
812 $schema['file_oembed'] = array(
813     'fields' => array(
814         'file_id' => array('type' => 'int', 'not null' => true, 'description' => 'oEmbed for that URL/file'),
815         'version' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed spec. version'),
816         'type' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed type: photo, video, link, rich'),
817         'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'),
818         'provider' => array('type' => 'varchar', 'length' => 50, 'description' => 'name of this oEmbed provider'),
819         'provider_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of this oEmbed provider'),
820         'width' => array('type' => 'int', 'description' => 'width of oEmbed resource when available'),
821         'height' => array('type' => 'int', 'description' => 'height of oEmbed resource when available'),
822         'html' => array('type' => 'text', 'description' => 'html representation of this oEmbed resource when applicable'),
823         'title' => array('type' => 'varchar', 'length' => 255, 'description' => 'title of oEmbed resource when available'),
824         'author_name' => array('type' => 'varchar', 'length' => 50, 'description' => 'author name for this oEmbed resource'),
825         'author_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'author URL for this oEmbed resource'),
826         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL for this oEmbed resource when applicable (photo, link)'),
827         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
828     ),
829     'primary key' => array('file_id'),
830     'foreign keys' => array(
831          'file_oembed_file_id_fkey' => array('file', array('file_id' => 'id')),
832     ),
833 );
834
835 $schema['file_redirection'] = array(
836     'fields' => array(
837         'url' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'short URL (or any other kind of redirect) for file (id)'),
838         'file_id' => array('type' => 'int', 'description' => 'short URL for what URL/file'),
839         'redirections' => array('type' => 'int', 'description' => 'redirect count'),
840         'httpcode' => array('type' => 'int', 'description' => 'HTTP status code (20x, 30x, etc.)'),
841         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
842     ),
843     'primary key' => array('url'),
844     'foreign keys' => array(
845          'file_redirection_file_id_fkey' => array('file' => array('file_id' => 'id')),
846     ),
847 );
848
849 $schema['file_thumbnail'] = array(
850     'fields' => array(
851         'file_id' => array('type' => 'int', 'not null' => true, 'description' => 'thumbnail for what URL/file'),
852         'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of thumbnail'),
853         'width' => array('type' => 'int', 'description' => 'width of thumbnail'),
854         'height' => array('type' => 'int', 'description' => 'height of thumbnail'),
855         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
856     ),
857     'primary key' => array('file_id'),
858     'foreign keys' => array(
859         'file_thumbnail_file_id_fkey' => array('file', array('file_id' => 'id')),
860     ),
861     'unique keys' => array(
862         'file_thumbnail_url_key' => array('url'),
863     ),
864 );
865
866 $schema['file_to_post'] = array(
867     'fields' => array(
868         'file_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of URL/file'),
869         'post_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of the notice it belongs to'),
870         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
871     ),
872     'primary key' => array('file_id', 'post_id'),
873     'foreign keys' => array(
874         'file_to_post_file_id_fkey' => array('file', array('file_id' => 'id')),
875         'file_to_post_post_id_fkey' => array('notice', array('post_id' => 'id')),
876     ),
877     'indexes' => array(
878         'post_id_idx' => array('post_id'),
879     ),
880 );
881
882 $schema['group_block'] = array(
883     'fields' => array(
884         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'),
885         'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'),
886         'blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'),
887         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking'),
888     ),
889     'primary key' => array('group_id', 'blocked'),
890     'foreign keys' => array(
891         'group_block_group_id_fkey' => array('user_group', array('group_id' => 'id')),
892         'group_block_blocked_fkey' => array('profile', array('blocked' => 'id')),
893         'group_block_blocker_fkey' => array('user', array('blocker' => 'id')),
894     ),
895 );
896
897 $schema['group_alias'] = array(
898     'fields' => array(
899         'alias' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'),
900         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'),
901         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date alias was created'),
902     ),
903     'primary key' => array('alias'),
904     'foreign keys' => array(
905         'group_alias_group_id_fkey' => array('user_group', array('group_id' => 'id')),
906     ),
907     'indexes' => array(
908         'group_alias_group_id_idx' => array('group_id'),
909     ),
910 );
911
912 $schema['session'] = array(
913     'fields' => array(
914         'id' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'),
915         'session_data' => array('type' => 'text', 'description' => 'session data'),
916         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
917         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
918     ),
919     'primary key' => array('id'),
920     'indexes' => array(
921         'session_modified_idx' => array('modified'),
922     ),
923 );
924
925 $schema['deleted_notice'] = array(
926     'fields' => array(
927         'id' => array('type' => 'int', 'not null' => true, 'description' => 'identity of notice'),
928         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'author of the notice'),
929         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'),
930         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice record was created'),
931         'deleted' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice record was created'),
932     ),
933     'primary key' => array('id'),
934     'unique keys' => array(
935         'deleted_notice_uri_key' => array('uri'),
936     ),
937     'indexes' => array(
938         'deleted_notice_profile_id_idx' => array('profile_id'),
939     ),
940 );
941
942 $schema['config'] = array(
943     'fields' => array(
944         'section' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration section'),
945         'setting' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration setting'),
946         'value' => array('type' => 'varchar', 'length' => 255, 'description' => 'configuration value'),
947     ),
948     'primary key' => array('section', 'setting'),
949 );
950
951 $schema['profile_role'] = array(
952     'fields' => array(
953         'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'account having the role'),
954         'role' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'string representing the role'),
955         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the role was granted'),
956     ),
957     'primary key' => array('profile_id', 'role'),
958     'foreign keys' => array(
959         'profile_role_profile_id_fkey' => array('profile', array('profile_id' => 'id')),
960     ),
961 );
962
963 $schema['location_namespace'] = array(
964     'fields' => array(
965         'id' => array('type' => 'int', 'not null' => true, 'description' => 'identity for this namespace'),
966         'description' => array('type' => 'varchar', 'length' => 255, 'description' => 'description of the namespace'),
967         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the record was created'),
968         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
969     ),
970     'primary key' => array('id'),
971 );
972
973 $schema['login_token'] = array(
974     'fields' => array(
975         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user owning this token'),
976         'token' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'token useable for logging in'),
977         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
978         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
979     ),
980     'primary key' => array('user_id'),
981     'foreign keys' => array(
982         'login_token_user_id_fkey' => array('user', array('user_id' => 'id')),
983     ),
984 );
985
986 $schema['user_location_prefs'] = array(
987     'fields' => array(
988         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who has the preference'),
989         'share_location' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Whether to share location data'),
990         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
991         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
992     ),
993     'primary key' => array('user_id'),
994     'foreign keys' => array(
995         'user_location_prefs_user_id_fkey' => array('user', array('user_id' => 'id')),
996     ),
997 );
998
999 $schema['inbox'] = array(
1000     'fields' => array(
1001         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user receiving the notice'),
1002         'notice_ids' => array('type' => 'blob', 'description' => 'packed list of notice ids'),
1003     ),
1004     'primary key' => array('user_id'),
1005     'foreign keys' => array(
1006         'inbox_user_id_fkey' => array('user', array('user_id' => 'id')),
1007     ),
1008 );
1009
1010 // @fixme possibly swap this for a more general prefs table?
1011 $schema['user_im_prefs'] = array(
1012     'fields' => array(
1013         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'),
1014         'screenname' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'screenname on this service'),
1015         'transport' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'),
1016         'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'),
1017         'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies  from people not subscribed to'),
1018         'microid' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'Publish a MicroID'),
1019         'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'),
1020         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
1021         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
1022     ),
1023     'primary key' => array('user_id', 'transport'),
1024     'unique keys' => array(
1025         'transport_screenname_key' => array('transport', 'screenname'),
1026     ),
1027     'foreign keys' => array(
1028         'user_im_prefs_user_id_fkey' => array('user', array('user_id' => 'id')),
1029     ),
1030 );
1031
1032 $schema['conversation'] = array(
1033     'fields' => array(
1034         'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'),
1035         'uri' => array('type' => 'varchar', 'length' => 225, 'description' => 'URI of the conversation'),
1036         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
1037         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
1038     ),
1039     'primary key' => array('id'),
1040     'unique keys' => array(
1041         'conversation_uri_key' => array('uri'),
1042     ),
1043 );
1044
1045 $schema['local_group'] = array(
1046     'description' => 'Record for a user group on the local site, with some additional info not in user_group',
1047     'fields' => array(
1048         'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group represented'),
1049         'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'group represented'),
1050
1051         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
1052         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
1053     ),
1054     'primary key' => array('group_id'),
1055     'foreign keys' => array(
1056         'local_group_group_id_fkey' => array('user_group', array('group_id' => 'id')),
1057     ),
1058     'unique keys' => array(
1059         'local_group_nickname_key' => array('nickname'),
1060     ),
1061 );
1062
1063 $schema['user_urlshortener_prefs'] = array(
1064     'fields' => array(
1065         'user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'),
1066         'urlshorteningservice' => array('type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'),
1067         'maxurllength' => array('type' => 'int', 'not null' => true, 'description' => 'urls greater than this length will be shortened, 0 = always, null = never'),
1068         'maxnoticelength' => array('type' => 'int', 'not null' => true, 'description' => 'notices with content greater than this value will have all urls shortened, 0 = always, null = never'),
1069         
1070         'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
1071         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
1072     ),
1073     'primary key' => array('user_id'),
1074     'foreign keys' => array(
1075         'user_urlshortener_prefs_user_id_fkey' => array('user', array('user_id' => 'id')),
1076     ),
1077 );
1078
1079 $schema['schema_version'] = array(
1080     'description' => 'To avoid checking database structure all the time, we store a checksum of the expected schema info for each table here. If it has not changed since the last time we checked the table, we can leave it as is.',
1081     'fields' => array(
1082         'table_name' => array('type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Table name'),
1083         'checksum' => array('type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Checksum of schema array; a mismatch indicates we should check the table more thoroughly.'),
1084         'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
1085     ),
1086     'primary key' => array('table_name'),
1087 );
1088
1089 $schema['group_join_queue'] = Group_join_queue::schemaDef();
1090
1091 $schema['subscription_queue'] = Subscription_queue::schemaDef();
1092
1093 $schema['oauth_token_association'] = Oauth_token_association::schemaDef();