Merge branch 'develop' into 'reactions'

# Conflicts:
#   CHANGELOG.md
This commit is contained in:
lain 2019-10-10 12:38:51 +00:00
commit d7f9679ff2
136 changed files with 864 additions and 320 deletions

View file

@ -1,3 +1,3 @@
[ [
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}", "priv/repo/migrations/*.exs"]
] ]

View file

@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OAuth: support for hierarchical permissions / [Mastodon 2.4.3 OAuth permissions](https://docs.joinmastodon.org/api/permissions/) - OAuth: support for hierarchical permissions / [Mastodon 2.4.3 OAuth permissions](https://docs.joinmastodon.org/api/permissions/)
- Authentication: Added rate limit for password-authorized actions / login existence checks - Authentication: Added rate limit for password-authorized actions / login existence checks
- Metadata Link: Atom syndication Feed - Metadata Link: Atom syndication Feed
- Mix task to re-count statuses for all users (`mix pleroma.count_statuses`)
- Pleroma API: Add Emoji reactions - Pleroma API: Add Emoji reactions
### Changed ### Changed
@ -28,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Admin API: Return link alongside with token on password reset - Admin API: Return link alongside with token on password reset
- MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities - MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities
- OStatus: Extract RSS functionality - OStatus: Extract RSS functionality
- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`)
### Fixed ### Fixed
- Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`) - Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`)
@ -86,6 +88,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user - ActivityPub: Fix `/users/:nickname/inbox` crashing without an authenticated user
- MRF: fix ability to follow a relay when AntiFollowbotPolicy was enabled - MRF: fix ability to follow a relay when AntiFollowbotPolicy was enabled
- Mastodon API: Blocks are now treated consistently between the Streaming API and the Timeline APIs - Mastodon API: Blocks are now treated consistently between the Streaming API and the Timeline APIs
- Mastodon API: `exclude_replies` is correctly handled again.
### Added ### Added
- Expiring/ephemeral activites. All activities can have expires_at value set, which controls when they should be deleted automatically. - Expiring/ephemeral activites. All activities can have expires_at value set, which controls when they should be deleted automatically.

View file

@ -0,0 +1,22 @@
defmodule Mix.Tasks.Pleroma.CountStatuses do
@shortdoc "Re-counts statuses for all users"
use Mix.Task
alias Pleroma.User
import Ecto.Query
def run([]) do
Mix.Pleroma.start_pleroma()
stream =
User
|> where(local: true)
|> Pleroma.Repo.stream()
Pleroma.Repo.transaction(fn ->
Enum.each(stream, &User.update_note_count/1)
end)
Mix.Pleroma.shell_info("Done")
end
end

View file

@ -806,8 +806,8 @@ defp restrict_media(query, _), do: query
defp restrict_replies(query, %{"exclude_replies" => val}) when val == "true" or val == "1" do defp restrict_replies(query, %{"exclude_replies" => val}) when val == "true" or val == "1" do
from( from(
activity in query, [_activity, object] in query,
where: fragment("?->'object'->>'inReplyTo' is null", activity.data) where: fragment("?->>'inReplyTo' is null", object.data)
) )
end end

View file

@ -167,7 +167,11 @@ def create(%{assigns: %{user: _user}} = conn, %{"media_ids" => _} = params) do
def show(%{assigns: %{user: user}} = conn, %{"id" => id}) do def show(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Activity.get_by_id_with_object(id), with %Activity{} = activity <- Activity.get_by_id_with_object(id),
true <- Visibility.visible_for_user?(activity, user) do true <- Visibility.visible_for_user?(activity, user) do
try_render(conn, "show.json", activity: activity, for: user) try_render(conn, "show.json",
activity: activity,
for: user,
with_direct_conversation_id: true
)
end end
end end

View file

@ -3,14 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.User do
def change do def change do
create_if_not_exists table(:users) do create_if_not_exists table(:users) do
add :email, :string add(:email, :string)
add :password_hash, :string add(:password_hash, :string)
add :name, :string add(:name, :string)
add :nickname, :string add(:nickname, :string)
add :bio, :string add(:bio, :string)
timestamps() timestamps()
end end
end end
end end

View file

@ -3,12 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.Activity do
def change do def change do
create_if_not_exists table(:activities) do create_if_not_exists table(:activities) do
add :data, :map add(:data, :map)
timestamps() timestamps()
end end
create_if_not_exists index(:activities, [:data], using: :gin) create_if_not_exists(index(:activities, [:data], using: :gin))
end end
end end

View file

@ -3,10 +3,9 @@ defmodule Pleroma.Repo.Migrations.CreatePleroma.Object do
def change do def change do
create_if_not_exists table(:objects) do create_if_not_exists table(:objects) do
add :data, :map add(:data, :map)
timestamps() timestamps()
end end
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddFollowingListToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :following, :map add(:following, :map)
end end
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddApIdToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :ap_id, :string add(:ap_id, :string)
end end
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddIndexToObjects do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:objects, [:data], using: :gin) create_if_not_exists(index(:objects, [:data], using: :gin))
end end
end end

View file

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.AddUniqueIndexToEmailAndNickname do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists unique_index(:users, [:email]) create_if_not_exists(unique_index(:users, [:email]))
create_if_not_exists unique_index(:users, [:nickname]) create_if_not_exists(unique_index(:users, [:nickname]))
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddAvatarObjectToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :avatar, :map add(:avatar, :map)
end end
end end
end end

View file

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateWebsubServerSubscription do
def change do def change do
create_if_not_exists table(:websub_server_subscriptions) do create_if_not_exists table(:websub_server_subscriptions) do
add :topic, :string add(:topic, :string)
add :callback, :string add(:callback, :string)
add :secret, :string add(:secret, :string)
add :valid_until, :naive_datetime add(:valid_until, :naive_datetime)
add :state, :string add(:state, :string)
timestamps() timestamps()
end end

View file

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.AddFieldsToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :local, :boolean, default: true add(:local, :boolean, default: true)
add :info, :map add(:info, :map)
end end
end end
end end

View file

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateWebsubClientSubscription do
def change do def change do
create_if_not_exists table(:websub_client_subscriptions) do create_if_not_exists table(:websub_client_subscriptions) do
add :topic, :string add(:topic, :string)
add :secret, :string add(:secret, :string)
add :valid_until, :naive_datetime_usec add(:valid_until, :naive_datetime_usec)
add :state, :string add(:state, :string)
add :subscribers, :map add(:subscribers, :map)
timestamps() timestamps()
end end

View file

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.AddUserAndHub do
def change do def change do
alter table(:websub_client_subscriptions) do alter table(:websub_client_subscriptions) do
add :hub, :string add(:hub, :string)
add :user_id, references(:users) add(:user_id, references(:users))
end end
end end
end end

View file

@ -2,10 +2,16 @@ defmodule Pleroma.Repo.Migrations.AddIdContraintsToActivitiesAndObjectsPartTwo d
use Ecto.Migration use Ecto.Migration
def up do def up do
drop_if_exists index(:objects, ["(data->>\"id\")"], name: :objects_unique_apid_index) drop_if_exists(index(:objects, ["(data->>\"id\")"], name: :objects_unique_apid_index))
drop_if_exists index(:activities, ["(data->>\"id\")"], name: :activities_unique_apid_index) drop_if_exists(index(:activities, ["(data->>\"id\")"], name: :activities_unique_apid_index))
create_if_not_exists unique_index(:objects, ["(data->>'id')"], name: :objects_unique_apid_index)
create_if_not_exists unique_index(:activities, ["(data->>'id')"], name: :activities_unique_apid_index) create_if_not_exists(
unique_index(:objects, ["(data->>'id')"], name: :objects_unique_apid_index)
)
create_if_not_exists(
unique_index(:activities, ["(data->>'id')"], name: :activities_unique_apid_index)
)
end end
def down, do: :ok def down, do: :ok

View file

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddLocalFieldToActivities do
def change do def change do
alter table(:activities) do alter table(:activities) do
add :local, :boolean, default: true add(:local, :boolean, default: true)
end end
create_if_not_exists index(:activities, [:local]) create_if_not_exists(index(:activities, [:local]))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddUniqueIndexToAPID do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists unique_index(:users, [:ap_id]) create_if_not_exists(unique_index(:users, [:ap_id]))
end end
end end

View file

@ -3,14 +3,13 @@ defmodule Pleroma.Repo.Migrations.LongerBios do
def up do def up do
alter table(:users) do alter table(:users) do
modify :bio, :text modify(:bio, :text)
end end
end end
def down do def down do
alter table(:users) do alter table(:users) do
modify :bio, :string modify(:bio, :string)
end end
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.RemoveActivitiesIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:activities, [:data]) drop_if_exists(index(:activities, [:data]))
end end
end end

View file

@ -2,7 +2,16 @@ defmodule Pleroma.Repo.Migrations.AddObjectActivityIndexPartTwo do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:objects, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index) drop_if_exists(
create_if_not_exists index(:activities, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index) index(:objects, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
create_if_not_exists(
index(:activities, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
end end
end end

View file

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.AddActorIndexToActivity do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:activities, ["(data->>'actor')", "inserted_at desc"], name: :activities_actor_index) create_if_not_exists(
index(:activities, ["(data->>'actor')", "inserted_at desc"], name: :activities_actor_index)
)
end end
end end

View file

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.AddFollowerAddressToUser do
def up do def up do
alter table(:users) do alter table(:users) do
add :follower_address, :string, unique: true add(:follower_address, :string, unique: true)
end end
end end
def down do def down do
alter table(:users) do alter table(:users) do
remove :follower_address remove(:follower_address)
end end
end end
end end

View file

@ -3,12 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddMastodonApps do
def change do def change do
create_if_not_exists table(:apps) do create_if_not_exists table(:apps) do
add :client_name, :string add(:client_name, :string)
add :redirect_uris, :string add(:redirect_uris, :string)
add :scopes, :string add(:scopes, :string)
add :website, :string add(:website, :string)
add :client_id, :string add(:client_id, :string)
add :client_secret, :string add(:client_secret, :string)
timestamps() timestamps()
end end

View file

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateOAuthAuthorizations do
def change do def change do
create_if_not_exists table(:oauth_authorizations) do create_if_not_exists table(:oauth_authorizations) do
add :app_id, references(:apps) add(:app_id, references(:apps))
add :user_id, references(:users) add(:user_id, references(:users))
add :token, :string add(:token, :string)
add :valid_until, :naive_datetime_usec add(:valid_until, :naive_datetime_usec)
add :used, :boolean, default: false add(:used, :boolean, default: false)
timestamps() timestamps()
end end

View file

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateOAuthToken do
def change do def change do
create_if_not_exists table(:oauth_tokens) do create_if_not_exists table(:oauth_tokens) do
add :app_id, references(:apps) add(:app_id, references(:apps))
add :user_id, references(:users) add(:user_id, references(:users))
add :token, :string add(:token, :string)
add :refresh_token, :string add(:refresh_token, :string)
add :valid_until, :naive_datetime_usec add(:valid_until, :naive_datetime_usec)
timestamps() timestamps()
end end

View file

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateNotifications do
def change do def change do
create_if_not_exists table(:notifications) do create_if_not_exists table(:notifications) do
add :user_id, references(:users, on_delete: :delete_all) add(:user_id, references(:users, on_delete: :delete_all))
add :activity_id, references(:activities, on_delete: :delete_all) add(:activity_id, references(:activities, on_delete: :delete_all))
add :seen, :boolean, default: false add(:seen, :boolean, default: false)
timestamps() timestamps()
end end
create_if_not_exists index(:notifications, [:user_id]) create_if_not_exists(index(:notifications, [:user_id]))
end end
end end

View file

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.AddContextIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["(data->>'type')", "(data->>'context')"], name: :activities_context_index, concurrently: true) create(
index(:activities, ["(data->>'type')", "(data->>'context')"],
name: :activities_context_index,
concurrently: true
)
)
end end
end end

View file

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddFTSIndexToActivities do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"], concurrently: true, using: :gin, name: :activities_fts) create(
index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"],
concurrently: true,
using: :gin,
name: :activities_fts
)
)
end end
end end

View file

@ -4,6 +4,12 @@ defmodule Pleroma.Repo.Migrations.AddTagIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["(data #> '{\"object\",\"tag\"}')"], concurrently: true, using: :gin, name: :activities_tags) create(
index(:activities, ["(data #> '{\"object\",\"tag\"}')"],
concurrently: true,
using: :gin,
name: :activities_tags
)
)
end end
end end

View file

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.CreatePasswordResetTokens do
def change do def change do
create_if_not_exists table(:password_reset_tokens) do create_if_not_exists table(:password_reset_tokens) do
add :token, :string add(:token, :string)
add :user_id, references(:users) add(:user_id, references(:users))
add :used, :boolean, default: false add(:used, :boolean, default: false)
timestamps() timestamps()
end end

View file

@ -4,7 +4,17 @@ defmodule Pleroma.Repo.Migrations.AddSecondObjectIndexToActivty do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
drop_if_exists index(:activities, ["(data->'object'->>'id')", "(data->>'type')"], name: :activities_create_objects_index) drop_if_exists(
create index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"], name: :activities_create_objects_index, concurrently: true) index(:activities, ["(data->'object'->>'id')", "(data->>'type')"],
name: :activities_create_objects_index
)
)
create(
index(:activities, ["(coalesce(data->'object'->>'id', data->>'object'))"],
name: :activities_create_objects_index,
concurrently: true
)
)
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropObjectIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:objects, [:data], using: :gin) drop_if_exists(index(:objects, [:data], using: :gin))
end end
end end

View file

@ -4,6 +4,11 @@ defmodule Pleroma.Repo.Migrations.AddObjectActorIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:objects, ["(data->>'actor')", "(data->>'type')"], concurrently: true, name: :objects_actor_type) create(
index(:objects, ["(data->>'actor')", "(data->>'type')"],
concurrently: true,
name: :objects_actor_type
)
)
end end
end end

View file

@ -5,16 +5,17 @@ defmodule Pleroma.Repo.Migrations.AddActorToActivity do
def up do def up do
alter table(:activities) do alter table(:activities) do
add :actor, :string add(:actor, :string)
end end
create index(:activities, [:actor, "id DESC NULLS LAST"], concurrently: true) create(index(:activities, [:actor, "id DESC NULLS LAST"], concurrently: true))
end end
def down do def down do
drop_if_exists index(:activities, [:actor, "id DESC NULLS LAST"]) drop_if_exists(index(:activities, [:actor, "id DESC NULLS LAST"]))
alter table(:activities) do alter table(:activities) do
remove :actor remove(:actor)
end end
end end
end end

View file

@ -5,17 +5,19 @@ defmodule Pleroma.Repo.Migrations.FillActorField do
def up do def up do
max = Repo.aggregate(Activity, :max, :id) max = Repo.aggregate(Activity, :max, :id)
if max do if max do
IO.puts("#{max} activities") IO.puts("#{max} activities")
chunks = 0..(round(max / 10_000)) chunks = 0..round(max / 10_000)
Enum.each(chunks, fn (i) -> Enum.each(chunks, fn i ->
min = i * 10_000 min = i * 10_000
max = min + 10_000 max = min + 10_000
execute(""" execute("""
update activities set actor = data->>'actor' where id > #{min} and id <= #{max}; update activities set actor = data->>'actor' where id > #{min} and id <= #{max};
""") """)
|> IO.inspect |> IO.inspect()
end) end)
end end
end end
@ -23,4 +25,3 @@ def up do
def down do def down do
end end
end end

View file

@ -3,6 +3,6 @@ defmodule Pleroma.Repo.Migrations.AddSortIndexToActivities do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["id desc nulls last"], concurrently: true) create(index(:activities, ["id desc nulls last"], concurrently: true))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddLocalIndexToUser do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:users, [:local]) create_if_not_exists(index(:users, [:local]))
end end
end end

View file

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddRecipientsToActivities do
def change do def change do
alter table(:activities) do alter table(:activities) do
add :recipients, {:array, :string} add(:recipients, {:array, :string})
end end
create_if_not_exists index(:activities, [:recipients], using: :gin) create_if_not_exists(index(:activities, [:recipients], using: :gin))
end end
end end

View file

@ -4,17 +4,21 @@ defmodule Pleroma.Repo.Migrations.FillRecipientsInActivities do
def up do def up do
max = Repo.aggregate(Activity, :max, :id) max = Repo.aggregate(Activity, :max, :id)
if max do if max do
IO.puts("#{max} activities") IO.puts("#{max} activities")
chunks = 0..(round(max / 10_000)) chunks = 0..round(max / 10_000)
Enum.each(chunks, fn (i) -> Enum.each(chunks, fn i ->
min = i * 10_000 min = i * 10_000
max = min + 10_000 max = min + 10_000
execute(""" execute("""
update activities set recipients = array(select jsonb_array_elements_text(data->'to')) where id > #{min} and id <= #{max}; update activities set recipients = array(select jsonb_array_elements_text(data->'to')) where id > #{
min
} and id <= #{max};
""") """)
|> IO.inspect |> IO.inspect()
end) end)
end end
end end

View file

@ -3,17 +3,18 @@ defmodule Pleroma.Repo.Migrations.MakeFollowingPostgresArray do
def up do def up do
alter table(:users) do alter table(:users) do
add :following_temp, {:array, :string} add(:following_temp, {:array, :string})
end end
execute """ execute("""
update users set following_temp = array(select jsonb_array_elements_text(following)); update users set following_temp = array(select jsonb_array_elements_text(following));
""" """)
alter table(:users) do alter table(:users) do
remove :following remove(:following)
end end
rename table(:users), :following_temp, to: :following
rename(table(:users), :following_temp, to: :following)
end end
def down, do: :ok def down, do: :ok

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddFollowerAddressIndexToUsers do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:users, [:follower_address], concurrently: true) create(index(:users, [:follower_address], concurrently: true))
create index(:users, [:following], concurrently: true, using: :gin) create(index(:users, [:following], concurrently: true, using: :gin))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropLocalIndexOnActivities do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:users, [:local]) drop_if_exists(index(:users, [:local]))
end end
end end

View file

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.ActuallyDropLocalIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:users, [:local]) create_if_not_exists(index(:users, [:local]))
drop_if_exists index("activities", :local) drop_if_exists(index("activities", :local))
end end
end end

View file

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateLists do
def change do def change do
create_if_not_exists table(:lists) do create_if_not_exists table(:lists) do
add :user_id, references(:users, on_delete: :delete_all) add(:user_id, references(:users, on_delete: :delete_all))
add :title, :string add(:title, :string)
add :following, {:array, :string} add(:following, {:array, :string})
timestamps() timestamps()
end end
create_if_not_exists index(:lists, [:user_id]) create_if_not_exists(index(:lists, [:user_id]))
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.ModifyActivityIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["id desc nulls last", "local"], concurrently: true) create(index(:activities, ["id desc nulls last", "local"], concurrently: true))
drop_if_exists index(:activities, ["id desc nulls last"]) drop_if_exists(index(:activities, ["id desc nulls last"]))
end end
end end

View file

@ -4,8 +4,15 @@ defmodule Pleroma.Repo.Migrations.AddTrigramExtension do
def up do def up do
Logger.warn("ATTENTION ATTENTION ATTENTION\n") Logger.warn("ATTENTION ATTENTION ATTENTION\n")
Logger.warn("This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n")
Logger.warn("sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n") Logger.warn(
"This will try to create the pg_trgm extension on your database. If your database user does NOT have the necessary rights, you will have to do it manually and re-run the migrations.\nYou can probably do this by running the following:\n"
)
Logger.warn(
"sudo -u postgres psql pleroma_dev -c \"create extension if not exists pg_trgm\"\n"
)
execute("create extension if not exists pg_trgm") execute("create extension if not exists pg_trgm")
end end

View file

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserTrigramIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:users, ["(nickname || name) gist_trgm_ops"], name: :users_trigram_index, using: :gist) create_if_not_exists(
index(:users, ["(nickname || name) gist_trgm_ops"], name: :users_trigram_index, using: :gist)
)
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddListFollowIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:lists, [:following]) create_if_not_exists(index(:lists, [:following]))
end end
end end

View file

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateApidHostExtractionIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["(split_part(actor, '/', 3))"], concurrently: true, name: :activities_hosts) create(
index(:activities, ["(split_part(actor, '/', 3))"],
concurrently: true,
name: :activities_hosts
)
)
end end
end end

View file

@ -3,8 +3,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserInviteTokens do
def change do def change do
create_if_not_exists table(:user_invite_tokens) do create_if_not_exists table(:user_invite_tokens) do
add :token, :string add(:token, :string)
add :used, :boolean, default: false add(:used, :boolean, default: false)
timestamps() timestamps()
end end

View file

@ -3,6 +3,11 @@ defmodule Pleroma.Repo.Migrations.CreateActivitiesInReplyToIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["(data->'object'->>'inReplyTo')"], concurrently: true, name: :activities_in_reply_to) create(
index(:activities, ["(data->'object'->>'inReplyTo')"],
concurrently: true,
name: :activities_in_reply_to
)
)
end end
end end

View file

@ -3,18 +3,21 @@ defmodule Pleroma.Repo.Migrations.CreateFilters do
def change do def change do
create_if_not_exists table(:filters) do create_if_not_exists table(:filters) do
add :user_id, references(:users, on_delete: :delete_all) add(:user_id, references(:users, on_delete: :delete_all))
add :filter_id, :integer add(:filter_id, :integer)
add :hide, :boolean add(:hide, :boolean)
add :phrase, :string add(:phrase, :string)
add :context, {:array, :string} add(:context, {:array, :string})
add :expires_at, :utc_datetime add(:expires_at, :utc_datetime)
add :whole_word, :boolean add(:whole_word, :boolean)
timestamps() timestamps()
end end
create_if_not_exists index(:filters, [:user_id]) create_if_not_exists(index(:filters, [:user_id]))
create_if_not_exists index(:filters, [:phrase], where: "hide = true", name: :hided_phrases_index)
create_if_not_exists(
index(:filters, [:phrase], where: "hide = true", name: :hided_phrases_index)
)
end end
end end

View file

@ -3,11 +3,11 @@ defmodule Pleroma.Repo.Migrations.AddRecipientsToAndCcFieldsToActivities do
def change do def change do
alter table(:activities) do alter table(:activities) do
add :recipients_to, {:array, :string} add(:recipients_to, {:array, :string})
add :recipients_cc, {:array, :string} add(:recipients_cc, {:array, :string})
end end
create_if_not_exists index(:activities, [:recipients_to], using: :gin) create_if_not_exists(index(:activities, [:recipients_to], using: :gin))
create_if_not_exists index(:activities, [:recipients_cc], using: :gin) create_if_not_exists(index(:activities, [:recipients_cc], using: :gin))
end end
end end

View file

@ -2,7 +2,12 @@ defmodule Pleroma.Repo.Migrations.ActivitiesAddToCcIndices do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:activities, ["(data->'to')"], name: :activities_to_index, using: :gin) create_if_not_exists(
create_if_not_exists index(:activities, ["(data->'cc')"], name: :activities_cc_index, using: :gin) index(:activities, ["(data->'to')"], name: :activities_to_index, using: :gin)
)
create_if_not_exists(
index(:activities, ["(data->'cc')"], name: :activities_cc_index, using: :gin)
)
end end
end end

View file

@ -3,15 +3,15 @@ defmodule Pleroma.Repo.Migrations.RemoveRecipientsToAndCcFieldsFromActivities do
def up do def up do
alter table(:activities) do alter table(:activities) do
remove :recipients_to remove(:recipients_to)
remove :recipients_cc remove(:recipients_cc)
end end
end end
def down do def down do
alter table(:activities) do alter table(:activities) do
add :recipients_to, {:array, :string} add(:recipients_to, {:array, :string})
add :recipients_cc, {:array, :string} add(:recipients_cc, {:array, :string})
end end
end end
end end

View file

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.UsersAddIsModeratorIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:users, ["(info->'is_moderator')"], name: :users_is_moderator_index, using: :gin) create_if_not_exists(
index(:users, ["(info->'is_moderator')"], name: :users_is_moderator_index, using: :gin)
)
end end
end end

View file

@ -3,16 +3,16 @@ defmodule Pleroma.Repo.Migrations.CreatePushSubscriptions do
def change do def change do
create_if_not_exists table("push_subscriptions") do create_if_not_exists table("push_subscriptions") do
add :user_id, references("users", on_delete: :delete_all) add(:user_id, references("users", on_delete: :delete_all))
add :token_id, references("oauth_tokens", on_delete: :delete_all) add(:token_id, references("oauth_tokens", on_delete: :delete_all))
add :endpoint, :string add(:endpoint, :string)
add :key_p256dh, :string add(:key_p256dh, :string)
add :key_auth, :string add(:key_auth, :string)
add :data, :map add(:data, :map)
timestamps() timestamps()
end end
create_if_not_exists index("push_subscriptions", [:user_id, :token_id], unique: true) create_if_not_exists(index("push_subscriptions", [:user_id, :token_id], unique: true))
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.UsersAddLastRefreshedAt do
def change do def change do
alter table(:users) do alter table(:users) do
add :last_refreshed_at, :naive_datetime_usec add(:last_refreshed_at, :naive_datetime_usec)
end end
end end
end end

View file

@ -3,9 +3,9 @@ defmodule Pleroma.Repo.Migrations.AddTagsToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :tags, {:array, :string} add(:tags, {:array, :string})
end end
create_if_not_exists index(:users, [:tags], using: :gin) create_if_not_exists(index(:users, [:tags], using: :gin))
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddBookmarksToUsers do
def change do def change do
alter table(:users) do alter table(:users) do
add :bookmarks, {:array, :string}, null: false, default: [] add(:bookmarks, {:array, :string}, null: false, default: [])
end end
end end
end end

View file

@ -16,32 +16,34 @@ def up do
# Old serial int ids are transformed to 128bits with extra padding. # Old serial int ids are transformed to 128bits with extra padding.
# The application (in `Pleroma.FlakeId`) handles theses IDs properly as integers; to keep compatibility # The application (in `Pleroma.FlakeId`) handles theses IDs properly as integers; to keep compatibility
# with previously issued ids. # with previously issued ids.
#execute "update activities set external_id = CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid);" # execute "update activities set external_id = CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid);"
#execute "update users set external_id = CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid);" # execute "update users set external_id = CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid);"
clippy = start_clippy_heartbeats() clippy = start_clippy_heartbeats()
# Lock both tables to avoid a running server to meddling with our transaction # Lock both tables to avoid a running server to meddling with our transaction
execute "LOCK TABLE activities;" execute("LOCK TABLE activities;")
execute "LOCK TABLE users;" execute("LOCK TABLE users;")
execute """ execute("""
ALTER TABLE activities ALTER TABLE activities
DROP CONSTRAINT activities_pkey CASCADE, DROP CONSTRAINT activities_pkey CASCADE,
ALTER COLUMN id DROP default, ALTER COLUMN id DROP default,
ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid), ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid),
ADD PRIMARY KEY (id); ADD PRIMARY KEY (id);
""" """)
execute """ execute("""
ALTER TABLE users ALTER TABLE users
DROP CONSTRAINT users_pkey CASCADE, DROP CONSTRAINT users_pkey CASCADE,
ALTER COLUMN id DROP default, ALTER COLUMN id DROP default,
ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid), ALTER COLUMN id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(id), 32, '0' ) AS uuid),
ADD PRIMARY KEY (id); ADD PRIMARY KEY (id);
""" """)
execute "UPDATE users SET info = jsonb_set(info, '{pinned_activities}', array_to_json(ARRAY(select jsonb_array_elements_text(info->'pinned_activities')))::jsonb);" execute(
"UPDATE users SET info = jsonb_set(info, '{pinned_activities}', array_to_json(ARRAY(select jsonb_array_elements_text(info->'pinned_activities')))::jsonb);"
)
# Fkeys: # Fkeys:
# Activities - Referenced by: # Activities - Referenced by:
@ -56,18 +58,19 @@ def up do
# TABLE "push_subscriptions" CONSTRAINT "push_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE # TABLE "push_subscriptions" CONSTRAINT "push_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
# TABLE "websub_client_subscriptions" CONSTRAINT "websub_client_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) # TABLE "websub_client_subscriptions" CONSTRAINT "websub_client_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
execute """ execute("""
ALTER TABLE notifications ALTER TABLE notifications
ALTER COLUMN activity_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(activity_id), 32, '0' ) AS uuid), ALTER COLUMN activity_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(activity_id), 32, '0' ) AS uuid),
ADD CONSTRAINT notifications_activity_id_fkey FOREIGN KEY (activity_id) REFERENCES activities(id) ON DELETE CASCADE; ADD CONSTRAINT notifications_activity_id_fkey FOREIGN KEY (activity_id) REFERENCES activities(id) ON DELETE CASCADE;
""" """)
for table <- ~w(notifications filters lists oauth_authorizations oauth_tokens password_reset_tokens push_subscriptions websub_client_subscriptions) do for table <-
execute """ ~w(notifications filters lists oauth_authorizations oauth_tokens password_reset_tokens push_subscriptions websub_client_subscriptions) do
execute("""
ALTER TABLE #{table} ALTER TABLE #{table}
ALTER COLUMN user_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(user_id), 32, '0' ) AS uuid), ALTER COLUMN user_id SET DATA TYPE uuid USING CAST( LPAD( TO_HEX(user_id), 32, '0' ) AS uuid),
ADD CONSTRAINT #{table}_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; ADD CONSTRAINT #{table}_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
""" """)
end end
flush() flush()
@ -78,41 +81,50 @@ def up do
def down, do: :ok def down, do: :ok
defp start_clippy_heartbeats() do defp start_clippy_heartbeats() do
count = from(a in "activities", select: count(a.id)) |> Repo.one! count = from(a in "activities", select: count(a.id)) |> Repo.one!()
if count > 5000 do if count > 5000 do
heartbeat_interval = :timer.minutes(2) + :timer.seconds(30) heartbeat_interval = :timer.minutes(2) + :timer.seconds(30)
all_tips = Clippy.tips() ++ [
all_tips =
Clippy.tips() ++
[
"The migration is still running, maybe it's time for another “tea”?", "The migration is still running, maybe it's time for another “tea”?",
"Happy rabbits practice a cute behavior known as a\n“binky:” they jump up in the air\nand twist\nand spin around!", "Happy rabbits practice a cute behavior known as a\n“binky:” they jump up in the air\nand twist\nand spin around!",
"Nothing and everything.\n\nI still work.", "Nothing and everything.\n\nI still work.",
"Pleroma runs on a Raspberry Pi!\n\n … but this migration will take forever if you\nactually run on a raspberry pi", "Pleroma runs on a Raspberry Pi!\n\n … but this migration will take forever if you\nactually run on a raspberry pi",
"Status? Stati? Post? Note? Toot?\nRepeat? Reboost? Boost? Retweet? Retoot??\n\nI-I'm confused.", "Status? Stati? Post? Note? Toot?\nRepeat? Reboost? Boost? Retweet? Retoot??\n\nI-I'm confused."
] ]
heartbeat = fn(heartbeat, runs, all_tips, tips) -> heartbeat = fn heartbeat, runs, all_tips, tips ->
tips = if Integer.is_even(runs) do tips =
if Integer.is_even(runs) do
tips = if tips == [], do: all_tips, else: tips tips = if tips == [], do: all_tips, else: tips
[tip | tips] = Enum.shuffle(tips) [tip | tips] = Enum.shuffle(tips)
Clippy.puts(tip) Clippy.puts(tip)
tips tips
else else
IO.puts "\n -- #{DateTime.to_string(DateTime.utc_now())} Migration still running, please wait…\n" IO.puts(
"\n -- #{DateTime.to_string(DateTime.utc_now())} Migration still running, please wait…\n"
)
tips tips
end end
:timer.sleep(heartbeat_interval) :timer.sleep(heartbeat_interval)
heartbeat.(heartbeat, runs + 1, all_tips, tips) heartbeat.(heartbeat, runs + 1, all_tips, tips)
end end
Clippy.puts [ Clippy.puts([
[:red, :bright, "It looks like you are running an older instance!"], [:red, :bright, "It looks like you are running an older instance!"],
[""], [""],
[:bright, "This migration may take a long time", :reset, " -- so you probably should"], [:bright, "This migration may take a long time", :reset, " -- so you probably should"],
["go drink a cofe, or a tea, or a beer, a whiskey, a vodka,"], ["go drink a cofe, or a tea, or a beer, a whiskey, a vodka,"],
["while it runs to deal with your temporary fediverse pause!"] ["while it runs to deal with your temporary fediverse pause!"]
] ])
:timer.sleep(heartbeat_interval) :timer.sleep(heartbeat_interval)
spawn_link(fn() -> heartbeat.(heartbeat, 1, all_tips, []) end) spawn_link(fn -> heartbeat.(heartbeat, 1, all_tips, []) end)
end end
end end
@ -120,8 +132,7 @@ defp stop_clippy_heartbeats(pid) do
if pid do if pid do
Process.unlink(pid) Process.unlink(pid)
Process.exit(pid, :kill) Process.exit(pid, :kill)
Clippy.puts [[:green, :bright, "Hurray!!", "", "", "Migration completed!"]] Clippy.puts([[:green, :bright, "Hurray!!", "", "", "Migration completed!"]])
end end
end end
end end

View file

@ -43,6 +43,8 @@ def down do
) )
) )
execute("drop function if exists activity_visibility(actor varchar, recipients varchar[], data jsonb)") execute(
"drop function if exists activity_visibility(actor varchar, recipients varchar[], data jsonb)"
)
end end
end end

View file

@ -2,7 +2,8 @@ defmodule Pleroma.Repo.Migrations.CreateUserFtsIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index( create_if_not_exists(
index(
:users, :users,
[ [
""" """
@ -13,5 +14,6 @@ def change do
name: :users_fts_index, name: :users_fts_index,
using: :gin using: :gin
) )
)
end end
end end

View file

@ -27,10 +27,8 @@ def up do
""" """
execute(definition) execute(definition)
end end
def down do def down do
end end
end end

View file

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.UsersAddIsAdminIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists(index(:users, ["(info->'is_admin')"], name: :users_is_admin_index, using: :gin)) create_if_not_exists(
index(:users, ["(info->'is_admin')"], name: :users_is_admin_index, using: :gin)
)
end end
end end

View file

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.CreateInstances do
def change do def change do
create_if_not_exists table(:instances) do create_if_not_exists table(:instances) do
add :host, :string add(:host, :string)
add :unreachable_since, :naive_datetime_usec add(:unreachable_since, :naive_datetime_usec)
timestamps() timestamps()
end end
create_if_not_exists unique_index(:instances, [:host]) create_if_not_exists(unique_index(:instances, [:host]))
create_if_not_exists index(:instances, [:unreachable_since]) create_if_not_exists(index(:instances, [:unreachable_since]))
end end
end end

View file

@ -27,11 +27,8 @@ def up do
""" """
execute(definition) execute(definition)
end end
def down do def down do
end end
end end

View file

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddActivitiesLikesIndex do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:activities, ["((data #> '{\"object\",\"likes\"}'))"], concurrently: true, name: :activities_likes, using: :gin) create(
index(:activities, ["((data #> '{\"object\",\"likes\"}'))"],
concurrently: true,
name: :activities_likes,
using: :gin
)
)
end end
end end

View file

@ -2,9 +2,17 @@ defmodule Pleroma.Repo.Migrations.SplitHideNetwork do
use Ecto.Migration use Ecto.Migration
def up do def up do
execute("UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network') AND local") execute(
execute("UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network') WHERE local") "UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network') AND local"
execute("UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network') WHERE local") )
execute(
"UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network') WHERE local"
)
execute(
"UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network') WHERE local"
)
end end
def down do def down do

View file

@ -3,10 +3,10 @@ defmodule Pleroma.Repo.Migrations.CreateThreadMutes do
def change do def change do
create_if_not_exists table(:thread_mutes) do create_if_not_exists table(:thread_mutes) do
add :user_id, references(:users, type: :uuid, on_delete: :delete_all) add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
add :context, :string add(:context, :string)
end end
create_if_not_exists unique_index(:thread_mutes, [:user_id, :context], name: :unique_index) create_if_not_exists(unique_index(:thread_mutes, [:user_id, :context], name: :unique_index))
end end
end end

View file

@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.AddScopeSToOAuthEntities do
def change do def change do
for t <- [:oauth_authorizations, :oauth_tokens] do for t <- [:oauth_authorizations, :oauth_tokens] do
alter table(t) do alter table(t) do
add :scopes, {:array, :string}, default: [], null: false add(:scopes, {:array, :string}, default: [], null: false)
end end
end end
end end

View file

@ -4,14 +4,20 @@ defmodule Pleroma.Repo.Migrations.ChangeAppsScopesToVarcharArray do
@alter_apps_scopes "ALTER TABLE apps ALTER COLUMN scopes" @alter_apps_scopes "ALTER TABLE apps ALTER COLUMN scopes"
def up do def up do
execute "#{@alter_apps_scopes} TYPE varchar(255)[] USING string_to_array(scopes, ',')::varchar(255)[];" execute(
execute "#{@alter_apps_scopes} SET DEFAULT ARRAY[]::character varying[];" "#{@alter_apps_scopes} TYPE varchar(255)[] USING string_to_array(scopes, ',')::varchar(255)[];"
execute "#{@alter_apps_scopes} SET NOT NULL;" )
execute("#{@alter_apps_scopes} SET DEFAULT ARRAY[]::character varying[];")
execute("#{@alter_apps_scopes} SET NOT NULL;")
end end
def down do def down do
execute "#{@alter_apps_scopes} DROP NOT NULL;" execute("#{@alter_apps_scopes} DROP NOT NULL;")
execute "#{@alter_apps_scopes} DROP DEFAULT;" execute("#{@alter_apps_scopes} DROP DEFAULT;")
execute "#{@alter_apps_scopes} TYPE varchar(255) USING array_to_string(scopes, ',')::varchar(255);"
execute(
"#{@alter_apps_scopes} TYPE varchar(255) USING array_to_string(scopes, ',')::varchar(255);"
)
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.DataMigrationPopulateOAuthScopes do
def up do def up do
for t <- [:oauth_authorizations, :oauth_tokens] do for t <- [:oauth_authorizations, :oauth_tokens] do
execute "UPDATE #{t} SET scopes = apps.scopes FROM apps WHERE #{t}.app_id = apps.id;" execute("UPDATE #{t} SET scopes = apps.scopes FROM apps WHERE #{t}.app_id = apps.id;")
end end
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.DataMigrationNormalizeScopes do
def up do def up do
for t <- [:apps, :oauth_authorizations, :oauth_tokens] do for t <- [:apps, :oauth_authorizations, :oauth_tokens] do
execute "UPDATE #{t} SET scopes = string_to_array(array_to_string(scopes, ' '), ' ');" execute("UPDATE #{t} SET scopes = string_to_array(array_to_string(scopes, ' '), ' ');")
end end
end end

View file

@ -2,7 +2,7 @@ defmodule Pleroma.Repo.Migrations.AddDefaultTagsToUser do
use Ecto.Migration use Ecto.Migration
def up do def up do
execute "UPDATE users SET tags = array[]::varchar[] where tags IS NULL" execute("UPDATE users SET tags = array[]::varchar[] where tags IS NULL")
end end
def down, do: :noop def down, do: :noop

View file

@ -4,7 +4,7 @@ defmodule Pleroma.Repo.Migrations.UpdateUserNoteCounters do
@public "https://www.w3.org/ns/activitystreams#Public" @public "https://www.w3.org/ns/activitystreams#Public"
def up do def up do
execute """ execute("""
WITH public_note_count AS ( WITH public_note_count AS (
SELECT SELECT
data->>'actor' AS actor, data->>'actor' AS actor,
@ -19,11 +19,11 @@ def up do
SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true) SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true)
FROM public_note_count AS o FROM public_note_count AS o
WHERE u.ap_id = o.actor WHERE u.ap_id = o.actor
""" """)
end end
def down do def down do
execute """ execute("""
WITH public_note_count AS ( WITH public_note_count AS (
SELECT SELECT
data->>'actor' AS actor, data->>'actor' AS actor,
@ -36,6 +36,6 @@ def down do
SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true) SET "info" = jsonb_set(u.info, '{note_count}', o.count::varchar::jsonb, true)
FROM public_note_count AS o FROM public_note_count AS o
WHERE u.ap_id = o.actor WHERE u.ap_id = o.actor
""" """)
end end
end end

View file

@ -3,16 +3,16 @@ defmodule Pleroma.Repo.Migrations.CreateRegistrations do
def change do def change do
create_if_not_exists table(:registrations, primary_key: false) do create_if_not_exists table(:registrations, primary_key: false) do
add :id, :uuid, primary_key: true add(:id, :uuid, primary_key: true)
add :user_id, references(:users, type: :uuid, on_delete: :delete_all) add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
add :provider, :string add(:provider, :string)
add :uid, :string add(:uid, :string)
add :info, :map, default: %{} add(:info, :map, default: %{})
timestamps() timestamps()
end end
create_if_not_exists unique_index(:registrations, [:provider, :uid]) create_if_not_exists(unique_index(:registrations, [:provider, :uid]))
create_if_not_exists unique_index(:registrations, [:user_id, :provider, :uid]) create_if_not_exists(unique_index(:registrations, [:user_id, :provider, :uid]))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.CreateNotificationIdIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:notifications, ["id desc nulls last"]) create_if_not_exists(index(:notifications, ["id desc nulls last"]))
end end
end end

View file

@ -3,6 +3,12 @@ defmodule Pleroma.Repo.Migrations.AddIndexOnSubscribers do
@disable_ddl_transaction true @disable_ddl_transaction true
def change do def change do
create index(:users, ["(info->'subscribers')"], name: :users_subscribers_index, using: :gin, concurrently: true) create(
index(:users, ["(info->'subscribers')"],
name: :users_subscribers_index,
using: :gin,
concurrently: true
)
)
end end
end end

View file

@ -19,8 +19,8 @@ def change do
timestamps() timestamps()
end end
create_if_not_exists index(:conversation_participations, [:conversation_id]) create_if_not_exists(index(:conversation_participations, [:conversation_id]))
create_if_not_exists unique_index(:conversation_participations, [:user_id, :conversation_id]) create_if_not_exists(unique_index(:conversation_participations, [:user_id, :conversation_id]))
create_if_not_exists unique_index(:conversations, [:ap_id]) create_if_not_exists(unique_index(:conversations, [:ap_id]))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddParticipationUpdatedAtIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:conversation_participations, ["updated_at desc"]) create_if_not_exists(index(:conversation_participations, ["updated_at desc"]))
end end
end end

View file

@ -2,6 +2,8 @@ defmodule Pleroma.Repo.Migrations.AddIndexOnUserInfoDeactivated do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists(index(:users, ["(info->'deactivated')"], name: :users_deactivated_index, using: :gin)) create_if_not_exists(
index(:users, ["(info->'deactivated')"], name: :users_deactivated_index, using: :gin)
)
end end
end end

View file

@ -29,7 +29,7 @@ def up do
def down do def down do
alter table(:users) do alter table(:users) do
add :bookmarks, {:array, :string}, null: false, default: [] add(:bookmarks, {:array, :string}, null: false, default: [])
end end
end end
end end

View file

@ -2,7 +2,18 @@ defmodule Pleroma.Repo.Migrations.AddFTSIndexToObjects do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"], using: :gin, name: :activities_fts) drop_if_exists(
create_if_not_exists index(:objects, ["(to_tsvector('english', data->>'content'))"], using: :gin, name: :objects_fts) index(:activities, ["(to_tsvector('english', data->'object'->>'content'))"],
using: :gin,
name: :activities_fts
)
)
create_if_not_exists(
index(:objects, ["(to_tsvector('english', data->>'content'))"],
using: :gin,
name: :objects_fts
)
)
end end
end end

View file

@ -2,18 +2,18 @@ defmodule Pleroma.Repo.Migrations.SetDefaultStateToReports do
use Ecto.Migration use Ecto.Migration
def up do def up do
execute """ execute("""
UPDATE activities AS a UPDATE activities AS a
SET data = jsonb_set(data, '{state}', '"open"', true) SET data = jsonb_set(data, '{state}', '"open"', true)
WHERE data->>'type' = 'Flag' WHERE data->>'type' = 'Flag'
""" """)
end end
def down do def down do
execute """ execute("""
UPDATE activities AS a UPDATE activities AS a
SET data = data #- '{state}' SET data = data #- '{state}'
WHERE data->>'type' = 'Flag' WHERE data->>'type' = 'Flag'
""" """)
end end
end end

View file

@ -3,13 +3,13 @@ defmodule Pleroma.Repo.Migrations.ChangeHideColumnInFilterTable do
def up do def up do
alter table(:filters) do alter table(:filters) do
modify :hide, :boolean, default: false modify(:hide, :boolean, default: false)
end end
end end
def down do def down do
alter table(:filters) do alter table(:filters) do
modify :hide, :boolean modify(:hide, :boolean)
end end
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddObjectInReplyToIndex do
use Ecto.Migration use Ecto.Migration
def change do def change do
create index(:objects, ["(data->>'inReplyTo')"], name: :objects_in_reply_to_index) create(index(:objects, ["(data->>'inReplyTo')"], name: :objects_in_reply_to_index))
end end
end end

View file

@ -2,7 +2,10 @@ defmodule Pleroma.Repo.Migrations.AddTagIndexToObjects do
use Ecto.Migration use Ecto.Migration
def change do def change do
drop_if_exists index(:activities, ["(data #> '{\"object\",\"tag\"}')"], using: :gin, name: :activities_tags) drop_if_exists(
create_if_not_exists index(:objects, ["(data->'tag')"], using: :gin, name: :objects_tags) index(:activities, ["(data #> '{\"object\",\"tag\"}')"], using: :gin, name: :activities_tags)
)
create_if_not_exists(index(:objects, ["(data->'tag')"], using: :gin, name: :objects_tags))
end end
end end

View file

@ -3,6 +3,8 @@ defmodule Pleroma.Repo.Migrations.CopyMutedToMutedNotifications do
alias Pleroma.User alias Pleroma.User
def change do def change do
execute("update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true") execute(
"update users set info = jsonb_set(info, '{muted_notifications}', info->'mutes', true) where local = true"
)
end end
end end

View file

@ -7,7 +7,7 @@ def change do
add(:participation_id, references(:conversation_participations, on_delete: :delete_all)) add(:participation_id, references(:conversation_participations, on_delete: :delete_all))
end end
create_if_not_exists index(:conversation_participation_recipient_ships, [:user_id]) create_if_not_exists(index(:conversation_participation_recipient_ships, [:user_id]))
create_if_not_exists index(:conversation_participation_recipient_ships, [:participation_id]) create_if_not_exists(index(:conversation_participation_recipient_ships, [:participation_id]))
end end
end end

View file

@ -2,6 +2,6 @@ defmodule Pleroma.Repo.Migrations.AddLikesIndexToObjects do
use Ecto.Migration use Ecto.Migration
def change do def change do
create_if_not_exists index(:objects, ["(data->'likes')"], using: :gin, name: :objects_likes) create_if_not_exists(index(:objects, ["(data->'likes')"], using: :gin, name: :objects_likes))
end end
end end

View file

@ -6,7 +6,8 @@ def change do
add(:object_id, references(:objects, type: :id), null: false) add(:object_id, references(:objects, type: :id), null: false)
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all), null: false) add(:user_id, references(:users, type: :uuid, on_delete: :delete_all), null: false)
end end
create_if_not_exists index(:deliveries, :object_id, name: :deliveries_object_id)
create_if_not_exists(index(:deliveries, :object_id, name: :deliveries_object_id))
create_if_not_exists(unique_index(:deliveries, [:user_id, :object_id])) create_if_not_exists(unique_index(:deliveries, [:user_id, :object_id]))
end end
end end

View file

@ -2,7 +2,6 @@ defmodule Pleroma.Repo.Migrations.DropSubscriptionIfExists do
use Ecto.Migration use Ecto.Migration
def change do def change do
end end
def up do def up do
@ -10,6 +9,7 @@ def up do
drop_if_exists(index(:subscription_notifications, ["id desc nulls last"])) drop_if_exists(index(:subscription_notifications, ["id desc nulls last"]))
drop_if_exists(table(:subscription_notifications)) drop_if_exists(table(:subscription_notifications))
end end
def down do def down do
:ok :ok
end end

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddKeysColumn do
def change do def change do
alter table("users") do alter table("users") do
add_if_not_exists :keys, :text add_if_not_exists(:keys, :text)
end end
end end
end end

View file

@ -2,6 +2,9 @@ defmodule Pleroma.Repo.Migrations.MoveKeysToSeparateColumn do
use Ecto.Migration use Ecto.Migration
def change do def change do
execute("update users set keys = info->>'keys' where local", "update users set info = jsonb_set(info, '{keys}'::text[], to_jsonb(keys)) where local") execute(
"update users set keys = info->>'keys' where local",
"update users set info = jsonb_set(info, '{keys}'::text[], to_jsonb(keys)) where local"
)
end end
end end

View file

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.cb3673e4b661fd9526ea.css rel=stylesheet></head><body><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.4cedffe4993b111c7421.js></script><script type=text/javascript src=/static/js/app.8098503330c7dd14a415.js></script></body></html> <!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.4e8e80a2f95232cff399.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.24e6ba2d196f6210feda.js></script><script type=text/javascript src=/static/js/app.4ab7097a5650339b9e3d.js></script></body></html>

View file

@ -1,6 +1,32 @@
.with-load-more-footer {
padding: 10px;
text-align: center;
border-top: 1px solid;
border-top-color: #222;
border-top-color: var(--border, #222);
}
.with-load-more-footer .error {
font-size: 14px;
}
.tab-switcher {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
}
.tab-switcher .contents {
-ms-flex: 1 0 auto;
flex: 1 0 auto;
min-height: 0px;
}
.tab-switcher .contents .hidden { .tab-switcher .contents .hidden {
display: none; display: none;
} }
.tab-switcher .contents.scrollable-tabs {
-ms-flex-preferred-size: 0;
flex-basis: 0;
overflow-y: auto;
}
.tab-switcher .tabs { .tab-switcher .tabs {
display: -ms-flexbox; display: -ms-flexbox;
display: flex; display: flex;
@ -65,16 +91,6 @@ .tab-switcher .tabs .tab-wrapper:not(.active)::after {
border-bottom-color: #222; border-bottom-color: #222;
border-bottom-color: var(--border, #222); border-bottom-color: var(--border, #222);
} }
.with-load-more-footer {
padding: 10px;
text-align: center;
border-top: 1px solid;
border-top-color: #222;
border-top-color: var(--border, #222);
}
.with-load-more-footer .error {
font-size: 14px;
}
.with-subscription-loading { .with-subscription-loading {
padding: 10px; padding: 10px;
text-align: center; text-align: center;
@ -83,4 +99,4 @@ .with-subscription-loading .error {
font-size: 14px; font-size: 14px;
} }
/*# sourceMappingURL=app.cb3673e4b661fd9526ea.css.map*/ /*# sourceMappingURL=app.4e8e80a2f95232cff399.css.map*/

Some files were not shown because too many files have changed in this diff Show more