Hello again > -----Original Message----- > From: pgsql-general-owner@xxxxxxxxxxxxxx [mailto:pgsql-general-owner@xxxxxxxxxxxxxx] On Behalf Of Charles > Clavadetscher > Sent: Dienstag, 17. Mai 2016 14:50 > To: pgsql-general@xxxxxxxxxxxxxx > Subject: Re: Ascii Elephant for text based protocols - Final function proposal > > Hello all > > > -----Original Message----- > > From: pgsql-general-owner@xxxxxxxxxxxxxx > > [mailto:pgsql-general-owner@xxxxxxxxxxxxxx] On Behalf Of Karsten > > Hilbert > > Sent: Dienstag, 17. Mai 2016 09:23 > > To: pgsql-general@xxxxxxxxxxxxxx > > Subject: Re: Ascii Elephant for text based protocols - Final > > > > On Tue, May 17, 2016 at 06:58:14AM +0200, Charles Clavadetscher wrote: > > > > > A question to the naming. I find pg_logo() also a good name, but is > > > the prefix pg_* not reserved for system functions? Of course I could > > > use the name I want, but was wondering if there is a policy or a > > > best practice in this area. > > > > pg_logo would only be suitable if it got blessing from "higher up". > > Well. This question will be addressed when the body of the function is complete. Now I have a proposal which is in > the attachment. In my function there was a problem with casting of values to real instead of numeric to compute the number of spaces required on the right side of a string to be centered. In some specific string lengths the rounding was not correct. Sorry. This should now be ok. In the attachment the corrected version. Bye Charles
------------------------------------------------------------------------------ -- Display the PostgreSQL logo as ASCII art with -- an optional frame and optional text. ------------------------------------------------------------------------------ CREATE OR REPLACE FUNCTION pg_logo(p_frame BOOLEAN DEFAULT false, p_text TEXT[] DEFAULT NULL, p_position TEXT DEFAULT 'bottom', p_align TEXT DEFAULT 'center', p_valign TEXT DEFAULT 'center') RETURNS SETOF TEXT AS $$ DECLARE v_pic TEXT[] := ARRAY[ ' ____ ______ ___ ', ' / )/ \/ \ ', '( / __ _\ )', ' \ (/ o) ( o) )', ' \_ (_ ) \ ) _/ ', ' \ /\_/ \)/ ', ' \/ <//| |\\> ', ' _| | ', ' \|_/ ']; v_pic_width INTEGER := coalesce((SELECT max(length(x)) FROM unnest(v_pic) x),0); v_pic_height INTEGER := array_length(v_pic,1); -- Get the longest text available or zero if none. v_max_text_width INTEGER := coalesce((SELECT max(length(x)) FROM unnest(p_text) x),0); v_text_height INTEGER := coalesce(array_length(p_text,1),0); -- Compute total width including a space if text is on the right. -- This value does not include the frame (if requested). v_tot_width INTEGER := CASE WHEN p_position = 'bottom' THEN greatest(v_max_text_width,v_pic_width) ELSE v_pic_width+v_max_text_width+1 END; v_pic_line TEXT; v_line_count INTEGER; -- Used for vertical alignment of text BEGIN IF v_text_height > 8 THEN END IF; -- Check positioning and alignments. Fall back to default if -- values are not allowed. IF lower(coalesce(p_position,'')) NOT IN ('bottom','right') THEN p_position := 'bottom'; p_position := lower(p_position); END IF; IF lower(coalesce(p_align,'')) NOT IN ('left','center','right') THEN p_align := 'center'; p_align := lower(p_align); END IF; IF lower(coalesce(p_valign,'')) NOT IN ('top','center','bottom') THEN p_valign := 'center'; p_valign := lower(p_position); END IF; -- Add top frame line. IF p_frame THEN RETURN QUERY SELECT '+-'||repeat('-',v_tot_width)||'-+'; END IF; -- Reset counter for vertical alignment of right positioned text. CASE WHEN p_valign = 'top' THEN v_line_count := -1; -- It looks better like this. WHEN p_valign = 'bottom' THEN v_line_count := v_text_height-v_pic_height; ELSE v_line_count := (v_text_height-v_pic_height)/2; IF v_line_count = 0 THEN v_line_count := -1; -- Correct for case when number END IF; -- of text lines is 8 END CASE; FOREACH v_pic_line IN ARRAY v_pic LOOP CASE WHEN p_position = 'bottom' THEN CASE WHEN p_align = 'left' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line))|| ' |' ELSE v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line)) END; WHEN p_align = 'right' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| repeat(' ',v_tot_width-length(v_pic_line))|| v_pic_line|| ' |' ELSE repeat(' ',v_tot_width-length(v_pic_line))|| v_pic_line END; ELSE RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| repeat(' ',(v_tot_width-length(v_pic_line))/2)|| v_pic_line|| repeat(' ',round((v_tot_width::NUMERIC-length(v_pic_line)::NUMERIC)/2::NUMERIC)::INTEGER)|| ' |' ELSE repeat(' ',(v_tot_width-length(v_pic_line))/2)|| v_pic_line|| repeat(' ',round((v_tot_width::NUMERIC-length(v_pic_line)::NUMERIC)/2::NUMERIC)::INTEGER) END; END CASE; ELSE -- This part only applies if there is a text that must be placed to the right of the pic. IF v_text_height > 0 THEN v_line_count := v_line_count + 1; CASE WHEN p_align = 'left' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| v_pic_line||' '|| coalesce(p_text[v_line_count],'')|| repeat(' ',v_tot_width-length(v_pic_line|| coalesce(p_text[v_line_count],''))-1)|| ' |' ELSE v_pic_line||' '|| coalesce(p_text[v_line_count],'')|| repeat(' ',v_tot_width-length(v_pic_line|| coalesce(p_text[v_line_count],''))-1) END; WHEN p_align = 'right' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line|| coalesce(p_text[v_line_count],'')))|| coalesce(p_text[v_line_count],'')|| ' |' ELSE v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line|| coalesce(p_text[v_line_count],'')))|| coalesce(p_text[v_line_count],'') END; ELSE RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| v_pic_line||' '|| repeat(' ',(v_max_text_width-(length(coalesce(p_text[v_line_count],''))))/2)|| coalesce(p_text[v_line_count],'')|| repeat(' ',round((v_max_text_width::NUMERIC-(length(coalesce(p_text[v_line_count],''))::NUMERIC))/2::NUMERIC)::INTEGER)|| ' |' ELSE v_pic_line||' '|| repeat(' ',(v_max_text_width-(length(coalesce(p_text[v_line_count],''))))/2)|| coalesce(p_text[v_line_count],'')|| repeat(' ',round((v_max_text_width::NUMERIC-(length(coalesce(p_text[v_line_count],''))::NUMERIC))/2::NUMERIC)::INTEGER) END; END CASE; END IF; END CASE; END LOOP; -- This part only applies if the there is a text that must be place below the pic. IF p_position = 'bottom' AND v_text_height > 0 THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '||repeat(' ',v_tot_width)||' |' ELSE repeat(' ',v_tot_width) END; FOREACH v_pic_line IN ARRAY p_text LOOP CASE WHEN p_align = 'left' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line))|| ' |' ELSE v_pic_line|| repeat(' ',v_tot_width-length(v_pic_line)) END; WHEN p_align = 'right' THEN RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| repeat(' ',v_tot_width-length(v_pic_line))|| v_pic_line|| ' |' ELSE repeat(' ',v_tot_width-length(v_pic_line))|| v_pic_line END; ELSE RETURN QUERY SELECT CASE WHEN p_frame THEN '| '|| repeat(' ',(v_tot_width-length(v_pic_line))/2)|| v_pic_line|| repeat(' ',round((v_tot_width::NUMERIC-length(v_pic_line)::NUMERIC)/2::NUMERIC)::INTEGER)|| ' |' ELSE repeat(' ',(v_tot_width-length(v_pic_line))/2)|| v_pic_line|| repeat(' ',round((v_tot_width::NUMERIC-length(v_pic_line)::NUMERIC)/2::NUMERIC)::INTEGER) END; END CASE; END LOOP; END IF; IF p_frame THEN RETURN QUERY SELECT '| '||repeat(' ',v_tot_width)||' |'; RETURN QUERY SELECT '+-'||repeat('-',v_tot_width)||'-+'; END IF; RETURN; END; $$ LANGUAGE plpgsql;
-- Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-general