Wednesday, August 19, 2020

Turbo Vision for terminals

I like terminal applications. When it is written in C language, then it is pretty fast, and it is different work. When I started my life with computers MS DOS terminals was stupid, computers was slow, but lot of MS DOS application had good look and comfort user interface. Unfortunately - lot of current terminal applications are ugly without comfortable user interface. I had nothing to special using vim or emacs or other Unix editors, but these editors are pretty unfriendly to occasional or new users. There are only few well look (and easy used) terminal applications - for me most important is mc and mcedit. 

When I worked on pspg I understood maybe why it is. There was not good libraries or frameworks for building these applications. NCurses is too level library. I had to write my own library for implementing menu - ncurses-st-menu.

There was more experiments about porting famous Turbo Vision framework to Linux environment with different success. One of these port is base for fp (Free Pascal IDE) editor. It looks well, but there is one significant limit. It doesn't support UTF8. 

 

There is another port of Turbo Vision to Linux https://github.com/magiblot/tvision with very interesting features. First - it still support DOS and Windows 10 builds. Second - it supports UTF8. It is pretty great project, and I hope so there will be more good look terminal applications based on this terminal. 

Some screenshots.

 

Thursday, August 13, 2020

New release of plpgsql_check - now with possibility to enable, disable checks, warnings, tracing inside functions

ADA language (ancestor of PL/SQL and PL/pgSQL languages) has PRAGMA clause for entering some compiler directives. Unfortunately PL/pgSQL has not this possibility, and it is very low possibility to have a PRAGMA in future. It is not a fundamental feature, but sometimes compiler directives can be practical.

When I use plpgsql_check, I usually find a parts of code with false alarms. The static analyse used by plpgsql_check cannot to work with dynamic SQL, it cannot to work with local temp tables, etc. Can be nice to have a possibility to disable check for these parts.

Now it is possible. I wrote special function plpgsql_check_pragma, that is identified by plpgsql_check, and plpgsql_check can read own directives from an arguments of this function. A implementation of pragma in plpgsql_check has static block or statement scope:

postgres=# create or replace function test_pragma()
 returns void
 language plpgsql
as $$
declare r record;
begin
  if false then
    -- check is disabled just for if body
    perform plpgsql_check_pragma('disable:check');
    raise notice '%', r.y;
  end if;
  select 10 as a, 20 as b into r;
  raise notice '%', r.a;
  raise notice '%', r.x;
end;
$$;
CREATE FUNCTION
postgres=# select * from plpgsql_check_function('test_pragma');
┌──────────────────────────────────────────────────┐
│              plpgsql_check_function              │
╞══════════════════════════════════════════════════╡
│ error:42703:11:RAISE:record "r" has no field "x" │
│ Context: SQL statement "SELECT r.x"              │
└──────────────────────────────────────────────────┘
(2 rows)

