diff --git a/classes/Confirm_address.php b/classes/Confirm_address.php index 46af2b461b..2f92e0a59a 100644 --- a/classes/Confirm_address.php +++ b/classes/Confirm_address.php @@ -49,6 +49,9 @@ class Confirm_address extends Managed_DataObject 'foreign keys' => array( 'confirm_address_user_id_fkey' => array('user', array('user_id' => 'id')), ), + 'indexes' => array( + 'confirm_address_user_id_idx' => array('user_id'), + ), ); } diff --git a/classes/File_redirection.php b/classes/File_redirection.php index 4bbb3f1484..50c6df4bc7 100644 --- a/classes/File_redirection.php +++ b/classes/File_redirection.php @@ -52,6 +52,9 @@ class File_redirection extends Managed_DataObject 'foreign keys' => array( 'file_redirection_file_id_fkey' => array('file', array('file_id' => 'id')), ), + 'indexes' => array( + 'file_redirection_file_id_idx' => array('file_id'), + ), ); } diff --git a/classes/Foreign_link.php b/classes/Foreign_link.php index 3d0dd8ccbd..b4265f1820 100644 --- a/classes/Foreign_link.php +++ b/classes/Foreign_link.php @@ -63,6 +63,10 @@ class Foreign_link extends Managed_DataObject 'foreign_link_foreign_id_service_fkey' => array('foreign_user', array('foreign_id' => 'id', 'service' => 'service')), 'foreign_link_service_fkey' => array('foreign_service', array('service' => 'id')), ), + 'indexes' => array( + 'foreign_link_foreign_id_service_idx' => array('foreign_id', 'service'), + 'foreign_link_service_idx' => array('service'), + ), ); } diff --git a/classes/Foreign_subscription.php b/classes/Foreign_subscription.php index 32d9dff1e9..e1f14fc846 100644 --- a/classes/Foreign_subscription.php +++ b/classes/Foreign_subscription.php @@ -51,6 +51,8 @@ class Foreign_subscription extends Managed_DataObject 'foreign_subscription_subscribed_service_fkey' => array('foreign_user', array('subscribed' => 'id', 'service' => 'service')), ), 'indexes' => array( + 'foreign_subscription_subscriber_service_idx' => array('subscriber', 'service'), + 'foreign_subscription_subscribed_service_idx' => array('subscribed', 'service'), 'foreign_subscription_service_subscribed_idx' => array('service', 'subscribed'), ), ); diff --git a/classes/Foreign_user.php b/classes/Foreign_user.php index b4c6be7e08..dfe65b8c4f 100644 --- a/classes/Foreign_user.php +++ b/classes/Foreign_user.php @@ -54,6 +54,9 @@ class Foreign_user extends Managed_DataObject 'unique keys' => array( 'foreign_user_uri_key' => array('uri'), ), + 'indexes' => array( + 'foreign_user_service_idx' => array('service'), + ), ); } diff --git a/classes/Group_block.php b/classes/Group_block.php index a52c0822c7..03dac31e19 100644 --- a/classes/Group_block.php +++ b/classes/Group_block.php @@ -54,6 +54,10 @@ class Group_block extends Managed_DataObject 'group_block_blocked_fkey' => array('profile', array('blocked' => 'id')), 'group_block_blocker_fkey' => array('user', array('blocker' => 'id')), ), + 'indexes' => array( + 'group_block_blocked_idx' => array('blocked'), + 'group_block_blocker_idx' => array('blocker'), + ), ); } diff --git a/classes/Oauth_application.php b/classes/Oauth_application.php index 1ef424267d..ed838d0602 100644 --- a/classes/Oauth_application.php +++ b/classes/Oauth_application.php @@ -200,6 +200,10 @@ class Oauth_application extends Managed_DataObject 'oauth_application_owner_fkey' => array('profile', array('owner' => 'id')), // Are remote users allowed to create oauth application records? 'oauth_application_consumer_key_fkey' => array('consumer', array('consumer_key' => 'consumer_key')), ), + 'indexes' => array( + 'oauth_application_owner_idx' => array('owner'), + 'oauth_application_consumer_key_idx' => array('consumer_key'), + ), ); } } diff --git a/classes/Oauth_application_user.php b/classes/Oauth_application_user.php index 1ed8bc706c..2ca199683d 100644 --- a/classes/Oauth_application_user.php +++ b/classes/Oauth_application_user.php @@ -52,6 +52,9 @@ class Oauth_application_user extends Managed_DataObject 'oauth_application_user_profile_id_fkey' => array('profile', array('profile_id' => 'id')), 'oauth_application_user_application_id_fkey' => array('oauth_application', array('application_id' => 'id')), ), + 'indexes' => array( + 'oauth_application_user_application_id_idx' => array('application_id'), + ), ); } diff --git a/classes/Oauth_token_association.php b/classes/Oauth_token_association.php index 221acdcecd..02191d8c10 100644 --- a/classes/Oauth_token_association.php +++ b/classes/Oauth_token_association.php @@ -68,6 +68,9 @@ class Oauth_token_association extends Managed_DataObject 'oauth_token_association_profile_id_fkey' => array('profile', array('profile_id' => 'id')), 'oauth_token_association_application_id_fkey' => array('oauth_application', array('application_id' => 'id')), ), + 'indexes' => array( + 'oauth_token_association_application_id_idx' => array('application_id'), + ), ); } } diff --git a/classes/Profile_block.php b/classes/Profile_block.php index eb1ddf4d5e..d4e7c83cf2 100644 --- a/classes/Profile_block.php +++ b/classes/Profile_block.php @@ -49,6 +49,9 @@ class Profile_block extends Managed_DataObject 'profile_block_blocked_fkey' => array('profile', array('blocked' => 'id')), ), 'primary key' => array('blocker', 'blocked'), + 'indexes' => array( + 'profile_block_blocked_idx' => array('blocked'), + ), ); } diff --git a/classes/Related_group.php b/classes/Related_group.php index 7ed64b9c47..ff51e6cd20 100644 --- a/classes/Related_group.php +++ b/classes/Related_group.php @@ -47,6 +47,9 @@ class Related_group extends Managed_DataObject 'related_group_group_id_fkey' => array('user_group', array('group_id' => 'id')), 'related_group_related_group_id_fkey' => array('user_group', array('related_group_id' => 'id')), ), + 'indexes' => array( + 'related_group_related_group_id_idx' => array('related_group_id'), + ), ); } } diff --git a/classes/Remember_me.php b/classes/Remember_me.php index 20c3d66a5a..f7cbee5f58 100644 --- a/classes/Remember_me.php +++ b/classes/Remember_me.php @@ -45,6 +45,9 @@ class Remember_me extends Managed_DataObject 'foreign keys' => array( 'remember_me_user_id_fkey' => array('user', array('user_id' => 'id')), ), + 'indexes' => array( + 'remember_me_user_id_idx' => array('user_id'), + ), ); } } diff --git a/classes/User.php b/classes/User.php index 142f8ed695..0a36357d0e 100644 --- a/classes/User.php +++ b/classes/User.php @@ -102,6 +102,7 @@ class User extends Managed_DataObject 'user_carrier_fkey' => array('sms_carrier', array('carrier' => 'id')), ), 'indexes' => array( + 'user_carrier_idx' => array('carrier'), 'user_created_idx' => array('created'), 'user_smsemail_idx' => array('smsemail'), ), diff --git a/lib/database/mysqlschema.php b/lib/database/mysqlschema.php index 6a4a5f017f..105ef54512 100644 --- a/lib/database/mysqlschema.php +++ b/lib/database/mysqlschema.php @@ -259,12 +259,9 @@ class MysqlSchema extends Schema << $fkey_def) { + $fkey_cols = array_keys($fkey_def[1]); + + // A list of all keys/indices + $keys = array_values(array_merge( + ($def['unique keys'] ?? []), + ($def['indexes'] ?? []) + )); + if (array_key_exists('primary key', $def)) { + $keys[] = $def['primary key']; + } + + $indexed = false; + foreach ($keys as $key_cols) { + // Only the beginning of a key counts + $cols = array_slice($key_cols, 0, count($fkey_cols)); + + if ($cols == $fkey_cols) { + $indexed = true; + break; + } + } + + if (!$indexed) { + throw new ServerException( + "Invalid table definition for {$tableName}: " + . "foreign key {$fkey_name} is not indexed." + ); + } + } } return $def; diff --git a/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php b/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php index 80f3cae151..e168149534 100644 --- a/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php +++ b/plugins/ActivityPub/classes/Activitypub_pending_follow_requests.php @@ -60,6 +60,10 @@ class Activitypub_pending_follow_requests extends Managed_DataObject 'activitypub_pending_follow_requests_local_profile_id_fkey' => ['profile', ['local_profile_id' => 'id']], 'activitypub_pending_follow_requests_remote_profile_id_fkey' => ['profile', ['remote_profile_id' => 'id']], ], + 'indexes' => [ + 'activitypub_pending_follow_requests_local_profile_id_idx' => ['local_profile_id'], + 'activitypub_pending_follow_requests_remote_profile_id_idx' => ['remote_profile_id'], + ], ]; } diff --git a/plugins/Event/classes/Happening.php b/plugins/Event/classes/Happening.php index ecbd7f18b3..2a2c7df6c4 100644 --- a/plugins/Event/classes/Happening.php +++ b/plugins/Event/classes/Happening.php @@ -95,6 +95,7 @@ class Happening extends Managed_DataObject 'happening_uri_fkey' => array('notice', array('uri' => 'uri')) ), 'indexes' => array( + 'happening_profile_id_idx' => array('profile_id'), 'happening_created_idx' => array('created'), 'happening_start_time_end_time_idx' => array('start_time', 'end_time'), ), diff --git a/plugins/Event/classes/RSVP.php b/plugins/Event/classes/RSVP.php index 653c482bea..a3be71aff5 100644 --- a/plugins/Event/classes/RSVP.php +++ b/plugins/Event/classes/RSVP.php @@ -85,7 +85,10 @@ class RSVP extends Managed_DataObject 'rsvp_event_uri_fkey' => array('happening', array('event_uri' => 'uri')), 'rsvp_profile_id_fkey' => array('profile', array('profile_id' => 'id')) ), - 'indexes' => array('rsvp_created_idx' => array('created')), + 'indexes' => array( + 'rsvp_event_uri_idx' => array('event_uri'), + 'rsvp_created_idx' => array('created'), + ), ); } diff --git a/plugins/ExtendedProfile/classes/GNUsocialProfileExtensionResponse.php b/plugins/ExtendedProfile/classes/GNUsocialProfileExtensionResponse.php index 5f7ed6004e..36e8b81c6d 100644 --- a/plugins/ExtendedProfile/classes/GNUsocialProfileExtensionResponse.php +++ b/plugins/ExtendedProfile/classes/GNUsocialProfileExtensionResponse.php @@ -55,6 +55,7 @@ class GNUsocialProfileExtensionResponse extends Managed_DataObject 'gnusocialprofileextensionresponse_extension_id_fkey' => ['gnusocialprofileextensionfield', ['extension_id' => 'id']], ], 'indexes' => [ + 'gnusocialprofileextensionresponse_profile_id_idx' => ['profile_id'], 'gnusocialprofileextensionresponse_extension_id_idx' => ['extension_id'], ], ]; diff --git a/plugins/GroupPrivateMessage/classes/Group_message_profile.php b/plugins/GroupPrivateMessage/classes/Group_message_profile.php index ad465b96ea..434ad2e8a2 100644 --- a/plugins/GroupPrivateMessage/classes/Group_message_profile.php +++ b/plugins/GroupPrivateMessage/classes/Group_message_profile.php @@ -1,48 +1,42 @@ . + /** * Who received a group message * - * PHP version 5 - * - * @category Data - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ - * - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2011, StatusNet, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . + * @category Data + * @package GNUsocial + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('STATUSNET')) { - exit(1); -} +defined('GNUSOCIAL') || die(); require_once INSTALLDIR . '/classes/Memcached_DataObject.php'; /** * Data class for group direct messages for users * - * @category GroupPrivateMessage - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 - * @link http://status.net/ + * @category GroupPrivateMessage + * @package GNUsocial + * @author Evan Prodromou + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * - * @see DB_DataObject + * @see DB_DataObject */ class Group_message_profile extends Managed_DataObject { @@ -66,10 +60,13 @@ class Group_message_profile extends Managed_DataObject 'group_message_profile_to_profile_fkey' => array('profile', array('to_profile' => 'id')), 'group_message_profile_group_message_id_fkey' => array('group_message', array('group_message_id' => 'id')), ), + 'indexes' => array( + 'group_message_profile_group_message_id_idx' => array('group_message_id'), + ), ); } - function send($gm, $profile) + public function send($gm, $profile) { $gmp = new Group_message_profile(); @@ -87,13 +84,13 @@ class Group_message_profile extends Managed_DataObject return $gmp; } - function notify() + public function notify() { // XXX: add more here $this->notifyByMail(); } - function notifyByMail() + public function notifyByMail() { $to = User::getKV('id', $this->to_profile); @@ -117,21 +114,23 @@ class Group_message_profile extends Managed_DataObject // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname, // TRANS: %3$s is the message content, %4$s a URL to the message, // TRANS: %5$s is the StatusNet sitename. - $body = sprintf(_m("%1\$s (%2\$s) sent a private message to group %3\$s:\n\n". - "------------------------------------------------------\n". - "%4\$s\n". - "------------------------------------------------------\n\n". - "You can reply to their message here:\n\n". - "%5\$s\n\n". - "Do not reply to this email; it will not get to them.\n\n". - "With kind regards,\n". - "%6\$s"), - $from_profile->getBestName(), - $from_profile->nickname, - $group->nickname, - $gm->content, - common_local_url('newmessage', array('to' => $from_profile->id)), - common_config('site', 'name')) . "\n"; + $body = sprintf( + _m("%1\$s (%2\$s) sent a private message to group %3\$s:\n\n" + . "------------------------------------------------------\n" + . "%4\$s\n" + . "------------------------------------------------------\n\n" + . "You can reply to their message here:\n\n" + . "%5\$s\n\n" + . "Do not reply to this email; it will not get to them.\n\n" + . "With kind regards,\n" + . "%6\$s"), + $from_profile->getBestName(), + $from_profile->nickname, + $group->nickname, + $gm->content, + common_local_url('newmessage', ['to' => $from_profile->id]), + common_config('site', 'name') + ) . "\n"; $headers = _mail_prepare_headers('message', $to->nickname, $from_profile->nickname); diff --git a/plugins/MentionURL/classes/Mention_url_profile.php b/plugins/MentionURL/classes/Mention_url_profile.php index 44c36a0362..b04d24ce42 100644 --- a/plugins/MentionURL/classes/Mention_url_profile.php +++ b/plugins/MentionURL/classes/Mention_url_profile.php @@ -37,6 +37,9 @@ class Mention_url_profile extends Managed_DataObject 'foreign keys' => array( 'mention_url_profile_profile_id_fkey' => array('profile', array('profile_id' => 'id')), ), + 'indexes' => array( + 'mention_url_profile_profile_id_idx' => array('profile_id'), + ), ); } diff --git a/plugins/ModLog/classes/ModLog.php b/plugins/ModLog/classes/ModLog.php index 0c61f488d3..c8ce036c7f 100644 --- a/plugins/ModLog/classes/ModLog.php +++ b/plugins/ModLog/classes/ModLog.php @@ -90,6 +90,7 @@ class ModLog extends Managed_DataObject ], 'indexes' => [ 'modlog_profile_id_created_idx' => ['profile_id', 'created'], + 'modlog_moderator_id_idx' => ['moderator_id'], ], ]; }