| Option | Description |
| -d | It is now possible to pass "" in order to avoid opening of the database which was used to compile the define section (DATABASE "dbname" before MAIN section). |
| Option | Description |
| -l | Outputs the tags which differ from the length of database columns. |
| -p | Prevents saving of duplicate string constants/literals in compiled files, which reduces the size of compiled CTL programs. |
| -s | Suppresses the creation of a ctl_name.err file and outputs these to stdout. |
| Option | Description |
| -lf | Allows to pass the list of modules (to be linked to a program) in a file. |
Example:
ctlink ... -lf filename ...
If a module was compile with "-g" option (with debug information) the module name and the line in which the error occured will be displayed during execution.
TEASY now returns data in lines when the output is sent to a file. This means that every output line equals a line in the file, whereby the line length of 80 characters might be exceeded.
The following additional command arguments can be passed to TDOCU:
The maximum number of variables for a mailing was increased from 100 to 200. Additionally it is now possible to continue a line in the following (up to 512 characters) if the line was ending in "\".
The programming environment was improved and a new option "Application...Modify Dictionary" was added. With this option it is possible to modify programming catalogues (the path to the modules) for Forms, Reports etc. (Attention: Backslash ‘\’ in MS-DOS/Windows must be entered as ‘\\’ in the relevant field i.e. "c:\\mbdemo").
The user interface of the Interactive SQL was modified in order to be able to modify scripts, direct the output to the screen, printer or a file.
The definition of a CHAR variable within the VARIABLES section of FORM/FRAME now allows to declare subindexes regarding the field length. This permits to define more than ‘a-z’ fields with the length of 1 (one) character.
Example:
screen
{
[a1]
}
...
variables
...
...
a1 = column char(1)
...
| Attributes | Description |
| LOOKUP | This attribute may be used also in FRAMES. |
| SCROLL | This attribute can be used in FORMs and FRAMEs for CHAR variables. The purpose is that horizontal scrolling of variables can be performed if the field is longer than the tag reserved in the SCREEN section. Example: |
screen
{
[a ]
}
end screen
variables
a = description char(30) scroll
...
The following clause was added to the CONTROL section of a FORM:
AFTER/BEFORE LINE OF table
The statements of these blocks will be executed before resp. after the selection of the current line.
Also it is now possible to use BEFORE CANCEL in the EDITING section, which helps to catch/prevent an abort. Together with NEXT FIELD editing can be continued even after pressing the cancel key.
The use of AFTER CANCEL in the EDITING section rep. BEFORE CANCEL in the CONTROL section will produce a compile error.
SQL attributes (FORMAT, LABEL, etc.) can now be used in temporary tables.
[STREAM]. INPUT-OUTPUT streams now allow the communication with a program running in an other machine. This machine has to use operating system UNIX. The syntax to open a STREAM in such a way is the following:
START INPUT-OUTPUT STREAM name_stream
THROUGH "@name_server:service"
Where:
«name_server» must exist within the file «host» of the client (MS-DOS, Windows or UNIX).
«service» must be available in the file «services» on both machines (client and server).
Also «service» must have a command assigned which will be executed when the stream is opened. This command must be defined in the file «inetd.conf» of the server. The syntax of the line to be added to this file has to look like this:
service STREAM TCP nowait root $TRANSDIR/BIN/CTL CTL
-ef configuration_file program
$TRANSDIR must be replaced by the directory in which MultiBase was installed. The execution and init parameters/environment variables of «program» can be indicated in the «configuration_ file».
Example 1: Program running on the «Client»:
database stock
define
parameter[1] server char(9)
parameter[2] host char(18)
parameter[3] service char(18)
variable v_read char(20)
variable frase1 char(500)
variable frase2 char(500)
variable err integer
stream serv
frame state
screen
{
%
State code ...:
[a1]
*
State name ....:
[a2 ]
}
end screen
variables
a1 = scode char(2)
a2 = sname char(20)
end variables
layout
label "S t a t e s"
box
end layout
end frame
form
screen
{
Client code .....: [f1 ]
Company .........: [f2 ]
Last name .......: [f3 ]
First name ......: [f4 ]
Adress 1 ........: [f5 ]
Adress 2 ........: [f6 ]
City ............: [f7 ]
State ...........: [f8] [u1 ]
Zip code ........: [f9 ]
Phone ...........: [f10 ]
Payment form ....: [a ]
Total invoiced ..: [f12 ]
}
end screen
tables
customers
end tables
variables
f1 = customers.customer required
f2 = customers.company
f3 = customers.surname
f4 = customers.fname
f5 = customers.adress1
f6 = customers.adress2
f7 = customers.city
f8 = customers.state
u1 = vartable.state_name char
f9 = customers.zip_code
f10 = customers.phone
a = customers.payform
f12 = customers.invoiced
end variables
menu mb ‘Clientes’
option a1 'Query' comments 'Perform a query-by-form.'
query
option a2 'Update' comments 'Updates one row.'
if numrecs > 0 then
modify
else begin
call disp_msg
('There are no rows in the current list.')
next option a1
end
option a3 'Delete' comments 'Delete the current row.'
if numrecs > 0 then
if yes ('Confirm delete',"n")
= true then
remove
else
next option a1
else begin
call disp_msg
('There are no rows in the current list.')
next option a1
end
option a4 'Add' comments 'Add a new row.'
add one
end menu
editing
after state
let frase1 = "select sname from states where state
= " && state left
let state_name = call_server (frase1, "L")
if state_name is null or state_name = "" then
begin
if yes("Non-existing state. Add it
now", "y") = true
then begin
let state.scode = state
let state.sname = NULL
input frame state for update
at 5,5 end input
let frase2 =
"insert into
states (state, sname) " &&
"values (" && state.scode && ", ‘" &&
state.sname && "’)"
clear frame state
let err = call_server(frase2, "I")
let state_name = call_server
(frase1, "L")
end
else begin
let state = null
next field "state"
end
end
end editing
layout
box
label "Maintenance of Customers"
end layout
end form
end define
global
control
on ending
call close_serv()
end control
end global
main begin
call open_serv()
menu form
end main
function call_server(stmt, oper)
begin
put stream serv oper, skip, flush
put stream serv stmt clipped, skip, flush
let v_read = NULL
prompt stream serv for v_read as line
end prompt
return v_read
end function
function open_serv()
begin
start input-output stream serv through "@" & host & ":" & service
clipped
put stream serv server clipped, skip, flush
end function
function close_serv()
begin
stop input-output stream serv
end function
Example 2: Program running on the «Server»:
define
variable server char(9)
variable directory char(60)
variable operation char(1)
variable frase char(500)
variable description char(20)
end define
main begin
prompt for server as line end prompt
call putenv("CTSQL", getenv("TRANSDIR") & "/lib/" & server)
database stock
forever begin
let operation = NULL
let frase = NULL
prompt for operation as line end prompt
if eof of standard = true then
break
prompt for frase as line end prompt
if frase is null then begin
put stream standard skip, flush
continue
end
prepare instr from frase clipped
switch operation
case "L"
declare cursor c_read for instr
let description = ""
open c_read
fetch c_read into description
close c_read
put stream standard description clipped,
skip, flush
case "I"
execute instr
put stream standard errno, skip, flush
end
end
end main
The above program is used to ask for a state in the server database which is then assigned to a customer table on the client.
If the state code is not found, a FRAME running on the client will be used to enter the data and the server database will then be updated. As two databases are concerned the local database can be CTSQL, while the server may work with Oracle, Informix or CTSQL.
Local variables within functions can be defined with LIKE as shown in the below example.
Example:
function namefunc()
vname like customers.company
begin
...
...
end
This statement allows to remove aktive elements from the display list which come after the identifier. This may effect screen elements (LINE, BOX) as well as defined OBJECTS (MENU, FRAME, FORM). All elements except identifier will be cleared.
Example:
display frame box at 5,5 with 10,70
for i = 1 to 60
display down line at 6,i with 8
view
...
clear from frame box at 5,5
The SQL cursor statements OPEN, EXECUTE, FETCH and FOREACH can be used with FRAMES with the clauses INTO and USING:
OPEN cur USING frame.*
EXECUTE cur USING frame.*
FETCH cur INTO frame.*
FOREACH cur INTO frame.* USING frame.*
This option influences all DISPLAY statements with exception of those for FORM/FRAME objects. The relevant elements are not put into the display list, which means that CTL does not maintain the concerned elements. You have to notice that these elements can't be cleared with the CLEAR statement but issue the associated error message. The only way to clear the elements is by overwriting them with blanks (spaces) or by using the CLEAR statement without any arguments.
Example:
for i = 1 to 1000
begin
display i using "&&&" at 10,10
no list
view
end
The clause LABEL was added. The window title is given in expr.
This option is used to automatically exit a menu after an option was selected and the instructions belonging to said option were executed.
Example:
menu ej_nw "EXAMPLE" no
wait
option "Add"
add
...
option "Delete"
remove
...
end menu
The statement MKDIR can be executed directly without RUN.
Example:
MKDIR "stock"
The statement used in FORMs now allows to optionally use expression. In case expression was not given the next field is taken from the VARIABLES section (the next field to follow). This is equivalent to setting the value "next" for expression.
Example:
editing
before column
next field
....
The FLUSH clause was introduced to immediateley FLUSH pending characters in a STREAM which was not opened as UNBUFFERED. The syntax is:
put [STREAM {stream_id | STANDARD}] [put_list,] [FLUSH]
The FLUSH clause can be combined with any expression.
Example:
put stream A var1, var2, flush
put stream A flush
The option «WITH LOG IN ""» was added to deactivate transaction handling for a database. The SQL will interpret the empty log file as your intension to drop transaction handling (the ‘syslog’ entry in ‘systables’ will be removed).
The following explaination is valid for all WINDOW instructions except those containing the clause BY COLUMNS.
New clauses:
CLIPPED: With this attribute all columns are displayed in one line even when the total length of of all fields exceeds the width of the WINDOW. Only the fields fitting into the window will be displayed, the rest will be truncated.
SCROLL: Equal to the above with the difference that horizontal scrolling is performed when data doesn't fit in one line of the windows' width.
These clauses are added to the the syntax of the WINDOW instruction as follows:
WINDOW [SCROLL | CLIPPED] FROM...
Clauses modified:
xx COLUMNS: Indicates the width of the window when used with CLIPPED or SCROLL.
SET: When SCROLL or CLIPPED are specified and the column which updates the variable is not displayed in the window the first visible is shown in "reverse" to indicate the current line. This clause, when combined with CLIPPED, allows to "set" fields not presented to the user. With this version SET can also be used with local variables.
STEP: In a WINDOW FROM file AS FILE with SCROLL this clause gives the number of characters were scrolling is performed. By default scrolling is initiated in the middle of the window depending from its width.
From Version 2.0 Release 05 on «WINDOW SCROLL» allows to fix columns as in traditional spreadsheets. This is done with the actions «fins-char» and «fdel-char» (in Windows you can do this with the mouse).