Skip to content

Instantly share code, notes, and snippets.

@NielsLiisberg
Last active June 10, 2020 14:47
Show Gist options
  • Save NielsLiisberg/7be6395b137b3379430782dc13d1a1e6 to your computer and use it in GitHub Desktop.
Save NielsLiisberg/7be6395b137b3379430782dc13d1a1e6 to your computer and use it in GitHub Desktop.
SQL runs bash scripts or commands
-- Run a bash command or script.
-- It assumes bash is installed by YUM so
-- it will be in the default location /QOpenSys/pkgs/bin/bash
-- You can use this aproach to other shells like sh, qsh setc.
-- I use qusrsys here however I suggest that you use your own toolibrary
-- you need library QSYSINC installed:
-- https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apiref/conQSYSINC.htm
-- I doubt this method is a good idea to build huge applications,
-- however it is a cool example how far you can go with SQL:
----------------------------------------------------------------------------------------------
call qcmdexc ('addlible qsysinc');
call qcmdexc ('crtsrcpf FILE(QTEMP/C) MBR(C)');
delete from qtemp.c;
insert into qtemp.c (srcdta) values
('{'),
('#include <QP2SHELL.h>'),
('BASH.COMMAND.DAT[BASH.COMMAND.LEN] = 0;'),
('QP2SHELL ("/QOpenSys/pkgs/bin/bash" , "-c" , BASH.COMMAND.DAT);'),
('}')
;
create or replace procedure qusrsys.bash (command varchar(32700) )
no external action
set option output=*print, commit=*none, dbgview = *source
begin
include qtemp/c(c);
end;
-- And a polymorph version to return a CLOB from STDOUT
-- (This is just a simple implementation - stay tuned)
create or replace function qusrsys.bash (
command varchar(32700),
ccsid int default 1252
)
returns clob
no external action
modifies sql data
set option output=*print, commit=*none, dbgview = *source
begin atomic
declare retval clob;
declare tmpfile varchar(256);
set tmpfile = '/tmp/x' || translate( char(now()), '--' , '.:');
call qusrsys.bash (command || '&>' || tmpfile || ';setccsid ' || ccsid || ' ' || tmpfile);
set retval = GET_CLOB_FROM_FILE(tmpfile);
call qusrsys.bash ('rm ' || tmpfile);
return retval;
end;
stop;
-- Test and usecase from here:
------------------------------
-- Test it like this
-- 1) makes nested directories from SQL:
call qusrsys.bash ('mkdir -p /a/b/c/d');
-- 2) List home directory
values (
qusrsys.bash ('ls /home')
);
-- 3) List home directory, by a script in the command. note the commands are separated by ;
values (
qusrsys.bash ('cd /home;ls')
);
--4) Get weather data using curl.
-- This works where SYSTOOLS.HTTPGETCLOB fails if you have another PASE process running
--- ( Only one PASE pr. job limitation)
values (
bash('curl -sS -k --url "https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk?cmd=llj&id=2618425&tz=Europe/Copenhagen"', 1208)
);
--4) Now combined and used as relational data with json_table
select jt.*
from
json_table (
bash('curl -sS -k --url "https://www.dmi.dk/NinJo2DmiDk/ninjo2dmidk?cmd=llj&id=2618425&tz=Europe/Copenhagen"',1208),
'$.timeserie'
columns (
sampletime char(14) path '$.time',
precipType varchar(16) path '$.precipType',
temerature double path '$.temp',
windspeed double path '$.windSpeed',
winddegree double path '$.windDegree',
humidity double path '$.humidity',
pressure double path '$.pressure',
visibility double path '$.visibility'
)
) as jt;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment