Merge pull request #2366 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 3a4d3e9d4b
local
commit
678fa1e6af
24 changed files with 224 additions and 20 deletions
@ -0,0 +1,21 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class Api::V1::Instances::LanguagesController < Api::BaseController |
||||
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? |
||||
skip_around_action :set_locale |
||||
|
||||
before_action :set_languages |
||||
|
||||
vary_by '' |
||||
|
||||
def show |
||||
cache_even_if_authenticated! |
||||
render json: @languages, each_serializer: REST::LanguageSerializer |
||||
end |
||||
|
||||
private |
||||
|
||||
def set_languages |
||||
@languages = LanguagesHelper::SUPPORTED_LOCALES.keys.map { |code| LanguagePresenter.new(code) } |
||||
end |
||||
end |
@ -0,0 +1,20 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class LanguagePresenter < ActiveModelSerializers::Model |
||||
attributes :code, :name, :native_name |
||||
|
||||
def initialize(code) |
||||
super() |
||||
|
||||
@code = code |
||||
@item = LanguagesHelper::SUPPORTED_LOCALES[code] |
||||
end |
||||
|
||||
def name |
||||
@item[0] |
||||
end |
||||
|
||||
def native_name |
||||
@item[1] |
||||
end |
||||
end |
@ -0,0 +1,5 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class REST::LanguageSerializer < ActiveModel::Serializer |
||||
attributes :code, :name |
||||
end |
@ -0,0 +1,39 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class AddUniqueIndexOnPreviewCardsStatuses < ActiveRecord::Migration[6.1] |
||||
disable_ddl_transaction! |
||||
|
||||
def up |
||||
add_index :preview_cards_statuses, [:status_id, :preview_card_id], name: :preview_cards_statuses_pkey, algorithm: :concurrently, unique: true |
||||
rescue ActiveRecord::RecordNotUnique |
||||
deduplicate_and_reindex! |
||||
end |
||||
|
||||
def down |
||||
remove_index :preview_cards_statuses, name: :preview_cards_statuses_pkey |
||||
end |
||||
|
||||
private |
||||
|
||||
def deduplicate_and_reindex! |
||||
deduplicate_preview_cards! |
||||
|
||||
safety_assured { execute 'REINDEX INDEX preview_cards_statuses_pkey' } |
||||
rescue ActiveRecord::RecordNotUnique |
||||
retry |
||||
end |
||||
|
||||
def deduplicate_preview_cards! |
||||
# Statuses should have only one preview card at most, even if that's not the database |
||||
# constraint we will end up with |
||||
duplicate_ids = select_all('SELECT status_id FROM preview_cards_statuses GROUP BY status_id HAVING count(*) > 1;').rows |
||||
|
||||
duplicate_ids.each_slice(1000) do |ids| |
||||
# This one is tricky: since we don't have primary keys to keep only one record, |
||||
# use the physical `ctid` |
||||
safety_assured do |
||||
execute "DELETE FROM preview_cards_statuses p WHERE p.status_id IN (#{ids.join(', ')}) AND p.ctid NOT IN (SELECT q.ctid FROM preview_cards_statuses q WHERE q.status_id = p.status_id LIMIT 1)" |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,20 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
class AddPrimaryKeyToPreviewCardsStatusesJoinTable < ActiveRecord::Migration[6.1] |
||||
disable_ddl_transaction! |
||||
|
||||
def up |
||||
safety_assured do |
||||
execute 'ALTER TABLE preview_cards_statuses ADD PRIMARY KEY USING INDEX preview_cards_statuses_pkey' |
||||
end |
||||
end |
||||
|
||||
def down |
||||
safety_assured do |
||||
# I have found no way to demote the primary key to an index, instead, re-create the index |
||||
execute 'CREATE UNIQUE INDEX CONCURRENTLY preview_cards_statuses_pkey_tmp ON preview_cards_statuses (status_id, preview_card_id)' |
||||
execute 'ALTER TABLE preview_cards_statuses DROP CONSTRAINT preview_cards_statuses_pkey' |
||||
execute 'ALTER INDEX preview_cards_statuses_pkey_tmp RENAME TO preview_cards_statuses_pkey' |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,19 @@ |
||||
# frozen_string_literal: true |
||||
|
||||
require 'rails_helper' |
||||
|
||||
RSpec.describe 'Languages' do |
||||
describe 'GET /api/v1/instance/languages' do |
||||
before do |
||||
get '/api/v1/instance/languages' |
||||
end |
||||
|
||||
it 'returns http success' do |
||||
expect(response).to have_http_status(200) |
||||
end |
||||
|
||||
it 'returns the supported languages' do |
||||
expect(body_as_json.pluck(:code)).to match_array LanguagesHelper::SUPPORTED_LOCALES.keys.map(&:to_s) |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue