Upgrade to Pro — share decks privately, control downloads, hide ads and more …

レガシーコード改善のために取り組んでいること

Avatar for yussak yussak
November 09, 2025

 レガシーコード改善のために取り組んでいること

Hello LT world『みんなで語る!好きと学びのアウトプット LT Night』

https://findy.connpass.com/event/372581/

Avatar for yussak

yussak

November 09, 2025
Tweet

More Decks by yussak

Other Decks in Programming

Transcript

  1. DROP TYPE IF EXISTS xxx CASCADE; CREATE TYPE xxx AS

    ( xxx BIGINT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx BOOLEAN ,xxx BOOLEAN ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ... 一部 ※ 一般化しています 10
  2. IF xxx = TRUE THEN xxx := true; ELSIF xxx

    = FALSE THEN xxx := false; ELSE xxx := NULL; END IF; IF xxx IS NOT NULL THEN SELECT array_agg(xxx) FROM xxx where xxx = ( SELECT xxx FROM xxx WHERE xxx = xxx ) INTO xxx ; ELSIF xxx IS NOT NULL THEN ... ; END IF; xxx := $$ FROM xxx AS xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx 一部 ※ 一般化しています 11
  3. ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx $$ || CASE WHEN

    xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || $$ ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,( SELECT count(*) FROM xxx AS xxx WHERE xxx.xxx = xxx.xxx ) AS xxx 一部 ※ 一般化しています 12
  4. DROP TYPE IF EXISTS xxx CASCADE; CREATE TYPE xxx AS

    ( xxx BIGINT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx BOOLEAN ,xxx BOOLEAN ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx TEXT ,xxx BOOLEAN ,xxx BIGINT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx INT ,xxx INT ,xxx INT ,xxx INT ,xxx BOOLEAN ,xxx INT ,xxx INT ,xxx INT ,xxx INT ,xxx BOOLEAN ,xxx TEXT ,xxx BOOLEAN ,xxx TEXT ,xxx BOOLEAN ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx TEXT ,xxx TEXT ,xxx BOOLEAN ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx TEXT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx BIGINT ,xxx BOOLEAN ,xxx BOOLEAN ,xxx BOOLEAN ,xxx BOOLEAN ,xxx TIMESTAMPTZ ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx TEXT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx TEXT[] ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx BIGINT ,xxx TEXT ,xxx TIMESTAMPTZ ,xxx TIMESTAMPTZ ,xxx BOOLEAN ,xxx BOOLEAN ,xxx TEXT ,xxx TEXT ,xxx BOOLEAN ,xxx BOOLEAN ,xxx TEXT[] ,xxx TEXT ,xxx TEXT ); CREATE OR REPLACE FUNCTION xxx( xxx BIGINT DEFAULT NULL ,xxx BIGINT DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ,xxx BIGINT DEFAULT NULL ,xxx TIMESTAMPTZ DEFAULT NULL ,xxx TIMESTAMPTZ DEFAULT NULL ,xxx TEXT[] DEFAULT ARRAY['01'] ,xxx BOOL[] DEFAULT ARRAY[TRUE] ,xxx DATE DEFAULT NULL ,xxx DATE DEFAULT NULL ,xxx BOOLEAN DEFAULT FALSE ,xxx TEXT DEFAULT NULL ,xxx TIMESTAMPTZ DEFAULT NULL ,xxx BIGINT DEFAULT NULL ,xxx BOOLEAN DEFAULT NULL ) RETURNS SETOF xxx AS $FUNCTION$ DECLARE xxx TEXT; xxx TEXT; xxx TEXT[]; xxx TEXT; xxx TEXT; xxx TEXT[]; xxx BOOLEAN; xxx TEXT := 'a'; xxx TEXT := 'b'; xxx TEXT := 'c'; xxx TEXT := 'd'; xxx TEXT := 'e'; BEGIN IF xxx = TRUE THEN xxx := true; ELSIF xxx = FALSE THEN xxx := false; ELSE xxx := NULL; END IF; IF xxx IS NOT NULL THEN SELECT array_agg(xxx) FROM xxx where xxx = xxx INTO xxx ; ELSIF xxx IS NOT NULL THEN SELECT array_agg(xxx) FROM xxx where xxx = ( SELECT xxx FROM xxx WHERE xxx = xxx ) INTO xxx ; END IF; xxx := $$ FROM xxx AS xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx LEFT OUTER JOIN xxx AS xxx ON xxx.xxx = xxx.xxx $$ ; IF xxx IS NOT NULL THEN xxx := xxx || $$ LEFT OUTER JOIN xxx AS xxx ON ( xxx.xxx = xxx.xxx AND $6 = xxx.xxx ) $$ ; END IF; xxx := xxx || $$ WHERE ($1 IS NULL OR xxx.xxx = $1) AND ($2 IS NULL OR (xxx.xxx = $2)) AND ($3 IS NULL OR xxx.xxx =$3) AND ($4 IS NULL OR xxx.xxx = $4) AND ($5 IS NULL OR xxx.xxx >= $5) AND ($7 IS NULL OR date_trunc('day', xxx.xxx) = date_trunc('day', $7)) AND ($8 IS NULL OR $8 = FALSE OR xxx.xxx < xxx.xxx OR xxx.xxx < xxx.xxx) AND ($9 IS NULL OR $9 = FALSE OR xxx.xxx < xxx.xxx) AND ($10 IS NULL OR $10 = FALSE OR xxx.xxx < xxx.xxx) AND ($12 IS NULL OR date_trunc('day', xxx.xxx) >= date_trunc('day', $12)) AND ($13 IS NULL OR date_trunc('day', xxx.xxx) <= date_trunc('day', $13)) AND ($18 IS NULL OR xxx.xxx = $18) AND ($19 IS NULL OR xxx.xxx >= $19) AND ( $20 IS NULL OR ( ( xxx.xxx IS TRUE AND xxx.xxx @> $20 ) OR xxx.xxx IS FALSE ) ) AND ($21 IS NULL OR (xxx.xxx = $21)) $$ ; IF xxx IS NOT NULL AND xxx !=1 AND xxx !=2 THEN SELECT xxx ,xxx FROM xxx AS xxx WHERE xxx.xxx = xxx INTO xxx ,xxx ; IF xxx IS TRUE THEN IF xxx = xxx THEN xxx := xxx || $$ AND xxx.xxx @> ARRAY[$14] AND xxx.xxx IN ($15,$17) AND xxx.xxx IS NULL AND xxx < xxx AND ($12 IS NULL OR xxx.xxx >= date_trunc('day', $12)) AND ($13 IS NULL OR xxx.xxx < date_trunc('day', $13)) $$ ; ELSE xxx := xxx || $$ AND xxx.xxx @> ARRAY[$14] AND xxx.xxx IN ($16,$17) AND xxx.xxx IS NULL AND xxx < xxx AND ($12 IS NULL OR xxx.xxx >= date_trunc('day', $12)) AND ($13 IS NULL OR xxx.xxx < date_trunc('day', $13)) $$ ; END IF; END IF; END IF; xxx := $$ SELECT xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx $$ || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx' ELSE ',NULL::BOOLEAN' END || CASE WHEN xxx IS NOT NULL THEN ',xxx.xxx IS NOT NULL' ELSE ',NULL::BOOLEAN' END || $$ ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,( SELECT count(*) FROM xxx AS xxx WHERE xxx.xxx = xxx.xxx AND xxx.xxx = '00101' AND xxx.xxx IS NOT NULL AND xxx.xxx = TRUE ) AS xxx ,( SELECT count(*) FROM xxx AS xxx WHERE xxx.xxx = xxx.xxx AND xxx.xxx = '00102' AND xxx.xxx IS NOT NULL AND xxx.xxx = TRUE ) AS xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx ,xxx.xxx $$ || xxx || dyn_order_by( '{01,02,03}' ,'{xxx.xxx,xxx.xxx,xxx.xxx}' ,xxx ,xxx ,0 ,xxx ) ; RETURN QUERY EXECUTE xxx USING xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ,xxx ; END; $FUNCTION$ LANGUAGE plpgsql; 全体像 ※ 一般化しています 13
  5. class X < Y def all(params={}) query = search_query(params) query.all

    end def first(params={}) query = search_query(params) query.first end def count(params={}) query = search_query(params) query.count end private def search_query(params) ... 改善後 15
  6. 仕様化テストの追加(既存実装に対して実施) 現状の動作を正として記録するテストコードを書く 例: 不正値のテストの時に、 「フィールド A だと Invalid Parameter となるが

    B だと成功する」のような違いをそのまま記録 新規実装は TDD で対応 Controller → model →DB まで一気にカバー Fat Controller の改善などの設計改善などもしやすくなる お手本となるテストケースを作る 他メンバーや AI がそれを参考にできる状態にする テストコードの追加・修正 20