HEX
Server: Apache/2.4.63 (Unix)
System: Linux Synopilou92 4.4.302+ #72806 SMP Mon Jul 21 23:16:00 CST 2025 x86_64
User: pilou92 (1026)
PHP: 8.0.30
Disabled: NONE
Upload Files
File: /volume1/@appstore/SynologyPhotos/etc/sql/143.sql
ALTER TABLE public.unit
  DROP CONSTRAINT IF EXISTS unit_id_item_type_uk CASCADE,
  ADD CONSTRAINT unit_id_item_type_uk UNIQUE (id, item_type);
CREATE TABLE IF NOT EXISTS public.many_unit_has_many_favorite_user(
  id_unit integer NOT NULL,
  id_user integer NOT NULL,
  id_favorite_user integer NOT NULL
);
CREATE INDEX IF NOT EXISTS id_user_id_favorite_user_idx ON public.many_unit_has_many_favorite_user (id_user, id_favorite_user);
CREATE INDEX IF NOT EXISTS id_unit_id_user_id_favorite_user_idx ON public.many_unit_has_many_favorite_user (id_unit, id_user, id_favorite_user);
ALTER TABLE public.many_unit_has_many_favorite_user
  DROP CONSTRAINT IF EXISTS favorite_pk CASCADE,
  DROP CONSTRAINT IF EXISTS unit_id_user_id_fk CASCADE,
  ADD CONSTRAINT favorite_pk PRIMARY KEY (id_unit, id_favorite_user),
  ADD CONSTRAINT unit_id_user_id_fk FOREIGN KEY (id_unit, id_user) REFERENCES public.unit (id, id_user) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE;
CREATE TABLE IF NOT EXISTS public.favorite_timeline(
  id_item integer NOT NULL,
  id_user integer NOT NULL,
  item_type integer NOT NULL,
  unit_type integer NOT NULL,
  id_unit integer NOT NULL,
  id_favorite_user integer[] NOT NULL,
  takentime bigint NOT NULL DEFAULT 0
);
CREATE INDEX IF NOT EXISTS id_user_idx ON public.favorite_timeline (id_user);
CREATE INDEX IF NOT EXISTS id_favorite_user_idx ON public.favorite_timeline USING GIN (id_favorite_user);
ALTER TABLE public.favorite_timeline
  DROP CONSTRAINT IF EXISTS favorite_timeline_pk CASCADE,
  DROP CONSTRAINT IF EXISTS unit_id_item_id_fk CASCADE,
  DROP CONSTRAINT IF EXISTS unit_id_user_id_fk CASCADE,
  DROP CONSTRAINT IF EXISTS unit_id_item_type_fk CASCADE,
  DROP CONSTRAINT IF EXISTS unit_id_takentime_fk CASCADE,
  ADD CONSTRAINT favorite_timeline_pk PRIMARY KEY (id_unit),
  ADD CONSTRAINT unit_id_item_id_fk FOREIGN KEY (id_unit, id_item) REFERENCES public.unit (id, id_item) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE,
  ADD CONSTRAINT unit_id_user_id_fk FOREIGN KEY (id_unit, id_user) REFERENCES public.unit (id, id_user) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE,
  ADD CONSTRAINT unit_id_item_type_fk FOREIGN KEY (id_unit, item_type) REFERENCES public.unit (id, item_type) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE,
  ADD CONSTRAINT unit_id_takentime_fk FOREIGN KEY (id_unit, takentime) REFERENCES public.unit (id, takentime) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE;
CREATE OR REPLACE FUNCTION public.create_user_event_history_table_by_id_user_func (id_user integer)
  RETURNS void
  LANGUAGE plpgsql
  VOLATILE
  CALLED ON NULL INPUT
  SECURITY INVOKER
  COST 1
  AS $$
DECLARE
  id_user_bucket INT;
  user_event_history_table text;
  user_event_history_table_name text;