On systems without plpgsql_check you can write own empty implementation of plpgsql_check_pragma function (because probably you don't want to change already checked source code):

create or replace function plpgsql_check_pragma(variadic text[])
returns int as $$
  select 1
$$ language sql immutable;

This functionality is available from 1.13.0 release

Tuesday, August 11, 2020

Gnome-terminal with sixel support

I like terminal applications - usually TUI applications are fast and clean, and well readable.  This interface is too simply, and then developers has to much more think about UI, and has not too much possibilities. On second hand sometimes the output of terminal applications are too limited. We run our terminal from GUI (usually), and then some graphic possibilities can be practical - graphs are better in pixel graphics than ascii art.

There is solution - from terminal's dark age there is a SIXEL protocol. Unfortunately only few terminals supports this protocol. But there is great hope - Gnome terminal in develop version supports this protocol now. I can call gnuplot from psql and I can have well looked graphs in psql too.

For more comfort work I define a psql macro (variable):

\set gnuplot '\\g (format=csv) |gnuplot -p -e "set datafile separator \',\'; set key autotitle columnhead; set terminal sixelgd enhanced font \'verdana,9\';" -e'

and a statement

SELECT i, sin(i) FROM generate_series(0, 6.3, 0.05) g(i) :gnuplot "plot '-'with lines ls 3"

generates this image:




Wednesday, August 5, 2020

plpgsql_check now supports tracing

The extension plpgsql_check can be used like linter, validator for PLpgSQL language. It can be used like profiler with possibility to calculate some basic coverage metrics. And now it can be used for code tracing. In this mode, plpgsql_check raises notice when function or statent is starting or is fininshing: Example of output in default verbosity level:
postgres=# do $$ begin perform fx(10,null, 'now', e'stěhule'); end; $$;
NOTICE:  #0   ->> start of block inline_code_block (oid=0)
NOTICE:  #2     ->> start of function fx(integer,integer,date,text) (oid=16405)
NOTICE:  #2          call by inline_code_block line 1 at PERFORM
NOTICE:  #2         "a" => '10', "b" => null, "c" => '2020-08-05', "d" => 'stěhule'
NOTICE:  #4       ->> start of function fx(integer) (oid=16404)
NOTICE:  #4            call by fx(integer,integer,date,text) line 1 at PERFORM
NOTICE:  #4           "a" => '10'
NOTICE:  #4       <<- end of function fx (elapsed time=0.336 ms)
NOTICE:  #2     <<- end of function fx (elapsed time=0.631 ms)
NOTICE:  #0   <<- end of block (elapsed time=0.978 ms)
DO
Example of output in verbose verbosity level:
postgres=# set plpgsql_check.tracer_verbosity TO verbose;
SET
postgres=# do $$ begin perform fx(10,null, 'now', e'stěhule'); end; $$;
NOTICE:  #0            ->> start of block inline_code_block (oid=0)
NOTICE:  #0.1       1  --> start of PERFORM (expr='fx(10,null, 'now', e'stěhule' ..')
NOTICE:  #2              ->> start of function fx(integer,integer,date,text) (oid=16405)
NOTICE:  #2                   call by inline_code_block line 1 at PERFORM
NOTICE:  #2                  "a" =>; '10', "b" => null, "c" => '2020-08-05', "d" => 'stěhule'
NOTICE:  #2.1       1    --> start of PERFORM (expr='fx(a)')
NOTICE:  #2.1                "a" => '10'
NOTICE:  #4                ->> start of function fx(integer) (oid=16404)
NOTICE:  #4                     call by fx(integer,integer,date,text) line 1 at PERFORM
NOTICE:  #4                    "a" => '10'
NOTICE:  #4.3       6      --> start of IF (cond='a > 10')
NOTICE:  #4.3                  "a" => '10'
NOTICE:  #4.3       8          ELSEIF (expr='a < 0')
NOTICE:  #4.3                  "a" => '10'
NOTICE:  #4.3              <-- end of IF (elapsed time=0.056 ms)
NOTICE:  #4.4      12      --> start of assignment (expr='100 + a + b')
NOTICE:  #4.4                  "a" => '10', "b" => '20'
NOTICE:  #4.4              <-- end of assignment (elapsed time=0.024 ms)
NOTICE:  #4.4                  "res" => '130'
NOTICE:  #4.5      13      --> start of RETURN
NOTICE:  #4.5                  "res" => '130'
NOTICE:  #4.5              <-- end of RETURN (elapsed time=0.045 ms)
NOTICE:  #4                <<- end of function fx (elapsed time=0.248 ms)
NOTICE:  #2.1            <-- end of PERFORM (elapsed time=0.354 ms)
NOTICE:  #2              <<- end of function fx (elapsed time=0.441 ms)
NOTICE:  #0.1          <-- end of PERFORM (elapsed time=0.710 ms)
NOTICE:  #0            <<- end of block (elapsed time=0.777 ms)