-- Enable trigram extension for fuzzy search CREATE EXTENSION IF NOT EXISTS pg_trgm; -- Table 1: Adresses CTOP complètes CREATE TABLE public.addresses ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, identifiant_unique_adresse TEXT NOT NULL UNIQUE, date_diffusion_version TEXT, date_creation TEXT, date_modification TEXT, date_fin TEXT, numero_municipal TEXT, numero_municipal_suffixe TEXT, numero_unite TEXT, type_unite TEXT, code_postal TEXT, seqodo TEXT, generique_odonyme TEXT, particule_odonyme TEXT, specifique_odonyme TEXT, point_cardinal_odonyme TEXT, odonyme_recompose_normal TEXT, odonyme_recompose_court TEXT, odonyme_recompose_long TEXT, discriminant_odonyme TEXT, odonyme_officiel_ctop TEXT, adresse_formatee TEXT, qualite_positionnement_geometrique TEXT, etat TEXT, code_utilisation TEXT, categorie TEXT, nombre_unite INTEGER, numero_lot TEXT, matricule_unite_evaluation TEXT, nosqnocivq TEXT, caracteristique_adresse TEXT, code_region_administrative TEXT, nom_region_administrative TEXT, code_mrc TEXT, nom_mrc TEXT, code_municipalite TEXT, nom_municipalite TEXT, nom_municipalite_complet TEXT, code_arrondissement TEXT, nom_arrondissement TEXT, code_communaute_metropolitaine TEXT, nom_communaute_metropolitaine TEXT, identifiant_reseau_routier TEXT, cote_route TEXT, longitude DOUBLE PRECISION, latitude DOUBLE PRECISION ); -- Table 2: Disponibilité fibre CREATE TABLE public.fiber_availability ( id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, id_placemark TEXT, id_appart TEXT, uuidadresse TEXT NOT NULL, nom TEXT, civique TEXT, appartement TEXT, rue TEXT, ville TEXT, code_postal TEXT, lien_googlemap TEXT, zone_tarifaire INTEGER NOT NULL DEFAULT 1, max_speed INTEGER NOT NULL DEFAULT 0, commentaire TEXT, CONSTRAINT fk_fiber_address FOREIGN KEY (uuidadresse) REFERENCES public.addresses(identifiant_unique_adresse) ); -- Index unique sur uuidadresse pour lookup rapide CREATE INDEX idx_fiber_uuidadresse ON public.fiber_availability(uuidadresse); -- Indexes trigram pour recherche fuzzy sur adresses CREATE INDEX idx_addr_odonyme_normal_trgm ON public.addresses USING GIN (odonyme_recompose_normal gin_trgm_ops); CREATE INDEX idx_addr_odonyme_court_trgm ON public.addresses USING GIN (odonyme_recompose_court gin_trgm_ops); CREATE INDEX idx_addr_odonyme_long_trgm ON public.addresses USING GIN (odonyme_recompose_long gin_trgm_ops); CREATE INDEX idx_addr_formatee_trgm ON public.addresses USING GIN (adresse_formatee gin_trgm_ops); CREATE INDEX idx_addr_municipalite_trgm ON public.addresses USING GIN (nom_municipalite gin_trgm_ops); CREATE INDEX idx_addr_code_postal ON public.addresses(code_postal); CREATE INDEX idx_addr_numero_municipal ON public.addresses(numero_municipal); -- Fonction de recherche d'adresses avec disponibilité fibre CREATE OR REPLACE FUNCTION public.search_addresses( search_term TEXT, result_limit INTEGER DEFAULT 10 ) RETURNS TABLE ( identifiant_unique_adresse TEXT, adresse_formatee TEXT, numero_municipal TEXT, numero_unite TEXT, code_postal TEXT, odonyme_recompose_normal TEXT, nom_municipalite TEXT, longitude DOUBLE PRECISION, latitude DOUBLE PRECISION, fiber_available BOOLEAN, zone_tarifaire INTEGER, max_speed INTEGER, similarity_score REAL ) LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ BEGIN RETURN QUERY SELECT a.identifiant_unique_adresse, a.adresse_formatee, a.numero_municipal, a.numero_unite, a.code_postal, a.odonyme_recompose_normal, a.nom_municipalite, a.longitude, a.latitude, (f.id IS NOT NULL) AS fiber_available, f.zone_tarifaire, f.max_speed, GREATEST( similarity(COALESCE(a.odonyme_recompose_normal, ''), search_term), similarity(COALESCE(a.odonyme_recompose_court, ''), search_term), similarity(COALESCE(a.odonyme_recompose_long, ''), search_term), similarity(COALESCE(a.adresse_formatee, ''), search_term) ) AS similarity_score FROM public.addresses a LEFT JOIN public.fiber_availability f ON f.uuidadresse = a.identifiant_unique_adresse WHERE a.odonyme_recompose_normal % search_term OR a.odonyme_recompose_court % search_term OR a.odonyme_recompose_long % search_term OR a.adresse_formatee % search_term ORDER BY similarity_score DESC LIMIT result_limit; END; $$; -- RLS: lecture publique pour l'auto-suggest ALTER TABLE public.addresses ENABLE ROW LEVEL SECURITY; CREATE POLICY "Public read access for addresses" ON public.addresses FOR SELECT USING (true); ALTER TABLE public.fiber_availability ENABLE ROW LEVEL SECURITY; CREATE POLICY "Public read access for fiber" ON public.fiber_availability FOR SELECT USING (true);