BEGIN
  id_user_bucket := CASE WHEN id_user = 0 THEN 0 ELSE (id_user - 1) % 13 + 1 END;
  user_event_history_table = 'public.user_event_history_' || id_user_bucket;
  user_event_history_table_name = 'user_event_history_' || id_user_bucket;
  IF EXISTS (
    SELECT 1
    FROM information_schema.tables
    WHERE table_schema = 'public'
    AND table_name = user_event_history_table_name
  ) THEN
    RETURN;
  END IF;
  EXECUTE format('CREATE TABLE %s (
    version BIGINT PRIMARY KEY,
    id_user INTEGER NOT NULL,
    target_type SMALLINT NOT NULL,
    target_id INTEGER[] NOT NULL,
    target_id_user INTEGER NOT NULL,
    trigger_id_user INTEGER,
    event_type TEXT NOT NULL,
    event_detail JSON)', user_event_history_table
  );
  EXECUTE format('CREATE INDEX IF NOT EXISTS user_event_history_%s_version_id_user_idx ON %s (id_user, version);', id_user_bucket, user_event_history_table);
END
$$;
DO $$
  DECLARE
    id_user INTEGER;
    max_id_user INTEGER;
    loop_limit INTEGER;
  BEGIN
    SELECT MAX(id) INTO max_id_user FROM public.user_info;
    loop_limit := LEAST(max_id_user, 13);
    FOR id_user IN 0..loop_limit LOOP
      EXECUTE format('SELECT public.create_user_event_history_table_by_id_user_func(%s);', id_user);
    END LOOP;
END $$;
DROP TRIGGER IF EXISTS create_version_time_by_id_user_trigger ON public.user_info CASCADE;
DROP FUNCTION IF EXISTS public.create_version_time_by_id_user_trigger_func CASCADE;
CREATE OR REPLACE FUNCTION public.create_version_time_by_id_user_func (id_user integer)
  RETURNS void
  LANGUAGE plpgsql
  VOLATILE
  CALLED ON NULL INPUT
  SECURITY INVOKER
  COST 1
  AS $$
DECLARE
  new_version_time_table text;
  new_version_time_table_name text;
  trigger_name text;
  pk_name text;
  idx_name text;
  new_sequence_name text;
  id_user_bucket integer;
BEGIN
  id_user_bucket := CASE WHEN id_user = 0 THEN 0 ELSE (id_user - 1) % 13 + 1 END;
  new_version_time_table = 'public.version_time_' || id_user_bucket;
  new_version_time_table_name = 'version_time_' || id_user_bucket;
  pk_name = 'version_id_' || id_user_bucket || '_primary';
  idx_name = 'version_time_' || id_user_bucket || '_idx';
  new_sequence_name = 'public.version_time_' || id_user_bucket || '_version_seq';
  trigger_name = 'delete_expired_version_time_' || id_user_bucket || '_data_trigger';
  -- check if the sequence and table already exists
  RAISE NOTICE 'Checking if sequence % and table % exist', new_sequence_name, new_version_time_table;
  IF EXISTS (
    SELECT 1
    FROM information_schema.tables
    WHERE table_schema = 'public'
    AND table_name = new_version_time_table_name
  ) THEN
    RETURN;
  END IF;
  EXECUTE format('CREATE SEQUENCE %s START WITH 1', new_sequence_name);
  EXECUTE format('CREATE TABLE %s (version BIGINT NOT NULL DEFAULT nextval(''%s''), modified_time BIGINT NOT NULL)',
    new_version_time_table, new_sequence_name, pk_name);
  EXECUTE format('CREATE UNIQUE INDEX %s ON %s USING btree (version, modified_time ASC NULLS LAST)', idx_name, new_version_time_table);
  EXECUTE format('CREATE TRIGGER %s BEFORE INSERT ON %s FOR EACH ROW EXECUTE PROCEDURE public.delete_expired_version_time_data_func()',
    trigger_name, new_version_time_table);
END;
$$;
CREATE OR REPLACE FUNCTION public.create_version_related_table_trigger_func()
  RETURNS TRIGGER
  LANGUAGE plpgsql
  AS $$
BEGIN
  -- take care, version_time table should be created before user_event_history table
  PERFORM public.create_version_time_by_id_user_func(NEW.id);
  PERFORM public.create_user_event_history_table_by_id_user_func(NEW.id);
  RETURN NEW;
END
$$;
DROP TRIGGER IF EXISTS create_version_related_table_trigger ON public.user_info CASCADE;
CREATE TRIGGER create_version_related_table_trigger
  AFTER INSERT ON public.user_info
  FOR EACH ROW
  EXECUTE PROCEDURE public.create_version_related_table_trigger_func();