-- ============================================================ -- CS2 Skin Tracker — find_listings() -- Run against the skintracker database as the app role (owner) -- to (re)create the function. Safe to re-run (CREATE OR REPLACE). -- -- Purpose: look up active listings for a specific skin by weapon -- name + finish name, with an optional wear filter. -- -- Examples: -- SELECT * FROM skintracker.find_listings('AK-47', 'Blue Laminate'); -- SELECT * FROM skintracker.find_listings('m4a1-s', 'Player Two', 'ft'); -- SELECT cs_float_listing_id, price, wear_name, float_value, is_stat_trak -- FROM skintracker.find_listings('M4A4', 'Howl', 'mw'); -- ============================================================ SET search_path = skintracker; CREATE OR REPLACE FUNCTION skintracker.find_listings( p_weapon text, -- e.g. 'AK-47', 'M4A4', 'M4A1-S' (case-insensitive) p_skin text, -- e.g. 'Blue Laminate', 'Electric Blue' (case-insensitive) p_wear text DEFAULT NULL -- optional: fn | mw | ft | ww | bs (case-insensitive) ) RETURNS SETOF skintracker.listings LANGUAGE plpgsql STABLE AS $$ DECLARE v_wear_name text; BEGIN -- Map the optional wear abbreviation to the full wear name CSFloat reports. -- NULL / blank means "any wear". An unrecognised value is an error rather than -- a silent empty result. IF p_wear IS NOT NULL AND btrim(p_wear) <> '' THEN v_wear_name := CASE lower(btrim(p_wear)) WHEN 'fn' THEN 'Factory New' WHEN 'mw' THEN 'Minimal Wear' WHEN 'ft' THEN 'Field-Tested' WHEN 'ww' THEN 'Well-Worn' WHEN 'bs' THEN 'Battle-Scarred' ELSE NULL END; IF v_wear_name IS NULL THEN RAISE EXCEPTION 'Unknown wear abbreviation: "%". Use one of: fn, mw, ft, ww, bs.', p_wear; END IF; END IF; RETURN QUERY SELECT l.* FROM skintracker.listings l JOIN skintracker.skins s ON s.id = l.skin_id JOIN skintracker.weapons w ON w.id = s.weapon_id WHERE l.status = 'Active' AND lower(w.name) = lower(btrim(p_weapon)) AND lower(s.name) = lower(btrim(p_skin)) AND (v_wear_name IS NULL OR l.wear_name = v_wear_name) ORDER BY l.price ASC, l.float_value ASC; END; $$; -- If you use the optional read-only reporting role (see 02_readonly_role.sql), -- let it call the function: -- GRANT EXECUTE ON FUNCTION skintracker.find_listings(text, text, text) TO skintracker_readonly;