Mum PSP SQL
Mum PSP SQL
with
PostgreSQL
by
Kevin C. Ó Kane
1
Copyright © 2009 by Kevin C. Ó Kane. All rights reserved.
[email protected]
[email protected]
http://www.omahadave.com
Revision: 2.01
November 29, 2009
2
Table of Contents
1 PostgreSQL Access.............................................4
1.1 Configuring Mumps to work with PostgreSQL ........................4
1.2 Basic Mumps SQL commands: ..............................................9
1.2.1 Connect to server.......................................................................9
1.2.2 Disconnect from server..............................................................9
1.2.3 Format/prepare global array table............................................10
1.2.4 Execute SQL command.............................................................10
1.2.5 Execute SQL command with file results....................................10
1.2.6 Re-direct Mumps global array table..........................................11
1.2.7 SQL related builtin functions....................................................11
1.2.8 Examples .................................................................................12
1.2.8.1 Database definition............................................................12
1.2.8.2 Accessing a relational database from Mumps: ...................12
1.2.8.3 With a web server .............................................................13
1.2.8.4 Using PostgreSQL to store the global arrays ......................15
1.2.8.5 More examples ..................................................................16
1.2.8.6 Timing comparisons. .........................................................19
1.2.8.7 SQL Commands generated by Mumps statements ............20
Index of Figures
Figure 1 PostgreSQL configuration.........5 Figure 9 - Browser display....................16
Figure 2 PostgreSQL connections...........9 Figure 10 - name.mps...........................17
Figure 3 - Accessing the RDBMS...........11 Figure 11 - rsltprint.mps.......................18
Figure 4 - Data base definition.............12 Figure 12 - labrpt.mps..........................19
Figure 5 - SQL from Mumps..................13 Figure 13 - Initial screen HTML ............19
Figure 6 - Web server SQL access........15 Figure 14 - Native vs. PostgreSQL........20
Figure 7 - Browser display....................15 Figure 15 - Mumps to SQL....................23
Figure 8 - Accessing RDBMS.................16
3
1 PostgreSQL Access
In order for PostgreSQL access to be enabled several things must
be done on both you host machine (the one running PostgreSQL)
and your client machine (the one running your Mumps program).
These include establishing user accounts on PostgreSQL and
configuring it to accept queries from the user id of the person
running the Mumps program.
You may also need to set encryption, access rights and establish
the IP number of the client as an authorized site. These are
detailed in the PostgreSQL manuals and only touched upon here.
The discussion here is sufficient to create a demonstration.
Refinements are left to the user. The PostgreSQL web site is:
http://www.postgresql.org/
Additionally, you must install the PostgreSQL server
development libraries on the machine which will run the client
Mumps programs even if this is not the machine running the
PostgreSQL server. Also, when you configure Mumps, you must
specify that PostgreSQL will be used for database activities.
4
server may contain other Mumps global arrays. These are
completely separate from one another.
When using a PostgreSQL server, it is possible to construct views
of non-Mumps RDBMS tables which can be directly accessed by
Mumps as though they were global arrays. An example of this is
given below.
When accessing data in global arrays on a PostgreSQL server,
Mumps does so by generating SQL commands that are sent to and
processed by the PostgreSQL server. Normally, PostgreSQL will
checkpoint each of transaction which modifies the database unless
you specify otherwise.
However, to improve performance, it may be desirable to initiate
this set of transactions with the SQL BEGIN command before
global array assignments ultimately followed by a SQL COMMIT
command when the assignments are done. This will permit the
Mumps global array inserts/updates to run faster. However, should
there be a server or client failure before the COMMIT, the data will
be lost and need to be re-assigned. An example is given below.
The BEGIN/COMMIT mechanism can also be used to rollback failed
transactions.
In order to use PostgreSQL for the global array backend server,
use the following configuration and make commands for Ubuntu
(you must be root when doing these):
configure prefix=/usr --with-pgdb=/usr/include/postgresql
make
make install
--with-cpu64
to reflect the correct location (insert the correct location for your
system in the above). For example, in Cygwin this would be:
--with-pgdb=/usr/include
ls /var/run/postgresql/ a
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
Where the high order 16 bits must match (134.161) but the
remaining 16 bits can be any value. The above enables any
machine on the UNI campus (134.161.....). See the PostgreSQL
documentation for further details.
After you have modified the configuration settings you need to
restart the server. As root, execute the following:
/etc/init.d/postgresql8.4 stop
/etc/init.d/postgresql8.4 start
sudo su postgres (system password will be requested)
createuser demo
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
createdb medical
7
Thus, you should to create the default database and initialize it at
this point. To do so, enter the following commands:
createdb mumps
mumps
sql/f
sql/c
halt
Now you can run mumps programs and all global array activity
will default to the database named mumps. When you run the
Mumps interpreter, you will not need to connect to the server and
specify a particular database. The interpreter will automatically
connect to the mumps database.
mumps
sql/d dbname=medical
sql/f
sql/c
8
1.2 Basic Mumps SQL commands:
dbname=medical
Examples:
1 sql/d dbname=medical
2 sql/d host=abc.def.xyz.edu dbname=medical
3 sql/d hostaddr=123.321.432.321 dbname=medical
4 sql/d user=joe password=abc123 dbname=medical host=abc.def.com
5 set x="dbname=medical"
6 sql/d &~x~
Figure 2 PostgreSQL connections
9
Disconnect from the database. No parameters, no other
commands on the line. No further commands may be sent to the
database server until a new connection is established.
sql/f
Note: this only clears the mumps table in the current database
(dbname=...). The contents of mumps tables in other databases
are unchanged.
sql string
sql/o=fileName string
For example:
1 #!/usr/bin/mumps
2 sql/d host=192.168.2.4 dbname=medical
3 write "msg=",$zsql,! // any message from the SQL server?
4 write $zsqlOpen,! // is the connection open?
5 sql/o="www" select * from ptname;
6 write $zsql,! // messages?
7 write $zsqlCols,! // TAB separated list of column names
sql/t=table,size
11
iii. $zsqlOpen Returns true if a connection to the SQL
server is open, false otherwise.
1.2.8 Examples
create table bp (ptid text, date text, time text, sys text,
dia text, pulse text);
create table labs (ptid text, date text, time text, test text,
result text);
13
6 set x="dbname=medical"
7
8 # Open the connection.
9 # The &~exp~ causes 'exp' to be inserted into the line
10
11 sql/d &~x~
12
13 # $test will be 1 and $zsql will be 'ok' if it worked
14
15 if $test html Connection to database open <br>
16 else do
17 . html Connection to database failed </body></html>
18 . halt
19
20 # Flush/delete/create a mumps table in the database.
21
22 sql/f
23
24 if $test html Mumps tables initialized <br>
25 else html Mumps table initialization failed <br>
26
27 # prepare a query and run it. Output will go to xxx.file
28 # where 'xxx' is the process id of this program
29
30 set x="select * from ptname;"
31
32 html Sending query: &~x~ <br>
33
34 sql/o="/tmp/"_$job_".file" &~x~
35
36 set ptname=$zsqlCols // gets column names TAB separated
37
38 if $test html Query successfully processed <p>
39 else do
40 . html Query failed. Message=&~$zsql~ <br></body></html>
41 . halt
42
43 # Open the file or results and process same.
44
45 open 1:"/tmp/"_$job_".file,old"
46
47 if '$test do
48 . html Results file error<br></body></html>
49 . halt
50
51 # Each line consists of columns separated by TAB characters
52 # $char(9) is a TAB. sepearte the lines. ptname is:
53
54 html <table border><tr>
55
56 for i=1:1:6 do
57 . html <td> &~$piece(ptname,$char(9),i)~ </td>
58
59 html </tr>
60
61 for do
62 . use 1 // unit 1 to be used for I/O
63 . read line
64 . if '$test break
65 . use 5 // unit 5 now used for I/O
66 . html <tr>
67 . for i=1:1 do
68 .. set col=$piece(line,$char(9),i)
69 .. if col="" break
14
70 .. html <td> &~col~ </td>
71 . html </tr>
72
73 use 5
74 html </table>
75
76 html </body>
77 html </html>
78
79 shell/g rm &~"/tmp/"_$job_".file"~
80 halt
1 # name.mps
2
3 #!/usr/bin/mumps
4
5 html Content-type: text/html &!&!
6 html <html><body bgcolor=silver><font size=+1>
7
8 set x="dbname=medical"
9
10 # Open the connection.
11 # &~exp~ causes result of 'exp' to be inserted in line
12
13 sql/d &~x~
14
15 # $test will be 1 and $zsql will be 'ok' if it worked
16
17 if $test html Connection to database open <br>
15
18 else do
19 . html Connection to database failed </body></html>
20 . halt
21
22 # Flush/delete/create a mumps table in the database.
23
24 sql/f
25
26 if $test html Mumps tables initialized <br>
27 else html Mumps table initialization failed <br>
28
29 set cmd="create temp view names (gbl,a1,a2,a3) as select"
30 set cmd=cmd_"text 'names', ptid, namefirst, namelast from
ptname;"
31
32 sql &~cmd~
33
34 sql/t="names",3
35
36 html <hr>
37 for ptid="":$order(^names(ptid)):"" do
38 . for first="":$order(^names(ptid,first)):"" do
39 .. for last="":$order(^names(ptid,first,last)):"" do
40 ... write ptid," ",first," ",last,"<br>"
41
42 html <hr></body></html>
43 halt
16
In these examples, the HTML page, when the SUBMIT button is
clicked, invokes the labrpt.mps program. This program, in turn,
invokes name.mps which gets data from the ptname table.
name.mps invokes rsltprint.mps which formats the results table
from the results file xxx.file (where xxx is the unique process id).
rsltprint.mps returns to name.mps which returns to labrpt.mps
which then queries the labs table then calls the rsltprint.mps
program a second time. Note, the connection to the server is
established at the beginning and remains open until labrpt.mps
finishes.
1 # name.mps
2
3 #!/usr/bin/mumps
4
5 # this module assumes that the connection is open
6
7 # prepare a query and run it. Output will go to xxx.file
8 # where 'xxx' is the process id of this program
9
10 set x="select * from ptname where ptid='"_ptid_"';"
11
12 sql/o="/tmp/"_$job_".file" &~x~
13
14 set cols=$zsqlCols
15
16 if '$test do
17 . html Query failed. <br></body></html>
18 . halt
19
20 # Open the file or results and process same.
21
22 do ^rsltprint.mps
Figure 10 - name.mps
1 #!/usr/bin/mumps
2
3 # rsltprint.mps
4
5 # this module assumes that the results file exists
6
7 open 1:"/tmp/"_$job_".file,old"
8
9 if '$test do
10 . html Results file error<br></body></html>
11 . halt
12
13 # Each line consists of columns separated by TAB characters
14 # $char(9) is a TAB. separate the lines.
15
16 html <table border=1><tr>
17
18 for i=1:1 do
19 . set x=$piece(cols,$char(9),i)
20 . if x="" break
21 . html <td> &~x~ </td>
22 html </tr><hr>
23
24 for do
25 . use 1 // unit 1 to be used for I/O
17
26 . read line
27 . if '$test break
28 . use 5 // unit 5 now used for I/O
29 . html <tr>
30 . for i=1:1 do
31 .. set col=$piece(line,$char(9),i)
32 .. if col="" break
33 .. html <td> &~col~ </td>
34 . html </tr>
35
36 use 5
37 html </table>
38
39 html </body>
40 html </html>
41
42 close 1
43
44 # delete the file
45
46 shell/g rm &~"/tmp/"_$job_".file"~
47 halt
Figure 11 - rsltprint.mps
1 # labrpt.mps
2
3 #!/usr/bin/mumps
4
5 html Content-type: text/html &!&!
6 html <html><body bgcolor=silver><font size=+1><center>
7
8 set x="user=okane host=192.168.2.4 dbname=medical"
9
10 # Open the connection.
11 # The &~exp~ causes 'exp' result inserted into the line
12
13 sql/d &~x~
14
15 # $test will be 1 and $zsql will be 'ok' if it worked
16
17 if '$test do
18 . html Connection to database failed </body></html>
19 . halt
20
21 if '$data(ptid) do
22 . html Error: no value specified for Patient ID (ptid).
23 . html </body></html>
24
25 # call a mumps routine to print the name of person ptid
26
27 do ^name.mps
28
29 # prepare a query and run it. Output will go to xxx.file
30 # where 'xxx' is the process id of this program
31
32 set x="select * from labs where ptid='"_ptid_"';"
33
34 sql/o="/tmp/"_$job_".file" &~x~
35
36 set cols=$zsqlCols
37
38 if '$test do
18
39 . html Query failed. Message=&~$zsql~ <br></body></html>
40 . halt
41
42 # print results
43
44 do ^rsltprint.mps
45
46 html </center></body>
47 html </html>
48 halt
Figure 12 - labrpt.mps
1 <html>
2 <body>
3 <font size=+2>
4 Worst General Hospital Lab Reports
5 <p>
6 <hr>
7 <form method=get action="cgi-bin/labrpt.mps">
8 Enter Patient Id:
9 <input type=text name=ptid value="" size=10>
10
11 <input type=submit value="Display Labs">
12 </form>
13 </body>
14 </html>
19
Figure 14 - Native vs. PostgreSQL
20
45 write "*** expect 5 ",i,!
46 set i=^a(1,2,3,4,5,6)
47 write "*** expect 6 ",i,!
48 set i=^a(1,2,3,4,5,6,7)
49 write "*** expect 7 ",i,!
50 set i=^a(1,2,3,4,5,6,7,8)
51 write "*** expect 8 ",i,!
52 set i=^a(1,2,3,4,5,6,7,8,9)
53 write "*** expect 9 ",i,!
54 set i=^a(1,2,3,4,5,6,7,8,9,10)
55 write "*** expect 10 ",i,!
56
57 write !,"*** execute an SQL command",!!
58
59 sql commit;
60
61 write !,"*** $order() examples",!!
62
63 set i=$order(^a(1))
64 write "*** $o(^a(1)) expect 2 ",i,!
65 set i=$order(^a(1,2))
66 write "*** $o(^a(1,2)) expect 3 ",i,!
67
68 write !,"*** $data() examples",!!
69
70 set i=$data(^a)
71 write "*** $d(^a) expect 10 ",i,!!
72
73 set i=$data(^a(1))
74 write "*** $d(^a(1)) expect 11 ",i,!!
75
76 set i=$data(^a(1,2))
77 write "*** $d(^a(1,2)) expect 11 ",i,!!
78
79 set i=$data(^a(1,2,3,4,5,6,7,8,9))
80 write "*** $d(^a(1,2...9)) expect 11 ",i,!!
81
82 set i=$data(^a(1,2,3,4,5,6,7,8,9,10))
83 write "*** $d(^a(1,2,...10)) expect 1 ",i,!!
84
85 write !,"*** $query() example",!!
86
87 set x="^a"
88 for do
89 . set x=$query(x)
90 . if x="" break
91 . write "*** returned: ",x,!
92
93 write !,"*** kill example",!!
94 kill ^a(1,2)
95
96 write !,"*** dump the entire mumps table",!!
97
98 sql/o="tmp" select * from mumps;
output:
21
cmd=create table mumps (gbl text, a1 text, a2 text, a3 text, a4 text,
a5 text, a6 text, a7 text, a8 text, a9 text, a10 text, a11
text);
cmd=create index m1 on mumps (gbl, a1, a2);
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='' and
a3='' and a4='' and a5='' and a6='' and a7='' and a8='' and
a9='' and a10='' limit 1;
*** expect 1 1
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='2' and
a3='' and a4='' and a5='' and a6='' and a7='' and a8='' and
a9='' and a10='' limit 1;
*** expect 2 2
...
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='2' and
a3='3' and a4='4' and a5='5' and a6='6' and a7='7' and a8='8'
and a9='9' and a10='10' limit 1;
*** expect 10 10
cmd01=select a11 from mumps where gbl='a' and a1='' and a2='' and
a3='' and a4='' and a5='' and a6='' and a7='' and a8='' and
a9='' and a10='' limit 1;
cmd05=select a1 from mumps where gbl='a' and a1>'' order by a1 limit
1;
*** $d(^a) expect 10 10
22
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='' and
a3='' and a4='' and a5='' and a6='' and a7='' and a8='' and
a9='' and a10='' limit 1;
cmd05=select a2 from mumps where gbl='a' and a1='1' and a2>'' order
by a2 limit 1;
*** $d(^a(1)) expect 11 11
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='2' and
a3='' and a4='' and a5='' and a6='' and a7='' and a8='' and
a9='' and a10='' limit 1;
cmd05=select a3 from mumps where gbl='a' and a1='1' and a2='2' and
a3>'' order by a3 limit 1;
*** $d(^a(1,2)) expect 11 11
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='2' and
a3='3' and a4='4' and a5='5' and a6='6' and a7='7' and a8='8'
and a9='9' and a10='' limit 1;
cmd05=select a10 from mumps where gbl='a' and a1='1' and a2='2' and
a3='3' and a4='4' and a5='5' and a6='6' and a7='7' and a8='8'
and a9='9' and a10>'' order by a10 limit 1;
*** $d(^a(1,2...9)) expect 11 11
cmd01=select a11 from mumps where gbl='a' and a1='1' and a2='2' and
a3='3' and a4='4' and a5='5' and a6='6' and a7='7' and a8='8'
and a9='9' and a10='10' limit 1;
*** $d(^a(1,2,...10)) expect 1 1
23
Alphabetical Index
B-tree......................................................4 SQL BEGIN..............................................5
configure.................................................5 SQL COMMIT...........................................5
Connect to server...................................9 sql/c........................................................9
cpu64......................................................5 sql/d........................................................9
create table..........................................12 sql/f.......................................................10
Disconnect from server..........................9 sql/o......................................................10
Execute SQL command.........................10 sql/t.......................................................11
Execute SQL command with file results SUBMIT button......................................17
..............................................................10 TCP/IP......................................................5
Format/prepare global array table.......10 Ubuntu....................................................5
pg_hba.conf ...........................................6 --with-pgdb...........................................20
psql.........................................................7 $zsql..................................................10p.
Re-direct Mumps global array table.....11 $zsqlCols...............................................11
SELECT..................................................10 $zsqlOpen.............................................12
sql.........................................................10
24