mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 05:37:59 +01:00
Multiple sources structural changes
This commit is contained in:
parent
1c5b07086e
commit
9bce2ca0a4
12 changed files with 393 additions and 101 deletions
|
@ -92,11 +92,6 @@ defmodule Philomena.Images do
|
|||
|> Image.cache_changeset()
|
||||
|> repo.update()
|
||||
end)
|
||||
|> Multi.run(:source_change, fn repo, %{image: image} ->
|
||||
%SourceChange{image_id: image.id, initial: true}
|
||||
|> SourceChange.creation_changeset(attrs, attribution)
|
||||
|> repo.insert()
|
||||
end)
|
||||
|> Multi.run(:added_tag_count, fn repo, %{image: image} ->
|
||||
tag_ids = image.added_tags |> Enum.map(& &1.id)
|
||||
tags = Tag |> where([t], t.id in ^tag_ids)
|
||||
|
@ -333,29 +328,69 @@ defmodule Philomena.Images do
|
|||
|> Repo.update()
|
||||
end
|
||||
|
||||
def update_source(%Image{} = image, attribution, attrs) do
|
||||
image_changes =
|
||||
image
|
||||
|> Image.source_changeset(attrs)
|
||||
|
||||
source_changes =
|
||||
Ecto.build_assoc(image, :source_changes)
|
||||
|> SourceChange.creation_changeset(attrs, attribution)
|
||||
def update_sources(%Image{} = image, attribution, attrs) do
|
||||
old_sources = attrs["old_source_input"]
|
||||
new_sources = attrs["source_input"]
|
||||
|
||||
Multi.new()
|
||||
|> Multi.update(:image, image_changes)
|
||||
|> Multi.run(:source_change, fn repo, _changes ->
|
||||
case image_changes.changes do
|
||||
%{source_url: _new_source} ->
|
||||
repo.insert(source_changes)
|
||||
|> Multi.run(:image, fn repo, _chg ->
|
||||
image = repo.preload(image, [:sources])
|
||||
|
||||
_ ->
|
||||
{:ok, nil}
|
||||
image
|
||||
|> Image.source_changeset(%{}, old_sources, new_sources)
|
||||
|> repo.update()
|
||||
|> case do
|
||||
{:ok, image} ->
|
||||
{:ok, {image, image.added_sources, image.removed_sources}}
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end)
|
||||
|> Multi.run(:added_source_changes, fn repo, %{image: {image, added_sources, _removed}} ->
|
||||
source_changes =
|
||||
added_sources
|
||||
|> Enum.map(&source_change_attributes(attribution, image, &1, true, attribution[:user]))
|
||||
|
||||
{count, nil} = repo.insert_all(SourceChange, source_changes)
|
||||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> Multi.run(:removed_source_changes, fn repo, %{image: {image, _added, removed_sources}} ->
|
||||
source_changes =
|
||||
removed_sources
|
||||
|> Enum.map(&source_change_attributes(attribution, image, &1, false, attribution[:user]))
|
||||
|
||||
{count, nil} = repo.insert_all(SourceChange, source_changes)
|
||||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
defp source_change_attributes(attribution, image, source, added, user) do
|
||||
now = DateTime.utc_now() |> DateTime.truncate(:second)
|
||||
|
||||
user_id =
|
||||
case user do
|
||||
nil -> nil
|
||||
user -> user.id
|
||||
end
|
||||
|
||||
%{
|
||||
image_id: image.id,
|
||||
source: source,
|
||||
user_id: user_id,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
ip: attribution[:ip],
|
||||
fingerprint: attribution[:fingerprint],
|
||||
user_agent: attribution[:user_agent],
|
||||
referrer: attribution[:referrer],
|
||||
added: added
|
||||
}
|
||||
end
|
||||
|
||||
def update_locked_tags(%Image{} = image, attrs) do
|
||||
new_tags = Tags.get_or_create_tags(attrs["tag_input"])
|
||||
|
||||
|
@ -787,6 +822,7 @@ defmodule Philomena.Images do
|
|||
:hiders,
|
||||
:deleter,
|
||||
:gallery_interactions,
|
||||
:sources,
|
||||
tags: [:aliases, :aliased_tag]
|
||||
]
|
||||
end
|
||||
|
|
|
@ -119,7 +119,7 @@ defmodule Philomena.Images.ElasticsearchIndex do
|
|||
mime_type: image.image_mime_type,
|
||||
uploader: if(!!image.user and !image.anonymous, do: String.downcase(image.user.name)),
|
||||
true_uploader: if(!!image.user, do: String.downcase(image.user.name)),
|
||||
source_url: image.source_url |> to_string |> String.downcase(),
|
||||
source_url: image.sources |> Enum.map(&String.downcase(&1.source)),
|
||||
file_name: image.image_name,
|
||||
original_format: image.image_format,
|
||||
processed: image.processed,
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule Philomena.Images.Image do
|
|||
alias Philomena.ImageVotes.ImageVote
|
||||
alias Philomena.ImageFaves.ImageFave
|
||||
alias Philomena.ImageHides.ImageHide
|
||||
alias Philomena.Images.Source
|
||||
alias Philomena.Images.Subscription
|
||||
alias Philomena.Users.User
|
||||
alias Philomena.Tags.Tag
|
||||
|
@ -18,6 +19,7 @@ defmodule Philomena.Images.Image do
|
|||
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Images.TagDiffer
|
||||
alias Philomena.Images.SourceDiffer
|
||||
alias Philomena.Images.TagValidator
|
||||
alias Philomena.Images.DnpValidator
|
||||
alias Philomena.Repo
|
||||
|
@ -42,6 +44,7 @@ defmodule Philomena.Images.Image do
|
|||
many_to_many :locked_tags, Tag, join_through: "image_tag_locks", on_replace: :delete
|
||||
has_one :intensity, ImageIntensity
|
||||
has_many :galleries, through: [:gallery_interactions, :image]
|
||||
has_many :sources, Source
|
||||
|
||||
field :image, :string
|
||||
field :image_name, :string
|
||||
|
@ -91,6 +94,8 @@ defmodule Philomena.Images.Image do
|
|||
|
||||
field :removed_tags, {:array, :any}, default: [], virtual: true
|
||||
field :added_tags, {:array, :any}, default: [], virtual: true
|
||||
field :removed_sources, {:array, :any}, default: [], virtual: true
|
||||
field :added_sources, {:array, :any}, default: [], virtual: true
|
||||
|
||||
field :uploaded_image, :string, virtual: true
|
||||
field :removed_image, :string, virtual: true
|
||||
|
@ -203,11 +208,10 @@ defmodule Philomena.Images.Image do
|
|||
|> change(image: nil)
|
||||
end
|
||||
|
||||
def source_changeset(image, attrs) do
|
||||
def source_changeset(image, attrs, old_sources, new_sources) do
|
||||
image
|
||||
|> cast(attrs, [:source_url])
|
||||
|> validate_required(:source_url)
|
||||
|> validate_format(:source_url, ~r/\Ahttps?:\/\//)
|
||||
|> cast(attrs, [])
|
||||
|> SourceDiffer.diff_input(old_sources, new_sources)
|
||||
end
|
||||
|
||||
def tag_changeset(image, attrs, old_tags, new_tags, excluded_tags \\ []) do
|
||||
|
|
|
@ -4,9 +4,10 @@ defmodule Philomena.Images.Source do
|
|||
|
||||
alias Philomena.Images.Image
|
||||
|
||||
@primary_key false
|
||||
schema "image_sources" do
|
||||
belongs_to :image, Image
|
||||
field :source, :string
|
||||
belongs_to :image, Image, primary_key: true
|
||||
field :source, :string, primary_key: true
|
||||
end
|
||||
|
||||
@doc false
|
||||
|
|
50
lib/philomena/images/source_differ.ex
Normal file
50
lib/philomena/images/source_differ.ex
Normal file
|
@ -0,0 +1,50 @@
|
|||
defmodule Philomena.Images.SourceDiffer do
|
||||
import Ecto.Changeset
|
||||
alias Philomena.Images.Source
|
||||
|
||||
def diff_input(changeset, old_sources, new_sources) do
|
||||
old_set = MapSet.new(old_sources)
|
||||
new_set = MapSet.new(new_sources)
|
||||
|
||||
source_set = MapSet.new(get_field(changeset, :sources), & &1.source)
|
||||
added_sources = MapSet.difference(new_set, old_set)
|
||||
removed_sources = MapSet.difference(old_set, new_set)
|
||||
|
||||
{sources, actually_added, actually_removed} =
|
||||
apply_changes(source_set, added_sources, removed_sources)
|
||||
|
||||
image_id = fetch_field!(changeset, :id)
|
||||
|
||||
changeset
|
||||
|> put_change(:added_sources, actually_added)
|
||||
|> put_change(:removed_sources, actually_removed)
|
||||
|> put_assoc(:sources, source_structs(image_id, sources))
|
||||
end
|
||||
|
||||
defp apply_changes(source_set, added_set, removed_set) do
|
||||
desired_sources =
|
||||
source_set
|
||||
|> MapSet.difference(removed_set)
|
||||
|> MapSet.union(added_set)
|
||||
|
||||
actually_added =
|
||||
desired_sources
|
||||
|> MapSet.difference(source_set)
|
||||
|> Enum.to_list()
|
||||
|
||||
actually_removed =
|
||||
source_set
|
||||
|> MapSet.difference(desired_sources)
|
||||
|> Enum.to_list()
|
||||
|
||||
sources = Enum.to_list(desired_sources)
|
||||
actually_added = Enum.to_list(actually_added)
|
||||
actually_removed = Enum.to_list(actually_removed)
|
||||
|
||||
{sources, actually_added, actually_removed}
|
||||
end
|
||||
|
||||
defp source_structs(image_id, sources) do
|
||||
Enum.map(sources, &%Source{image_id: image_id, source: &1})
|
||||
end
|
||||
end
|
|
@ -10,10 +10,10 @@ defmodule Philomena.SourceChanges.SourceChange do
|
|||
field :fingerprint, :string
|
||||
field :user_agent, :string, default: ""
|
||||
field :referrer, :string, default: ""
|
||||
field :new_value, :string
|
||||
field :initial, :boolean, default: false
|
||||
field :value, :string
|
||||
field :added, :boolean
|
||||
|
||||
field :source_url, :string, source: :new_value
|
||||
field :source_url, :string, source: :value
|
||||
|
||||
timestamps(inserted_at: :created_at, type: :utc_datetime)
|
||||
end
|
||||
|
|
|
@ -21,19 +21,18 @@ defmodule PhilomenaWeb.Image.SourceController do
|
|||
plug :load_and_authorize_resource,
|
||||
model: Image,
|
||||
id_name: "image_id",
|
||||
preload: [:user, tags: :aliases]
|
||||
preload: [:user, :sources, tags: :aliases]
|
||||
|
||||
def update(conn, %{"image" => image_params}) do
|
||||
attributes = conn.assigns.attributes
|
||||
image = conn.assigns.image
|
||||
old_source = image.source_url
|
||||
|
||||
case Images.update_source(image, attributes, image_params) do
|
||||
{:ok, %{image: image}} ->
|
||||
case Images.update_sources(image, attributes, image_params) do
|
||||
{:ok, %{image: {image, added_sources, removed_sources}}} ->
|
||||
PhilomenaWeb.Endpoint.broadcast!(
|
||||
"firehose",
|
||||
"image:source_update",
|
||||
%{image_id: image.id, added: [image.source_url], removed: [old_source]}
|
||||
%{image_id: image.id, added: [added_sources], removed: [removed_sources]}
|
||||
)
|
||||
|
||||
PhilomenaWeb.Endpoint.broadcast!(
|
||||
|
@ -49,7 +48,7 @@ defmodule PhilomenaWeb.Image.SourceController do
|
|||
|> where(image_id: ^image.id)
|
||||
|> Repo.aggregate(:count, :id)
|
||||
|
||||
if old_source != image.source_url do
|
||||
if Enum.any?(added_sources) or Enum.any?(removed_sources) do
|
||||
UserStatistics.inc_stat(conn.assigns.current_user, :metadata_updates)
|
||||
end
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ defmodule PhilomenaWeb.ImageController do
|
|||
_ in fragment("SELECT COUNT(*) FROM source_changes s WHERE s.image_id = ?", i.id),
|
||||
on: true
|
||||
)
|
||||
|> preload([:deleter, :locked_tags, user: [awards: :badge], tags: :aliases])
|
||||
|> preload([:deleter, :locked_tags, :sources, user: [awards: :badge], tags: :aliases])
|
||||
|> select([i, t, s], {i, t.count, s.count})
|
||||
|> Repo.one()
|
||||
|> case do
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
' Source:
|
||||
|
||||
p
|
||||
= if @image.source_url not in [nil, ""] do
|
||||
a.js-source-link href=@image.source_url
|
||||
strong
|
||||
= @image.source_url
|
||||
= if Enum.any?(@image.sources) do
|
||||
= for source <- @image.sources do
|
||||
a.js-source-link href=source.source
|
||||
strong= source.source
|
||||
|
||||
- else
|
||||
em> not provided yet
|
||||
|
||||
= if @source_change_count > 1 do
|
||||
= if @source_change_count > 0 do
|
||||
a.button.button--link.button--separate-left href=Routes.image_source_change_path(@conn, :index, @image) title="Source history"
|
||||
i.fa.fa-history>
|
||||
| History (
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
thead
|
||||
tr
|
||||
th colspan=2 Image
|
||||
th New Source
|
||||
th Source
|
||||
th Action
|
||||
th Timestamp
|
||||
th User
|
||||
th Initial?
|
||||
|
||||
tbody
|
||||
= for source_change <- @source_changes do
|
||||
|
@ -21,8 +21,13 @@
|
|||
= render PhilomenaWeb.ImageView, "_image_container.html", image: source_change.image, size: :thumb_tiny, conn: @conn
|
||||
|
||||
td
|
||||
= source_change.new_value
|
||||
|
||||
= source_change.source_url
|
||||
|
||||
= if source_change.added do
|
||||
td.success Added
|
||||
- else
|
||||
td.danger Removed
|
||||
|
||||
td
|
||||
= pretty_time(source_change.created_at)
|
||||
|
||||
|
@ -41,9 +46,5 @@
|
|||
br
|
||||
' Ask them before reverting their changes.
|
||||
|
||||
td
|
||||
= if source_change.initial do
|
||||
' ✓
|
||||
|
||||
.block__header
|
||||
= @pagination
|
||||
|
|
141
priv/repo/migrations/20211009011024_rewrite_source_changes.exs
Normal file
141
priv/repo/migrations/20211009011024_rewrite_source_changes.exs
Normal file
|
@ -0,0 +1,141 @@
|
|||
defmodule Philomena.Repo.Migrations.RewriteSourceChanges do
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
rename table(:source_changes), to: table(:old_source_changes)
|
||||
|
||||
execute(
|
||||
"alter index index_source_changes_on_image_id rename to index_old_source_changes_on_image_id"
|
||||
)
|
||||
|
||||
execute(
|
||||
"alter index index_source_changes_on_user_id rename to index_old_source_changes_on_user_id"
|
||||
)
|
||||
|
||||
execute("alter index index_source_changes_on_ip rename to index_old_source_changes_on_ip")
|
||||
|
||||
execute(
|
||||
"alter table old_source_changes rename constraint source_changes_pkey to old_source_changes_pkey"
|
||||
)
|
||||
|
||||
execute("alter sequence source_changes_id_seq rename to old_source_changes_id_seq")
|
||||
|
||||
create table(:source_changes) do
|
||||
add :image_id, references(:images, on_update: :update_all, on_delete: :delete_all),
|
||||
null: false
|
||||
|
||||
add :user_id, references(:users, on_update: :update_all, on_delete: :delete_all)
|
||||
add :ip, :inet, null: false
|
||||
timestamps(inserted_at: :created_at)
|
||||
|
||||
add :added, :boolean, null: false
|
||||
add :fingerprint, :string
|
||||
add :user_agent, :string, default: ""
|
||||
add :referrer, :string, default: ""
|
||||
add :value, :string, null: false
|
||||
end
|
||||
|
||||
alter table(:image_sources) do
|
||||
remove :id
|
||||
modify :source, :string
|
||||
end
|
||||
|
||||
create index(:image_sources, [:image_id, :source],
|
||||
name: "index_image_source_on_image_id_and_source",
|
||||
unique: true
|
||||
)
|
||||
|
||||
drop constraint(:image_sources, :length_must_be_valid,
|
||||
check: "length(source) >= 8 and length(source) <= 1024"
|
||||
)
|
||||
|
||||
create constraint(:image_sources, :image_sources_source_check,
|
||||
check: "substr(source, 1, 7) = 'http://' or substr(source, 1, 8) = 'https://'"
|
||||
)
|
||||
|
||||
execute("""
|
||||
insert into image_sources (image_id, source)
|
||||
select id as image_id, substr(source_url, 1, 255) as source from images
|
||||
where source_url is not null and (substr(source_url, 1, 7) = 'http://' or substr(source_url, 1, 8) = 'https://');
|
||||
""")
|
||||
|
||||
# First insert the "added" changes...
|
||||
execute("""
|
||||
with ranked_added_source_changes as (
|
||||
select
|
||||
image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent,
|
||||
substr(referrer, 1, 255) as referrer,
|
||||
substr(new_value, 1, 255) as value, true as added,
|
||||
rank() over (partition by image_id order by created_at asc)
|
||||
from old_source_changes
|
||||
where new_value is not null
|
||||
)
|
||||
insert into source_changes
|
||||
(image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent, referrer, value, added)
|
||||
select image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent, referrer, value, added
|
||||
from ranked_added_source_changes
|
||||
where "rank" > 1;
|
||||
""")
|
||||
|
||||
# ...then the "removed" changes
|
||||
execute("""
|
||||
with ranked_removed_source_changes as (
|
||||
select
|
||||
image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent,
|
||||
substr(referrer, 1, 255) as referrer,
|
||||
substr(new_value, 1, 255) as value, false as added,
|
||||
rank() over (partition by image_id order by created_at desc)
|
||||
from old_source_changes
|
||||
where new_value is not null
|
||||
)
|
||||
insert into source_changes
|
||||
(image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent, referrer, value, added)
|
||||
select image_id, user_id, ip, created_at, updated_at, fingerprint, user_agent, referrer, value, added
|
||||
from ranked_removed_source_changes
|
||||
where "rank" > 1;
|
||||
""")
|
||||
|
||||
create index(:source_changes, [:image_id], name: "index_source_changes_on_image_id")
|
||||
create index(:source_changes, [:user_id], name: "index_source_changes_on_user_id")
|
||||
create index(:source_changes, [:ip], name: "index_source_changes_on_ip")
|
||||
end
|
||||
|
||||
def down do
|
||||
drop table(:source_changes)
|
||||
rename table(:old_source_changes), to: table(:source_changes)
|
||||
|
||||
execute(
|
||||
"alter index index_old_source_changes_on_image_id rename to index_source_changes_on_image_id"
|
||||
)
|
||||
|
||||
execute(
|
||||
"alter index index_old_source_changes_on_user_id rename to index_source_changes_on_user_id"
|
||||
)
|
||||
|
||||
execute("alter index index_old_source_changes_on_ip rename to index_source_changes_on_ip")
|
||||
|
||||
execute(
|
||||
"alter table source_changes rename constraint old_source_changes_pkey to source_changes_pkey"
|
||||
)
|
||||
|
||||
execute("alter sequence old_source_changes_id_seq rename to source_changes_id_seq")
|
||||
|
||||
execute("truncate image_sources")
|
||||
|
||||
drop constraint(:image_sources, :image_sources_source_check,
|
||||
check: "substr(source, 1, 7) = 'http://' or substr(source, 1, 8) = 'https://'"
|
||||
)
|
||||
|
||||
create constraint(:image_sources, :length_must_be_valid,
|
||||
check: "length(source) >= 8 and length(source) <= 1024"
|
||||
)
|
||||
|
||||
drop index(:image_sources, [:image_id, :source],
|
||||
name: "index_image_source_on_image_id_and_source"
|
||||
)
|
||||
|
||||
alter table(:image_sources) do
|
||||
modify :source, :text
|
||||
end
|
||||
end
|
||||
end
|
|
@ -842,32 +842,12 @@ ALTER SEQUENCE public.image_intensities_id_seq OWNED BY public.image_intensities
|
|||
--
|
||||
|
||||
CREATE TABLE public.image_sources (
|
||||
id bigint NOT NULL,
|
||||
image_id bigint NOT NULL,
|
||||
source text NOT NULL,
|
||||
CONSTRAINT length_must_be_valid CHECK (((length(source) >= 8) AND (length(source) <= 1024)))
|
||||
source character varying(255) NOT NULL,
|
||||
CONSTRAINT image_sources_source_check CHECK (((substr((source)::text, 1, 7) = 'http://'::text) OR (substr((source)::text, 1, 8) = 'https://'::text)))
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: image_sources_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.image_sources_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: image_sources_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.image_sources_id_seq OWNED BY public.image_sources.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: image_subscriptions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1136,6 +1116,44 @@ CREATE SEQUENCE public.notifications_id_seq
|
|||
ALTER SEQUENCE public.notifications_id_seq OWNED BY public.notifications.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: old_source_changes; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.old_source_changes (
|
||||
id integer NOT NULL,
|
||||
ip inet NOT NULL,
|
||||
fingerprint character varying,
|
||||
user_agent character varying DEFAULT ''::character varying,
|
||||
referrer character varying DEFAULT ''::character varying,
|
||||
new_value character varying,
|
||||
initial boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
user_id integer,
|
||||
image_id integer NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: old_source_changes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.old_source_changes_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: old_source_changes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.old_source_changes_id_seq OWNED BY public.old_source_changes.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: poll_options; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1414,17 +1432,17 @@ ALTER SEQUENCE public.site_notices_id_seq OWNED BY public.site_notices.id;
|
|||
--
|
||||
|
||||
CREATE TABLE public.source_changes (
|
||||
id integer NOT NULL,
|
||||
id bigint NOT NULL,
|
||||
image_id bigint NOT NULL,
|
||||
user_id bigint,
|
||||
ip inet NOT NULL,
|
||||
fingerprint character varying,
|
||||
user_agent character varying DEFAULT ''::character varying,
|
||||
referrer character varying DEFAULT ''::character varying,
|
||||
new_value character varying,
|
||||
initial boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL,
|
||||
updated_at timestamp without time zone NOT NULL,
|
||||
user_id integer,
|
||||
image_id integer NOT NULL
|
||||
created_at timestamp(0) without time zone NOT NULL,
|
||||
updated_at timestamp(0) without time zone NOT NULL,
|
||||
added boolean NOT NULL,
|
||||
fingerprint character varying(255),
|
||||
user_agent character varying(255) DEFAULT ''::character varying,
|
||||
referrer character varying(255) DEFAULT ''::character varying,
|
||||
value character varying(255) NOT NULL
|
||||
);
|
||||
|
||||
|
||||
|
@ -2265,13 +2283,6 @@ ALTER TABLE ONLY public.image_features ALTER COLUMN id SET DEFAULT nextval('publ
|
|||
ALTER TABLE ONLY public.image_intensities ALTER COLUMN id SET DEFAULT nextval('public.image_intensities_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: image_sources id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.image_sources ALTER COLUMN id SET DEFAULT nextval('public.image_sources_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: images id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2307,6 +2318,13 @@ ALTER TABLE ONLY public.moderation_logs ALTER COLUMN id SET DEFAULT nextval('pub
|
|||
ALTER TABLE ONLY public.notifications ALTER COLUMN id SET DEFAULT nextval('public.notifications_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: old_source_changes id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.old_source_changes ALTER COLUMN id SET DEFAULT nextval('public.old_source_changes_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: poll_options id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2627,14 +2645,6 @@ ALTER TABLE ONLY public.image_intensities
|
|||
ADD CONSTRAINT image_intensities_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: image_sources image_sources_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.image_sources
|
||||
ADD CONSTRAINT image_sources_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: images images_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2675,6 +2685,14 @@ ALTER TABLE ONLY public.notifications
|
|||
ADD CONSTRAINT notifications_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: old_source_changes old_source_changes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.old_source_changes
|
||||
ADD CONSTRAINT old_source_changes_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: poll_options poll_options_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3407,6 +3425,13 @@ CREATE INDEX index_image_hides_on_user_id ON public.image_hides USING btree (use
|
|||
CREATE UNIQUE INDEX index_image_intensities_on_image_id ON public.image_intensities USING btree (image_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_image_source_on_image_id_and_source; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_image_source_on_image_id_and_source ON public.image_sources USING btree (image_id, source);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_image_subscriptions_on_image_id_and_user_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3540,6 +3565,27 @@ CREATE INDEX index_mod_notes_on_notable_type_and_notable_id ON public.mod_notes
|
|||
CREATE UNIQUE INDEX index_notifications_on_actor_id_and_actor_type ON public.notifications USING btree (actor_id, actor_type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_old_source_changes_on_image_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_old_source_changes_on_image_id ON public.old_source_changes USING btree (image_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_old_source_changes_on_ip; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_old_source_changes_on_ip ON public.old_source_changes USING btree (ip);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_old_source_changes_on_user_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_old_source_changes_on_user_id ON public.old_source_changes USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_poll_options_on_poll_id_and_label; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -4177,10 +4223,10 @@ ALTER TABLE ONLY public.image_taggings
|
|||
|
||||
|
||||
--
|
||||
-- Name: source_changes fk_rails_10271ec4d0; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: old_source_changes fk_rails_10271ec4d0; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.source_changes
|
||||
ALTER TABLE ONLY public.old_source_changes
|
||||
ADD CONSTRAINT fk_rails_10271ec4d0 FOREIGN KEY (image_id) REFERENCES public.images(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
|
||||
|
@ -4577,10 +4623,10 @@ ALTER TABLE ONLY public.polls
|
|||
|
||||
|
||||
--
|
||||
-- Name: source_changes fk_rails_8d8cb9cb3b; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
-- Name: old_source_changes fk_rails_8d8cb9cb3b; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.source_changes
|
||||
ALTER TABLE ONLY public.old_source_changes
|
||||
ADD CONSTRAINT fk_rails_8d8cb9cb3b FOREIGN KEY (user_id) REFERENCES public.users(id) ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
|
||||
|
||||
|
@ -4950,6 +4996,19 @@ ALTER TABLE ONLY public.image_tag_locks
|
|||
|
||||
ALTER TABLE ONLY public.moderation_logs
|
||||
ADD CONSTRAINT moderation_logs_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
|
||||
-- Name: source_changes source_changes_image_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.source_changes
|
||||
ADD CONSTRAINT source_changes_image_id_fkey FOREIGN KEY (image_id) REFERENCES public.images(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: source_changes source_changes_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.source_changes
|
||||
ADD CONSTRAINT source_changes_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
|
@ -4988,6 +5047,7 @@ INSERT INTO public."schema_migrations" (version) VALUES (20210912171343);
|
|||
INSERT INTO public."schema_migrations" (version) VALUES (20210917190346);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210921025336);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210929181319);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20211009011024);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20211107130226);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20211219194836);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20220321173359);
|
||||
|
|
Loading…
Reference in a new issue