basd_52

428
UniData Developing UniBasic Applications Version 5.2 June 2000 Part No. 000-6837

Upload: cuteguy01

Post on 08-Mar-2015

115 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Basd_52

UniData

Developing UniBasicApplications

Version 5.2June 2000Part No. 000-6837

Page 2: Basd_52

ii Developing UniBa

s,

ce.

if forendorwith

Published by Informix Press Informix Corporation4100 Bohannon DriveMenlo Park, CA 94025-1032

© 2000 Informix Corporation. All rights reserved. The following are trademarks of Informix Corporation or its affiliateone or more of which may be registered in the United States or other jurisdictions:

Answers OnLineTM; ArdentTM; AxielleTM; C-ISAM; Client SDKTM; CloudconnectorTM; CloudscapeTM; CloudsyncTM;CloudviewTM; DataBlade; Data DirectorTM; Data MineTM; Data Mine BuilderTM; DataStage; Decision FastStartTM;Decision for Telecommunications Campaign ManagementTM; Decision FrontierTM; Decision Solution SuiteTM;DecisionscapeTM; DialogueTM; Dynamic Scalable ArchitectureTM; Dynamic ServerTM; Dynamic Server.2000TM;Dynamic ServerTM, Developer EditionTM; Dynamic ServerTM with Advanced Decision Support OptionTM;Dynamic ServerTM with Extended Parallel OptionTM; Dynamic ServerTM with MetaCube ROLAP Option;Dynamic ServerTM with Universal Data OptionTM; Dynamic ServerTM with Web Integration OptionTM;Dynamic ServerTM, Workgroup EditionTM; Dynamic Virtual MachineTM; Encrypt.CSMTM; Enterprise Decision ServerTM;E-stageTM; FormationTM; Formation ArchitectTM; Formation Flow EngineTM; Foundation.2000TM;Frameworks for Business IntelligenceTM; Frameworks TechnologyTM; Gold Mine Data Access; i.DecideTM;i.Financial ServicesTM; i.FoundationTM; i.IntelligenceTM; i.ReachTM; i.SellTM; Illustra; Informix; Informix 4GL;Informix COM AdapterTM; Informix Enterprise Command CenterTM; Informix Extended Parallel ServerTM;Informix Informed DecisionsTM; Informix InquireSM; Informix Internet Foundation.2000TM; InformixLink;InformiXML TM; Informix Red Brick Decision ServerTM; Informix Session ProxyTM; Informix VistaTM; InfoShelfTM;Installation AssistantTM; InterforumTM; I-SpyTM; IterationsTM; J/FoundationTM; LUCIDTM; MaxConnectTM; Media360TM;MediazationTM; MetaArchitectTM; MetaBrokerTM; MetaCube; MetaHubTM; MetaStageTM; NewEraTM; O2 & DesignTM;O2 Technology & DesignTM; Object TranslatorTM; Office ConnectTM; ON-BarTM; OnLine Dynamic ServerTM;OnLine/Secure Dynamic ServerTM; OpenCase; OrcaTM; PaVERTM; Prism; Prism & DesignTM; RedBack; RedBeanTM;RedBeans & DesignTM; Red Brick and Design; Red Brick Data MineTM; Red Brick Decision ServerTM;Red Brick Mine BuilderTM; Red Brick DecisionscapeTM; Red Brick ReadyTM; Red Brick Systems;Regency Support; Rely on Red BrickSM; RISQL; Server AdministratorTM; Solution DesignSM; STARindexTM;STARjoinTM; SuperTerm; SuperView; SureStartTM; SystemBuilderTM; TARGETindexTM; TARGETjoinTM;The Data Warehouse Company; UniData; UniData & Design; UniVerse; Universal Data Warehouse BlueprintTM;Universal Database ComponentsTM; Universal Web ConnectTM; ViewPoint; Virtual Table InterfaceTM; VisionaryTM;Web Integration SuiteTM; XML D ataPortTM; Zero Defect Data. The Informix logo is registered with the United StatesPatent and Trademark Office. The DataBlade logo is registered with the United States Patent and Trademark Offi

Documentation Team: Claire Gustafson

GOVERNMENT LICENSE RIGHTS

Software and documentation acquired by or for the US Government are provided with rights as follows:(1) if for civilian agency use, with rights as restricted by vendor’s standard license, as prescribed in FAR 12.212; (2)Dept. of Defense use, with rights as restricted by vendor’s standard license, unless superseded by a negotiated vlicense, as prescribed in DFARS 227.7202. Any whole or partial reproduction of software or documentation markedthis legend must reproduce this legend.

sic Applications

Page 3: Basd_52

Contents

Chapter 1 - Introduction to UniBasic............................................13

In This Chapter .........................................................................................14

UniBasic Capabilities ...............................................................................15

UniBasic Statements .................................................................................16

Types of Statements ............................................................................16

Building Blocks for Writing Statements .............................................16

Statement Syntax and Layout .............................................................19

UniData File Types ...................................................................................23

Data Representation in UniBasic Programs ..............................................24

Delimiters and the Null Value ............................................................24

Constants .............................................................................................25

Variables .............................................................................................25

Arrays ..................................................................................................26

Getting System Information ......................................................................27

@Variables .........................................................................................27

STATUS Function ..............................................................................28

Developing UniBasic Applications 3

Page 4: Basd_52

Contents

Chapter 2 - Program Control.........................................................29

In This Chapter .........................................................................................30

Subroutines ...............................................................................................31

Internal Subroutines ............................................................................31

External Subroutines ...........................................................................33

Looping .....................................................................................................36

Conditional Tests ......................................................................................38

IF/THEN/ELSE Statements ................................................................38

CASE Statements ................................................................................41

Reversing Conditional Evaluations: The NOT Function ....................43

Comparison Operators Used in Conditional Statements ....................44

Branching ............................................................................................48

Summary of Program Control Commands ...............................................49

Chapter 3 - Creating and Running a Program.............................51

In This Chapter .........................................................................................52

Creating a Program with AE .....................................................................53

Creating a Program Record .................................................................53

More AE Commands ..........................................................................56

Compiling a UniBasic Program ................................................................59

Compile Commands ...........................................................................59

Directing the Compiler .......................................................................59

Compiler Messages .............................................................................65

Creating Cross-Reference Reports ......................................................68

Cataloging a UniBasic Program ...............................................................73

Points to Remember about CATALOG ..............................................73

4 Developing UniBasic Applications

Page 5: Basd_52

Contents

Direct Cataloging ................................................................................74

Local Cataloging .................................................................................75

Global Cataloging ...............................................................................75

Using the ECL CATALOG Command ...............................................77

Removing a Catalog Entry ..................................................................78

CATALOG Examples .........................................................................79

Running a UniBasic Program ...................................................................82

Running a Program from AE ..............................................................82

Running a Program from ECL ............................................................82

Chapter 4 - Maintaining Data in Files ...........................................93

In This Chapter .........................................................................................94

UniData Locks ..........................................................................................95

Database Triggers .....................................................................................96

Trigger Rules ......................................................................................96

The Nature of Triggers .......................................................................97

ECL Commands and Triggers ............................................................97

UniBasic Commands Affected by Triggers ........................................98

Writing an UPDATE Trigger Subroutine ...........................................99

Writing a DELETE Trigger Subroutine ............................................102

UniBasic STATUS Function Return Values ....................................105

Troubleshooting ................................................................................106

Maintaining Files ....................................................................................107

UniData Hashed Data Files ...............................................................107

Alternate Key Indexes ......................................................................108

Non-UniData Sequential Files ..........................................................112

Developing UniBasic Applications 5

Page 6: Basd_52

Contents

Opening Files ..........................................................................................115

Example ............................................................................................115

Selecting Records ...................................................................................116

Creating a Select List of Record IDs ................................................116

Clearing a Select List ........................................................................118

Reading, Writing, and Deleting Data from Files ....................................119

Getting Ready to Read ......................................................................119

Reading Record IDs from a Select List ............................................119

Reading Data from Files ...................................................................119

Example ............................................................................................122

Writing Data to Files .........................................................................123

Example ............................................................................................125

Deleting Data from Files ...................................................................126

Closing Files ...........................................................................................128

Accessing Data in Unopened Files .........................................................129

Chapter 5 - Using UniData Locks ...............................................131

In This Chapter .......................................................................................132

Understanding the UniData Locking System .........................................133

How UniData Locks Work ...............................................................133

Types of UniData Locks ...................................................................133

When UniBasic Finds a Lock ...........................................................135

Points to Remember about Locks .....................................................135

Locking Commands ................................................................................136

Checking Lock Status .......................................................................137

What Commands Do with Locks ............................................................138

6 Developing UniBasic Applications

Page 7: Basd_52

Contents

When to Use Locking Commands ..........................................................140

Programming Problems ..........................................................................142

Causes ...............................................................................................142

Minimizing Problems .......................................................................142

Locking Example ....................................................................................144

Chapter 6 - Working with Data in Programs ..............................147

In This Chapter .......................................................................................148

UniData Arrays .......................................................................................149

Dynamic Arrays ................................................................................149

Example ............................................................................................153

Dimensioned Arrays .........................................................................153

Inquiring about Data .........................................................................155

Type ..................................................................................................155

Location ............................................................................................157

Extraction ..........................................................................................157

Performing Numeric Operations .............................................................159

Arithmetic Operators ........................................................................159

Mathematic Functions .......................................................................164

Formatting and Converting Data ............................................................166

ICONV and OCONV: The All-Purpose Functions ..........................166

Character Format Conversion ...........................................................168

Strings and Dynamic Arrays .............................................................168

Numbers ............................................................................................170

Dates and Times ................................................................................175

UniBasic Multibyte Support ...................................................................181

Developing UniBasic Applications 7

Page 8: Basd_52

Contents

Modified Functions and Commands .................................................181

Single-Byte Functions .......................................................................183

Multibyte Functions ..........................................................................184

Chapter 7 - External Interaction..................................................187

In This Chapter .......................................................................................188

Interacting with Other UniBasic Programs .............................................189

Sharing Data .....................................................................................189

Including Code at Compilation .........................................................193

Interacting with UniData ........................................................................195

Executing Virtual Attributes .............................................................195

Executing ECL Statements ...............................................................196

Executing UniData SQL Statements .................................................197

Defining and Using Programs and Functions ...................................198

Writing User Exits ..................................................................................199

What Are User Exits? .......................................................................199

Calling a User Exit from UniBasic ...................................................200

Calling a User Exit from a Virtual Attribute ....................................200

Calling a User Exit from a Proc ........................................................201

Parameters in User Exits ...................................................................202

Interacting with Hardware I/O Devices ..................................................203

Display Terminals .............................................................................203

Printers ..............................................................................................209

Tape Drives .......................................................................................212

Interacting with the Operating System ...................................................213

8 Developing UniBasic Applications

Page 9: Basd_52

Contents

Chapter 8 - Linking Programs with UniData ..............................215

In This Chapter .......................................................................................216

Linking C Programs (UNIX Only) .........................................................217

Before You Begin .............................................................................217

Calling a C Function from UniBasic with CALLC ..........................219

Calling a UniBasic Subroutine from a C Program with CallBasic ...235

If This Is Not the First Time .............................................................246

File Examples ...................................................................................249

More on make, makeudt, and makeudapi .........................................254

Troubleshooting CALLC ..................................................................257

Linking C Programs (Windows NT or Windows 2000 Only) ................259

Dynamic Link Libraries (DLLs) and UniData .................................259

CALLC Features and Components ...................................................260

Using CALLC ...................................................................................264

CallBasic Features and Components ................................................267

Using CallBasic ................................................................................272

Chapter 9 - UniBasic Transaction Processing ..........................279

In This Chapter .......................................................................................281

Transaction Processing Commands ........................................................282

Executing TP and Non-TP Transactions ..........................................282

Starting a Transaction .......................................................................283

Committing a Transaction ................................................................285

Aborting a Transaction .....................................................................287

Testing for an Active Transaction ....................................................288

Transaction Processing Programming Example ...............................289

Developing UniBasic Applications 9

Page 10: Basd_52

Contents

Creating or Converting to a Recoverable File ........................................290

Creating a Recoverable File ..............................................................290

Converting to a Recoverable File .....................................................291

Transaction Processing Programming Problems ....................................293

Transaction Abort .............................................................................293

Degraded Performance .....................................................................297

Chapter 10 - Null Value Handling................................................299

Representing Unknown Values ..............................................................300

Turning Null Value Handling Off ....................................................300

Null Value Handling in UniBasic ...........................................................301

Printing and Displaying ....................................................................301

Sorting and Indexing .........................................................................301

Summary of Effects on Commands and Functions ..........................302

The Null Value in Numeric Functions ..............................................303

The Null Value in Conditional Tests ................................................305

The Null Value in Conversion Functions .........................................313

The Null Value in String Functions ..................................................315

Chapter 11 - Managing Named Pipes .........................................323

Points to Remember ..........................................................................325

OSOPEN .................................................................................................326

Opening Named Pipes ......................................................................327

OSBREAD ..............................................................................................330

Reading from a Named Pipe .............................................................330

OSBWRITE ............................................................................................334

Writing to Named Pipes ....................................................................334

10 Developing UniBasic Applications

Page 11: Basd_52

Contents

OSCLOSE ...............................................................................................337

STATUS Function Return Values ..........................................................339

INMAT ...................................................................................................340

Syntax ...............................................................................................340

Description ........................................................................................340

Troubleshooting ......................................................................................341

Example ..................................................................................................342

Chapter 12 - Using CallHTTP ......................................................345

Configuring the Default HTTP Settings .................................................346

Getting the Current HTTP Default Settings ...........................................349

Creating an HTTP Request .....................................................................350

Setting Additional Headers for a Req .............................................. uest 353

Adding a Parameter to the Request .........................................................355

Submitting a Request ..............................................................................357

Getting a Response Header .....................................................................360

Protocol Logging ....................................................................................361

Chapter 13 - Using the Socket Interface ....................................363

Socket Function Error Return Codes ......................................................364

Opening a Socket ....................................................................................368

Closing a Socket .....................................................................................370

Getting Information From a Socket ........................................................371

Reading From a Socket ...........................................................................373

Writing to a Socket .................................................................................375

Setting the Value for a Socket Option ....................................................377

Parameters .........................................................................................377

Developing UniBasic Applications 11

Page 12: Basd_52

Contents

Getting the Value of a Socket Option .....................................................379

Initializing a Server Side Socket Connection .........................................382

Accepting an Incoming Connection Attempt on the Server Side ...........383

Protocol Logging ....................................................................................385

Appendix A - Sample Program ...................................................387

UPDATE_ORDER .................................................................................388

DISPLAY_MESSAGE ...........................................................................395

Appendix B - UniBasic Transaction Processing Concepts......397

In This Appendix ....................................................................................398

Transaction Processing Rules: The ACID Properties .............................399

Atomicity ..........................................................................................399

Consistency .......................................................................................399

Isolation ............................................................................................399

Durability ..........................................................................................400

Transaction Isolation ...............................................................................401

Transaction Processing Errors ..........................................................401

What Are Isolation Levels? ..............................................................404

Programming to Isolation Levels ......................................................405

Example: Programming to Isolation Level 2 ....................................406

Example: Programming to Isolation Level 3 ....................................407

Updating Nonrecoverable Files in Transactions .....................................408

Index

12 Developing UniBasic Applications

Page 13: Basd_52

Chapter 1 - Introductionto UniBasic

asewrite

This manual is for programmers who write applications that use the UniData relational databmanagement system (RDBMS). It explains how to use UniBasic commands and functions toapplication programs.

Devloping UniBasic Applications 13

Page 14: Basd_52

Chapter 1 - Introduction to UniBasic

In This Chapter

This chapter introduces the concepts and terms used throughout this manual and in theUniBasicCommands Reference. It includes the following sections:

• “UniBasic Capabilities”

• “UniBasic Statements”

• “UniData File Types”

• “Data Representation in UniBasic Programs”

• “Getting System Information”

14 Devloping UniBasic Applications

Page 15: Basd_52

UniBasic Capabilities

s.

other

ta’s

s

UniBasic Capabilities

UniBasic is UniData’s structured programming language intended for a variety of applicationUniBasic provides you with the following capabilities:

• The modular language style enables you to create general UniBasic subroutines thatprocesses can call.

• From within a UniBasic program, you can perform the following tasks:

• Access other UniData products and operating system tools.

• Call external C functions.

• Pass data to and from external C programs.

• Manage display terminal input and output.

• Dynamic arrays and a full set of array commands provide an easy interface to UniDaextended relational database structure.

• An interface with the query languages UniData SQL and UniQuery enable you to pasrecord IDs or entire records to the query language.

For the syntax of UniBasic commands and functions, see theUniBasic Commands Reference

Devloping UniBasic Applications 15

Page 16: Basd_52

Chapter 1 - Introduction to UniBasic

uildingyour

lue of

de

UniBasic Statements

This section describes the types of statements you can use in UniBasic. Statements are the bblocks you use to write UniBasic programs. This section also describes how you can lay outstatements in a program.

Types of StatementsYou can write four types of UniBasic statements:

• Assignments – Load numeric or string values into variables. You also can assign theresults of a function to a variable:variable= OCONV(1286, “MD/2”).

• Control statements – Direct the order in which commands are executed, such as in asubroutine call: GOSUBupdate_client.

• Conditional statements – Control the execution of a set of operations based on the vaa variable: IF...THEN or DO...UNTIL.

• Compiler directives – Instruct the UniBasic compiler to evaluate and conditionally inclustatements: $INCLUDE.

Building Blocks for Writing StatementsStatements consist of five types of building blocks, which are described in the followingsubsections:

• “Commands”

• “Functions”

• “Operators”

• “Special Characters”

• “Comments”

16 Devloping UniBasic Applications

Page 17: Basd_52

UniBasic Statements

on

and

canCT

n:

ing

see

Commands

Commands are the primary building blocks of the UniBasic instruction set. Generally, eachstatement begins with a command word. In structured coding, only one command is includedeach line of code. TheUniBasic Commands Referenceexplains the syntax and use of eachcommand. In the following UniBasic statement, SELECT is the command word, and ORDER1 are arguments used by the command:SELECT ORDER TO 1.

Functions

Functions reformat, extract, and perform mathematical calculations. The result of a functionbe stored in a variable or used in a command. In the following statement, the function EXTRAis an argument in the PRINT command:PRINT EXTRACT(A,2,2) .

You can nest UniBasic functions. Therefore, a function can be an argument in a function as iPRINT OCONV(EXTRACT(A,2,2),"MD2,$") . This statement extracts data from the array A andprints out the extracted data with two decimal places, preceded by $.

TheUniBasic Commands Referenceexplains the syntax and use of each function.

Operators

UniBasic supports the following operator types:

• Arithmetic – For computing and assigning values.

• Conditional – For testing data and directing program execution. You can use the followoperator types:

• Relational

• Boolean

NoteFor information about arithmetic operators, see“Chapter 6 - Working with Data in Programs.”Forinformation about conditional operators, including how they are used in UniBasic programs,“Chapter 2 - Program Control.”

Devloping UniBasic Applications 17

Page 18: Basd_52

Chapter 1 - Introduction to UniBasic

ding.

be

s are

nent.

er the

Special Characters

You can use the following special characters in UniBasic statements:

• Continuation character (|) – Placed at the end of a line. It indicates that a commandcontinues on the next line.

• Semicolon (;) – Separates commands on the same line. Be aware, though, that inclumore than one command on a line makes your code more difficult to read and debug

• Quotation marks (“ ” or ‘ ’) – Must enclose string variables and literal values. They canused together to differentiate a literal that is embedded in a string.

• Backslash (\) – Can also be used to replace quotation marks when a string variable isembedded in a literal.

In the following example, HISTORY4 is assigned to a string that includes the HEADINGcommand. Single quotation marks are embedded in double quotation marks, and backslasheused to enclose the entire string:

Program Example

MON = @MONTHDA = @DAYHISTORY1 = "LIST ALMANAC WITH MONTH = ":MON:" AND DAY = ":DAHISTORY2 = "BY TYPE BY YEAR"HISTORY3 = "YEAR TYPE EVENT ID.SUP COL.SUP NI.SUP "HISTORY4 = \HEADING "'C'Today is 'DLC' On This Day in History 'LL'" \HISTORY = HISTORY1:HISTORY2:HISTORY3:HISTORY4PERFORM HISTORY

Comments

Comments narrate the actions of a program for clarity, but the compiler ignores them. You caenter a comment on a line by itself, or you can enter it on the same line as a program statemThe comment commands are *, !, and REM.

To enter a comment on a line by itself, begin the line with a comment command, and then entcomment text.

18 Devloping UniBasic Applications

Page 19: Basd_52

UniBasic Statements

nd withB

ines,

aon a

In the following example, two asterisks (**) are used for commented text:

Program Example

** Program : UPDATE_ORDERS** Programmer : Todd Roemmich** Created : 04/02/1996** Description: Check and/or alter Order records** : Display Screen and ask for Order #** : Read record (if it exists) and display fields** : Prompt for a command (Alter, Delete, or Quit)** : A) Allow the user to change price or address** : D) Delete the record** : Q) Exit the program

To enter a comment on the same line as a program statement, precede the comment commaa semicolon. In the following example, a comment is entered on the same line as the GOSUcommand:

Program Example

GOSUB OPEN_FILES ; ** go open files based on user input

Statement Syntax and LayoutThe syntax for each command and function is included in theUniBasic Commands Reference.Multiple statements can be grouped on one line, single statements can extend over several land statements can be nested.

Stacking Multiple Statements on a Line

Structured programming conventions suggest that you place no more than one statement onsingle line. For backward compatibility, UniBasic enables you to include multiple statementssingle line separated by a semicolon (;).

Devloping UniBasic Applications 19

Page 20: Basd_52

Chapter 1 - Introduction to UniBasic

his

eed

d bye

ften

ReminderPrograms are easier to follow if you place a single command on each line.

Extending Statements Across Multiple Lines

Individual statements can extend across several lines if you follow one of these rules:

• Break the statement as shown in the syntax of the command or function in theUniBasicCommands Reference.

• Use a continuation character (|) at the end of the line. The following example prints “Tline is CONTINUED”:

Program Example

001: PRINT "This line is ": OCONV(|002: "continued","MCU")

While Informix recommends that you use a single-line construction, in two cases you might nto use a multiline construction:

• Statements with arguments – Statements or functions that have arguments separatecommas, such as CALL, COMMON, and DATA, often require several lines. A multilinCOMMON statement follows:

Program Example

COMMON NAME,DOB,SS.NUM,ADDRESS,CITY,STATE,ZIP,HOME.PHONE,BUS.PHONE,ACC.NUM

• Long statements – Lengthy constructions, such as FOR/NEXT and IF/THEN/ELSE, orequire several lines.

20 Devloping UniBasic Applications

Page 21: Basd_52

UniBasic Statements

ion,is

The following example, which is taken from the sample program in“Appendix A - SampleProgram,”shows a lengthy IF/THEN/ELSE construction:

Program Example

IF PRODUCT_LINE = '' THENPRODUCT_LINE = PRODUCT_NUMBER "R#10"COLOR_LINE = COLOR "R#10"QUANTITY_LINE = QUANTITY "R#10"PRICE_LINE = PRICE

END ELSEPRODUCT_LINE := " ":PRODUCT_NUMBER "R#10"COLOR_LINE := " ":COLOR "R#10"QUANTITY_LINE := " ":QUANTITY "R#10"PRICE_LINE := " ":PRICE

END

Nesting Statements

You can nest a statement within another statement. For example, you can test for one conditand if it is true, test for an additional condition. In the following example, the second IF/THENnested:

Program Example

IF expression THENstatementsIF expression THEN

statementsEND ELSE

statementsEND

END

Devloping UniBasic Applications 21

Page 22: Basd_52

Chapter 1 - Introduction to UniBasic

The following program segment, which is taken from the sample program in“Appendix A -Sample Program,”is an example of an IF/THEN/ELSE nested inside a conditional LOOP. TheLOOP test is in the UNTIL statement.

Program Example

LOOPDISPLAY @(15,6):INPUT ORDER_NUMBERORDER_NUMBER = OCONV(ORDER_NUMBER,"MCU")IF NUM(ORDER_NUMBER) OR ORDER_NUMBER[1,1] = "Q"THEN

VALID_ORDER_NUMBER = 1END ELSE

VALID_ORDER_NUMBER = 0MESSAGE = "Order # must be a Number, or the letter 'Q'"

CALL DISPLAY_MESSAGE(MESSAGE)END

UNTIL VALID_ORDER_NUMBERREPEAT

22 Devloping UniBasic Applications

Page 23: Basd_52

UniData File Types

more

s

ata

UniData File Types

File types that make up the UniData database include those listed in the following table. Forinformation about UniData files, seeUsing UniData.

UniData FileType Description

Static hashed file Data file.

Dynamic hashedfile

Directory file that contains a data and an overflow portion. UniData treatthese two portions as one file. UniData automatically resizes the file toavoid level 2 overflow.

Dictionary(DICT) file

Data file that contains attribute definitions for a UniData file.

Alternate keyindex (static file)

Data file located in the same directory at the same level as the indexed dfile. This index is based on an attribute other than the primary key.

Alternate keyindex (dynamicfile)

Data file located in the dynamic file directory along with the data file andthe overflow file.

DIR file An operating system directory directly accessible by UniData.

MULTIFILE(multilevel file)

A directory that contains one or more UniData hashed files. There is onedictionary for the MULTIFILE. All hashed files in the MULTIFILE sharethe same dictionary.

MULTIDIR (mul-tilevel DIR file)

A directory that contains one or more subdirectories. There is onedictionary for the MULTIDIR. All subdirectories in the MULTIDIR sharethe same dictionary. If you copy records from a file into one of thesubdirectories, each record is stored as a text file.

UniData File Types

Devloping UniBasic Applications 23

Page 24: Basd_52

Chapter 1 - Introduction to UniBasic

a

alueeseted.

.

Data Representation in UniBasic Programs

Before you can work with data in a program, you must bring it into the program and store it inusable form. In UniBasic programs, data is represented in the following ways:

• Delimiters and the null value

• Constants

• Variables

• Arrays

• @variables

Delimiters and the Null ValueInformix recommends that you use @variables to represent UniData delimiters and the null vin UniBasic programs instead of entering the ASCII code directly. The ASCII code used for thvalues is determined by the language (such as English, Chinese, or Spanish) being represenThe @values to use are:

• Null value – @NULL

• Record mark – @RM

• Attribute mark – @AM, @FM

• Value mark – @VM

• Subvalue mark – @SM

• Text mark – @TM

NoteYou turn on or off null value handling with the UniData configuration parameter NULL_FLAGFor a full explanation, see“Chapter 10 - Null Value Handling.”

24 Devloping UniBasic Applications

Page 25: Basd_52

Data Representation in UniBasic Programs

st use

Basicype

ore

gns.

ConstantsA constant can be a numeric value, such as 25, or a string value, such as “inventory.” You muquotation marks to enclose string values. You can use up to 32,765 constants at one time.

VariablesA variable can be as simple as a character string or as complex as a dimensioned array. Unidoes not require explicit declaration of variable data type (unless it is a dimensioned array). Tis inferred from the data initially assigned to it.

Setting Variable Values

Variables receive their values from one of the following:

• Data input through the keyboard.

• An assignment (variable_name= 1234).

• A computation statement.

• Data read from a file.

• Data stored in virtual memory or on hard disk, tape, or another storage medium. For minformation, see“Chapter 3 - Creating and Running a Program.”

• Arguments in a program call. For more information, see“Chapter 3 - Creating andRunning a Program.”

Variable Names

Variable names must follow the conventions described below:

• Must be unique.

• Must begin with a letter.

• Can contain any combination of letters, numbers, underscores, periods, and dollar si

Devloping UniBasic Applications 25

Page 26: Basd_52

Chapter 1 - Introduction to UniBasic

a

ers.

data

ta toments

• Are limited to a length of 64 characters.

• Cannot be a reserved word. For a list of reserved words, see theUniBasic CommandsReference.

ArraysAn array is simply a form of variable, which is a place reserved in memory for storing data inUniBasic program. Each element of an array can contain a constant, a simple variable, or adynamic array. UniBasic allows for two types of arrays:

• Dynamic arrays – Separate each attribute, value, and subvalue of a record by delimit

• Dimensioned arrays – Store data in designated cells of a fixed-sized matrix. Access toin a dimensioned array is rapid, but less flexible.

TipUse dynamic arrays when the number of elements is small, unknown, varied, or when the daexamine is near the beginning of the array. Use dimensioned arrays when the number of eleis large or the program will process the elements nonsequentially.

For more information about using arrays to process data in a UniBasic program, see“Chapter 6 -Working with Data in Programs.”

26 Devloping UniBasic Applications

Page 27: Basd_52

Getting System Information

d

s, andor 4-

fter

es,

s

Getting System Information

A wealth of information is available to your UniBasic program through system variables (calle@variables) and through the UniBasic STATUS function.

@VariablesUniData @variables store and make available information about the system, the user procesthe UniBasic program being executed. Some @variables are available through any UniDataGL tool. Others are available through UniBasic only.

• UniData – Available through any tool. For a complete list of UniData @variables, seeUsing UniData. For example:

@SYSTEM.RETURN.CODE returns a value indicating a condition or error after theexecution of an ECL command. It also returns additional information. For example, aSELECT, it reports the number of records selected.

• UniBasic – Available through UniBasic only. For a complete list of UniBasic @variablsee theUniBasic Commands Reference.For example:

@SENTENCE stores the statement that invoked the current UniBasic program.

@TRANSACTION returns 1 if a transaction is active, and returns 0 if no transaction iactive.

ReminderUse @variables to represent UniData delimiters and the null value. Do not use the UniBasicCHAR function because the ASCII code varies with language group.

Devloping UniBasic Applications 27

Page 28: Basd_52

Chapter 1 - Introduction to UniBasic

ted.cates

ues

STATUS FunctionThe UniBasic STATUS function provides information about the last UniBasic statement execuGenerally, a return value of 0 indicates successful execution, while 1 or any other number indian error condition. For cases in which return values are set by a command, those values aredocumented with the command in theUniBasic Commands Reference.

UniData triggers also set STATUS values. For more information about triggers, the return valset for the STATUS function, and an additional return value set by triggers, see“Chapter 4 -Maintaining Data in Files.”

28 Devloping UniBasic Applications

Page 29: Basd_52

Chapter 2 - ProgramControl

A structured program consists of:

• A main routine that controls the order of program execution, and

• Subroutines that perform functions such as screen, printer, and data manipulation.

This chapter introduces the UniBasic program control mechanisms that enable you to writestructured code. If you are new to programming or new to UniBasic, read“Chapter 1 -Introduction to UniBasic”first.

For more information about the syntax of UniBasic commands and functions, seeUniBasicCommands Reference.

Developing UniBasic Applicatons 29

Page 30: Basd_52

Chapter 2 - Program Control

w.:

In This Chapter

The UniBasic commands control the order of execution of statements in the program. Thesecommands create subroutines, loops, and conditional tests, and otherwise direct program floThese structures and the commands that build them are introduced in the following sections

• “Subroutines”

• “Looping”

• “Conditional Tests”

• “Summary of Program Control Commands”

30 Developing UniBasic Applicatons

Page 31: Basd_52

Subroutines

nd

s do

Subroutines

In UniBasic, you can code subroutines that are internal to the calling program or separatelycompiled and cataloged. You can nest subroutines up to 1024 levels deep.

Internal SubroutinesInternal subroutines are self-contained units within a program. They begin with a label and ewith a RETURN statement.

Commands That Call Internal Subroutines

Within the constraints of structured programming, GOSUB and ON GOSUB are the onlyacceptable statements to use for calling an internal subroutine:

• GOSUBlabel1RETURN [TO]

• ON exprGOSUBlabel1[:][, label2[:]...]RETURN [TO]

TipGOTO and ON GOTO are provided in UniBasic for backward compatibility. These commandnot return control to the calling statement and are generally not used in structured programsbecause they make the code difficult to read and maintain.

Naming Internal Subroutines

Each internal subroutine must begin with a label. Labels can be numbers or short descriptivestrings. The following labels are used in the sample program in“Appendix A - Sample Program”:

INITIALIZEALTER_RECORDWRITE_RECORDGET_RECORD_COMMAND

Developing UniBasic Applicatons 31

Page 32: Basd_52

Chapter 2 - Program Control

ntable

You must observe the following conventions when creating statement labels:

• If a label begins with a number, it must contain only numbers.

• If the label begins with a letter, it can contain any combination of letters, numbers,underscores, periods, and dollar signs.

• Spaces are not allowed in subroutine names.

• If the label is alpha or alphanumeric, it must end with a colon to differentiate it from avariable.

• The label cannot be a reserved keyword.

When you select names for subroutine labels, choose meaningful, descriptive names. Avoidabbreviations. Add comments after the statement label, and when you use numeric statemelabels, arrange the subroutines in ascending order. If you follow these guidelines, you will beto locate internal subroutines easily.

Example of an Internal Subroutine

The following example, taken from the sample program in“Appendix A - Sample Program,”illustrates calling internal subroutines:

Program Example

*-------------- Main Logic -----------------------------GOSUB INITIALIZELOOP

GOSUB DISPLAY_SCREENGOSUB GET_ORDER_NUMBER

UNTIL ORDER_NUMBER[1,1] = 'Q'GOSUB DISPLAY_DATAIF RECORD_FOUND THEN GOSUB GET_RECORD_COMMANDRELEASE

REPEATGOSUB EXIT

32 Developing UniBasic Applicatons

Page 33: Basd_52

Subroutines

rom

the

ramrough

lling

In the previous example, the first line calls the subroutine INITIALIZE. Processing proceeds fthe “INITIALIZE:” label, as the following example shows, until it reaches RETURN:

Program Example

INITIALIZE:DISPLAY @(-1)PROMPT ''RETURN

Processing picks up again at the next line that follows the subroutine call in Main Logic (seepreceding program example). This line contains the command LOOP.

External SubroutinesExternal subroutines are separately compiled programs that are called from a UniBasic progusing the CALL statement. You can pass variables and constants to an external subroutine tharguments. The structural requirements of external subroutines include the following:

• The SUBROUTINE statement must be the first noncomment line in the subroutine.

• The SUBROUTINE statement must contain the same number of arguments as the caprogram.

• The subroutine must finish with a RETURN command.

• The compiled subroutine must be cataloged so that the main program can locate it.

• You can nest subroutines up to 1024 levels deep.

Calling an External Subroutine

Use the CALL command to initiate an external subroutine.

The syntax of the CALL command follows:

CALL sub.name[(argument1[,argument2]...)]

CHAIN and ENTER also execute subroutines, but they do not return control to the callingprogram and are not recommended in structured programming.

Developing UniBasic Applicatons 33

Page 34: Basd_52

Chapter 2 - Program Control

e of

Naming an External Subroutine

The SUBROUTINE command names the external routine. This command must be the first lincode in the called routine, and the last line must be RETURN. The syntax follows:

SUBROUTINEsub.name[(argument1[,argument2]...) statement(s)RETURN

Examples

The following sample program calls the external subroutine CALLED.PGM. It passes on theoperation code selected by the user.

Program Example

PRINT "Enter operation to perform: (1)add, (2)delete, (3)update : ";INPUT opera-tionCALL CALLED.PGM(operation,ret.val)PRINT "Operation completed: ":ret.valEND

The following subroutine accepts the code, passes in the parameteroperation, and returns a valuein ret.value:

Program Example

SUBROUTINE CALLED.PGM(operation,ret.val)BEGIN CASE

CASE operation = 1ret.val = "Record added."

CASE operation = 2ret.val = "Record deleted."

CASE operation = 3ret.val = "Record updated."

END CASERETURN

34 Developing UniBasic Applicatons

Page 35: Basd_52

Subroutines

The following program is the globally-cataloged subroutine DISPLAY_MESSAGE that isincluded in“Appendix A - Sample Program.”It displays the message passed in the variableMESSAGE.

Program Example

SUBROUTINE DISPLAY_MESSAGE(MESSAGE)DISPLAY @(5,20):MESSAGEDISPLAY @(5,21):"Press the (Return) key.":INPUT PAUSE,1_RETURN

The following program segment is an example of a call to the preceding subroutine fromUPDATE_ORDER:

Program Example

MESSAGE ="**(Record Does Not Exist)**"GO_BACK = "Y"CALL DISPLAY_MESSAGE(MESSAGE)

Developing UniBasic Applicatons 35

Page 36: Basd_52

Chapter 2 - Program Control

of

nts

Looping

UniBasic provides the following commands that support looping to repeatedly execute a setcommands.

NoteTo test for the null value, you must test the return value of the function ISNV or ISNVS, as inLOOP

UNTIL ISNV(X) = 1 . You cannot test for the null value directly, as inLOOP UNTIL X = @NULL,because the null value is not comparable to any value. For information about how null valuesaffect UniBasic, see“Chapter 10 - Null Value Handling.”

Command Action

LOOP/REPEAT Statements can precede and/or follow the evaluation. You can includemultiple UNTIL and/or WHILE clauses. The loop continues until theUNTIL condition is satisfied or until WHILE is false.

FOR/NEXT Executes statements repeatedly while a counter increments or decreme(default is +1). The loop continues until the counter reaches a specifiednumber or the UNTIL condition is satisfied or until WHILE is false.

CONTINUE Transfers control to the next iteration of a FOR/NEXT or LOOP/REPEATstatement.

EXIT Transfers control to the line after REPEAT or NEXT.

Commands for Looping

36 Developing UniBasic Applicatons

Page 37: Basd_52

Looping

Example

The following program segment is taken from the sample program in“Appendix A - SampleProgram.”This segment updates the price if the user has entered a new one.

Program Example

*------------ Subroutines ----------------------------ALTER_RECORD:

* Create a new screen, and allow PRICE and ADDRESS to be changed.

* Initialize variables and draw the screenNEED.TO.WRITE = 0DISPLAY @(-1):@(15,5):"Alter ORDER":DISPLAY @(10,8):"(Press RETURN to leave un-changed)"DISPLAY @(8,9):"Old Price":@(42,9):"New Price (Enter 2 decimal places)"

* Change the PRICE field (if desired)FOR ENTRY = 1 TO NUM_ENTRIES

NEW.PRICE = ""DISPLAY @(10,9+ENTRY):OCONV(ORDER.REC<7,ENTRY>,"MR2$,"):INPUT @(45,9+ENTRY):NEW.PRICENEW.PRICE = OCONV(NEW.PRICE,"MCN")IF NEW.PRICE # '' AND NUM(NEW.PRICE) THEN

ORDER.REC<7,ENTRY> = NEW.PRICENEED.TO.WRITE = 1

ENDNEXT ENTRY

Developing UniBasic Applicatons 37

Page 38: Basd_52

Chapter 2 - Program Control

ononal

s:

Conditional Tests

Two primary functions of a program are evaluating and processing data appropriately basedthat evaluation. To evaluate data, you need to build conditional statements. UniBasic conditistatements include the following:

• IF/THEN/ELSE

• CASE

Within these statements, you can nest additional conditional tests with the following keyword

• WHILE

• UNTIL

IF/THEN/ELSE StatementsAn IF/THEN/ELSE statement evaluates a piece of data and then processes it in a mannerappropriate for that particular data.

NoteFor information about how null values affect UniBasic, see“Chapter 10 - Null Value Handling.”

You can use the syntax in any of the following IF/THEN/ELSE statements.

Type Syntax Example

1 IF ...THEN ... IF confirmed = "Y" THEN ...

2 IF ... THEN ... ELSE ... IF confirmed = "Y" THEN GOSUB DISPLAYELSE ...

IF/THEN/ELSE Statement Syntax

38 Developing UniBasic Applicatons

Page 39: Basd_52

Conditional Tests

You can test for a true condition in a variable with a statement similar to the following:

IF var THEN statements1 ELSE statements2

When var is true, (specifically, when it is anything other than 0),statements1are executed. Whenvar is false (when it is 0),statements2are executed.

3 IF ... THEN ...

...

END ELSE...

IF confirmed = "Y" THEN

INFOMESSAGE = ...

GOSUB DISPLAY_INFO

END ELSE

GOSUB DISPLAY_ERR

END

4 IF exprTHEN

...

END ELSE

...

END

IF confirmed = "Y" THEN

INFOMESSAGE = ...

GOSUB DISPLAY_INFO

END ELSE

INFOMESSAGE = ...

GOSUB DISPLAY_INFO

END

Type Syntax Example

IF/THEN/ELSE Statement Syntax

Developing UniBasic Applicatons 39

Page 40: Basd_52

Chapter 2 - Program Control

Example

The following program segment is taken from the sample program in“Appendix A - SampleProgram.”This statement is an example of Type 1, which is described in the previous table.

Program Example

* Accept INPUT to change values of addressINPUT @(40,13):STREET1IF STREET1 = '' THEN STREET1 = CLIENT.REC<4>INPUT @(40,14):STREET2IF STREET2 = '' THEN STREET2 = CLIENT.REC<5>

The following program segment is taken from the sample program in“Appendix A - SampleProgram.”This statement is an example of Type 4, which is described in the precedingIF/THEN/ELSE Statement Syntax table.

Program Example

IF STATUS( ) = 1 THENDISPLAY "A Transaction had already been started, NESTED Transactions"DISPLAY "are NOT Allowed. (Contact System Administrator)"INPUT PAUSE,1_

END ELSEDISPLAY "The Recoverable File System is not enabled."

END

40 Developing UniBasic Applicatons

Page 41: Basd_52

Conditional Tests

ndi-ion is

andicions.

vious

CASE StatementsThe CASE statement accommodates multiple conditions. When testing for more than two cotions, the CASE statement is more efficient than IF/THEN/ELSE because when a true conditencountered, UniBasic skips all subsequent CASE evaluations.

Syntax:

BEGIN CASECASE expr1

statementsCASE expr2

statements. . .

{ CASE 1statements}

END CASE

If a condition is true, UniBasic performs all statements associated with that CASE statementthen transfers control to the statement that follows END CASE. If a condition is false, UniBasgoes on to test the next CASE condition. You can enter an unlimited number of CASE condit

The CASE 1 statement always evaluates to true. Placed as the last test, it executes if all preCASE conditions are false.

NoteThe null value is always evaluated to false. For information about how the null value affectsUniBasic, see“Chapter 10 - Null Value Handling.”

Developing UniBasic Applicatons 41

Page 42: Basd_52

Chapter 2 - Program Control

nd1

Example

The following program segment is taken from UPDATE_ORDER in“Appendix A - SampleProgram.”In this subroutine, the user selects an operation to perform (alter, delete, or quit), athen the program calls the appropriate subroutine to perform that operation. Note that CASEhandles the user entering an invalid response.

Program Example

GET_RECORD_COMMAND:* Enter a valid command to act upon (the Desired record is already shown).

DISPLAY @(7,22):"Enter A)lter, D)elete, or Q)uit: ":INPUT COMMAND,1COMMAND = OCONV(COMMAND[1,1],"MCU")

BEGIN CASECASE COMMAND = "A"

GOSUB ALTER_RECORDCASE COMMAND = "D"

GOSUB DELETE_RECORDCASE COMMAND = "Q"

FINISHED = 1CASE 1

MESSAGE = "Valid options are A, D, or Q. Please try again"CALL DISPLAY_MESSAGE(MESSAGE)

END CASERETURN

42 Developing UniBasic Applicatons

Page 43: Basd_52

Conditional Tests

falsee

thatosed

ed tosee

Reversing Conditional Evaluations: The NOTFunctionThe NOT function inverts the result of conditional statements, making a true result false or aresult true. If the expression is true, the function returns 0 (false). If the expression is false, thfunction returns 1 (true). You must enclose the expression being reversed in parentheses.

The STATUS function in the following program tests for a value other than 0, which indicatesthe record was not found. Note that the comparison of the STATUS return value with 0 is enclin parentheses.

NoteYou cannot use NOT to test for the absence of the null value because NOT @NULL is evaluat@NULL. For more information about how the null value is handled in conditional statements,“Chapter 10 - Null Value Handling.”

Program Example

OPEN "INVENTORY" TO open.file ELSE PRINT "Open error." ;STOPPRINT "Enter product to display: ";INPUT search_productsearch_product = OCONV(search_product, "MCT")new_product = search_productSETINDEX "PROD_NAME", search_product ON open.fileIF NOT(STATUS()=0) THEN PRINT "Record not found.";STOPLOOP UNTIL new_product <> search_product

READFWD dyn.array.var FROM open.file ELSE PRINT "Readfwd error."new_product = EXTRACT(dyn.array.var,3)IF new_product = search_product THEN PRINT "Record is: ":dyn.array.var

REPEATEND

Developing UniBasic Applicatons 43

Page 44: Basd_52

Chapter 2 - Program Control

f the

Comparison Operators Used in ConditionalStatementsComparison operators can be used to make compound conditional statements. Comparisonoperators include Boolean and relational operators.

Boolean Operators

Boolean operators combine or compare sets of relational data. A common use for Booleanoperators is to check if a numeric variable falls within a range. Boolean operators take one ofollowing forms.

NoteWith null value handling turned on, the logical operators AND and OR follow the ANSI SQL3-way logic and null value evaluation comparison rules. For more information, see“Chapter 10 -Null Value Handling.”

In the following example, either expression (NEW_CLIENT # OLD_CLIENT) orNEED.TO.WRITE must be true for the CLIENT.REC values to be updated. The values inNEW_CLIENT and OLD_CLIENT must not be equal, or NEED.TO.WRITE must be 1.

Program Example

IF (NEW_CLIENT # OLD_CLIENT) OR NEED.TO.WRITE THEN* Re-assign values to CLIENT.REC

CLIENT.REC<4> = STREET1CLIENT.REC<5> = STREET2CLIENT.REC<6> = CITY

Expression Description

expr1AND expr2 When both expressions are true, the result is true.

expr1OR expr2 When either expression is true, the result is true.

Boolean Operators

44 Developing UniBasic Applicatons

Page 45: Basd_52

Conditional Tests

CLIENT.REC<7> = STATECLIENT.REC<8> = ZIPGOSUB WRITE_RECORD

END

Relational Operators

UniBasic supports the following relational operators for making comparisons.

NoteSome symbols serve as both relational and arithmetic operators.

Operator Description

EQ = Equal to.

NE # <> >< Not equal to.

GT > Greater than.

LT < Less than.

GE >= => Greater than or equal to.

LE <= =< Less than or equal to.

#> Not greater than.

#< Not less than.

MATCHMATCHES

Value matches a pattern (such as 0N or0A) or a literal.

Relational Operators

Developing UniBasic Applicatons 45

Page 46: Basd_52

Chapter 2 - Program Control

eFor

ssion

calm left

UDT.OPTIONSUDT.OPTIONS provide settings that modify the operation of UniData and UniBasic. For valucomparison, if you set UDT.OPTION 1 ON, UniData evaluates zero and empty string equally.more information, see theUDT.OPTIONS Commands Reference.

Operator Precedence

Within nested operations, you can control the order of execution by using parentheses witharithmetic or comparison operators. UniBasic first resolves the innermost parenthetical expreand then works outward.

If multiple operators appear within a single command statement or within a single parenthetiexpression, and the operators have equal precedence, UniBasic performs the operations froto right.

In the absence of parentheses, UniBasic uses the following order of precedence.

Order ofPrecedence Operator Description

First ^ ** Exponentiation

Second */

Multiplication

Division

Third -+-

Unary minus

Addition

Subtraction

Fourth : CAT Concatenation

Operator Precedence

46 Developing UniBasic Applicatons

Page 47: Basd_52

Conditional Tests

Example

You can use the following sample program to test the logical operator OR. To test the logicaloperator AND, substitute AND for OR in the program.

Program Example

PROMPT''PRINT "First value: Enter true or false: ";INPUT answeranswer = UPCASE(answer)GOSUB SET.VALval.one=valuePRINT "Second value: Enter true or false: ";INPUT answeranswer = UPCASE(answer)GOSUB SET.VALval.two=value

If (val.one OR val.tw o ) = 1

Fifth > GT

< r

= EQ

>= => GE

#>

<= =< LE

#<

<> >< # NE

MATCH MATCHES

Greater than

Less than

Equal to

Greater than or equal to

Not greater than

Less than or equal to

Not less than

Not equal to

Matching

Sixth & AND! OR

AndOr

Order ofPrecedence Operator Description

Operator Precedence (continued)

Developing UniBasic Applicatons 47

Page 48: Basd_52

Chapter 2 - Program Control

mp

PRINT "Condition True."ELSE PRINT "Condition is false."

BranchingFor backward compatibility, UniBasic supports branching, although this practice makes codedifficult to follow and maintain. The GOTO and ON GOTO commands direct the program to juto another place in the code. For the syntax of these commands, see theUniBasic CommandsReference.

48 Developing UniBasic Applicatons

Page 49: Basd_52

Summary of Program Control Commands

in

Summary of Program Control Commands

The following table summarizes the UniBasic commands that facilitate structure and controlprograms.

Command Action

ABORT Stops program execution.

CALL Calls an external subroutine.

CALLC Calls an external C subroutine.

CASE Executes statements based on a condition.

CHAIN Branches to a separate program.

CONTINUE Transfers control to the next iteration of theFOR/NEXT or LOOP/REPEAT statement.

END Indicates the end of a conditional statement, program,or subroutine.

EXECUTE Executes an external UniData statement, such as aUniQuery, UniData SQL, or operating systemcommand. (Identical to PERFORM.)

EXECUTESQL Executes a UniData SQL statement from within aUniBasic program.

EXIT Ends a FOR/NEXT or LOOP/REPEAT statement andtransfers control to the first statement after the loopstatement.

FOR/NEXT Repeats statements based on a condition.

GOSUB Executes an internal subroutine, and then returns to thenext statement after GOSUB.

IF/THEN/ELSE Executes statements one time based on a condition.

Program Control Commands

Developing UniBasic Applicatons 49

Page 50: Basd_52

Chapter 2 - Program Control

LOOP/REPEAT Repeats a set of statements based on a condition.

ON exprGOSUBname

Branches to a subroutine based on the value of anexpression.

PCPERFORM Executes an operating system command from within aUniBasic program.

PERFORM Executes an external UniData statement, such as aUniQuery, UniData SQL, or operating systemcommand from within a UniBasic program. (Identicalto EXECUTE.)

RETURN Returns control from an external subroutine back tothe original program, or returns control from aninternal subroutine to the next statement that followsGOSUB.

STOP Stops program execution.

Command Action

Program Control Commands (continued)

50 Developing UniBasic Applicatons

Page 51: Basd_52

Chapter 3 - Creatingand Running a Program

the

This chapter describes how to create and run a UniBasic program. If you are not familiar withUniData RDBMS, the UniBasic statement types, and how data is represented in UniBasicprograms, Informix recommends that you review“Chapter 1 - Introduction to UniBasic”beforeyou begin this chapter.

Developing UniBasic Applications 51

Page 52: Basd_52

Chapter 3 - Creating and Running a Program

des

In This Chapter

This chapter introduces the tools that you need to create and edit UniBasic programs. It inclucompiling, cataloging, and running the program. These topics are presented in the followingsections:

• “Creating a Program with AE”

• “Compiling a UniBasic Program”

• “Cataloging a UniBasic Program”

• “Running a UniBasic Program”

52 Developing UniBasic Applications

Page 53: Basd_52

Creating a Program with AE

s youileline

youlp.

ame

Creating a Program with AE

You can use any ASCII text editor or word processor to create a UniBasic program, as long asave it in ASCII format as a record in a directory file. UniData creates a basic program (BP) ffor this purpose when you initiate a new account. UniData provides the Alternate Editor (AE)editor, or you can use the operating system default editor (with the ECL command ED). Thissection provides instructions for using AE.

TipAE is designed for writing UniBasic programs. It recognizes UniData hashed files, it enablesto execute UniData commands from within a file you are editing, and it comes with online he

For information about the building blocks used to create UniBasic programs, see“Chapter 1 -Introduction to UniBasic.”

Creating a Program RecordPerform the following steps to create a program record:

1. Start AE

To create a program using AE, enter the AE command at the ECL prompt. You will use this scommand later to edit the program.

Syntax:

AE directory.file prog.name

directory.file is the directory in which the source code is located (usually BP);prog.nameis thename you choose for the program.

TipUniData creates a BP directory file when you create your account.

Developing UniBasic Applications 53

Page 54: Basd_52

Chapter 3 - Creating and Running a Program

nd

ffect

oes

t

If You Are Successful

After you start the AE editor, UniBasic opens the program at the top and displays the commamode prompt:

Screen Example

: AE BP NEWFILTop of New "NEWFIL" in "BP".*--:

When you first start AE, you are in command mode. This is where you enter commands that athe entire file.

If You Are Not Successful

If you fail to indicate a directory file where the program is to reside (such as the BP file), AE dnot recognize the file name, and it displays a message like this:

Screen Example

: AE NEWFILUnable to find file "NEWFIL".File >

At this point, your best option is to press ENTER and start over.

2. Change to dInput Mode

For now, you want to key in the program, so you want to be in input mode. To change to inpumode, enteri. AE changes the prompt to reflect your current line number.

Screen Example

*--: i001=

54 Developing UniBasic Applications

Page 55: Basd_52

Creating a Program with AE

input

the

andtratedt

Enter as many lines of code as you want. Press ENTER at the end of each line. You remain inmode as long as you enter text on a line before pressing ENTER, as shown in the followingexample:

Screen Example

001= ! Program: NEWFIL002= ! Created: 1/1/96003= !

TipTo display and enter the ASCII code for control characters (including UniData delimiters andnull value) in AE, press SHIFT+6.

3. Return to Command Mode

When you want to get help, save the file, compile the program, or execute some other commdirective, press ENTER at the line number. You are returned to command mode, as demonsby the return of the command mode prompt. In the following example, the line number promp“004=” is replaced by the command mode prompt “*--”:

Screen Example

004= <-- line number prompt*--: <-- is replaced by command mode prompt

Developing UniBasic Applications 55

Page 56: Basd_52

Chapter 3 - Creating and Running a Program

s.

tine.

de.

4. Access AE Help

To get help on AE, enterHELP or H at the command-line prompt, as shown in the followingexample:

Screen Example

*--: HELP

You can also enter a help topic on the same line. To get a list of all topics, enterALL or A.

Screen Example

*--: H ALL

5. File, Save, or Quit

You file, save, or quit in command mode. To save and quit the program, enterFI . To quit theprogram without saving it, enterEX or Q. After you quit the program, the ECL prompt reappear

Use the FIBCFN or ECL NEWPCODE command to dynamically activate a cataloged subrouYou can use a UniBasic shell to modify, recompile, recatalog, and retest a UniBasic programwithout returning to the ECL prompt.

More AE CommandsYou can enter any of the following basic AE editor commands when you are in command mo

Command Description

C/old.string/new.string Changes the current character string to a new characterstring on the current line.

More AE Commands

56 Developing UniBasic Applications

Page 57: Basd_52

Creating a Program with AE

R/old.string/new.string Replaces the current line with new text entered.

P Displays one page of the record.

HELP Displays online help for AE. You can also enter HELPfollowed by a topic or AE command.

I Changes to input mode so you can enter text.

EX or Q Quits the record without saving changes made duringthis editing session.

FI Files the program record and saves changes.

FIB Files the program record and compiles it.

FIBR Files the record, compiles it, and runs it.

Note - If the compile is unsuccessful, the program youexecute is an earlier version that does not includechanges in the most recent version.

FIR Files the record and runs the compiled version.

Note - Be aware that the version run can differ from theone you are editing.

FIBCFN The N option of the FI command equates to the ECLNEWPCODE command. FIBCFN compiles a programand catalogs it (locally) with NEWPCODE. You need touse F (force) in conjunction with the N option. For moreinformation, see the online help for the AE editor.

Tip - Use FIBCFN or ECL NEWPCODE todynamically activate a cataloged subroutine. You canuse a UniBasic “shell” to modify, recompile, recatalog,and retest a UniBasic program without exiting to ECL.

LNn Lists the number of lines specified, with no linenumbers.

Command Description

More AE Commands (continued)

Developing UniBasic Applications 57

Page 58: Basd_52

Chapter 3 - Creating and Running a Program

mand

TipDo you need to cut and paste lines in a program without the line numbers? AE offers the comLNn, which lists no line numbers.n is the number of lines to list.

n Goes to line numbern.

T Goes to the top of the record.

SPOOLHELP Prints brief help.

SPOOLHELP -FULL Prints extensive help.

ENTER Returns to command mode.

Command Description

More AE Commands (continued)

58 Developing UniBasic Applications

Page 59: Basd_52

Compiling a UniBasic Program

t

m,

Compiling a UniBasic Program

The UniBasic compiler processes UniBasic code into the interpretive code (also called objeccode) that is used by the UniBasic interpreter at runtime.

Compile CommandsYou can compile a program using the following commands:

• Compiling within AE – You can compile a program you are currently editing in AE byentering FIB at the command prompt. When you enter FIB, UniData saves the progracompiles it, files the compiled code, and returns you to the ECL prompt. For moreinformation about compiling from AE, see“Creating a Program with AE”earlier in thischapter.

• Compiling from ECL – The BASIC command compiles the program from the ECLprompt. For the syntax of the BASIC command, see“ECL BASIC Command Options”later in this chapter.

Directing the CompilerYou can direct the compiler to take some action during compilation with the following:

• ECL BASIC command options

• ECL and UniBasic commands

ECL BASIC Command Options

One way to direct the compiler is with ECL BASIC command options.

Syntax:

BASIC filename[TO filename] progname1[progname2...] [option]

Developing UniBasic Applications 59

Page 60: Basd_52

Chapter 3 - Creating and Running a Program

d.

e

n

The following table describes each parameter of the syntax.

The following table lists compile options available with the ECL BASIC command.

Parameter Description

filename Specifies the file from which the source program code is compile

Note - The compiled version is saved in_filename.

progname Specifies the source code program to be compiled and used withthe UniData Basic interpreter. If you do not enterprogname, and ifyou do not have a select list active, UniData prompts for a programname.

Tip - You can create a select list before executing BASIC; thiscompiles all programs in the select list. For example, to select allUniBasic source files in the BP directory, enter

SELECT BP WITH @ID UNLIKE "_..."

Then, enter

BASIC BP

UniData compiles all programs in BP.

option Specifies additional function(s) to be performed. You must choosand option and include the hyphen. For valid options, see theBASIC Command Optionstable.

BASIC Command Parameters

Option Description

-D Creates a symbol table for use with the UniBasic debugger. For more informatioabout the debugger, seeUsing the UniBasic Debugger.

-G Reports on execution time for the program, as described in“Reporting ExecutionTime” later in this chapter.

BASIC Command Options

60 Developing UniBasic Applications

Page 61: Basd_52

Compiling a UniBasic Program

ction

tin

a

eree

d in

n

ECL and UniBasic Commands

Some additional ECL and UniBasic commands are provided to instruct the compiler to take aof the following types:

• Select a compiler type.

• Define variables and include or exclude blocks of code.

Selecting a Compiler Type

You can tune your UniBasic program to be more compatible with other software that does nofollow UniData syntax. You can direct the compiler to do this from the ECL prompt or from witha UniBasic program, as follows:

• ECL BASICTYPE command, entered from the ECL prompt, sets the currentBASICTYPE to be used by the UniBasic compiler. You can also use this command tolearn which BASICTYPE is currently active or which BASICTYPE was used to compileprogram.

-I Compiles UniBasic reserved words regardless of the case in which they areentered (uppercase, lowercase, or mixed case). Without this option, the compilrecognizes uppercase reserved words. For a list of UniBasic reserved words, stheUniBasic Commands Reference.

-L-LIST

Generates a list of the program.

-X -L-XREF -L

Generates a cross-reference table of statement labels and variable names usethe program. For more information, see“Creating Cross-Reference Reports”laterin this chapter.

-Z1-Z2

Creates a symbol table for use with the UniBasic debugger. For more informatioabout the debugger, seeUsing the UniBasic Debugger.

-I If you compile a program with the -I option, all reserved words in UniBasic arecase insensitive.

Option Description

BASIC Command Options (continued)

Developing UniBasic Applications 61

Page 62: Basd_52

Chapter 3 - Creating and Running a Program

.CL

These

• UniBasic $BASICTYPE command, entered as the first line in a UniBasic program,determines the BASICTYPE to be used in the compilation of the program that follows$BASICTYPE in a UniBasic program overrides the BASICTYPE established at the Eprompt.

The following options are available for use with both BASICTYPE and $BASICTYPE.

For more information about the ECL BASICTYPE command, see theUniData CommandsReference. For more information about the compiler directive $BASICTYPE, see theUniBasicCommands Reference.

More Compiler Directives

Along with $BASICTYPE, UniData offers other compiler directives that you can use withinUniBasic programs to define variables and establish blocks of code based on the variables.directives are shown in the following table.

Parameter Description

U UniBasic

P Pick® BASIC

R Advanced Revelation® BASIC

M McDonnell Douglas BASIC/Reality® BASIC

$BASICTYPE Parameters

CompilerCommand Description

$DEFINEvar$UNDEFINEvar

Defines and clears a control variablevar.

More Compiler Directives

62 Developing UniBasic Applications

Page 63: Basd_52

Compiling a UniBasic Program

f

The constructions of these compiler directives are very similar to Boolean IF... THEN... ELSElogic. However, these compiler directives instruct the compiler to include or exclude blocks ocode based on the variables provided.

Compiler Directives Example

When you compile the following program, UniBasic compiles either the first section (line 4) toopen files for factory 1, or it compiles the second section (line 17) to open files for factory 2:

Program Example

comp_dir001: CANT.OPEN = ''002: $DEFINE FACT1003:004: $IFDEF FACT1005: OPEN 'PARTS1' TO PARTS ELSE006: CANT.OPEN<-1> = 'PARTS1'007: END

$IFDEFvarstatements1[$ELSEstatements2]$ENDIF

If var is defined, includestatements1in compiled code. Otherwise, includestatements2.

$IFNDEFvarstatements1[$ELSEstatements2]$ENDIF

If var is not defined, includestatements1in compiled code. Otherwise,includestatements2.

$INCLUDE$INSERT

Inserts the indicated UniBasic program or program segment into yourprogram during compilation. A common use is to insert frequently usedblocks of code or data into appropriate programs.

CompilerCommand Description

More Compiler Directives (continued)

Developing UniBasic Applications 63

Page 64: Basd_52

Chapter 3 - Creating and Running a Program

008:009: OPEN 'PURCHASE.ORDERS1' TO PURCHASE.ORDERS ELSE010: CANT.OPEN<-1> = 'PURCHASE.ORDERS1'011: END012:013: OPEN 'SALES.ORDERS1' TO SALES.ORDERS ELSE014: CANT.OPEN<-1> = 'SALES.ORDERS1'015: END016:017: $ELSE018:019: OPEN 'PARTS2' TO PARTS ELSE020: CANT.OPEN<-1> = 'PARTS2'021: END022:023: OPEN 'PURCHASE.ORDERS2' TO PURCHASE.ORDERS ELSE024: CANT.OPEN<-1> = 'PURCHASE.ORDERS2'025: END026:027: OPEN 'SALES.ORDERS2' TO SALES.ORDERS ELSE028: CANT.OPEN<-1> = 'SALES.ORDERS2'029: END030: $ENDIF031:032: IF CANT.OPEN THEN033: PRINT 'Cannot open file(s): '034: LOOP035: REMOVE FILE FROM CANT.OPEN SETTING MORE.FILES036: PRINT SPACE(5):FILE037: WHILE MORE.FILES REPEAT038: PRINT 'Stopping...':039: INPUT ANYTHING040: STOP041: END042: END

64 Developing UniBasic Applications

Page 65: Basd_52

Compiling a UniBasic Program

piler

objectple,

s you

es are

onlyessing.

Compiler MessagesThe UniBasic compiler displays both warning and error messages. If the compiler generateswarning messages only, it compiles the program and produces object code. However, if thecompiler generates any error messages, it does not produce object code. The last line of commessages indicates whether the program compiled successfully.

Object code is stored in the same DIR-type file as the source code. The record name for thecode is the same as that for the source code, but is prefixed with an underscore (_). For examthe source code record TEST1 generates object code record _TEST1.

Successful Compilation

After UniBasic successfully compiles a program, it displays a completion message and returnto the UniData colon (ECL) prompt. The following example demonstrates the successfulcompilation of program TEST1:

Screen Example

...Compiling Unibasic: BP/TEST1 in mode 'u'.compilation finished:

The compiler might return warning messages when compilation is successful. These messagpreceded by “Warning: ”.

NoteIf you run batch jobs to compile groups of programs, you need to code these jobs to terminatewhen error messages are returned by the compiler. Warning messages do not terminate proc

Developing UniBasic Applications 65

Page 66: Basd_52

Chapter 3 - Creating and Running a Program

t the

The following program prints a variable that is never assigned a value:

Screen Example

PROMPT ''PRINT @(-1)PRINT varPRINT "Enter record to update: "; INPUT answerOPEN 'STUDENT' TO STU ELSE PRINT "Can't open STUDENT file."READU RECORD FROM STU,answerLOCKED PRINT "Record locked by another user, waiting..." THEN

PRINT "I am locking the record now and going to sleep."FOR X = 1 TO 10

SLEEP 2NEXT X

ENDPRINT "Waking up now."RELEASEEND

The UniBasic compiler returns a warning message when it compiles this program. Notice thaprogram is compiled, and object code is produced.

Screen Example

Compiling Unibasic: BP/LOCKUP in mode 'u'.Warning: Variable 'var' never assigned a valuecompilation finished:

66 Developing UniBasic Applications

Page 67: Basd_52

Compiling a UniBasic Program

to

Unsuccessful Compilation

If UniBasic fails to compile a program, it returns the cursor to the colon (ECL) prompt.

The example that follows is a UniBasic program that contains the following errors:

• The variable answer is spelled two different ways. See lines 3 and 5.

• The FOR/NEXT loop beginning on line 8 contains a misspelling: “T” should be “TO.”

Screen Example

001: PROMPT ''002: PRINT @(-1)003: PRINT "Enter record to update: "; INPUT answer004: OPEN 'STUDENT' TO STU ELSE PRINT "Can't open STUDENT file."005: READU RECORD FROM STU,answr006: LOCKED PRINT "Record locked by another user, waiting..." THEN007: PRINT "I am locking the record now and going to sleep."008: FO R X = 1 T 10009: SLEEP 2010: NEXT X011: END012: PRINT "Waking up now."013: RELEASE014: END

The UniBasic compiler produces the following warning and error messages when it attemptscompile this program:

Screen Example

Compiling Unibasic: BP/LOCKUP in mode 'u'.main program: syntax error at or before<line 8> FO R X = 1 T 10

----------------^Expecting: array,string,number,function,variable,TO,OR,AND,!,>,>=,<,<=,=,<>,MATCH,CAT,:,+,-

main program: syntax error at or before<line 10> NEXT X

Developing UniBasic Applications 67

Page 68: Basd_52

Chapter 3 - Creating and Running a Program

uldwould

n theequentr of

enthe

and

-----^Expecting: end-of-line,END,;

Warning: Variable 'X' never assigned a valueWarning: Variable 'T' never assigned a valueWarning: Variable 'answr' never assigned a valuecompilation failed:

The missing “O” in “TO” causes the compiler to misinterpret line 8, the NEXT statement online10 is not matched, and two unassigned variable warning messages result. Finally, themisspelling of the “answer” variable produces an unassigned variable message.

If the only error in this program had been the misspelled variable, only warning messages wohave been displayed, and object code would have been produced. However, a runtime erroroccur if you tried to execute the program.

NoteSyntax errors are sometimes reported on a line following the actual error. This happens whestatement is incomplete, and the compiler looks for the remainder of the statement on a subsline. Also, combining multiple statements on the same line, or including an inordinate numbecomment lines could cause the line counter to be incorrect.

Creating Cross-Reference ReportsWith the UniBasic cross-reference capability, you can generate a table that describes statemlabels and variables. This capability is especially useful when you use it in conjunction with tUniBasic debugger.

You can use the cross-referencing feature by compiling programs with the BASIC commandthe -L (or -LIST) and -X -L (or -XREF -L) options, using the syntax introduced in“ECL BASICCommand Options”earlier in this chapter.

68 Developing UniBasic Applications

Page 69: Basd_52

Compiling a UniBasic Program

am,

d a

tinghech

r X.

which

Listing Included Code

When you use the -L (or -LIST) option, UniBasic generates a source code listing of the progrincluding all lines brought in with an $INSERT or $INCLUDE statement. UniBasic saves thelisting in the source directory with an underscore (_) prefix, followed by the program name anLIST suffix.

Listing Statements and Variables

When you use the -X -L (or -XREF -L) option, UniBasic produces a cross-reference report lisstatement label and variable names used in the program. The report states where and how tprogram uses its labels and variables by listing the name, type, reference, and function of eavariable.

• Name – Name of the label or variable used in the program, such as 100, PARTNO, o

• Type – Type of label or variable. UniData sorts the report by type starting with labelbecause its type is 0, and ending with equate because it has the highest type number,is 14. The cross-reference types are described in the following table.

Type Description

0 Label

1 Common area

2 Compiler @variable

3 Read-only @variable

4 @variable

5 Variable

6 Variable function

7 Common variable

8 One-dimensioned array

9 Two-dimensioned array

Cross-Reference Types

Developing UniBasic Applications 69

Page 70: Basd_52

Chapter 3 - Creating and Running a Program

their

• Reference – Line number on which the program refers to the label or variable.

• Function – UniBasic uses the function symbol to reference the variable. Symbols andfunctions are listed in the following table.

10 One-dimensioned array argument

11 Two-dimensioned array argument

12 One-dimensioned array in COMMON

13 Two-dimensioned array in COMMON

14 Equate

Symbol Function

* Definition of variable or label.

= Assignment of variable.

! Dimension of array.

@ Argument to called subroutine.

$ Variable or label is inside an INCLUDE or INSERT statement.

no symbol Simple reference such asIF X = 7 THEN.

Function Symbol References

Type Description

Cross-Reference Types (continued)

70 Developing UniBasic Applications

Page 71: Basd_52

Compiling a UniBasic Program

sting

Cross-Reference Report Examples

The following example shows the compile command with cross-referencing options and the liUniData generates using the -L option:

Screen Example

: BASIC BP -X -LPlease enter BASIC program file name: index.test

: SPOOL BP _index.test.LIST -TBP:

_index.test.LISTBP/index.test Source Listing0001 OPEN "INVENTORY" TO open.file ELSE PRINT "Open error." ;STOP0002 PRINT "Enter product to display: ";INPUT search_product0003 search_product = OCONV(search_product, "MCT")0004 new_product = search_product0005 SETINDEX "PROD_NAME", search_product ON open.file0006 IF NOT(STATUS()=0) THEN PRINT "Record not found.";STOP0007 LOOP UNTIL new_product <> search_product0008 READFWD dyn.array.var FROM open.file ELSE PRINT "Readfwd error."0009 new_product = EXTRACT(dyn.array.var,3)0010 IF new_product = search_product THEN PRINT "Record is: ":dyn.array.var0011 REPEAT0012 END

Developing UniBasic Applications 71

Page 72: Basd_52

Chapter 3 - Creating and Running a Program

The following example shows the output from the -X -L option:

Screen Example

: SPOOL BP _index.test.XREF -TBP:

_index.test.XREFBP/index.test Cross Reference Listing

Name....................... Type.. References...................................dyn.array.var 5 0008= 0009 0010new_product 5 0004= 0007 0009= 0010open.file 5 0001= 0005 0008search_product 5 0002= 0003= 0003 0004 0005

0007 0010

0 Label1 Common Area2 Compiler @ Variable3 Readonly @ Variable4 @ Variable5 Variable6 Variable Argument7 Common Variable8 One Dimension Array9 Two Dimension Array10 One Dimension Array Argument11 Two Dimension Array Argument12 Common One Dimension Array13 Common Two Dimension Array14 Equate

* Definition of Symbol= Assignment of Variable! Dimension of Array@ Argument to CALL$ Include or Insert statement

72 Developing UniBasic Applications

Page 73: Basd_52

Cataloging a UniBasic Program

s-mem-

rams

same

Cataloging a UniBasic Program

Cataloging UniBasic programs simplifies program execution and can improve efficiency of sytem resource use by letting multiple users access a single copy of a compiled program fromory. Use the ECL CATALOG command to catalog one or more UniBasic programs.

NoteFor more information about the CATALOG command, see theUniData Commands Reference. Formore information about managing catalogs, seeAdministering UniData on UNIXor AdministeringUniData on Windows NT or Windows 2000.

Compiled UniBasic programs can be cataloged directly, locally, or globally.

The process and options for cataloging a UniBasic program are introduced in the followingsections:

• “Points to Remember about CATALOG”

• “Direct Cataloging”

• “Local Cataloging”

• “Global Cataloging”

• “Using the ECL CATALOG Command”

• “Removing a Catalog Entry”

• “CATALOG Examples”

Points to Remember about CATALOGThe ECL CATALOG command copies the compiled code of a UniBasic program or list ofUniBasic programs into the system catalog. Some points to remember about cataloged progare listed below:

• When you catalog a program globally, more than one user can run the program at thetime, even though only one copy resides in system memory.

Developing UniBasic Applications 73

Page 74: Basd_52

Chapter 3 - Creating and Running a Program

e

thening

m

le.t the

to

gram

ompile

• You can use the ECL VCATALOG command to find out if your source code is the samversion as the cataloged program.

• A recataloged program is not available until the user who is recataloging it returns toECL prompt. You can use the ECL NEWPCODE command to ensure that you are runthe latest version.

NoteFor more information about NEWPCODE and VCATALOG, seeAdministering UniData on UNIXor Administering UniData on Windows NT or Windows 2000, and theUniData CommandsReference.

Direct CatalogingKeep in mind the following points about direct cataloging:

• Compiled code is located in the program file in the UniData account where the prograwas compiled and cataloged.

• The VOC file in the account contains a pointer to the compiled code in the program fiUsers in the same account can execute the program by entering the program name aECL prompt.

• Because users access the compiled code in the program file, developers do not needrecatalog the code if they recompile.

• When a user executes a directly cataloged program, UniData loads a copy of the prointo the address space of the user.

• Because users execute the programs from their own address space, one user can reca directly cataloged program while another user is running the program.

74 Developing UniBasic Applications

Page 75: Basd_52

Cataloging a UniBasic Program

-rd is

s inL

om-

ram

ompile

opy

onit,nd

bal

Local CatalogingKeep in mind the following points about local cataloging:

• Compiled code is located in the CTLG directory in the UniData account where the program was cataloged, as well as in the program file. CTLG is a directory, and each recoa compiled UniBasic program.

• The account’s VOC file contains a pointer to the compiled program in the CTLG. Userthe same account can execute the program by entering the program name at the ECprompt.

• Developers must recatalog a program after recompiling, to place a new copy of the cpiled code into the CTLG.

• When a user executes a locally cataloged program, UniData loads a copy of the proginto the user’s address space.

• Because users execute the programs from their own address space, one user can reca directly cataloged program while another user is running the program.

Global CatalogingKeep in mind the following points about global cataloging:

• When a user tries to globally catalog a UniBasic program, UniData checks to see if a cof the program resides in memory.

• If a copy exists in memory, a process is currently executing either the program inquestion or a program that called the program in question. The program in questicannot be recataloged until all processes executing it, or all programs that calledhave completed. UniData displays an error message, and the CATALOG commafails.

• If a copy does not exist in memory, no one is currently executing it and no programthat is still running has called it. UniData copies the new compiled code into the glocatalog.

• Global cataloging is the default. If you execute the CATALOG command withoutspecifying local or direct cataloging, your program is globally cataloged.

Developing UniBasic Applications 75

Page 76: Basd_52

Chapter 3 - Creating and Running a Program

is

reames

oged

ltiple

ugh

in thet, or

• Compiled code is located in a system wide global catalog. The default global catalog/udthome/sys/CTLG (for UNIX) or \udthome\sys\CTLG (for Windows NT or Windows2000).

• Even though Windows NT or Windows 2000 do not require file and path names that acase sensitive, UniData uses case-sensitive strings for comparing and searching for nin cataloged programs.

• Developers must recatalog a program after recompiling, to place a new copy of thecompiled code into the global catalog.

• To run a globally cataloged program if you have a program with the same name catallocally or directly, precede the program name with an asterisk, as in *prog.name.

NoteA UniData installation can have more than one global catalog space.udthomedetermines whichglobal catalog space a particular UniData session accesses. For more information about muglobal catalog spaces, seeAdministering UniData on UNIXor Administering UniData onWindows NT or Windows 2000.

• A system-wide global catalog space is a directory with 26 subdirectories named A throZ. Compiled code is stored in the subdirectory corresponding to the first letter of theprogram name. Cataloged programs that begin with nonalpha characters are storedsubdirectory named X. The program name can be the same as the source and objecyou can specify a different name when you execute the CATALOG command.

TipConsider your program naming conventions if you are using global cataloging. Because thecompiled code is placed in subdirectories according to name, you could have an unbalancedsituation if a large number of your program names begin with the same letter (for instance, ageneral ledger application in which all the files begin with “gl”).

• A globally cataloged program is available to users in all UniData accounts.

• When a user executes a globally cataloged program, UniData checks to see if a copyalready exists in shared memory.

76 Developing UniBasic Applications

Page 77: Basd_52

Cataloging a UniBasic Program

.

py of

c

be

ne

• If so, UniData notifies the udt process where to locate the copy in shared memory

• If not, UniData loads a copy into shared memory for the user to execute.

Using the ECL CATALOG CommandTo catalog a program, enter the following command at the ECL prompt:

Syntax:

CATALOG file.name cat.name prog.name[LOCAL | DIRECT] [FORCE][NEWVERSION | newversion]

By default, cataloged code is placed in the program directory with the source code and in thesystem global catalog. This makes the program available to all accounts. Users share one cothe cataloged code.

The following table describes each parameter of the syntax.

Option Features

file.name Specifies the file containing the program to be cataloged. Usually a basiprogram (BP) file.

cat.name Specifies the name of the system catalog into which the object code is tocopied.

prog.name Specifies the UniBasic program containing object code to be cataloged.

GLOBAL This is the default option (do not specify it in the CATALOG command);the compiled code is placed in the program file and in the system globalcatalog. This makes the program available to all accounts. Users share ocopy of the compiled code.

LOCAL Compiled code is located in the program file and in local catalog space.The LOCAL option is available on the local account. To use it fromanother account, catalog it in the other account also.

Catalog Command Options

Developing UniBasic Applications 77

Page 78: Basd_52

Chapter 3 - Creating and Running a Program

lynt

am

it

ReminderYou can execute a cataloged program from the ECL prompt or from any UniBasic program.

Removing a Catalog EntryUse the ECL DELETE.CATALOG command to remove a cataloged program. For moreinformation about this command, see theUniData Commands Reference.

DIRECT The compiled code is placed in the program file only and is available onon the local account. To use it on another account, catalog it in that accoualso; recataloging is not required when you recompile the program.

FORCE Replace a cataloged program without prompting.

NEWVERSIONnewversion

Directs the shared basic code server (sbcs) to replace the current progrversion in shared memory with the new version just cataloged. To useNEWVERSION, you must have root privileges on UNIX or Administratorprivileges on Windows NT or Windows 2000.

Tip - The N option of the Alternate Editor (AE) FI command equates toNEWPCODE. For example, FIBCFN compiles a program and catalogs(locally) with NEWPCODE. You need to use F (force) in conjunction withthe N option. For more information, see the online help for AE.

Note - For more information about the NEWVERSION option, seeAdministering UniData on UNIXor Administering UniData on WindowsNT or Windows 2000.

Option Features

Catalog Command Options (continued)

78 Developing UniBasic Applications

Page 79: Basd_52

Cataloging a UniBasic Program

talog

CATALOG ExamplesThe following example shows the FORCE option to globally catalog the object code of theprogram CUST.XREF, whose source code is located in the BP.UTIL directory file:

Screen Example

: CATALOG BP.UTIL CUST.XREF FORCE

The next example shows the CATALOG command without the FORCE option. Because theprogram GPA was already cataloged, UniData requests verification before proceeding to recathe item.

Screen Example

: CATALOG BP GPA/usr/ud/sys/CTLG/GPA exists, do you want to overwrite?(Y/N) Y

The following example lists the contents of the CTLG file in the demo database:

Screen Example

:LIST CTLGLIST CTLG 17:39:37 Aug 04 1999 1CTLG......

AddRecordDelRecordDUMMYEXAMPLEFndRecordUpdRecord6 records listed:

Developing UniBasic Applications 79

Page 80: Basd_52

Chapter 3 - Creating and Running a Program

.

ReminderYou must compile your programs successfully before you can catalog them.

In the next example, UniData catalogs the compiled object code of the PSTLCODE_FMTprogram locally. Afterwards, notice the following:

• The local CTLG directory shows an entry for PSTLCODE_FMT.

• A VOC pointer exists that shows a path to a copy of the program (in this case,\UniData\demo\CTLG) and shows where the program source is kept (BP_SOURCE)

Screen Example

:CATALOG BP_SOURCE PSTLCODE_FMT LOCAL:LIST CTLGLIST CTLG 17:39:37 Aug 04 1999 1CTLG......

AddRecordDelRecordDUMMYEXAMPLEFndRecordPSTLCODE_FMTUpdRecord7 records listed:CT VOC PSTLCODE_FMTVOC:

PSTLCODE_FMT:CD:\UNIDATA\DEMO\CTLG\PSTLCODE_FMTBP_SOURCE PSTLCODE_FMT:

80 Developing UniBasic Applications

Page 81: Basd_52

Cataloging a UniBasic Program

OCRECT

TEnd.

In the next example, UniData directly catalogs the PSTLCODE_FMT program. Compare the Vrecord to the previous example, and notice how the path to the program has changed. The DIkeyword causes UniData to create a VOC pointer that points to the file in which the programresides. UniData does not place a copy of the program in either CTLG directory.

Screen Example

:CATALOG BP_SOURCE PSTLCODE_FMT DIRECTPSTLCODE_FMT has been cataloged, do you want to overwrite(Y/N)? Y:CT VOC PSTLCODE_FMTVOC:

PSTLCODE_FMT:CBP_SOURCE\_PSTLCODE_FMT:

TipTo remove a copy of a program from the local or system CTLG directory, use the ECL DELEcommand or DELETE.CATALOG. In ECLTYPE P, you also can use the DECATALOG comma

Developing UniBasic Applications 81

Page 82: Basd_52

Chapter 3 - Creating and Running a Program

AE

on

twoto

,

ther its

Running a UniBasic Program

You can run a program from AE or from ECL.

Running a Program from AETo compile and run a program you are currently editing, enter the AE command FIBR at thecommand prompt. UniData compiles and files the program, runs the compiled version, anddisplays the ECL prompt. If compilation is unsuccessful, the last successfully compiled versiruns.

ReminderThe FIR command files the source code you are editing and runs the compiled version. Theversions will be different if you have modified the program since the last compilation. Be sureuse the AE command FIBR to compile, file, and run the program.

Running a Program from ECLThe RUN command tells UniData to run a compiled UniBasic program. If the program is notglobally cataloged, you must specify the directory file that contains the program (for exampleBP).

Syntax:

RUN directory.file program.name[-option]

If the program is globally cataloged, you must have a pointer to the directory file that containsprogram in your VOC file to execute the globally cataloged version. To run the program, entecataloged name at the ECL prompt.

Syntax:

catalog.name[-option]

82 Developing UniBasic Applications

Page 83: Basd_52

Running a UniBasic Program

L

In addition, you can run a program that is locally cataloged by entering the its name at the ECprompt. UniBasic programs are usually stored in the BP directory.

Syntax:

program.name[-option]

RUN Options

The following table describes the options [-option] in the syntax for running a program.

ReminderSeveral of the following RUN options invoke the UniBasic Debugger. To make full use of thedebugger, you must prepare your program as explained in theUsing the UniBasic Debugger.

Option Description

-D Invokes the UniBasic debugger immediately before theprogram executes.

-E Invokes the UniBasic debugger when a warning or runtimeerror occurs.

-F Invokes the UniBasic debugger when a fatal error occurs.

-D -E Invokes the UniBasic debugger immediately. After youexecute the program from the debugger, if UniDataencounters a warning or runtime error, UniData returns tothe debugger.

-D -F Invokes the UniBasic debugger immediately. After youexecute the program from the debugger, if UniDataencounters a fatal error, UniData returns to the debugger.

-G Creates a cross-reference report (program profile). Forfurther information, see“Reporting Execution Time”laterin this chapter.

Program Run Options

Developing UniBasic Applications 83

Page 84: Basd_52

Chapter 3 - Creating and Running a Program

tion.

re of

me

UDT.OPTIONSYou can determine how UniBasic sets an uninitialized variable with UDT.OPTIONS 15 on forempty string or off for zero. For more information about UDT.OPTIONS, see theUDT.OPTIONSCommands Reference.

Reporting Execution Time

UniData generates a program profile report when you run or execute a program with the -G opIf you previously compiled the program with the -G option, the profile also reports on internalsubroutines. UniData creates two reports that it stores in the current directory. Both reports athe same format, and are named as follows:

• "profile."@USERNO (for UNIX) or "profile."pid (for Windows NT or Windows 2000)– Calculates CPU execution time. For example, the fileprofile.3 would be a report ofCPU time generated for the user whose user number is 3.

• "profile.elapse."@USERNO (for UNIX) or "profile.elapse."pid (for Windows NT orWindows 2000) – Calculates real execution time (CPU and I/O). For example,profile.elapse.3 would be the corresponding report of real execution time for the sauser.

-N Displays output without pausing at the bottom of thescreen. Without this option, scrolling stops at the bottomof each page, prompting the user to press ENTER tocontinue.

Tip - Use UDT.OPTIONS 32 to direct UniData to retain orsuppress the HEADING statement when the “no page”option is used.

-P Routes all program output to the system printer.

-S Suppresses warning messages.

Option Description

Program Run Options (continued)

84 Developing UniBasic Applications

Page 85: Basd_52

Running a UniBasic Program

D

,

shedoresber;

NoteFor Windows NT or Windows 2000, run the LISTUSER command to determine the process I(pid). It is listed as USRNBR.

For more information about program profiling, seeAdministering UniData on UNIXorAdministering UniData on Windows NT or Windows 2000.

Layout of Profile Reports

Summary Section – Summary statistics regarding execution time are listed for each programsubroutine, and called program; entries are sorted by decreasing execution time.

Body Section – Each program or subroutine is assigned an identifying index number, indescending order of execution time. Each index is analyzed in a subsection delineated by dalines. Within the subdivided sections, the first column lists the index number for the programsubroutine analyzed in that section. Parent programs and subroutines are analyzed on the linpreceding the index number; the indexed item is analyzed on the line containing the index numand child programs or subroutines are analyzed on subsequent lines.

The following UNIX example is the profile report for the UPDATE_ORDER program in“Appendix A - Sample Program”:

Screen Example

%time cumsecs seconds calls name

%time cumsecs seconds calls name

25.0 0.02 0.02 1 BP/_UPDATE_ORDER25.0 0.04 0.02 3 BP/_UPDATE_ORDER:DISPLAY_SCREEN25.0 0.06 0.02 2 BP/_UPDATE_ORDER:DISPLAY_DATA25.0 0.08 0.02 1 BP/_UPDATE_ORDER:ALTER_RECORD

0.0 0.08 0.00 1 BP/_UPDATE_ORDER:OPEN_FILES0.0 0.08 0.00 1 BP/_UPDATE_ORDER:INITIALIZE0.0 0.08 0.00 3 BP/_UPDATE_ORDER:GET_ORDER_NUMBER0.0 0.08 0.00 1 /users/ud_51/sys/CTLG/d/DISPLAY_MESSAGE0.0 0.08 0.00 1 BP/_UPDATE_ORDER:GET_RECORD_COMMAND0.0 0.08 0.00 1 BP/_UPDATE_ORDER:WRITE_RECORD0.0 0.08 0.00 1 BP/_UPDATE_ORDER:EXIT

Developing UniBasic Applications 85

Page 86: Basd_52

Chapter 3 - Creating and Running a Program

called/total parentsindex %time self descendents called+self name index

called/total children<spontaneous>

[1] 100.0 0.02 0.06 1 BP/_UPDATE_ORDER [1]0.02 0.00 3/3 BP/_UPDATE_ORDER:DISPLAY_SCREEN

[2]0.02 0.00 2/2 BP/_UPDATE_ORDER:DISPLAY_DATA

[3]0.00 0.02 1/1

BP/_UPDATE_ORDER:GET_RECORD_COMMAND [5]0.00 0.00 1/1 BP/_UPDATE_ORDER:OPEN_FILES [6]0.00 0.00 1/1 BP/_UPDATE_ORDER:INITIALIZE [7]

0.00 0.00 3/3BP/_UPDATE_ORDER:GET_ORDER_NUMBER [8]

0.00 0.00 1/1 BP/_UPDATE_ORDER:EXIT [11]----------------------------------------------

0.02 0.00 3/3 BP/_UPDATE_ORDER [1][2] 25.0 0.02 0.00 3 BP/_UPDATE_ORDER:DISPLAY_SCREEN[2]----------------------------------------------

0.02 0.00 2/2 BP/_UPDATE_ORDER [1][3] 25.0 0.02 0.00 2 BP/_UPDATE_ORDER:DISPLAY_DATA [3]

0.00 0.00 1/1/users/ud_51/sys/CTLG/d/DISPLAY_MESSAGE [9]----------------------------------------------

0.02 0.00 1/1BP/_UPDATE_ORDER:GET_RECORD_COMMAND [5][4] 25.0 0.02 0.00 1 BP/_UPDATE_ORDER:ALTER_RECORD [4]

0.00 0.00 1/1 BP/_UPDATE_ORDER:WRITE_RECORD[10]----------------------------------------------

0.00 0.02 1/1 BP/_UPDATE_ORDER [1][5] 25.0 0.00 0.02 1BP/_UPDATE_ORDER:GET_RECORD_COMMAND [5]

0.02 0.00 1/1 BP/_UPDATE_ORDER:ALTER_RECORD[4]----------------------------------------------

0.00 0.00 1/1 BP/_UPDATE_ORDER [1][6] 0.0 0.00 0.00 1 BP/_UPDATE_ORDER:OPEN_FILES [6]----------------------------------------------

86 Developing UniBasic Applications

Page 87: Basd_52

Running a UniBasic Program

0.00 0.00 1/1 BP/_UPDATE_ORDER [1][7] 0.0 0.00 0.00 1 BP/_UPDATE_ORDER:INITIALIZE [7]----------------------------------------------

0.00 0.00 3/3 BP/_UPDATE_ORDER [1][8] 0.0 0.00 0.00 3 BP/_UPDATE_ORDER:GET_ORDER_NUMBER[8]----------------------------------------------

0.00 0.00 1/1 BP/_UPDATE_ORDER:DISPLAY_DATA[3][9] 0.0 0.00 0.00 1/users/ud_51/sys/CTLG/d/DISPLAY_MESSAGE [9]----------------------------------------------

0.00 0.00 1/1 BP/_UPDATE_ORDER:ALTER_RECORD[4][10] 0.0 0.00 0.00 1 BP/_UPDATE_ORDER:WRITE_RECORD [10]----------------------------------------------

0.00 0.00 1/1 BP/_UPDATE_ORDER [1][11] 0.0 0.00 0.00 1 BP/_UPDATE_ORDER:EXIT [11]----------------------------------------------

----------------------------------------------

The summary section of the report provides information in the following columns.

Parameter Description

%time Percentage of the total runtime used by this program orsubroutine.

cumsecs Execution time, in number of seconds, for this program orsubroutine and all called programs and subroutines.

seconds Execution time, in number of seconds, for this program orsubroutine alone.

calls Number of times this program or subroutine is called.

name Name of the program or subroutine.

Program Profile – Summary

Developing UniBasic Applications 87

Page 88: Basd_52

Chapter 3 - Creating and Running a Program

.

The body of the report provides information in the following columns.

The tables that follow the next example explain the detail report lines for item [3] in the reportThe subject lines are repeated here.

Parameter Description

index An identifying number assigned to this program or subroutine.Index numbers are assigned in descending order of execution time.

%time Percentage of the total program runtime used by this program orsubroutine and its descendents.

self Execution time for this program or subroutine.

descendents Execution time for descendents of this program or subroutine.

called Line contents differ according to the line of the subsection you arereading:

• called/total – Lines preceding the index analyze parents; listsnumber of times this index is called by the parent listed in thename field.

• called+self – Line containing the index; lists number of times theroutine is called and the number of times it calls itself.

• called/total – Lines following the index number analyze childrenand descendents; lists number of times this index calls the childlisted in the name field.

name Name of the program or subroutine analyzed in this row of thereport subsection.

index Index identifying the program or subroutine listed in the namefield.

Program Profile – Body

88 Developing UniBasic Applications

Page 89: Basd_52

Running a UniBasic Program

Screen Example

called/total parentsindex %time self descendents called+self name index

called/total children<spontaneous>

----------------------------------------------0.02 0.00 2/2 BP/_UPDATE_ORDER [1]

[3] 25.0 0.02 0.00 2 BP/_UPDATE_ORDER:DISPLAY_DATA [3]0.00 0.00 1/1

/users/ud_51/sys/CTLG/d/DISPLAY_MESSAGE [9]----------------------------------------------

The following table describes the first line of the preceding report segment.

Data Column Description

0.02 self The execution time for parent (callingprogram); in this case,BP/_UPDATE_ORDER.

0.00 descendents The execution time for parent (callingprogram); in this case,BP/_UPDATE_ORDER.

2/2 called/total The number of times parentBP/_UPDATE_ORDER

calledBP/_UPDATE_ORDER:DISPLAY_DATA.

BP/_UPDATE_ORDER parents The parent (calling subroutine).

[1] index The index number forBP/_UPDATE_ORDER.

Program Profile Detail: First Line

Developing UniBasic Applications 89

Page 90: Basd_52

Chapter 3 - Creating and Running a Program

The next table describes the second line of the preceding report segment.

The final table describes the third line of the preceding report segment.

Data Column Description

[3] index The index number forBP/_UPDATE_ORDER:DISPLAY_DATA.

25.0 %time The percentage of the total programruntime used byBP/_UPDATE_ORDER:DISPLAY_DATA.

0.00 self The execution time forBP/_UPDATE_ORDER:DISPLAY_DATA.

0.02 descendents The execution time for/users/ud_52/sys/CTLG/d/DISPLAY_MESSAGE .

BP/_UPDATE_ORDER:DISPLAY_DATA

name The name of this subroutine.

[3] index number The index number forBP/_UPDATE_ORDER:

DISPLAY_DATA.

Program Profile Detail: Second Line

Data Column Description

0.00 self The execution time for child (called program);in this case,/users/ud_52/sys/CTLG/d/

DISPLAY_MESSAGE.

0.00 descendents The execution time for child (called program);in this case,/users/ud_52/sys/CTLG/d/

DISPLAY_MESSAGE.

Program Profile Detail: Third Line

90 Developing UniBasic Applications

Page 91: Basd_52

Running a UniBasic Program

1/1 called/total The number of times parentBP/_UPDATE_ORDER:DISPLAY_DATAcalled child/users/ud_52/sys/CTLG/d/DISPLAY_MESSAGE .

/users/ud_52/sys/CTLG/d/DISPLAY_MESSAGE

child The name of this child (called program).

[9] index The index number for/users/ud_52/sys/CTLG/d/

DISPLAY_MESSAGE.

Data Column Description

Program Profile Detail: Third Line (continued)

Developing UniBasic Applications 91

Page 92: Basd_52

Chapter 3 - Creating and Running a Program

92 Developing UniBasic Applications

Page 93: Basd_52

Chapter 4 - MaintainingData in Files

rthe

This chapter provides the information you need to select the correct command or function fomaintaining data in files through UniBasic programs. For the syntax of these commands, seeUniBasic Commands Reference.

Developing UniBasic Applications 93

Page 94: Basd_52

Chapter 4 - Maintaining Data in Files

the

In This Chapter

This chapter introduces the concepts and commands you use to maintain files. It consists offollowing sections:

• “UniData Locks”

• “Database Triggers”

• “Maintaining Files”

• “UniData Hashed Data Files”

• “Alternate Key Indexes”

• “Non-UniData Sequential Files”

• “Opening Files”

• “Selecting Records”

• “Reading, Writing, and Deleting Data from Files”

• “Closing Files”

• “Accessing Data in Unopened Files”

94 Developing UniBasic Applications

Page 95: Basd_52

UniData Locks

user

eck,e. For

or

UniData Locks

In a multiuser system, record and file locks, when used consistently, prevent more than onefrom accessing the same record at the same time.

UniBasic locks are advisory only. You must observe locking conventions consistently in all ofyour applications to prevent one user from overwriting another user’s updates.

You can use resource locks to reserve computer resources for your exclusive use. To set, chand release UniBasic locks, you must use the commands specifically created for the purposinformation about using UniBasic locks, see“Chapter 5 - Using UniData Locks.”

TipAnother way to ensure consistency among files is through UniData transaction processing. Fmore information, see“Chapter 9 - UniBasic Transaction Processing.”or “Appendix B - UniBasicTransaction Processing Concepts.”

Developing UniBasic Applications 95

Page 96: Basd_52

Chapter 4 - Maintaining Data in Files

ecord.s

nst

access

e

f

canbe

iles

n a

Database Triggers

A database trigger specifies a UniBasic subroutine to call when a user attempts to access a rThe UniBasic subroutine can then allow or prevent access. Triggers are tied to record update(modifying or inserting) and deletions.

A UniData trigger can be used to validate an attempt to make a change to the database agaiuser-defined constraints, or “business rules,” and allow the change only if the constraint issatisfied. Triggers are associated with the data file, so the business rules are applied to anyto the file or record, not just access through a particular application. For instance, a triggersubroutine might allow only certain users to update records in a UniData file, or prevent somrecords from being updated at all, or prevent entry of the null value.

Trigger RulesUniData triggers are governed by the following rules:

• A UniData trigger must be a globally cataloged UniBasic subroutine.

• When running Network File Access (NFA), the trigger subroutine and the trigger itselmust reside on the server where the hashed file resides, not on the host.

• UniData triggers are activated before the update or delete.

• A trigger can invoke another trigger. UniData does not limit the number of levels younest triggers. Be careful to use conditional statements to avoid infinite loops that cancaused by nested triggers.

• You can call an external C routine from a trigger.

• File types:

• Hashed files – You can use triggers only with static or dynamic hashed files. The fcan be recoverable or nonrecoverable.

• No DIR or multilevel directories – You cannot set a trigger on a DIR file or a multi-level directory. You can associate triggers with the static or dynamic subfiles withimultilevel file, but not with the multilevel file itself.

• Writing from a trigger subroutine:

96 Developing UniBasic Applications

Page 97: Basd_52

Database Triggers

lly

ainsst

triggerow to

rwedile.

r you

nds

• Writes allowed to DIR files – You can write to a directory file from within a triggersubroutine. You might want to do so to create a log of trigger operations.

• Writes allowed to hashed files – You can include write commands within a triggersubroutine.

The Nature of TriggersTriggers are composed of the trigger definition, which is stored in the file header, and a globacataloged UniBasic subroutine that is called when you attempt to update or delete a record.

Use the ECL CREATE.TRIGGER command to define a trigger. If the file header already conta trigger by the same name, UniData does not overwrite the existing trigger. Instead, you mudelete the existing trigger before you can create the new one.

Three ECL commands let you create, delete, and list triggers. Note that these changes to thein the file header do not affect the UniBasic subroutine. Command syntax and details about hcode these commands follow this section.

The UniBasic trigger subroutine can contain any operation on a file, including writing to it. Foexample, the subroutine could stipulate that certain kinds of record modifications are not allofor a file, or it might place restrictions on whether users can delete records from a particular fYou can change the underlying trigger subroutine without having to delete and re-create thetrigger.

NoteTo create or delete a trigger, you must be the owner of the file at the operating system level, omust have root privileges on UNIX or Administrator privileges on Windows NT or Windows2000.

ECL Commands and TriggersThis section discusses ECL command that create or maintain triggers, and lists ECL commathat are affected by triggers.

Developing UniBasic Applications 97

Page 98: Basd_52

Chapter 4 - Maintaining Data in Files

, see

ne.

ct

wing

ECL Commands That Create or Maintain Triggers

The following ECL commands create or maintain triggers. For the syntax of these commandstheUniData Commands Reference.

• CREATE.TRIGGER – Creates a trigger in a file header that calls a UniBasic subrouti

• DELETE.TRIGGER – Deletes the trigger definition from a file header. It does not affethe UniBasic trigger subroutine.

• LIST.TRIGGER – Displays a list of triggers.

ECL Commands Affected by Triggers

The UniData triggers feature has an impact on how some ECL commands behave. The follocommands have changed behavior. For the syntax of these commands, see theUniDataCommands Reference.

• CLEAR.FILE

• COPY

• DELETE

• ED

• MODIFY

• UNIENTRY

UniBasic Commands Affected by TriggersThe following UniBasic commands invoke triggers:

• DELETE

• DELETEU

• WRITE

• WRITEU

• WRITEV

98 Developing UniBasic Applications

Page 99: Basd_52

Database Triggers

• WRITEVU

If a trigger returns a constraint violation, control is passed to the ON ERROR clause of thecommand, if one exists. If no ON ERROR clause is included in the command, the UniBasicprogram aborts.

Developing UniBasic Applications 99

Page 100: Basd_52

Chapter 4 - Maintaining Data in Files

itthe

s of

ing

r

a

-

TipThe UniBasic STATUS function returns the status of the preceding command. You can placewithin the trigger subroutine to learn about the status of individual commands executed withintrigger. If you place it immediately after the statement that calls the trigger, it returns the statuthe UniBasic command as determined by the trigger. These values are listed in“UniBasic STATUSFunction Return Values”later in this chapter. The trigger subroutine also returns a value indicatits status in the parameterexecstat; the values returned inexecstatare listed in the Parameterssections for the UPDATE and DELETE trigger subroutines.

Writing an UPDATE Trigger SubroutineA UniBasic subroutine or function serves as the UPDATE trigger that is executed when a useattempts to update a record in the subject file.

TipYou can call an external C routine from the UniBasic subroutine or function that is called fromtrigger.

Subroutine

The following SUBROUTINE definition must be the first noncomment line in the UniBasic trigger subroutine.

Syntax:

SUBROUTINE trigname(execstat, dictflag, filename, record.ID.expr, recordval)

The parameters in this statement are defined later in this section.

Function

The following FUNCTION definition must be the first line in the UniBasic trigger function.

Syntax:

FUNCTION trigname(dictflag, filename, record.ID.expr, recordval)

100 Developing UniBasic Applications

Page 101: Basd_52

Database Triggers

The function must include the following statement:

RETURNexcstat

Parameters

The following table describes each parameter of the syntax.

Parameter Description

trigname The name of the globally cataloged subroutine.

execstat The execution status returned by the trigger subroutine:

• 0 – No updates are allowed.

• 1 – Updates are allowed.

• 2 – Updates are allowed, using the returnrecordval.

dictflag • “DICT” – Indicates that the trigger is operating on thedictionary file.

• “” – Indicates that the trigger is operating on the datafile.

Note - The quotation marks are required.

filename The name of the file on which the trigger is operating.

record.ID.expr The record to be updated.

Trigger Parameters

Developing UniBasic Applications 101

Page 102: Basd_52

Chapter 4 - Maintaining Data in Files

e

UPDATE Trigger Example

The following example begins with an UPDATE trigger subroutine called TRIG1. Because threturn status is always 5, no record in the file can be updated.

Program Example

SUBROUTINE TRIG1(exec.stat,dict.flag,trig.name,rec.id.expr,rec.val)exec.stat=5RETURN

recordval The input record value submitted to the UPDATEtrigger.recordvalis both an input and output parameter.The trigger can change this value (for example, byperforming a conversion). Then, if the trigger setsexecstatto 2, this value is passed back inrecordvalandupdates the data record. Only strings and numbers arevalid.

Note - If the value returned inrecordvalis invalid, therecord is not updated, even if the trigger subroutine setsexecstatto 2. In this case, the UniBasic STATUSfunction returns 3 when executed immediately after thecommand that calls the trigger. Only strings andnumbers are valid.

Parameter Description

Trigger Parameters (continued)

102 Developing UniBasic Applications

Page 103: Basd_52

Database Triggers

with

r

a

Next, we create the trigger, associate it with the ORDERS file, and list the triggers associatedthe ORDERS file:

Screen Example

: CREATE.TRIGGER ORDERS TRIG1 UPDATE: LIST.TRIGGER ORDERSBEFORE UPDATE TRIGGER: TRIG1BEFORE DELETE TRIGGER: not defined

Finally, we attempt to copy record 969 into record 970 in the ORDERS file, and the triggerprevents the copy:

Screen Example

:COPY FROM ORDERS TO ORDERS 969,970Cannot update 970, due to trigger constraint.0 records copied

Writing a DELETE Trigger SubroutineA UniBasic subroutine or function serves as the DELETE trigger that is executed when a useattempts to delete a record in the subject file.

TipYou can call an external C routine from the UniBasic subroutine or function that is called fromtrigger.

Developing UniBasic Applications 103

Page 104: Basd_52

Chapter 4 - Maintaining Data in Files

e.

Subroutine

The following SUBROUTINE definition must be the first line in the UniBasic trigger subroutin

Syntax:

SUBROUTINE trigname(execstat, dictflag, filename, record.ID.expr)

The parameters in this statement are listed later in this section.

Function

The following FUNCTION definition must be the first line in the UniBasic trigger function.

Syntax:

FUNCTION trigname(dictflag, filename, record.ID.expr)

The function must include the following statement:

RETURNexecstat

Parameters

The following table describes each parameter of the syntax.

Parameter Description

trigname The name of the globally cataloged subroutine.

execstat The execution status returned by the trigger subroutine.Valid values for this include:

• 0 – Delete is not allowed

• 1 – Delete is allowed

Trigger Parameters

104 Developing UniBasic Applications

Page 105: Basd_52

Database Triggers

ys

DELETE Trigger Example

The following example begins with a DELETE trigger subroutine called DEL_TRIG that alwareturns 1 and always allows records to be deleted:

Program Example

SUBROUTINE DEL_TRIG(exec.stat,dict.flag,trig.name,rec.id.expr,rec.val)exec.stat=1RETURN

ReminderAfter creating and compiling the subroutine, you must catalog it globally.

Next, we create the trigger and associate it with the ORDERS file:

Screen Example

: CREATE.TRIGGER ORDERS DEL_TRIG DELETE

dictflag • “DICT” – Indicates that the trigger is operating on thedictionary file.

• “” – Indicates that the trigger is operating on the datafile.

Note - The quotation marks are required.

filename The name of the file the trigger is operating on.

record.ID.expr The record to be deleted.

Parameter Description

Trigger Parameters (continued)

Developing UniBasic Applications 105

Page 106: Basd_52

Chapter 4 - Maintaining Data in Files

e the

t the

Finally, we delete records in the ORDERS file. The trigger always allows the deletion becaussubroutine sets the execution status to 1.

Screen Example

: DELETE ORDERS 912'912' deleted.:

UniBasic STATUS Function Return ValuesThe UniBasic STATUS function returns values that give information about trigger operations.

NoteMost UniBasic commands and some ECL commands, within a trigger or outside a trigger, sevalue of STATUS.

ReturnValue Description

0 No error.

1 System error, such as a damaged file.

2 Constraint violation. In this case, the UniBasic trigger subroutinereturns a value of 0 in the parameterexcstat, indicating that theupdate or delete is not allowed.

3 Trigger execution error or unexpected return from trigger routine (forexample, trigger subroutine is not cataloged).

STATUS Function Values

106 Developing UniBasic Applications

Page 107: Basd_52

Database Triggers

rse anysent.

WarningWhen you write UniBasic programs or subroutines, always include the ON ERROR clause fostatements that update hashed files. This is especially important when using triggers, becaufailure caused by a trigger aborts the UniBasic program unless the ON ERROR clause is pre

TroubleshootingIf a trigger does not work correctly, check the following:

• Debug and test trigger subroutines.

• Check the return values. Are they what UniData expects?

• Is the trigger subroutine cataloged?

Developing UniBasic Applications 107

Page 108: Basd_52

Chapter 4 - Maintaining Data in Files

on-

or a

Maintaining Files

You can write UniBasic programs to maintain hashed data files, alternate key indexes, and nUniData sequential files. The following sections describe how to maintain them:

• “UniData Hashed Data Files”

• “Alternate Key Indexes”

• “Non-UniData Sequential Files”

UniData Hashed Data FilesThe types of UniData files that you can maintain with UniBasic programs are introduced in“Chapter 1 - Introduction to UniBasic.”This section suggests the steps you might follow tomaintain files.

Maintaining UniData Hashed Files

The following procedure is one that you might follow when updating a UniData hashed file. (Fsample program, see“Appendix A - Sample Program.”)

1. Use the OPEN command to open the data file.

2. Use one of the following methods to select records:

• Create a select list using SELECT, SELECTINDEX,UniQuery SELECT, UniData SQL SELECT, or a paragraph select.

• Set a pointer in an alternate index with SETINDEX.

3. Use one of the following commands to read data from selected records:

READU (use this command to set an exclusive lock),READ, READV, READVL, READVU,READNEXTTUPLE, READFWD, READBCK, READFWDL,READBCKL, READFWDU,READBCKU

4. Manipulate data in arrays. See“Chapter 6 - Working with Data in Programs.”

108 Developing UniBasic Applications

Page 109: Basd_52

Maintaining Files

ccessey

ecord

themation

ee

5. Use one of the following commands to write data to selected records:

WRITE, WRITEU, WRITEV, WRITEVU, WRITET

6. Use the CLOSE command to close the data file.

Alternate Key IndexesAlternate key indexing speeds searching for records within a database. Alternate keys allow ato records without the need to use the record ID or read through the entire file. An alternate kindex consists of values for the alternate key and the associated @IDs of each record.

The Primary Key

UniData requires that each record in the database have a unique identifier, which is called threcord ID, @ID, or primary key. The UniData hashing algorithm uses the @ID to locate the rein the database. When UniData looks for a record, it uses the @ID as the “key” to finding therecord quickly.

TipCreate an index for @ID to speed access to data records.

The Alternate Key

UniData allows only one primary key for a record. If you are searching for a record based onprimary key, searches are fast. Most of the time, however, searches are based on other inforcontained in a record, such as a name, city, phone number, or the result of a virtual attributecalculation. These searches are slower than a search based on the primary key.

You can create alternate keys any time after you create the data file. For more information, sUsing UniDataor the CREATE.INDEX command in theUniData Commands Reference.

Developing UniBasic Applications 109

Page 110: Basd_52

Chapter 4 - Maintaining Data in Files

entrye the

ile.fatal

king:

x of

L

Duplicate Alternate Keys

Although primary keys must be unique, duplicate alternate keys can be entered. To block theof duplicate keys in indexes of non-RFS files, specify the NO.DUPS keyword when you creatindex (with CREATE.INDEX). However, if you do so, you will not be able to build the index byusing BUILD.INDEX if duplicate values are already present in the key attribute in your data fAlso, any WRITE command that attempts to create a duplicate alternate key will generate aerror if no ON ERROR clause is coded.

NoteThe Recoverable File System (RFS) does not support NO.DUPS.

You can detect duplicate keys by executing the ECL command DUP.STATUS ON, then checfor a STATUS function return value of 10 immediately after the following UniBasic commands

• WRITE, WRITEU, WRITEV, WRITEVU

• READFWD, READFWDL, READFWDU

• READBCK, READBCKL, READBCKL

Creating and Maintaining Alternate Indexes

You might perform the following steps to create and manage alternate indexes. For the syntathe ECL commands, see theUniData Commands Reference.

1. Use the ECL CREATE.INDEX command to create the index.

2. Use the ECL BUILD.INDEX command to load alternate keys into the index.

NoteYou cannot execute BUILD.INDEX while users are accessing the file.

3. Use the ECL ENABLE.INDEX or DISABLE.INDEX command to enable or disable(respectively) the automatic updating of the alternate key index. You also can use the ECUPDATE.INDEX command to update the index manually.

110 Developing UniBasic Applications

Page 111: Basd_52

Maintaining Files

or

iles.

4. Use the SELECTINDEX command to build a select list based on the alternate index file,use the SETINDEX command to set a pointer to an alternate key value in the index.

5. Read records from the UniData file by using the alternate index and any of the followingUniBasic commands:

READFWD, READFWDL, REAFWDU, READBK, READBKL, READBKU

Using Alternate Index Files

Use the following alternate index commands and functions to speed access to UniData fFor syntax and usage, see theUniBasic Commands Reference.

Command/Function Action

FILEINFO Returns the name of the index to which the lastSETINDEX statement was applied. Also requests the keyvalue of the index for the record that was read by the lastbrowsing statement, such as READFWD or READBCK.

READBCK Retrieves one record ID from an index, assigns thecontents of the record to a dynamic array, and assigns therecord ID to the @ID variable.

READBCKL Same as READBCK, but places a shared lock on therecord.

READBCKU Same as READBCK, but places an exclusive lock on therecord.

READFWD Retrieves one record ID from an index, assigns thecontents of the record to a dynamic array, and assigns therecord ID to the @ID variable.

READFWDL Same as READFWD, but places a shared lock on therecord.

Alternate Index Commands

Developing UniBasic Applications 111

Page 112: Basd_52

Chapter 4 - Maintaining Data in Files

base

The following program demonstrates use of an alternate index file for the demonstration datafile INVENTORY. The index is on attribute 3,PROD_NAME. The program prompts the user for aproduct, and then it prints all records for that product.

Program Example

OPEN "INVENTORY" TO open.file ELSE PRINT "Open error." ;STOPPRINT "Enter product to display: ";INPUT search_productsearch_product = OCONV(search_product, "MCT")new_product = search_productSETINDEX "PROD_NAME", search_product ON open.fileIF STATUS()>0 THEN PRINT "Record not found.";STOPLOOP UNTIL new_product <> search_product

READFWD dyn.array.var FROM open.file ELSE PRINT "Record not found."new_product = EXTRACT(dyn.array.var,3)IF new_product = search_product THEN PRINT "Record is: ":dyn.array.var

REPEATEND

READFWDU Same as READFWD, but places an exclusive lock on therecord.

SELECTINDEX Creates a select list based on an alternate key. The list cancontain all records for this alternate index or a subsetbased on a particular key value.

SETINDEX Sets a pointer to the initial alternate key value in thealternate index. Use READFWD or READBACK totraverse the index.

Command/Function Action

Alternate Index Commands (continued)

112 Developing UniBasic Applications

Page 113: Basd_52

Maintaining Files

s:

es.

ee

tm file

entc

The following example shows user input and output from the preceding program:

Screen Example

Enter product to display:?trackballRecord is: 01/17/1996p09:00AMpTrackballpDeluxe ModelpGrayp2373p5799p30Record is: 01/18/1996p10:00AMpTrackballpEconomy ModelpWhitep2299p4499p30Record is: 01/11/1996p12:00PMpTrackballpSuper Deluxe ModelpGrayp494p9899p70

Non-UniData Sequential FilesYou can use the following types of commands to maintain data in non-UniData sequential file

• Sequential File Commands – Specifically for manipulating non-UniData sequential fil

• UniData Hashed File Commands – You can use these after you make an entry for thesequential file in the UniData VOC file. For instructions about creating a VOC entry, sUsing UniData.

Sequential File Commands

UniBasic provides commands to manipulate non-UniData sequential files, including files thacontain data stored in binary format. These commands access the file via the operating systename or place name and therefore do not use a VOC entry to locate the file. Access to differtypes of sequential files lets you modify print jobs, log files, and source code using a UniBasiprogram.

Developing UniBasic Applications 113

Page 114: Basd_52

Chapter 4 - Maintaining Data in Files

readng atad

uld bee

ad aust

UniBasic provides several sets of commands to handle sequential file operations. To open asequential file, use either the OSOPEN or OPENSEQ command. After opening a file, you canand write the entire file, read and write one record at a time, or read and write the file beginnia specified byte location. The following table lists the commands that pertain to sequential reand write operations.

To close a sequential file, use either the OSCLOSE or CLOSESEQ command. To delete asequential file, use the OSDELETE command.

NoteEven though you can use any combination of sequential read and write commands, you shocareful to avoid writing data in unintended areas of the file. Informix recommends you becomthoroughly familiar with them before you mix their use. For the syntax and use of thesecommands, see theUniBasic Commands Reference.

In addition, if you have opened a named pipe, you cannot use the READSEQ command to rerecord from it, and you cannot use WRITESEQ or WRITESEQF to write a record to it. You muse the OSBREAD and OSBWRITE commands.

Read/WriteEntire File

Read/WriteOne Record

Read/WriteStarting at a

Specified ByteLocation

OSREAD READSEQ OSBREAD

OSWRITE WRITESEQWRITESEQF

OSBWRITE

n/a WEOFSEQ n/a

Commands for Reading/Writing Non-UniData Sequential Files

114 Developing UniBasic Applications

Page 115: Basd_52

Maintaining Files

d

rable

seential

WarningThe UniBasic OSDELETE command is intended for use on OS-type files (not UniData hashefiles). If you execute the command against a recoverable hashed file, UniData could crashimmediately or at the next RFS checkpoint. If the command is executed against a nonrecovehashed file, UniData will not crash, but other unpredictable problems could occur.

UniData Hashed File Commands

You can use hashed file commands (OPEN, READ, WRITE, CLOSE, and DELETE) on non-UniData sequential files that have VOC entries. However, we discourage this practice becauUniData could, in some cases, insert characters in the file, even upon opening it. Use the sequfile commands listed earlier, or operating system commands.

Developing UniBasic Applications 115

Page 116: Basd_52

Chapter 4 - Maintaining Data in Files

sic

Opening Files

UniBasic provides the following commands for opening files. You must open a file in a UniBaprogram before you can access the data in it.

For the syntax and use of these commands, see theUniBasic Commands Reference.

ExampleThe following program segment is taken from the sample program in“Appendix A - SampleProgram.”It demonstrates opening a UniData hashed file.

Program Example

OPEN_FILES:OPEN "CLIENTS" TO CLIENT_FILE ELSE

MESSAGE = "The CLIENT file could not be opened."CALL DISPLAY_MESSAGE(MESSAGE)STOP

END

Command Action

OPEN Open a file. Generally, you store a pointer to the open filein a variable. However, you can open a default file by omit-ting the variable. Then you can execute file-level com-mands against this default file by again omitting the filevariable.

OPENSEQ Open a sequential file, starting at the beginning of the file.

OSOPEN Open a sequential file that does not use CHAR(10) as theline delimiter.

Commands That Open Files

116 Developing UniBasic Applications

Page 117: Basd_52

Selecting Records

reas

om

ta

ntievinglists,

ile bye the

Selecting Records

Some ways you might determine which record(s) to retrieve include:

• Prompting the user or a data stack for record ID(s) or other selection criteria.

• Performing calculations.

• Executing conditional tests.

Creating a Select List of Record IDsThe record IDs of selected records are placed in a select list. UniData provides ten storage aidentified by their number: 0 through 9. If you do not specify a list number when you selectrecords IDs, UniData stores them in list 0. You can use multiple select lists to process data frseveral files simultaneously.

UniBasic supports record selection by internal and external statements and commands, orexternally from ECL, a paragraph, or a paragraph that performs an ECL (UniQuery or UniDaSQL) SELECT statement.

After you create a select list, the prompt changes to a greater than symbol (>), any subsequeselect statement acts against that list. You must delete or deactivate the select list before retrIDs based on completely new criteria. For information about deleting and deactivating selectsee the ECL commands CLEARSELECT and SAVE.LIST in theUniData Commands Referenceor the UniBasic CLEARSELECT command in theUniBasic Commands Reference.

Saving a Select List

Select lists are available only during the current work session. You can save a select list to a fusing the UniBasic WRITELIST command. Then, when you want to use the list again, executSELECT command followed by the name of the file.

Developing UniBasic Applications 117

Page 118: Basd_52

Chapter 4 - Maintaining Data in Files

ram

e

Internal Select

You can select records within a UniBasic program using the following commands.

For the syntax and use of UniBasic commands, see theUniBasic Commands Reference.For thesyntax and use of UniQuery commands, seeUsing UniQuery. For the syntax and use of UniDataSQL SELECT, see theUniData SQL Commands Reference.

External Select

You can select records from the ECL prompt or from a UniData paragraph. Then run the progor paragraph using the select list.

Command Action

SELECT Collect a list of all @IDs from a specified file.

SELECTINDEX Create a select list based on an alternate key index. Thlist can be made up of an entire index or can be limitedto a particular alternate key value or values.

Note - You must use the SETINDEX command to setthe pointer before you can read records.

FORMLIST Create a select list from a dynamic array.

EXECUTE a UniQuery SELECTEXECUTE a UniData SQL SELECT

Execute a UniData SQL or UniQuery SELECTcommand using the UniBasic EXECUTE orEXECUTESQL command to create a list of recordIDs.

Note - These SELECT statements offer the advantageof letting you use selection criteria.

SELECTINFO Determine if a select list is active.

Selecting Records within a UniBasic Program

118 Developing UniBasic Applications

Page 119: Basd_52

Selecting Records

pte

asic

t delete

or all

r

Examples of External Select

In the following example, a UniQuery SELECT is executed from the ECL prompt. The > promindicates that a select list is active. The UniBasic program executed from this prompt uses thactive select list.

Screen Example

: SELECT INVENTORY WITH QUANTITY > '999'>RUN BP OVERSTOCK_REPORT

The following example UniData paragraph selects a stored select list, and then it runs a UniBprogram using the selected records:

Program Example

PASELECT INVENTORY3RUN BP NEWITEMS_REPORT

Clearing a Select ListOnce you create a select list, any subsequent select statement acts against that list. You musor deactivate the active select list before retrieving IDs based on completely new criteria.

CLEARSELECT empties a record ID list created by a SELECT statement. You can clear oneselect lists.

The ECL commands CLEARSELECT and SAVE.LIST also clear or deactivate select lists. Fomore information about these commands, see theUniData Commands Reference.

Developing UniBasic Applications 119

Page 120: Basd_52

Chapter 4 - Maintaining Data in Files

rection.

ion ofat the

Reading, Writing, and Deleting Data from Files

This section describes how to read, write, and delete data from files.

Getting Ready to ReadBefore you start reading records, you might want to take one of the following steps:

• Make a record ID available to the program with the UniBasic READNEXT orREADNEXTTUPLE command.

• Set a pointer to an initial alternate key value in an alternate index with the SETINDEXcommand.

ReminderAfter you open a file and before you read data, you need to select records for processing. Foinformation about selecting records and creating select lists of record IDs, see the previous s

Reading Record IDs from a Select ListAfter you have selected record IDs for processing, you can use the UniBasic READNEXTcommand to assign the next record ID from an active select list to a variable.

Reading Data from Files

ReminderYou must understand the UniBasic record locking system to select the appropriate combinatcommands to prevent data inconsistency, which can result from multiple users updating filessame time. For more information, see“Chapter 5 - Using UniData Locks.”

120 Developing UniBasic Applications

Page 121: Basd_52

Reading, Writing, and Deleting Data from Files

efileny)ad

a

UniBasic supplies a number of commands for reading records so that the data in them can bmanipulated in a UniBasic program. You will want to use the proper command for the type offrom which you are reading, the type of variable you are reading into, and the type of lock (if ayou want to check for and set. The following table introduces the UniBasic commands that rerecords from files and data from records.

READ Command Action

MATREAD Assigns values in attributes of a record to corresponding elementsof a dimensioned array regardless of lock status. Retains existinglocks.

MATREADL If the record is available (unlocked or shared lock), sets a sharedlock on the record. Assigns the contents of the record to adimensioned array.

MATREADU If the record is available (no locks), sets an exclusive lock. Assignsthe attributes of the record to a dimensioned array.

READ Reads a record regardless of lock status and assigns its contents todynamic array. Retains existing locks.

READL If the record is available (unlocked or shared lock), sets a sharedlock on the record. Assigns the record’s contents to a dynamicarray.

READU If the record is available (no locks), set an exclusive lock. Assignsthe contents of the record to a dynamic array.

READV Reads data from an attribute and assigns it to a variable regardlessof lock status. Retains existing locks.

READVL If the record is available (unlocked or shared lock), sets a sharedlock. Reads data from an attribute and assigns it to a variable.

READVU If the record is available (no locks), sets an exclusive lock on therecord. Reads data from an attribute and assigns it to a variable.

READSEQ Reads the next record from a non-UniData sequential file andassigns the data to a variable regardless of lock status.

READ Commands

Developing UniBasic Applications 121

Page 122: Basd_52

Chapter 4 - Maintaining Data in Files

ds

For syntax and instructions for coding read statements, see theUniBasic Commands Reference.

TipUsing UniBasic commands to modify files and records containing binary data (for example,directory files such as BP) could have unpredictable results. Use operating system commaninstead, such as cp (for UNIX) or copy (for Windows NT or Windows 2000).

OSREAD Reads an entire sequential file and assigns the contents to avariable.

OSBREAD Reads data from a sequential file starting at a specified bytelocation for a certain length of bytes, and assigns the data to avariable.

READT Regardless of lock status, reads the next available record from atape and assigns it to a variable.

READNEXTTUPLE Using a list of record IDs, reads the next record to a variableregardless of lock status. Retains existing locks.

READFWDREADBCK

Retrieves one record ID from an index, assigns the contents of therecord to a dynamic array, and assigns the record ID to the @IDvariable regardless of lock status. Retains existing locks.

READFWDLREADBCKL

If the record is available (unlocked or shared lock), sets a sharedlock. Retrieves one record ID from an index, assigns the contentsof the record to a dynamic array, and assigns the record ID to the@ID variable.

READFWDU

READBCKU

If the record is available (no locks), sets an exclusive lock.Retrieves one record ID from an index, assigns the contents of therecord to a dynamic array, and assigns the record ID to the @IDvariable.

READ Command Action

READ Commands (continued)

122 Developing UniBasic Applications

Page 123: Basd_52

Reading, Writing, and Deleting Data from Files

o

ExampleThe following program segment is taken from the sample program UPDATE_ORDER in“Appen-dix A - Sample Program.”The READU command reads a record in the ORDERS file (in the demdatabase), converting attributes in preparation for displaying them on the screen.

Program Example

DISPLAY_DATA:* Display the current information in the desired record. This is* determined by the number the user entered (ORDER_NUMBER).

READUORDER.REC FROM ORDERS_FILE,ORDER_NUMBER THEN* Read with a lock so that no one else can modify it at the same time.

RECORD_FOUND = 1ORDER_DATE = OCONV(ORDER.REC<1>,"D4/")ORDER_TIME = OCONV(ORDER.REC<2>,"MT")CLIENT_NUMBER = ORDER.REC<3>ADDRESS = ''

Developing UniBasic Applications 123

Page 124: Basd_52

Chapter 4 - Maintaining Data in Files

ith thefiles

erse

Writing Data to Files

ReminderWrite statements execute regardless of lock status. For this reason, you must precede them wREADU command to prevent data inconsistency that can result from multiple users updatingat the same time. For more information, see“Chapter 5 - Using UniData Locks.”

UniBasic supplies a number of commands for writing records into UniData hashed files fromUniBasic variables, including dynamic and dimensioned arrays. You will want to use the propcommand for the type of file you are writing to and the type of variable you are writing from. Uthe following table to decide which UniBasic command to use to write to a file.

WRITECommand Action

MATWRITE Writes elements of a dimensioned array to correspondingattributes of a record regardless of lock status.

MATWRITEL If the record is available (unlocked or shared lock), sets ashared lock on the record. Writes elements of a dimensionedarray to corresponding attributes of a record.

MATWRITEU If the record is available (no locks), sets an exclusive lock.Writes elements of a dimensioned array to correspondingattributes of a record.

WRITE Writes an expression to a record regardless of lock status.Releases any record or file lock this process set.

WRITEU Writes an expression to a record regardless of lock status,but retains locks if present.

WRITEV Writes an expression to an attribute of a data record regard-less of lock status.

WRITEVU Writes an expression to an attribute of a data record.

WRITE Commands

124 Developing UniBasic Applications

Page 125: Basd_52

Reading, Writing, and Deleting Data from Files

ds

For syntax and instructions for coding write statements, see theUniBasic Commands Reference.

TipUsing UniBasic commands to modify files and records containing binary data (for example,directory files, such as BP) could have unpredictable results. Use operating system commaninstead, such as cp (for UNIX) or copy (for Windows NT or Windows 2000).

OSWRITE Writes the contents of a variable to a sequential file.

OSBWRITE Writes a variable starting at a specified byte location to asequential file.

WRITESEQ Writes a variable as a record on a sequential file from acurrent record pointer position.

WRITESEQF Writes a variable as a record on a sequential file from acurrent record pointer position. Forces UniData toimmediately write the data to the disk.

WRITET Writes the value of an expression onto a tape.

WRITECommand Action

WRITE Commands (continued)

Developing UniBasic Applications 125

Page 126: Basd_52

Chapter 4 - Maintaining Data in Files

ed from

ExampleThe following program segment is taken from the sample program, UPDATE_ORDER in“Appen-dix A - Sample Program.”The WRITEV command writes an attribute to the ORDERS file (in thdemo database) after an order number (one value in a multivalued attribute) has been deleteit.

Program Example

DELETE_RECORD:* (Assuming the order #'s are on line 12)

READVU ORDER_LINE FROM CLIENT_FILE,CLIENT_NUMBER,12 THENLOCATE ORDER_NUMBER IN ORDER_LINE<1> SETTING POSITION THEN

DEL ORDER_LINE<1,POSITION>ENDWRITEV ORDER_LINE ON CLIENT_FILE, CLIENT_NUMBER, 12

END*

DELETE ORDERS_FILE, ORDER_NUMBERRELEASE CLIENT_FILE,CLIENT_NUMBER

RETURN

126 Developing UniBasic Applications

Page 127: Basd_52

Reading, Writing, and Deleting Data from Files

t can.

rom

shed

rable

Deleting Data from Files

ReminderDELETE executes regardless of lock status. The only way to prevent data inconsistency tharesult from multiple users updating files at the same time is to precede DELETE with READUFor more information, see“Chapter 5 - Using UniData Locks.”

The following table provides a brief introduction to the UniBasic commands that delete data ffiles and/or records.

WarningThe UniBasic OSDELETE command is intended for use on OS-type files (not on UniData hafiles). If the command is executed against a recoverable hashed file, UniData could crashimmediately or at the next RFS checkpoint. If the command is executed against a nonrecovehashed file, UniData will not crash, but other unpredictable problems could occur.

For the syntax and use of these commands, see theUniBasic Commands Reference.

Command Action

DELETE Deletes a record from a UniData file regardless oflock status. Releases all locks set by this process.

DELETEU Checks for locks. If the record is available, deletesit.

OSDELETE Deletes a sequential file.

Commands that Close Files

Developing UniBasic Applications 127

Page 128: Basd_52

Chapter 4 - Maintaining Data in Files

Program Example

DELETE_RECORD:* (Assuming the order #'s are on line 12)

READVU ORDER_LINE FROM CLIENT_FILE,CLIENT_NUMBER,12 THENLOCATE ORDER_NUMBER IN ORDER_LINE<1> SETTING POSITION THEN

DEL ORDER_LINE<1,POSITION>ENDWRITEV ORDER_LINE ON CLIENT_FILE, CLIENT_NUMBER, 12

END*

DELETE ORDERS_FILE, ORDER_NUMBERRELEASE CLIENT_FILE,CLIENT_NUMBER

RETURN

128 Developing UniBasic Applications

Page 129: Basd_52

Closing Files

Closing Files

The following table introduces the commands that close files.

For the syntax of these commands and instructions for coding close statements, see theUniBasicCommands Reference.

Command Action

CLOSE Releases locks and closes a data or dictionary file.

CLOSESEQ Releases locks and closes a sequential file.

OSCLOSE Closes a sequential file.

Commands that Close Files

Developing UniBasic Applications 129

Page 130: Basd_52

Chapter 4 - Maintaining Data in Files

ulti-

RS,erts

Accessing Data in Unopened Files

With the ICONV T and OCONV T functions you can access singlevalued, multivalued, and msubvalued attributes in a file that you have not opened. You can also use these functions todetermine if a particular record or attribute exists or contains an empty string.

The first line of the following program segment reads the demonstration database file ORDEaccessing the record with @ID 912, and retrieving the second attribute. OCONV T also convthe internal date to external display format. The second line prints the value in that attribute.

Program Example

record.ret = OCONV("912"," TORDERS;V;;2")PRINT "Record retrieved: ":record.retEND

The following output is obtained by running the preceding program:

Screen Example

Record retrieved: 12:30PM

130 Developing UniBasic Applications

Page 131: Basd_52

Chapter 5 - UsingUniData Locks

cords

g

In a multiuser environment, you must be able to prevent more that one user from updating resimultaneously. By observing the UniBasic locking conventions consistently in all of yourapplications, you can provide this protection. You can also use locks to reserve computerresources.

This chapter introduces UniBasic locks and the commands that comprise the UniBasic lockinsystem. For more information about ensuring database consistency, see“Chapter 9 - UniBasicTransaction Processing.”

Developing UniBasic Applications 131

Page 132: Basd_52

Chapter 5 - Using UniData Locks

In This Chapter

This chapter contains the following sections:

• “Understanding the UniData Locking System”

• “Locking Commands”

• “What Commands Do with Locks”

• “When to Use Locking Commands”

• “Programming Problems”

• “Locking Example”

132 Developing UniBasic Applications

Page 133: Basd_52

Understanding the UniData Locking System

ame

cal

not

king

r

Understanding the UniData Locking System

In a multiuser system, record and file locks prevent more than one user from accessing the srecord at the same time.

How UniData Locks WorkUnlike physical locks that prevent access, UniBasic locks are advisory only. Imagine a physilock as the deadbolt on a hotel room door and an advisory lock as a “Do Not Disturb” sign.UniBasic locks merely inform others attempting access that the “locked” entity is in use, whileexplicitly preventing access.

Types of UniData LocksThe UniData lock types are:

• Exclusive lock – Checks for and sets locks before updating data.

• Shared lock – Used for read-only operations. Prevents other users (who also use loccommands) from writing to the record while it is being read.

Exclusive Locks (U)

Records locked with exclusive (U) locks:

• Cannot be accessed by any READ U or L command.

• Are accessed by commands that do not check for locks and that are issued from otheprocesses.

NoteThe original lock, although ignored, is retained.

• Are accessed and modified by any WRITE or DELETE command.

• Are released by the commands WRITE and DELETE issued from the same process.

Developing UniBasic Applications 133

Page 134: Basd_52

Chapter 5 - Using UniData Locks

t dataes

• Cannot be locked by RECORDLOCKU or RECORDLOCKL issued from anotherprocess.

Shared Locks (L)

Records locked with shared (L) locks:

• Cannot be accessed or locked by READ U commands.

• Are accessed by READ L commands.

NoteThe original lock is retained.

• Are accessed by READ commands that do not check for locks.

• Are accessed and changed by any WRITE or DELETE command.

NoteEven though these commands update regardless of lock status, they retain the original lock.

• Are released by the commands WRITE or DELETE issued from the same process.

• Cannot be locked by RECORDLOCKU from another process.

TipWRITE and DELETE commands execute regardless of lock status. For this reason, to preveninconsistency, these commands must be preceded by READU or another command that issulocks.

134 Developing UniBasic Applications

Page 135: Basd_52

Understanding the UniData Locking System

ing

When UniBasic Finds a LockWhen a locking command encounters a locked file or record, UniBasic does one of the follow(in order of preference):

1. Executes the LOCKED clause of the UniBasic command, if present.

2. Beeps periodically while waiting if the ECL commandDEFAULT.LOCKED.ACTION BELL [interval] is set.

3. Waits for the record to be unlocked, but does not send a signal to the terminal.

Points to Remember about LocksKeep in mind the following points about locks:

• Anyone can update or delete locked files and records with any WRITE or DELETEcommand.

• If you set a lock, only you, or someone signed on with root privileges on UniData forUNIX or Administrator privileges on UniData for Windows NT or Windows 2000, canrelease it.

• TRANSACTION COMMIT and TRANSACTION ABORT releases all locks yourprocess has set within the transaction.

NoteFor more information about using transactions to ensure database consistency, see“Chapter 9 -UniBasic Transaction Processing.”

Developing UniBasic Applications 135

Page 136: Basd_52

Chapter 5 - Using UniData Locks

name,no

com-k the

file

d in

Locking Commands

ReminderUniBasic locks are advisory only. To maintain data consistency, all programs that update thedatabase must check for locks.

Keep the following points in mind when writing UniBasic programs:

• Locking Records – UniBasic provides distinct read, write, and delete commands thatcheck and set locks. These commands all have an appended U or L in the commandindicating the type of locks they set. All other commands ignore locks, operating as iflock is set. A chart of locking commands is provided in“What Commands Do withLocks” later in this chapter.

• Locking Files – You can set an advisory lock on an entire file by issuing a FILELOCKagainst it. Use the FILEUNLOCK command to unlock the file.

• Locking Resources – Use the LOCK command to set an advisory lock that reserves aputer resource (such as a printer or tape drive) for use by a particular program. Unlocresource with the UNLOCK command.

• Unlocking – You can use the ECL command SUPERRELEASE to release record andlocks. To unlock resources, use the CLEAR.LOCKS and SUPERCLEAR.LOCKScommands.

For more information about ECL commands, see theUniData Commands Reference.

UDT.OPTIONSSetting UDT.OPTIONS 35 on prevents locking a record in a called subroutine that was lockethe calling program. UDT.OPTIONS 78 addresses two situations in which UniBasic locking isincompatible with Pick®-style locking. For more information about UDT.OPTIONS, see theUDT.OPTIONS Commands Reference.

136 Developing UniBasic Applications

Page 137: Basd_52

Locking Commands

ftere

the

sthis

Checking Lock StatusTo learn about a the lock status of a record, use the UniBasic RECORDLOCKED function. Acalling RECORDLOCKED, you can use the STATUS function to obtain the user number of thuser who set the lock.

The GETREADU function returns a dynamic array containing detailed information about allrecords that have been locked by any UniBasic or ECL command. The ECL commandLIST.READU also provides this same information (for more information, see GETREADU inUniBasic Commands Reference).

The GETQUEUE function returns a dynamic array that contains information about all recordcurrently locked and waiting to be released. The ECL command LIST.QUEUE also providesinformation (for more information, see GETQUEUE in theUniBasic Commands Reference).

Developing UniBasic Applications 137

Page 138: Basd_52

Chapter 5 - Using UniData Locks

s.esill

nters

What Commands Do with Locks

The following table identifies how the previously discussed commands react to UniBasic lockNote that some commands execute regardless of lock status, but leave locks in place (Ignorcolumn). Others, regardless of lock status, release locks and execute (Releases column). Stothers delay file activity until locks are released (Sets Exclusive and Sets Shared columns).

ReminderInclude the LOCKED clause in command statements to tell UniData what to do when it encoua lock.

Command IgnoresSets

ExclusiveSets

Shared Releases

READ X

READU X

READV X

READVU X

MATREAD X

MATREADU X

READBCKU X

READFWDU X

RECORDLOCKU X

READL X

READVL X

MATREADL X

READBCKL X

What Commands Do with Locks

138 Developing UniBasic Applications

Page 139: Basd_52

What Commands Do with Locks

READFWDL X

RECORDLOCKL X

WRITE X

WRITEU X

WRITEVU X

MATWRITE X

MATWRITEU X

DELETE X

DELETEU X

Command IgnoresSets

ExclusiveSets

Shared Releases

What Commands Do with Locks (continued)

Developing UniBasic Applications 139

Page 140: Basd_52

Chapter 5 - Using UniData Locks

When to Use Locking Commands

Follow the guidelines in this table when selecting record- and file-locking commands.

When to Use Action Files Dynamic Arrays

Attributesof

DynamicArrays

DimensionedArrays

Retrievinginformation;allowing updatewhile reading.

Readwithoutcheckinglocks.

READ READV MATREAD

Updatingrecords (must bepreceded byREADU toensure data con-sistency).

Write;releaselocks.

WRITE WRITEV MATWRITE

Reading andsecuring infor-mation forupdate (otherprograms mustcheck forlocks).

Read andset exclu-sive lock.

FILELOCK READURECORDLOCKU

READVU MATREADU

Updating; keep-ing ownershipof lock (otherprograms mustcheck forlocks).

Write; donot releaselocks.

WRITEU WRITEVU MATWRITEU

Record Locking Guidelines

140 Developing UniBasic Applications

Page 141: Basd_52

When to Use Locking Commands

Retrievinginformation, butkeeping othersfrom updating(using READUor WRITEU)while you arereading (otherprograms mustcheck forlocks).

Read andlock forread-only.

READL READVL MATREADL

Release locksyou placed.

Releaselocks.

FILEUN-LOCK

RELEASE RELEASE RELEASE

When to Use Action Files Dynamic Arrays

Attributesof

DynamicArrays

DimensionedArrays

Record Locking Guidelines (continued)

Developing UniBasic Applications 141

Page 142: Basd_52

Chapter 5 - Using UniData Locks

stions

t the

rentof

nate

might

Programming Problems

This section discusses how UniBasic programming problems may arise, and provides suggeon how to minimize the problems.

CausesA multiuser environment creates opportunities for two programs to access the same record asame time, resulting in the following types of problems:

• Inconsistent data caused by the following:

• Lost updates – The updates from one program overlay those of another.

• Dirty reads – A program reads a record that is in the process of being modified byanother.

• Unrepeatable reads – A program reads the same record twice, obtaining two diffevalues. This results when the first read executes while the record is in the processbeing updated, and the second read executes after the record has been updated.

• Bottlenecks – Result when one program retains a lock on a file or record for an inordiamount of time, causing other programs to wait.

• Deadlocks – Occur when two or more programs are waiting for each other to releaserecords with no chance of either being released.

Minimizing ProblemsUsing record locking consistently, you can eliminate the programming problems listed earlierwhile reducing bottlenecks and deadlocks. To do so, use the following guidelines:

• Always check for locks and always lock records before writing.

• Minimize the amount of time records are locked.

• Request user input before locking records, not while the records are locked.

• Impose a protocol on the order data items can be updated. For example, the protocollet programs lock record B only after locking record A (to avoid deadlocks).

142 Developing UniBasic Applications

Page 143: Basd_52

Programming Problems

ore

NoteDeadlocks cause transaction processing to abort one of the deadlocked transactions. For minformation about UniData transactions, see“Chapter 9 - UniBasic Transaction Processing.”

Developing UniBasic Applications 143

Page 144: Basd_52

Chapter 5 - Using UniData Locks

ases,could

the

Locking Example

The following program segments are portions of the sample program in“Appendix A - SampleProgram.”The main routine (Main Logic), drives the program by calling subroutines to performthe main tasks. Notice that RELEASE is executed as the last step in the LOOP. In almost all crecords are released as soon as they are written to the file. However, some error conditionscause records to remain locked when control is returned to the LOOP.

Program Example

*-------------- Main Logic -----------------------------

GOSUB INITIALIZE

LOOPGOSUB DISPLAY_SCREENGOSUB GET_ORDER_NUMBER

UNTIL ORDER_NUMBER[1,1] = 'Q'GOSUB DISPLAY_DATAIF RECORD_FOUND THEN GOSUB GET_RECORD_COMMANDRELEASE

REPEATGOSUB EXIT

The following program segment shows the READU command that sets an exclusive lock onrecord that the user has selected for update:

Program Example

DISPLAY_DATA:* Display the current information in the desired record. This is* determined by the number the user entered (ORDER_NUMBER).

READUORDER.REC FROM ORDERS_FILE,ORDER_NUMBER THEN* Read with a lock so that no one else can modify it at the same time.

144 Developing UniBasic Applications

Page 145: Basd_52

Locking Example

leases

ORDER_DATE = OCONV(ORDER.REC<1>,"D4/")ORDER_TIME = OCONV(ORDER.REC<2>,"MT")CLIENT_NUMBER = ORDER.REC<3> "R#5"

In the next program segment, the WRITE command updates the previous record read and rethe exclusive lock (WRITE always releases locks that were set by the same user process):

Program Example

WRITE_RECORD:...

WRITE CLIENT.REC ON CLIENT_FILE,CLIENT_NUMBERWRITE ORDER.REC ON ORDERS_FILE,ORDER_NUMBER

Developing UniBasic Applications 145

Page 146: Basd_52

Chapter 5 - Using UniData Locks

146 Developing UniBasic Applications

Page 147: Basd_52

Chapter 6 - Workingwith Data in Programs

sulate

In most cases, you select from a number of similar commands to perform a specific task. Thichapter provides the information you need to select the correct command or function to manipdata in UniBasic programs.

Developing UniBasic Applications 147

Page 148: Basd_52

Chapter 6 - Working with Data in Programs

y tog

In This Chapter

You have read data into the program from files or accepted input from the user. You are readmanipulate the data before writing it to a file or report. This chapter introduces in the followinsections the concepts and commands you will use to do this manipulation:

• “UniData Arrays”

• “Inquiring about Data”

• “Performing Numeric Operations”

• “Formatting and Converting Data”

• “UniBasic Multibyte Support”

148 Developing UniBasic Applications

Page 149: Basd_52

UniData Arrays

me

ers;

data

UniData Arrays

You generally use an array to store data that you read into a UniBasic program from UniDatahashed files. Multivalued and multi-subvalued attributes can be loaded into an array in the saway that you load an individual value into a variable.

The following two types of UniBasic arrays are introduced in“Chapter 1 - Introduction to UniBa-sic.”

• Dynamic arrays – Separate each attribute, value, and subvalue of a record by delimitthey are flexible, allowing easy modification.

• Dimensioned arrays – Store data in designated cells of a fixed-sized matrix; access toin a dimensioned array is rapid but less flexible.

Dynamic ArraysThe UniData file structure uses reserved delimiters to partition data items that are storedsequentially. The same delimiters are used in dynamic arrays (see“Dynamic Array Delimiters”).As the name implies, the size of a dynamic array is determined by the data contained in it.

Advantages of Using Dynamic Arrays

Dynamic arrays have the following advantages over dimensioned arrays:

• Need not be defined before you use them.

• Can be assigned quickly.

• Require less memory than dimensioned arrays.

• Can be three-dimensional.

Developing UniBasic Applications 149

Page 150: Basd_52

Chapter 6 - Working with Data in Programs

aal-

ent

r

ed in

data

:

Dynamic Array Delimiters

UniData uses the same delimiters to separate elements in a dynamic array as those used inUniData hashed file. UniBasic evaluates the delimiter symbols and writes the correct ASCII vues when you write a record. The following table illustrates common symbols used to represdelimiters. The character used to display the delimiter symbols depends on your terminalemulation.

NoteYou must use the @variables to refer to delimiters within UniBasic programs, not the delimitesymbols. The symbols that display for these delimiters could differ on your system.

Maintaining Dynamic Arrays

The commands you use to load data into an array and write to a file from an array are introduc“Chapter 4 - Maintaining Data in Files.”After data is loaded into the sorted array, you might usethe following procedure to add, replace, insert, and delete data in the array:

1. Make sure that the data in the array is sorted. Performing a LOCATE or FIND on unsortedproduces unpredictable results.

2. Execute the LOCATE or FIND command to determine the location of one of the following

• Where new data should be inserted in a multivalued attribute.

DelimiterSymbol Meaning @variable

(unprintable) Record mark @RM

~ Attribute mark @AM, @FM

} Value mark @VM

| Subvalue mark @SM

{ Text mark @TM

Dynamic Array Delimiters

150 Developing UniBasic Applications

Page 151: Basd_52

UniData Arrays

ub-

array

• Of a string that you intend to update or delete within a multivalued attribute.

3. Use the EXTRACT command (or < >) to extract an attribute (value, multivalue, or multi-svalue) from the array.

4. Use one of the following commands as appropriate to insert, delete, update, or replace anelement:

• INSERT, INS

• DEL, DELETE (the function)

• REPLACE (or < >)

Summary of Dynamic Array Commands

Use the following commands and functions to create and maintain data in a dynamic array.

Command/Function Action

FIND, LOCATE Determines the location of an existing array element. Sets apointer to the location where an array element should beinserted.

EXTRACT, < > Copies an array element (attribute, value, multivalue, or multi-subvalue) into a variable.

REPLACE, < > Inserts or replaces an array element (attribute, value,multivalue, or multi-subvalue) from a variable.

DEL, DELETE Deletes an array element.

Dynamic Array Commands

Developing UniBasic Applications 151

Page 152: Basd_52

Chapter 6 - Working with Data in Programs

FIND vs. LOCATE

UniBasic provides two commands that return the location of a string within a dynamic array:FIND and LOCATE. The following table contrasts the two commands.

For the syntax and use of these commands, see theUniBasic Commands Referencemanual.

FIND LOCATE

Returns attribute position. Returns attribute, value, and subvalue position.

Expression searched for could be avariable, matrix element, function, ora literal string.

Expression searched for must be numeric or string.

Can limit the search to a specificattribute, value, or subvalue.

Searches the entire array.

Can begin the search at a specificattribute, value, or subvalue.Assumes the records are sorted andjustified.

Can find thenth occurrence of a string.Assumes the records are sorted and justified.

SETTING returns the position afterthe last value if the string is notfound.

SETTING returns 0 if the string is not located.

Must match the entire element in anarray at the level specified.

Locates an element or part of an element in anarray.

FIND vs. LOCATE

152 Developing UniBasic Applications

Page 153: Basd_52

UniData Arrays

yin

clarededour

ExampleThe following example is taken from the sample program UPDATE_ORDER in“Appendix A -Sample Program.”In this example, the user has entered a record to be deleted. The desiredattribute (containing the order line) is read from the CLIENT file and placed in a dynamic arra(ORDER_LINE). Then, the LOCATE command is used to determine the position of the orderthe array. That order is deleted and the attribute is written back to the file.

Program Example

DELETE_RECORD:...(Assuming the order #'s are on line 12)READVU ORDER_LINE FROM CLIENT_FILE,CLIENT_NUMBER,12 THENLOCATE ORDER_NUMBER IN ORDER_LINE<1> SETTING POSITIONTHENDEL ORDER_LINE<1,POSITION>ENDWRITEV ORDER_LINE ON CLIENT_FILE, CLIENT_NUMBER, 12END*

Dimensioned ArraysA dimensioned array stores data in the elements of a fixed-size matrix. The array must be dein your UniBasic program before you can use it. When you read data in from a UniData hashfile, the delimited data is placed in the matrix elements in the order they appear in the file. If yarray is not large enough to contain all the data read in, all leftover data is placed in the zeroelement, even if more than one attribute is left over.

Advantages of Using Dimensioned Arrays

Dimensioned arrays have the following advantages over dynamic arrays:

• Access is faster.

• Access time is not affected by the size of the array.

• Can contain dynamic arrays.

Developing UniBasic Applications 153

Page 154: Basd_52

Chapter 6 - Working with Data in Programs

.

opy

.

a

ay.

Maintaining Dimensioned Arrays

Perform the following steps to create and use a dimensioned array:

1. Use the DIM or DIMENSION command to create the array and assign a static dimension

2. Manipulate data in the array:

• Use the MATREAD, MATREADL, or MATREADU command to place data in thearray from a record.

• Use the MATPARSE command to place data in the array from a dynamic array orstring.

• Use the MAT command to assign a single value to all elements of the array or to cone dimensioned array to another.

• Use the MATBUILD command to convert a dimensioned array to a dynamic array

3. Use a statement (for example,X1 = var ) to update elements in the dimensioned array.

4. Use the MATWRITE, MATWRITEL, or MATWRITEU command to write array elements torecord.

Summary of Dimensioned Array Commands

Use the following commands and functions to create and maintain data in a dimensioned arr

Command/Function Action

DIMDIMENSION

Creates a dimensioned array. Required before data can beloaded into the array.

INMAT Returns the number of elements or the dimension of thearray. Also returns the status of some commands.

MAT Assigns a value to all elements of a dimensioned array, orcopies one array to another.

Dimensioned Array Commands

154 Developing UniBasic Applications

Page 155: Basd_52

UniData Arrays

the

. In

the

For the syntax and use of these commands and functions, see theUniBasic Commands Reference.

Inquiring about DataA number of UniBasic functions provide information about a string or array without modifyingoriginal data. They fall into three categories:

• Type – Functions that qualify the data (such as alpha or numeric and length).

• Location – Functions that return the positions of strings or attributes in the data.

• Extraction – Functions that return values found within the string or array.

TypeThis section describes functions that qualify the data.

Testing for the Null Value

The null value is defined within UniData as an unknown value, as opposed to an empty stringUniBasic programs, this unknown value is represented by @NULL, which is translated into aspecific language-dependent (such as English, German, or Chinese) ASCII code. The emptystring, represented by “” is no longer considered to be null in UniData. Two functions test fornull value: ISNV and ISNVS.

MATBUILD Generates a dynamic array from a dimensioned array.

MATPARSE Distributes elements in a delimited string or dynamic arrayto consecutive elements of a dimensioned array.

dim.array(x,y,z)=var Extracts a value from an element of a dimensioned array.

Command/Function Action

Dimensioned Array Commands (continued)

Developing UniBasic Applications 155

Page 156: Basd_52

Chapter 6 - Working with Data in Programs

Testing for Other Data Types

The following functions provide information about type of data.

For the syntax and use of these functions, see theUniBasic Commands Reference.

Function Action

ALPHA Determines whether a string is made up exclusively ofalphabetic characters.

NUM,NUMS

Determines whether a value is numeric.

LEN Determines the length of a string.

MAXIMUM Determines the largest numeric element found in an array.

MINIMUM Determines the smallest numeric element in an array.

COUNTS Determines the number of times a substring appears withinone or more elements of an array.

COUNT Determines the number of times a substring appears withina string or all elements within an array.

DCOUNT Determines the number of delimited substrings in a string.

ISNV/ISNVS Tests for the null value (the unknown value, not emptystring).

Functions That Inquire about Data Type

156 Developing UniBasic Applications

Page 157: Basd_52

UniData Arrays

LocationThe following functions return the location of substrings in a string or array.

For the syntax and use of these functions, see theUniBasic Commands Reference.

ExtractionThe following functions return values found in a string or array without modifying the originaldata.

Function Action

COL1 Returns the column position before the string located by the FIELDfunction.

Note - For an introduction to FIELD, see“Extraction” in this chapter.

COL2 Determines the column position after the string located by the FIELDfunction.

Note - For an introduction to FIELD, see“Extraction” following thistable.

FIND

LOCATE

Determines the position of a string in a dynamic array.

FINDSTR Determines the position of a string in a dynamic array element.

INDEX Determines the starting position of a substring within a string; user canspecify occurrence.

Functions That Inquire about Location

Function Action

[] Returns a specified number of characters beginning at aspecified location.

Functions That Extract Without Modifying

Developing UniBasic Applications 157

Page 158: Basd_52

Chapter 6 - Working with Data in Programs

For the syntax and use of these functions, see theUniBasic Commands Reference.

OCONV/S T Returns a contiguous string of a specified length starting ata specified location.

REMOVE Successively copies each element of a dynamic array to avariable. Maintains a pointer to the location in the array ofthe last element copied.

EXTRACT<>

Returns data from an attribute, value, or subvalue in adynamic array.

FIELD Returns a substring or group of substrings. Treats a stringas an array with fields delimited by any specified ASCIIcharacter.

OCONV/S G Returns one or more strings separated by a specifieddelimiter.

OCONV/S L Returns a string if it is of a specified length or falls withinthe specified range of lengths.

OCONV/S R Returns data values that fall within specified ranges.

OCONV/S P Returns data values that match a specified pattern.

OCONV/S MCA Extracts all alphabetic characters.

OCONV/S MC/A Extracts all nonalphabetic characters.

OCONV/S MCN Extracts all numeric characters (0-9).

OCONV/S MC/N Extracts nonnumeric characters.

OCONV/S MCB Extracts all alphabetic and numeric values.

OCONV/S MC/B Extracts characters that are neither alphabetic nor numeric.

Function Action

Functions That Extract Without Modifying (continued)

158 Developing UniBasic Applications

Page 159: Basd_52

Performing Numeric Operations

e

e of

Performing Numeric Operations

You can perform numeric operations in UniBasic with the two tools, which are described in thfollowing sections:

• “Arithmetic Operators”

• “Mathematic Functions”

Arithmetic OperatorsArithmetic operators compute values. For example, the following statement multiplies the valuCOST by the value of QUANTITY and stores the result in the variable PRICE:

PRICE = COST * QUANTITY

The following table lists valid arithmetic and concatenation operators.

Operator Action

+ Unary plus (same as multiplying by +1).

- Unary minus (use to change a value to negative:var = -var).

+ Addition.

- Subtraction.

* Multiplication.

/ Division.

** or ^ Exponentiation.

: Concatenation.

Arithmetic Operators

Developing UniBasic Applications 159

Page 160: Basd_52

Chapter 6 - Working with Data in Programs

ons:

gg

nce

You can combine arithmetic and concatenation operators to perform special functions as thefollowing table shows.

Points to Remember

Keep in mind the following points when you write UniBasic commands that perform calculati

• Floating point – When you execute an arithmetic operation, UniData invokes theappropriate host operating system command, which performs the operation in floatinpoint. When the results are converted to string format for print or display, the roundinthat is automatically applied can produce unexpected results. Use the ECL commandFLOAT.PRECISION to control when and how rounding is applied.

• Significance – UniData supports up to 14 digits of significance (although this significacan vary across hardware lines). If you use more than 14 digits, accuracy is not

Operator Action

+= Increments the value of a variable.LINES += 1 is more efficient thanLINES=LINES+1.

- = Decrements the value of a variable.LINES –= 1 is more efficient thanLINES=LINES-1.

*= Multiplies the value to the left of the operatorby the value to the right of the operator, as invar *= var .

/= Divides the value to the left of the operatorby the value to the right of the operator, as invar /= var .

:= Concatenates the value to the left of the oper-ator by the value to the right of the operator,as invar := var .

Combined Arithmetic and Concatenation Operators

160 Developing UniBasic Applications

Page 161: Basd_52

Performing Numeric Operations

f the

e.

.

ut

three

guaranteed. Use the UniBasic PRECISION command to set significance for a worksession. The default is 4.

• Data type – Be aware of data type when you execute arithmetic calculations. Results osame calculations executed on string and numeric data occasionally differ.

• Null value – The result of calculations on data containing the null value is the null valuGenerally, null is converted to 0 for arithmetic calculations. However, when UniDataencounters the null value as a divisor, 1 is used to avoid a system error.

ReminderThe null value is defined within UniData as an unknown value, as opposed to an empty string

UDT.OPTIONSBefore you execute an arithmetic operation, you can set UDT.OPTIONS 10 on to trim blankspaces around a numeric value. The trim prevents a runtime error. For more information aboUDT.OPTIONS, see theUDT.OPTIONS Commands Reference.

Arithmetic Operations on Arrays

When you execute arithmetic operations on dynamic arrays, you can apply them in one of thefollowing ways:

• Apply the operation to just the first element in the array.

• Apply the operation to all elements in the array.

• Apply an operation to two arrays (for example, multiply one array by another).

Developing UniBasic Applications 161

Page 162: Basd_52

Chapter 6 - Working with Data in Programs

f the

ple

SEd to

Applying the Operation to the First Element in the Array

Performing an arithmetic operation on an array applies the operation to just the first element oarray. For example, the program segment:

X = 1:@VM:2:@VM:3

Y = X/100

PRINT Y

prints0.01y2y3 (where y represents the value mark).

Applying the Operation to All Elements in the Array

To apply the operation to all elements, include the REUSE command, as in the following samprogram:

Program Example

VIEWERS = 100:@VM:200:@VM:300COST = 40VCOST = VIEWERS*COSTPRINT "1. ":VCOSTVCOST = VIEWERS*REUSE(COST)PRINT "2. ":VCOST

In the following execution of this program, notice that the first result reflects application of thearithmetic operation (multiplication) is applied to only the first element of the array. The REUcommand is used to produce the second result, causing the arithmetic operation to be applieeach element in the array (y represents the value mark in this display).

Screen Example

:RUN BP arith1. 4000y0y02. 4000y8000y12000

162 Developing UniBasic Applications

Page 163: Basd_52

Performing Numeric Operations

swith

ion,the

f the

Applying Operations to Two Dynamic Arrays

When an arithmetic operation is applied to dynamic arrays of different length, the operation iapplied to only the number of element in the shortest array. The remaining elements are filled1 or 0, depending on the operation performed: for division, elements are filled with 1; for additsubtraction, and multiplication, elements are filled with 0. In the following example program,first two elements are multiplied, and then the second two elements are multiplied. The thirdelement is filled with 1, which results in VCOST = 4000:@VM:200:@VM.

Program Example

VIEWERS = 100:@VM:200:@VM:300COST = 40:@VM:1VCOST = VIEWERS*COST

However, if you apply the REUSE function, the last element in the shorter array is used tocomplete the operation on the remaining elements of the longer array. The following version oprogram produces a result of 4000:@VM:200:@VM:300:

Program Example

VIEWERS = 100:@VM:200:@VM:3COST = 40:@VM:1VCOST = VIEWERS*REUSE(COST)

Developing UniBasic Applications 163

Page 164: Basd_52

Chapter 6 - Working with Data in Programs

wing

Mathematic FunctionsNumeric functions process variables, constants, tables, or data in a variety of ways. The follotable lists UniBasic mathematical functions.

Function Action

ABS Returns the positive value of a number.

ACOS Returns the arc cosine (inverse cosine) in degrees.

ASIN Returns the arc sine (inverse sine) in degrees.

ATAN Returns the arc tangent (inverse tangent) in degrees.

COS Returns the cosine of a number.

EXP Returns the base number raised to the power specified.EXP is the inverse of LN.

INT Returns the integer value of a number. INT truncates; itdoes not round the value.

LN Returns the natural base logarithm. LN is the inverse ofEXP.

MOD Returns the remainder of the division operation usingspecified numbers.

PWR Raises a number to the power specified.

RND Returns a random integer from 0 to a specified number-1.

SIN Returns the sine of a number.

SQRT Return the square root of a positive numeric expression.

SUM Totals the numeric values in an attribute according todynamic array delimiters. You can enter a range, startingposition, and level for which to calculate the total.

Mathematic Functions

164 Developing UniBasic Applications

Page 165: Basd_52

Performing Numeric Operations

For the syntax and use of these functions, see theUniBasic Commands Reference.

ReminderNumeric functions on data containing the null value result in the null value.

TAN Returns the tangent of numeric expression.

Function Action

Mathematic Functions (continued)

Developing UniBasic Applications 165

Page 166: Basd_52

Chapter 6 - Working with Data in Programs

ter

imal.

at.the

ns.

d

at.. You

n

ese

Formatting and Converting Data

UniData provides functions to format, modify, and convert the following types of data:

• Characters – Convert between EBCDIC and ASCII for compatibility with other compusystems. You can also convert from ASCII character to ASCII code (decimal value).

• Strings and dynamic arrays – Justify and format using special characters.

• Numbers – Justify and format using special characters for dollars and other numericdisplay formats. Convert among ASCII character, decimal, binary, octal, and hexadecModify, justify, scale, and round numbers.

• Dates and times – Convert between external display format and UniData internal formFormat dates and time for display using special characters; spell out month or day ofweek.

Before getting into the types of data, you should understand the ICONV and OCONV functio

ICONV and OCONV: The All-Purpose FunctionsThe UniBasic functions ICONV and OCONV perform many conversions between internal andisplay format, among numbering systems, and others. ICONV primarily converts to internalformat for date and number storage, and OCONV primarily converts to external display formYet both perform many other conversions, and sometimes both execute the same conversionwill see the different options for these commands listed throughout the following sections.

OCONVS performs on an array the same function that OCONV performs on a variable. WheOCONVS is available, the functions are represented in the tables that follow as OCONV/S.

NoteWhen invalid data is submitted to ICONV or OCONV, or an invalid conversion code is used, thfunctions return the original value. In BASICTYPE P, with UDT.OPTIONS 56 on, OCONVreturns an empty string if the input value or conversion code is invalid.

166 Developing UniBasic Applications

Page 167: Basd_52

Formatting and Converting Data

le for

r

You can use the following program example to test the many conversion code options availabICONV and OCONV:

Program Example

PROMPT ""LOOP

PRINT "Input or output [I/O]?" :INPUT i_or_oIF i_or_o = "" THEN STOPPRINT "Conversion code? " :INPUT y_conv_codePRINT "Argument? " :INPUT z_argumentIF OCONV(i_or_o, "MCU")= "O" THEN

PRINT "Executing OCONV"answer = OCONV(z_argument,y_conv_code)

END ELSEanswer = ICONV(z_argument,y_conv_code)

ENDPRINT \"\ : answer : \"\

WHILE 1 DO REPEAT

The following screen example shows how you can test the masked extended (MD) option foOCONV by running the previous program:

Screen Example

Input or output [I/O]?OConversion code? ME2;1Argument? 123.123Executing OCONV"12.31"Input or output [I/O]?:

Developing UniBasic Applications 167

Page 168: Basd_52

Chapter 6 - Working with Data in Programs

from

Character Format ConversionUse the character conversion functions described in the following table to convert data to andformats for other computer systems.

For the syntax and use of these functions, see theUniBasic Commands Reference.

Strings and Dynamic ArraysSeveral formatting functions are available for manipulating data in strings or dynamic arrays.

Function Action

ASCII Converts the string expressionstr.exprfrom EBCDIC to thecorresponding ASCII values. This is the inverse of the EBCDICfunction.

EBCDIC Converts the string expressionstr.exprfrom ASCII to thecorresponding EBCDIC values. This is the inverse of the ASCIIfunction.

CHAR Converts from ASCII code (decimal value) to ASCII character.

SEQ Converts from ASCII character to ASCII code (decimal).

Converting Character Formats

Function Action

FMTS Formats a multivalued attribute for output, adding specialcharacters for dollars, dates, or other number formats.

[] Replaces a string, starting at the position indicated.

: Concatenates strings.

Formatting and Modifying Strings

168 Developing UniBasic Applications

Page 169: Basd_52

Formatting and Converting Data

For the syntax and use of these functions, see theUniBasic Commands Reference.

DOWNCASEICONV MCLOCONV/S MCL

Converts characters to lowercase.

UPCASEICONV MCUOCONV/S MCU

Converts characters to uppercase.

OCONV/S MCTICONV MCT

Converts to initial caps style. The first character in eachword is uppercase, and the remaining characters arelowercase.

OCONV/S MLICONV ML

Left-justifies a string or dynamic array.

CONVERT Replaces selected characters in a string.

OCONV/S MCCICONV MCC

Converts all occurrences of substringx to substringy.

OCONV/S MCPICONV MCP

Converts nonprinting characters to tildes (~).

TRIM Removes all extraneous spaces from a string.

TRIMB Removes all trailing spaces from a string.

TRIMF Removes all leading spaces from a string.

OCONV/S S Converts to SOUNDEX phonetic code.

Function Action

Formatting and Modifying Strings (continued)

Developing UniBasic Applications 169

Page 170: Basd_52

Chapter 6 - Working with Data in Programs

rl,the

In the following example, OCONV MCU converts all characters in the variablei_or_o touppercase:

Program Example

PROMPT ""LOOP

PRINT "Input or output [I/O]?" :INPUT i_or_oIF i_or_o = "" THEN STOPPRINT "Conversion code? " :INPUT y_conv_codePRINT "Argument? " :INPUT z_argumentIF OCONV(i_or_o, "MCU") = "O" THEN

PRINT "Executing OCONV"

answer = OCONV(z_argument,y_conv_code)END ELSE

answer = ICONV(z_argument,y_conv_code)ENDPRINT \"\ : answer : \"\

WHILE 1 DO REPEAT

DISPLAY @(10,9+ENTRY):OCONV(ORDER.REC<7,ENTRY>,"MR2$,"):

NumbersYou can round and scale numbers, and you can use special characters to format numbers fodisplay as dollars or other styles. You can also convert numbers among decimal, binary, octahexadecimal, and ASCII. The following two sections introduce the conversions available andfunctions for performing these conversions:

• Formatting and modifying numbers.

• Converting among numbering systems and ASCII.

170 Developing UniBasic Applications

Page 171: Basd_52

Formatting and Converting Data

bers.

s

.

Formatting and Modifying Numbers

You can use the functions described in the following table to format, convert, and modify num

For the syntax and use of these commands, see theUniBasic Commands Reference.

Function Action

FMT Right or left justifies, suppresses zeros, and formats using specialcharacters.

OCONV/S ML Left justifies, suppresses zeros, scales a specified number of decimalplaces, rounds to specified number of decimal places, and formatsusing special characters.

ICONV ML Left justifies, scales a specified number of decimal places, and roundsto specified number of decimal places.

ICONV MROCONV/S MR

Right justifies, scales a specified number of decimal places, rounds tothe number of decimal places indicated, and suppresses or adds zeroto the left or right.

ICONV MRnOCONV/S MRnICONV MDOCONV/S MD

Formats for dollars using special characters. For OCONV only, addsspecial characters for credit, debit, and other monetary indicators.

FMT Specifies length of converted string, fills string with a specifiedcharacter if data is shorter than the length indicated, breaks up thestring if it is longer than the length indicated, centers text, scales aspecified number of decimal places, and adds other special characters

ICONV MD Converts decimal to integer, scales a specified number of decimalplaces, and rounds to specified number of decimal places.

OCONV/S MPOCONV/S MP1

Converts integer to packed decimal.

ICONV MP Converts packed decimal to integer.

Functions for Formatting and Modifying Numbers

Developing UniBasic Applications 171

Page 172: Basd_52

Chapter 6 - Working with Data in Programs

rious

The following program segment is taken from the sample program in“Appendix A - SampleProgram.”In this example, OCONV MR2$ is used to display the price of an item.

Program Example

ALTER_RECORD:* Create a new screen, and allow PRICE and ADDRESS to be changed.

* Initialize variables and draw the screenNEED.TO.WRITE = 0DISPLAY @(-1):@(15,5):"Alter ORDER":DISPLAY @(10,8):"(Press RETURN to leave un-changed)"DISPLAY @(8,9):"Old Price":@(42,9):"New Price (Enter 2 decimal places)"

* Change the PRICE field (if desired)FOR ENTRY = 1 TO NUM_ENTRIES

NEW.PRICE = ""DISPLAY @(10,9+ENTRY): OCONV(ORDER.REC<7,ENTRY>,"MR2$,") :INPUT @(45,9+ENTRY):NEW.PRICENEW.PRICE = OCONV(NEW.PRICE,"MCN")IF NEW.PRICE # '' AND NUM(NEW.PRICE) THEN

ORDER.REC<7,ENTRY> = NEW.PRICENEED.TO.WRITE = 1

ENDNEXT ENTRY

Alternate Numbering Systems and ASCII

You can convert among decimal, ASCII character, binary, octal, and hexadecimal by using vaoptions of the ICONV and OCONV functions.

Function From To

ICONV MB Binary Decimal

ICONV MB0C Binary ASCII characters

OCONV/S MB Decimal Binary

Converting Among Numbering Systems and ASCII

172 Developing UniBasic Applications

Page 173: Basd_52

Formatting and Converting Data

ple,

OCONV conversions from ASCII characters produce multiple-digit numbers in the targetnumbering system:

• Hexadecimal – One ASCII character produces two hexadecimal characters. For examASCII character 0 is equal to hexadecimal 30.

• Octal – One ASCII character produces three octal characters.For example, ASCII character 0 is equal to octal 060.

• Binary–One ASCII character produces eight binary characters.For example, ASCII character 0 is equal to octal 00110000.

For the syntax and use of these commands, see theUniBasic Commands Reference.

OCONV/S MO Decimal Octal

OCONV/S MXOCONV/S MCD[x]ICONV MCX[D]

Decimal Hexadecimal

SEQ Decimal ASCII character

ICONV MO Octal Decimal

ICONV MO0C Octal ASCII characters

OCONV/S MCX[D]OCONV/S MCDICONV MXICONV MCD[X]

Hexadecimal Decimal

ICONV MX0CICONV HEX

Hexadecimal ASCII characters

OCONV/S MB0C ASCII character Binary

OCONV/S MO0C ASCII character Octal

Function From To

Converting Among Numbering Systems and ASCII (continued)

Developing UniBasic Applications 173

Page 174: Basd_52

Chapter 6 - Working with Data in Programs

ong

II

Numbering System Examples

The following table provides examples using the ICONV and OCONV functions to convert amnumbering systems and ASCII characters.

For the syntax and use of these functions, see theUniBasic Commands Reference.

The following example demonstrates the use of ICONV to convert from hexadecimal to ASCcharacter:

Function From To

ICONV MB 01100100 100

ICONV MB0C 01100100 d

OCONV/S MB 100 01100100

OCONV/S MO 100 144

OCONV/S MX 100 64

SE 100 d

ICONV MO 144 100

ICONV MO0C 144 d

ICONV MX 64 100

ICONV MX0CICONV HEX

64 d

OCONV/S MB0C d 01100100

OCONV MO0C d 64

OCONV/S MX0COCONV/S HEX

d 64

CHAR d 100

Examples of Numbering System Conversions

174 Developing UniBasic Applications

Page 175: Basd_52

Formatting and Converting Data

Program Example

PRINT "Convert hex to ASCII character."PRINT "Enter hex number to convert: " :INPUT i_numo_num = ICONV(i_num,'MX0C')PRINT "hex ":i_num:" = ASCII character ": o_numEND

Here is the output from the previous program:

Screen Example

Convert hex to ASCII character.Enter hex number to convert: ?64hex 64 = ASCII character d

Dates and TimesThe OCONV and ICONV functions convert dates and times from the internal format stored inUniData files to a more readable external format suitable for display or inclusion in a report.

Developing UniBasic Applications 175

Page 176: Basd_52

Chapter 6 - Working with Data in Programs

s,

lled

.

Date Formats

Valid formats for internal storage and external display of dates include the following:

• Internal format – The number of days before or since December 31, 1967.

• External format – You can direct UniData to use spaces, forward or backward slasheperiods, or commas as delimiters when converting to or from the following outputformats:

• Standard U.S.: MM/DD/YY

• International: DD/MM/YY

• Month, Day, Year (month can be a number, three-digit abbreviation, or can be speout; day of the week can be added)

TipStore dates in internal format so that you can then perform arithmetic operations on them.

Functions for Converting Dates

Use the ICONV and OCONV functions to convert between internal and external date formats

For the syntax and use of these functions, see theUniBasic Commands Reference.

Function Action

ICONV D Converts from standard U.S. external date format tosystem date.

OCONV/S D Converts from internal system date to a specifiedexternal date format.

ICONV MT Converts from external time format to system time.

OCONV/S MT Converts from internal system time to external timeformat.

Functions for Converting Dates

176 Developing UniBasic Applications

Page 177: Basd_52

Formatting and Converting Data

ter

and

ry.ot

V

igitsthe

ext

Points to Remember When Entering Dates

If you are not aware of the following defaults, conversions into internal date format (usingICONV) might not produce the effects you expect:

• If you do not enter a year, UniData defaults to the current year. For example, if you en12/1 and the year is 1996, the system stores 10563 (12/1/96).

• If you enter a number between 1 and 12, UniData defaults to the first day of the monththe current year. For example, if this year is 1996 and you enter 12 only as the date,UniData stores 10563 (12/1/96).

UDT.OPTIONSYou can invalidate all date input of less than six digits by setting UDT.OPTIONS 82 on.

Century Pivot Date

Prior to UniData 5.2, any 2-digit year entered from 01 through 29 defaulted to the next centuFor example, UniData interpreted 12/31/29 as December 31, 2029. 1930 was the century pivdate.

You can now set your own century pivot date. The century pivot date only applies to the ICONfunction when using the D2 format, not D3 or D4.

The udtconfig file, located in /usr/ud52/include on UniData for UNIX or \udthome\include onUniData for Windows NT or Windows 2000, now contains the CENTURY_PIVOT parameter,with a default value of 1930. You can change this value in one of the following ways:

• Enter a 4-digit year. UniData interprets this first 2 digits as the century, and the last 2 das the year. The last 2 digits of the year you enter, through 99, are considered to be incentury you specify. 0, through the year you entered -1, are considered to be in the ncentury. For example, if the century pivot date is 1950, years 50 through 99 are in the1900’s, and years 0 through 49 are in the 2000’s. If the century pivot date is 2000, 0through 99 are in the 2000’s.

• Enter a code in the form ofnn, indicating that the nextnn years are in the next century.UniData calculates the century pivot date as:

current_year - (100 -nn)

Developing UniBasic Applications 177

Page 178: Basd_52

Chapter 6 - Working with Data in Programs

date

the

ury

slash,at:

For example, if the current year is 2000 and the century pivot code is 50, the century pivotis 1950 (2000 - (100 - 50)).

The CENTURY.PIVOT ECL command overrides the systemwide century pivot date defined inudtconfig file.

Syntax:

CENTURY.PIVOT [4-digit year| nn]

If you enter CENTURY.PIVOT with no options, UniData returns the current setting for the centpivot date.

You can also use the UniBasic CENTURY.PIVOT function to set the century pivot date.

Syntax:

CENTURY.PIVOT (4-digit year| nn)

Time Formats

Valid formats for internal and external storage and display of time include the following:

• Internal format – The number of seconds since midnight.

• External format – You can direct UniData to use spaces or special characters such asperiod, comma, or asterisk as delimiters when converting to the following output formHH MM [SS].

178 Developing UniBasic Applications

Page 179: Basd_52

Formatting and Converting Data

e is

ear.

Date and Time Examples

The following program demonstrates conversion into internal date format. First, the user isprompted for date, and that date is converted to internal format. On the first print line, the datdisplayed both as entered and in internal format. The next print line displays the internal dateconverted back to external format with a slash between the two-character month, day, and y

Program Example

PRINT "Enter date to be converted to internal format:"INPUT i_dateo_date = ICONV(i_date,"D")PRINT "Date ":i_date:" was converted to ":o_datePRINT o_date:" converts back to ":OCONV(o_date,"D2/")END

The following results if the year is 1995 and you enter 3 in response to the prompt:

Screen Example

Enter date to be converted to internal format:?3Date 3 was converted to 99229922 converts back to 03/01/95

The following table shows several date and time conversions.

Function InputValue

Output Format

OCONV/S D2/ 1 1/1/68

OCONV/S D4* 10300 03*13*1996

ICONV MT 12:00 43260

Date and Time Conversion Examples

Developing UniBasic Applications 179

Page 180: Basd_52

Chapter 6 - Working with Data in Programs

NoteDates default to U.S. format. For European format, use the ECL command DATE.FORMAT,which is described in theUniData Commands Reference.

ICONV D 12/1/28 22251

OCONV/SDDMY,A,Z4

22251 01 December 2028

OCONV/S MT 82800 23:00

FunctionInputValue Output Format

Date and Time Conversion Examples (continued)

180 Developing UniBasic Applications

Page 181: Basd_52

UniBasic Multibyte Support

single

one

de

nt.

UniBasic Multibyte Support

This section summarizes the support of languages that require multiple bytes to represent acharacter.

• Modified Functions and Commands – Support multibyte languages.

• Single-Byte Functions – Support only single-byte languages.

• Multibyte Functions – Designed specifically for multibyte language support.

Multibyte languages require that strings be recognized by character rather than byte. Thesechanges do not affect functionality for single-byte languages, because, for these languages,byte represents each character.

Modified Functions and CommandsThe following table lists the UniBasic functions that have been modified to analyze strings bycharacter instead of byte.

Function Comment

CHANGE Replaces all occurrences of a substring with a string.

CHAR Changes a numeric expression to its ASCII (American Standard Cofor Information Interchange) character string equivalent.

CHARS Changes a numeric value in an array to its ASCII character equivale

COL1 Returns the column position preceding a substring found by theFIELD function.

COL2 Returns the column position following a substring found by the FIELDfunction.

CONVERT Converts a single- or multibyte character string to another characterstring.

COUNT Returns the number of times a substring appears within a string.

UniBasic Character Recognition Functions

Developing UniBasic Applications 181

Page 182: Basd_52

Chapter 6 - Working with Data in Programs

nt

as1

ed

r in

tic

e

t

COUNTS Returns the number of times a substring appears within each elemeof an array.

DCOUNT Counts delimited substrings.

FIELD Locates and returns a substring or group of substrings; treats a stringan array, with fields delimited by any ASCII character. See also COLand COL2 in this table.

FINDSTR Determines the position of a substring in a dynamic array.

GET Receives unprompted input from an attached line.

ICONV Converts string or numeric data to internal representation format bason conversion codes.

INDEX Returns the starting position of a specified occurrence of a substringwithin a string.

INPUT Requests data from an input queue or the terminal screen.

INPUT @ Places the cursor at a specific location on the terminal screen andrequests input from the user. See the note on mask parameters latethis chapter.

LEN Returns the length of an expression.

LENS Returns the length of the values within each element of a dynamicarray.

MATCH Determines if a variable matches a specific pattern of characters ornumbers. Only single-byte characters are considered to be alphabeor numeric.

MATCHFIELD Returns a substring that matches a pattern or literal. Only single-bytcharacters are considered to be alphabetic or numeric.

OCONV Converts string or numeric data from internal format to display formabased on conversion codes.

Function Comment

UniBasic Character Recognition Functions (continued)

182 Developing UniBasic Applications

Page 183: Basd_52

UniBasic Multibyte Support

ytek "

e

,

NoteMask – Multibyte characters could be masked for display purposes. However, each double-bcharacter uses two display characters. So, four double-byte characters displayed in the mas###-

### " prints as "XX -XX " (two characters, a space, a hyphen, two characters, and a space).

Single-Byte FunctionsThe following table lists the functions that might not work properly when used with a multibytcharacter set.

REMOVE Searches a dynamic array for system delimiters, then assigns thedelimiter and following array element to a variable. Recognizescol.posas a character position.

SEQ Converts a single character to its ASCII code value.

SEQS Converts the first character in each element of a dynamic array to itsASCII code value.

SUBSTRINGS Extracts strings from elements within a dynamic array.

SWAP Replaces all occurrences of one substring with a second substring.

Function Comment

ALPHA Because UniBasic does not recognize multibyte characters as alphabeticreturns 0 instead of converting them.

DOWNCASE Converts only single-byte characters to lowercase.

Single-Byte Functions

Function Comment

UniBasic Character Recognition Functions (continued)

Developing UniBasic Applications 183

Page 184: Basd_52

Chapter 6 - Working with Data in Programs

te“

ber

n

rs.

NoteMask – Multibyte characters can be masked for display purposes. However, each double-bycharacter uses two display characters. So, four double-byte characters displayed in the mask###-

### ” prints as “XX -XX ” (two characters, space, hyphen, two characters, and a space).

Multibyte FunctionsThe following UniBasic functions are designed for use with multibyte character sets.

FMT Formats an expression for display. The length parameter defines the numof display characters. The fill character must be single-byte, and thejustification option does not work for multibyte languages. See the note omask following this table.

NUM Determines if an expression is numeric. Returns 0 for multibyte characte

NUMS Determines, for each element of an array, if that element is numeric.Returns 0 if the dynamic array element contains multibyte characters.

PROMPT Sets the prompt displayed by the INPUT command to a specified single-byte character. You cannot prompt with a multibyte character.

SOUNDEX Converts an expression into a phonetic code. Can return unpredictableresults with multibyte characters.

UPCASE Converts only single-byte characters to uppercase.

Function Description

BYTELEN Returns the number of bytes in a string.

CHARLEN Returns the number of characters in a string.

UniBasic Functions for Multibyte Languages

Function Comment

Single-Byte Functions (continued)

184 Developing UniBasic Applications

Page 185: Basd_52

UniBasic Multibyte Support

NoteFor examples of these commands in multibyte languages, seeUniData International.

DISPLAYWIDTH Returns the number of bytes required to display a stringexpression.

ISMB Returns a 0 for single-byte language setting, 1 for multi-byte language setting.

LEN Returns the number of bytes in a string.

MBLEN Returns the number of bytes required to display acharacter.

Function Description

UniBasic Functions for Multibyte Languages

Developing UniBasic Applications 185

Page 186: Basd_52

Chapter 6 - Working with Data in Programs

186 Developing UniBasic Applications

Page 187: Basd_52

Chapter 7 - ExternalInteraction

gram

This chapter introduces the concepts and commands that enable you to write a UniBasic prothat communicates with external software and hardware.

Developing UniBasic Applications 187

Page 188: Basd_52

Chapter 7 - External Interaction

ns:

r

In This Chapter

UniBasic program interaction with software and hardware is presented in the following sectio

• “Interacting with Other UniBasic Programs”

• “Interacting with UniData”

• “Writing User Exits”

• “Interacting with Hardware I/O Devices”

• “Interacting with the Operating System”

For more information about running UniBasic programs from ECL, see theUniData CommandsReference. For more information about using C programs (for UNIX) or external programs (foWindows NT or Windows 2000) with UniData, see“Chapter 8 - Linking Programs with UniData.”For more information about the interaction of UniBasic with paragraphs, menus, and virtualattributes, see theUsing UniData.

188 Developing UniBasic Applications

Page 189: Basd_52

Interacting with Other UniBasic Programs

easic

ve

E

Interacting with Other UniBasic Programs

You can interact with other UniBasic programs by sharing data, by incorporating code atcompilation, and by calling programs. These commands and concepts are presented in thefollowing parts of this section:

• Sharing Data

• Including Code at Compilation

Sharing DataWhen you design an application, you can divide processing into several programs that use thsame variables. You can use one of the following vehicles for passing variables among UniBprograms:

• Program Arguments (using @SENTENCE)

• Subroutine Call Arguments

• COMMON

• Data Stacks

Program Arguments

You can execute a UniBasic program from ECL, from a paragraph, or from another UniBasicprogram. The statement that executes the program is stored in @SENTENCE. You can retriearguments that were included in this statement by parsing the contents of @SENTENCE.

TipRemember that if you include EXECUTE or CHAIN in the program, the value of @SENTENCwill be updated.

Developing UniBasic Applications 189

Page 190: Basd_52

Chapter 7 - External Interaction

lesinede forthe

a

asicr one.

ram

Subroutine Call Arguments

When only few variables are being passed, or only two programs share them, passing variabthrough arguments is the most expedient method of sharing data. The variables must be defthe same in the calling and called routines, and the called program or subroutine must providthe arguments in the SUBROUTINE statement. The CALL command transfers processing tocalled program and lists the arguments to be passed. The SUBROUTINE command beginscataloged subroutine and lists the arguments to be received.

Regardless of the BASICTYPE you use to compile, if you pass the same variable twice, UniBupdates the variable values for both occurrences of the variable whenever you change eitheFor this reason, both xx and yy always contain the same value in the following program:

test program:

tv1 = "howdy"

CALL test.sub(tv1,tv1)

test.sub program:

SUBROUTINE test.sub(xx,yy)xx = xx : "!"yy = yy : "?"PRINT "xx = ":xxPRINT "yy = ":yyRETURN

In the preceding subroutine, both variables, xx and yy refer to the variable tv1. So when xx isupdated by being concatenated with !, yy is also updated, and when yy, which now containshowdy!, is updated by being concatenated with ?, xx is also updated. The output for this progfollows:

xx = howdy!?yy = howdy!?

190 Developing UniBasic Applications

Page 191: Basd_52

Interacting with Other UniBasic Programs

Eacha(s), bylish

areas.

and

rompt.

.

he

COMMON

When you are sharing groups of variables among multiple programs, you can use the singleunnamed common or multiple named common areas to pass a stack or stacks of variables.program that needs to access the variables must define the named or unnamed common areexecuting the COMMON command, before accessing them. You can most efficiently accompthis by defining common in a file and including that file in programs at compile time (with$INCLUDE).

TipWhen possible, pass parameters in SUBROUTINE arguments rather than through commonThis makes it easier to tell which subroutine uses which arguments.

WarningTrying to access variables in common areas before defining them with the COMMON commcould result in a core dump.

Data Stacks

You can use a data stack to pass data to INPUT statements in called processes or UniBasicprograms. The stack is available until the user process ends, returning the user to the ECL p

TipThe DATA statement, which loads the data stack, can also be placed in a UniData paragraph

The data stack is managed as follows:

• The stack is stored in the @DATA system variable.

• The stack is loaded by the DATA command.

• Items in the stack are delimited by CR (carriage return).

• The stack is built and depleted on a first in first out basis. After UniData exhausts all tresponses in the data stack, it reverts to the terminal for user input.

Developing UniBasic Applications 191

Page 192: Basd_52

Chapter 7 - External Interaction

e thee are

userms

pting

ata

TipTo suppress output to the terminal, execute the UniBasic HUSH command immediately beforINPUT command that reads the stack; otherwise, the INPUT prompt and data stack responsdisplayed.

Examples of Passing Data Through a Data Stack

In this example, a program prompts for user input and displays information requested by theon a display terminal; another program prints the same information in hardcopy. Both prograrequire input to be loaded into the variables ACTIVITY.END.DATE and REGION. The firstprogram CHAINs to the second program, passing the values in a data stack rather than promthe user for the same data twice. The first program contains the following code:

Program Example

PRINT "Enter the last date for activity"INPUT ACT.END.DATE* check for valid dates and convert to internal formPRINT "Enter Region"INPUT REGION* check for valid regions* display dataPRINT "Do you want a hardcopy?"INPUT ANSIF ANS = "Y" THEN

DATA ACT.END.DATEDATA REGIONCHAIN "REGION.PRINT"; * execute REGION.PRINT program

END...

When the INPUT statements in REGION.PRINT are executed, UniBasic fills them from the dstack.

192 Developing UniBasic Applications

Page 193: Basd_52

Interacting with Other UniBasic Programs

dlowed

nes

The following program segment, which is taken from REGION.PRINT, prompts for the passedata. The presence of the data stack does not inhibit the prompt; it displays on the screen folby the response from the data stack.

Program Example

PRINT "Enter the last date for activity"INPUT ACT.END.DATE* check for valid dates and convert to internal formPRINT "Enter Region"INPUT REGION* check for valid regions

NoteYou can clear the stack created by DATA statements using either the UniBasic or ECLCLEARDATA commands.

Including Code at CompilationYou can insert a UniBasic program or program segment during compilation with the UniBasiccommands $INCLUDE and $INSERT. You might use these commands to include stack routithat perform frequently used operations, such as EQUATE and DEFFUN.

Executing UniBasic Programs and Subroutines

The following table lists commands that execute other UniBasic programs and subroutines.

Command Acton

CALL Transfers control to an external subroutine. When UniBasicencounters a RETURN statement in the subroutine, it returnscontrol to the calling program.

Executing UniBasic Programs and Subroutines

Developing UniBasic Applications 193

Page 194: Basd_52

Chapter 7 - External Interaction

and

UDT.OPTIONSUDT.OPTIONS 6 and 40 determine where control is passed on RETURN; UDT.OPTIONS 1127 clear the data stack. For more information, see theUDT.OPTIONS Commands Reference.

CHAIN Terminates the current UniBasic program and executes anotherprogram. A common use of CHAIN is to execute a catalogedprogram.

ENTER Transfers control to a cataloged program.

EXECUTE/PERFORM

Executes an ECL or UniData SQL command. (You canEXECUTE “RUN program.)

Command Acton

Executing UniBasic Programs and Subroutines (continued)

194 Developing UniBasic Applications

Page 195: Basd_52

Interacting with UniData

r 4-s,

nto

Interacting with UniData

Interaction with other UniBasic programs and UniData products is presented in the followingsections:

• “Executing Virtual Attributes”

• “Executing ECL Statements”

• “Executing UniData SQL Statements”

• “Defining and Using Programs and Functions”

ReminderUniData stores and makes available information about the system, the user process, and theUniBasic program being executed in @variables. Some are available through any UniData oGL tool; others are available only through UniBasic. For a complete list of UniData @variableseeUsing UniData. The UniBasic @variables are listed in theUniBasic Commands Reference.

Executing Virtual Attributes

ReminderVirtual attributes are dictionary records that contain executable code. They are explained inUsingUniData.

You can execute a virtual attribute from within a UniBasic program with the UniBasicCALCULATE or {} command, or the ITYPE function. You must first open the dictionarycontaining the virtual attribute to @DICT and read a record from the corresponding data file i@RECORD.

Developing UniBasic Applications 195

Page 196: Basd_52

Chapter 7 - External Interaction

pt

Executing ECL StatementsYou can execute ECL commands within a UniBasic program. Any entry valid at the ECL promcan follow an execute command.

The following table lists the UniBasic commands for executing UniData commands.

The following UniBasic statement executes the ECL command LIST.READU:

Program Example

EXECUTE "LIST.READU"

Command Action

EXECUTEPERFORM

Executes an ECL command. Returns output and error messages invariables if specified.

Note -Use the CAPTURING clause to save output of the executedcommand in an dynamic array. Use the RETURNING clause tosave error messages.

MDPERFORM Executes a UniData command, and transfers a select list ifspecified. Also returns output and error messages in variables ifspecified.

UDTEXECUTE Executes an ECL command in BASICTYPE U regardless of theBASICTYPE the program was compiled in. Also returns outputand error messages in variables if specified.

Execute Commands

196 Developing UniBasic Applications

Page 197: Basd_52

Interacting with UniData

SQLnclude

,

ated

The next UniBasic statement executes a UniQuery statement:

Program Example

EXECUTE "SSELECT CUSTOMER WITH STATE='CO' BY ZIP"

For more information about ECL, seeUsing UniData.

Executing UniData SQL StatementsYou can use the EXECUTESQL, EXECUTE, and PERFORM commands to execute UniDatastatements. If you need to return selected items for subsequent processing by the program, ia TO clause and a variable in which UniData SQL can return selected items.

In the following example, the variable SQL_INPUT is provided for the return of NAME, ADDRand CITY:

Screen Example

EXECUTESQL "SELECT NAME,ADDRESS,CITY FROM CLIENTS TO SQL_INPUT;"DONE=0LOOPPRINT "DONE = ":DONE

READNEXTTUPLE CLIENT.REC FROM 'SQL_INPUT' ELSE DONE = 1UNTIL DONE

CONVERT @AM TO " " IN CLIENT.RECCONVERT @VM TO "," IN CLIENT.RECPRINT "CLIENT.REC = ":CLIENT.REC

REPEATEND

NoteYou must use the UniBasic command CLEARSQL to clear active UniData SQL variables crewith EXECUTESQL...TO statements.

Developing UniBasic Applications 197

Page 198: Basd_52

Chapter 7 - External Interaction

rite

Defining and Using Programs and FunctionsWithin a UniBasic program, you can use the commands described in the following table to wand call other programs and functions.

Command/Function Action

PROGRAM Provided for backward compatibility. Defines a program.

FUNCTION Creates a user-written function that accepts passed argumentsand can return values.

DEFFUN Declares a user-written function that was defined by theUniBasic FUNCTION command.

Commands for Defining and Using Programs and Functions

198 Developing UniBasic Applications

Page 199: Basd_52

Writing User Exits

the

any

a-

xits

y a

Writing User Exits

An explanation of user exits and the procedures for writing and calling them are explained infollowing subsections:

• “What Are User Exits?”

• “Calling a User Exit from UniBasic”

• “Calling a User Exit from a Virtual Attribute”

• “Calling a User Exit from a Proc”

• “Parameters in User Exits”

What Are User Exits?Some RDBMS systems employ “user exits” to convert and format data. UniBasic provides mof these conversions in the UniBasic ICONV and OCONV functions. However, for backwardcompatibility, UniData supports user exits, which consist of a calling statement and a UniDatprovided or user-defined UniBasic subroutine.

You can call user exits from UniBasic, UniQuery, and UniData paragraphs. For backwardcompatibility, UniData supports user exits from Procs. This section focuses on calling user efrom UniBasic programs and calling UniBasic subroutines that serve as user exit functions.

TipYou might find that the operations provided by user exits can be performed more efficiently bUniData @variable, a UniBasic command or function, or a UniData paragraph.

Developing UniBasic Applications 199

Page 200: Basd_52

Chapter 7 - External Interaction

can

ine

are

ta-

ine

Calling a User Exit from UniBasicPerform the following steps to call a user exit from a UniBasic program. The called user exitbe UniData-defined or user-defined.

1. Select a UniData user exit that performs the conversion you want. For a list of user exitconversion routines, seeUsing UniData.

or

Write a UniBasic subroutine to perform the conversion. The first command in the subroutmust be the following:

Syntax:

SUBROUTINE Uuser.exit(ret.val, status, input.val, type)

2. Write the user exit call in your UniBasic program. Regardless of the type of user exit youcalling, use the following syntax:

Syntax:

ret.val= {ICONV | OCONV}( input.val,"Uuser.exit")

The parameters used in these commands are explained in“Parameters in User Exits”later in thissection.

Calling a User Exit from a Virtual AttributePerform the following steps to write a virtual attribute that calls a UniBasic user exit or UniDadefined user exit:

1. Select a UniData user exit that performs the conversion you want. For a list of user exitconversion routines, seeUsing UniData.

or

Write a UniBasic subroutine to perform the conversion. The first command in the subroutmust be the following:

SUBROUTINE Uuser.exit(ret.val, status, input.val, type)

200 Developing UniBasic Applications

Page 201: Basd_52

Writing User Exits

her

it:

2. Write a virtual attribute that calls the user exit. The syntax that you use depends on whetyou are converting single or multivalued/multi-subvalued attributes:

• Singlevalued:{ICONV | OCONV}( input.val,"Uuser.exit")

• Multivalued/Multi-subvalued:SUBR(’-{ICONVS | OCONVS}’,input.val,"Uuser.exit")

The parameters used in these commands are explained in“Parameters in User Exits”later in thissection.

Calling a User Exit from a ProcPerform the following steps to write a Proc that calls a UniBasic- or UniData-defined user ex

1. Select a UniData user exit that performs the conversion you want. For a list of user exitconversion routines, seeUsing UniData.

or

Write a UniBasic subroutine to perform the conversion using the following syntax:

Syntax:

SUBROUTINE Uuser.exit(proc,cib,pib,sib,ibp,cob,pob,sob)

2. Write a statement in a Proc that calls the user exit.

Syntax:

Uuser.exitparam1[,param2]...[,]...

Developing UniBasic Applications 201

Page 202: Basd_52

Chapter 7 - External Interaction

Parameters in User ExitsThe following table describes each parameter of the syntax.

Parameter Description

Uuser.exit The name of the UniData user exit or user-defined UniBasic subroutinethat performs the conversion.

ret.val The string or value UniData returns to the calling program as a result of theconversion function.

status The status of the conversion; 0 indicates a successful conversion.

input.val The input string or value to be converted.

type The type of conversion: 0 for external format to internal format and 1 forinternal format to external format.

proc The source code of the Proc itself. UniData reads the Proc user exitstatement, then passes it and all subsequent lines asproc.

cib The current input buffer: 0 for primary and 1 for secondary.

pib The primary input buffer.

sib The secondary input buffer.

ibp The input buffer pointer.

cob The current output buffer: 0 for primary and 1 for secondary.

pob The primary output buffer.

sob The secondary output buffer.

Parameters in User Exits

202 Developing UniBasic Applications

Page 203: Basd_52

Interacting with Hardware I/O Devices

ytions:

a

Interacting with Hardware I/O Devices

When programming in UniBasic, you can direct input and output (I/O) devices such as displaterminals, printers, and tape drives. These commands are introduced in the following subsec

• “Display Terminals”

• “Printers”

• “Tape Drives”

Display Terminals

Input Commands

Input commands request data from a user’s keyboard or a data stack and store the result invariable for use in a UniBasic program.

For more information about data stacks, seeUsing UniData.

UniBasic provides the following commands for accepting and acting on user input from theterminal.

Command Action

INPUT Requests data from a user terminal or a data stack.

INPUT @ Requests data from a user terminal or a data stack, determines thecursor position and display a mask on the terminal, and determines thecharacteristics of the data received.

INPUTNULL Allows a single character to be defined as the null character in anINPUT @ statement.

INPUTERR Prints a user-defined error message on the bottom line of the displayterminal and clears the error message when UniData receives the nextinput.

Input Commands

Developing UniBasic Applications 203

Page 204: Basd_52

Chapter 7 - External Interaction

ethe

tack,

TipYou can fill input statements from the data stack rather than from user input. For example, thfollowing program segment loads the string “FINISHED” in the data stack and then loads it invariable CODE.

Program Example

DATA "FINISHED"INPUT CODE

UniBasic allows up to 500 elements in the data stack. For more information about the data ssee“Sharing Data”earlier in this chapter, or see the DATA command in theUniBasic CommandsReference.

The UDT.OPTIONS described in the following table affect the input commands.

INPUTIF Assigns data from the type-ahead buffer to a variable.

CLEARINPUTINPUTCLEAR

Clears the type-ahead buffer.

INPUTTRAP Conditionally branches to a specific statement label when specificcharacters are entered.

UDT.OPTION Description When ON

12 If you use INPUTvar, exprwith a data stack and an element in the datastack is shorter thanexpr,UniData retains unused characters and they areavailable for subsequent input statements.

UDT.OPTIONS for Input

Command Action

Input Commands (continued)

204 Developing UniBasic Applications

Page 205: Basd_52

Interacting with Hardware I/O Devices

.

,

UDT.OPTIONSFor more information about UDT.OPTIONS, see theUDT.OPTIONS Commands Reference.

More Display Terminal Commands and Functions

You can use the following UniBasic commands to manage display terminal and keyboard I/O

Terminal Control

Use the commands in the following table to control display on the terminal.

18 When UniData passes data to a UniBasic program to fill an input statementUniData suppresses the echo of the prompt character and the data.

65 If you exceed the field length during an INPUT command, the terminalbeeps.

Command Action

CRT,DISPLAY

Directs output to the display terminal (CRT) regardless of the setting ofthe PRINTER command.

HUSH Enables or disables terminal output.

PAGE Prints the current output page.

PRINT Prints to the display terminal or printer.

PRINT @ Prints to the display terminal at a specific column and row position. Formore about the @ function, see“Enhanced Terminal Capabilities”laterin this chapter.

Terminal Control Commands

UDT.OPTION Description When ON

UDT.OPTIONS for Input (continued)

Developing UniBasic Applications 205

Page 206: Basd_52

Chapter 7 - External Interaction

s and

NotePrint lines can be up to 256 characters. For more information about LIMITS, see theUniDataCommands Reference.

Keyboard Control

Use the ECHO and BREAK commands to control keyboard input.

Prompt, Headings, and Footings

The commands in the following table control the display of the prompt character and headingfootings.

Command Action

ECHO Enables or disables display of keyboard input on the terminal.

BREAK Enables or disables the break key. When enabled, the break keyinterrupts program execution and places the user at thedebugger prompt.

Keyboard Control Commands

Command Action

PROMPT Sets the input prompt to a user-supplied one-character string orempty string.

HEADING Displays a heading at the top of each page, which can be up to536 characters.

FOOTING Displays a footing at the bottom of each page, which can be upto 536 characters.

Prompt, Heading, and Footing Commands

206 Developing UniBasic Applications

Page 207: Basd_52

Interacting with Hardware I/O Devices

as

Enhanced Terminal Capabilities

The UniBasic @ function has two forms, which enable you to:

• Specify a column and row to position the cursor.

• Perform one of 84 terminal actions.

Syntax:

@(col[,row])@(-num.expr)

For a table of all @ options, see the @ function in theUniBasic Commands Reference.

Some commonly used options are provided in the following table.

ReminderBecause @ is a function, it must be used within a statement that contains a command, suchPRINT @ or DISPLAY @.

Option Action

-1 Clears the screen and places the cursor at position 0,0.

-2 Places the cursor at position 0,0.

-3 Clears from cursor to end of screen.

-4 Clears from cursor to end of line.

-19 Sends audible signal. (Terminal beeps.)

-10 Moves cursor up one line.

-17 Move cursor down one line.

@ Function Options for Terminal Control

Developing UniBasic Applications 207

Page 208: Basd_52

Chapter 7 - External Interaction

0:

de.

capfault

Examples

The PRINT @ statement prints data at a specific column and row. For example, the followingstatement prints three asterisks on row 1 beginning in column 38:

Screen Example

PRINT @(38,1):'***'

The following command clears the display terminal and positions the cursor at row 0, column

Screen Example

PRINT @(-1)

In the next example the terminal bell beeps after an error message is printed:

Screen Example

PRINT @(0,23):"Invalid choice. Please re-enter.":@(-19)

NoteUniBasic searches the /usr/lib/terminfo file (for UNIX) or theudthome\include\udtermcap file (forWindows NT or Windows 2000) to obtain terminal configuration and interpretation of the @ coFor UNIX, if terminfo does not exist, UniBasic queries the /etc/termcap file. Obtain terminalemulation settings from your hardware vendor. For Windows NT or Windows 2000, if udtermdoes not exist, UniBasic returns a status message stating that it cannot find the file and will deto vt100 terminal emulation.

208 Developing UniBasic Applications

Page 209: Basd_52

Interacting with Hardware I/O Devices

PrintersThe following table lists the commands that direct the printer.

NotePrint lines can be up to 256 characters. For more information about LIMITS, see theUniDataCommands Reference.

ReminderThe following commands manage both display terminal and printer output: FOOTING,HEADING, PAGE, and PRINT.

Command Action

PRINT ON Direct output to a specific printer.

PRINTER CLOSE Direct output stored in a print file or a printbuffer to the print queue.

PRINTER OFF Direct output to the display terminal.

PRINTER ON Direct output to the printer.

Printer Commands

Developing UniBasic Applications 209

Page 210: Basd_52

Chapter 7 - External Interaction

UDT. OPTIONS and Printing

The UDT.OPTIONS in the following table affect the way in which data is printed.

UDT.OPTION CommandAffected Effect When On

4 OCONV When printing dates, formats month inuppercase.

5 in the absence ofHEADING

Pauses at the bottom of each screen page.

7 n/a Page feeds or returns to the colon promptafter the last line of data is printed ratherthan printing blank lines to end of page.

9 EXECUTE,

PERFORM

Closes the print job after printingcompletes.

25 UniQueryBREAK.ON

keyword

Prints the break line and suppresses thepreceding blank line, essentially inhibitingdouble spacing.

29 OCONV When printing dates, converts Sunday to 7(rather than 0).

32 HEADING,

@ function

Retains the heading when the @ function isused.

34 HEADING,FOOTING

Displays the system date in a specificformat. This option also is affected by theECL command DATE.FORMAT.

UDT.OPTIONS for Printing

210 Developing UniBasic Applications

Page 211: Basd_52

Interacting with Hardware I/O Devices

UDT.OPTIONSFor detailed information about UDT.OPTIONS, see theUDT.OPTIONS Commands Reference.

46 PRINT, CRT

DISPLAY,EXECUTEPERFORM,

INPUT,

SLEEP, STOP

Waits for PRINT, INPUT, EXECUTE, orFLUSH before flushing data to the systembuffer.

48 PRINT,

DISPLAY, CRT

When printing right-justified data, does notbreak as specified in format. (Willoverwrite another column of data.)

59 PRINT,

DISPLAY, CRT

When generating a BSELECT list, doesnot create a blank line for a key when theselected attribute is an empty string.

64 FOOTING Forces the footing to print on the final pageof a report.

UDT.OPTIONCommandAffected Effect When On

UDT.OPTIONS for Printing (continued)

Developing UniBasic Applications 211

Page 212: Basd_52

Chapter 7 - External Interaction

Tape DrivesBefore you execute the UniBasic tape drive commands, you must:

• Initialize the tape drive with the ECL SETTAPE command.

• Attach the tape drive with the ECL T.ATT command.

Other ECL commands also manage the tape drive. For more information, seeUsing UniData.

UniBasic manages tape drive I/O with the following commands.

Command Action

READT Reads the next available record from a tape.

RESIZET Changes the block size used by the WRITETcommand when the block size in one file is not thesame as the block size in T.ATT.

REWIND Rewinds the tape.

WEOF Writes an EOF (end-of-file) mark to tape.

WRITET Writes a record onto tape.

Tape Drive Commands

212 Developing UniBasic Applications

Page 213: Basd_52

Interacting with the Operating System

sic

)

Interacting with the Operating System

Use the commands in the following table to interact with the operating system within a UniBaprogram.

For more information about these functions, see theUniBasic Commands Reference.

The following UniBasic statement executes the UNIX command pwd (print working directoryand stores the results in the variable MY.LOCATION:

Screen Example

PCPERFORM 'pwd' CAPTURING MY.LOCATION

Command/Function Action

PCPERFORM Executes an operating system command within a UniBasicprogram.

SYSTEM Retrieve system-level information set by previous UniBasic orECL commands such as SETPTR and TERM.

UniBasic Operating System Commands

Developing UniBasic Applications 213

Page 214: Basd_52

Chapter 7 - External Interaction

214 Developing UniBasic Applications

Page 215: Basd_52

Chapter 8 - LinkingPrograms with UniData

or is

This chapter introduces the concepts and procedures for writing a UniBasic program that callscalled by an external C program.

For more information about CALLC, seeAdministering UniData on UNIXor theAdministeringUniData on Windows NT or Windows 2000.

Developing UniBasic Applications 215

Page 216: Basd_52

Chapter 8 - Linking Programs with UniData

In This Chapter

This chapter consists of the following sections:

• “Linking C Programs (UNIX Only)”

• “Linking C Programs (Windows NT or Windows 2000 Only)”

216 Developing UniBasic Applications

Page 217: Basd_52

Linking C Programs (UNIX Only)

s

on,

y thethe

ta.

n

arily

Linking C Programs (UNIX Only)

The information in this section applies to the UNIX operating system only. If you use WindowNT or Windows 2000, see“Linking C Programs (Windows NT or Windows 2000 Only)”later inthis chapter.

Before You BeginBefore you try to set up links between UniData and C programs, review the following tips.

• Before you link a C program for CallBasic

Determine whether someone has previously modified the executable files inudthome/work in an effort to link C programs to your UniData executable. If these fileshave been changed, you must restore them to their original state. For more informatisee“If This Is Not the First Time”later in this chapter.

• Before you link a C program for CALLC

When you upgrade from an earlier release, UniData asks whether you want to overlacfuncdef file. If someone installing or upgrading UniData chose not to overlay this file,wrong version could reside inudthome/work. The cfuncdef file printed in the section“FileExamples”later in this chapter shows the correct version of this file to use with UniDa

• Set up a test environment

You can set up an alternate test environment with a separate udt to use to test linkedprograms so you do not disrupt the work of others. For instructions, seeAdministeringUniData on UNIX.

• Sign on as root

UniData supplies required files and templates needed to link the C program or functiowith UniData. These files and templates reside in theudthome/work directory, to whichonly root has read or write access. You can copy the files to another directory temporto work on them. However, unless you set up a test environment, they must reside inudthome/work before you run the make, makeudt, or makeudapi command to set up aCallBasic or CALLC link with UniData.

Developing UniBasic Applications 217

Page 218: Basd_52

Chapter 8 - Linking Programs with UniData

• Provide absolute path

Any time you specify a path in a file, you must specify the absolute path, such as/usr/ud52/work, rather than using an environment variable, such asudthome/work.

• Regarding triggers

You can call a C function from a UniBasic trigger subroutine. For information aboutUniData triggers, see“Chapter 4 - Maintaining Data in Files.”

• Define environment variables

The following environment variables must be defined:udthome, udtlib, andudtbin. Forinformation about setting up environment variables, seeAdministering UniData on UNIX.

You must have the following components to use the CallBasic API:

• Development environment

Your system must have a full software development kit. (A base compiler is not suffi-cient.) You also will need network libraries if you are using NFA.

TipConsult your host operating system documentation and your hardware vendor if you havequestions about your C development environment.

• C program

You need to code and compile the C application that calls UniBasic.

• Function definitions and makefiles

When you install UniData, the file callbas.mk is installed into the directoryudthome/work. You will use this makefile as a template to build your application with

UniData linked into it.

218 Developing UniBasic Applications

Page 219: Basd_52

Linking C Programs (UNIX Only)

be

n be

C

sns.

Calling a C Function from UniBasic with CALLCFollow the procedure described in this section to link a C function with UniData so that it cancalled by a UniBasic program.

TipTo save time and frustration, read“Before You Begin”earlier in this chapter.

Procedure Summary

Here is a summary of the steps you must follow to link a C program with UniData so that it cacalled by a UniBasic program:

1. Write the C program.

2. Compile the C program.

3. Tell UniData about the C program (in cfuncdef_user).

4. Rebuild the UniData executable (using makeudt or makeudapi).

5. Write and compile the UniBasic subroutine.

6. Execute the UniBasic subroutine.

1. Write the C Program

The first step in creating a C function that you will call from a UniBasic program is to write theprogram with the standard compiler for your platform and operating system.

Guidelines for Writing C Programs

You might find the following guidelines helpful when writing the C program.

• Naming Variables

Avoid naming variables or functions with the prefix U and an underscore (U_), such aU_unit and U_errout. UniData uses U_ as an identifier for variable names and functio

Developing UniBasic Applications 219

Page 220: Basd_52

Chapter 8 - Linking Programs with UniData

s.

size

e the

llye

ames to

his

• Passing Arguments

You cannot pass more than 22 arguments. Each argument is limited to 255 characterInclude the bstring header to pass binary data. For more information, see the“Data Typesfor UNIX C Definition” table later in this chapter.

• Returning Arguments

The maximum number of bytes allowed in a function return is 256. If you increase theof a variable of data type bstring, you must free the original memory assignment andreallocate it and reassign the length to avoid a memory leak. For more information, se“Data Types for UNIX C Definition”table later in this chapter.

• Passing Binary Data

Include the bstring header file to pass a binary string to or from a C program, especiawhen that data could contain imbedded ASCII character 0 (which C interprets as a linterminator). To do this, the C function must include the header file callc_bstr.h, whichcontains the definition of bstring, and set the returning string length (for example,retbuf->len and out->len). A sample C program is provided in“Passing bstring-TypeData” later in this chapter.

• Displaying Error Messages

To display error messages, use the UniBasic C function U_errout. U_errout has the ssyntax as U_preprint, except the variable U_unit is replaced by 0. U_erroutoutput goeerrout whereas U_preprint output goes to stdout.

Syntax:

• U_errout(0,"error message from the routine, value is %d",value);

• Printing – To maintain screen integrity and I/O redirection, use the UniBasic Cfunction U_preprint instead of the C function printf. The U_preprint functionrefreshes the screen, enabling the C subroutine to properly manage screen I/O. Tfunction follows syntax similar to printf.

Syntax:

• U_preprint pattern,arg1,arg2...

220 Developing UniBasic Applications

Page 221: Basd_52

Linking C Programs (UNIX Only)

e

• For example:

Program Example

extern int U_unit;...U_preprint (U_unit,"message from the routine, value is %d",value);

• Ending the C Program

Do not use exit to end the C program. Instead, use U_done, which performs variouscleanup tasks, and then terminates the C program.

C Program Example

The following C function (c_example) emulates the UniBasic GETENV function. Both retrievthe value of the specified UNIX environment variable using the UNIX getenv system call.

Program Example

char *c_example(envar)char *envar;{char *getenv();static char buf[100];char *pathlist;sprintf (buf,"%s",getenv(envar));return(buf); /* return string to UniData */}

Developing UniBasic Applications 221

Page 222: Basd_52

Chapter 8 - Linking Programs with UniData

2. Compile the C Program

A. Use the UNIX cc command with the -c option to produce the object code. Verify thefollowing before you proceed to the next step:

• The C program does not contain the main() function.

• The C program compiles cleanly.

For our example, you enter the following commands at the UNIX shell prompt:

Screen Example

$ cc -c c_example.c

B. Copy the object code to theudthome/work directory:

Program Example

$ cp c_example.o $UDTHOME/work

PermissionsTo place the program inudthome/work, you must have write permission to that directory. Forassistance, see your system administrator.

222 Developing UniBasic Applications

Page 223: Basd_52

Linking C Programs (UNIX Only)

d

to

ro-

y of

3. Tell UniData about the C Program

A. Check for required files inudthome/work.

To proceed, the C program must reside in theudthome/work directory, along with themakefile (c_example.mk in this example) and the function definition file (cfuncdef), anthe C functions that the makeudt or makeudapi utility uses (funchead.o interfunc.ocallcf.o, and efs_init.o).

B. Look at cfuncdef.

This file, placed inudthome/work at installation, must not refer to any UniData or site-specific C programs. It could contain reference to site-specific libraries.

Some earlier releases of UniData included some UniData functions in cfuncdef. If theperson installing UniData Release 5.2 or upgrading from an earlier version chose notoverlay this file, you could have the wrong version. Also, if someone has previouslylinked C programs to UniData for CALLC, cfuncdef could contain reference to these pgrams. For an example of an “empty” cfuncdef file, see the template in“File Examples”later in this chapter.

C. Create cfuncdef_user.

After making sure that cfuncdef is free of references to other C programs, make a copit, and call it cfuncdef_user. The file should contain the following three lines:

• $$FUN(you put the C function definition here)

• $$OBJ(you put the object file here)

• $$LIB(you put the library path here if the C function is not stored inudtlib)

Developing UniBasic Applications 223

Page 224: Basd_52

Chapter 8 - Linking Programs with UniData

t upmple.

r more

cfuncdef_user File Example

The following example shows a version of the cfuncdef_user file that has been modified to sethe function c_example on a Hewlett Packard computer. The next few steps refer to this exa

Program Example

/* this is a test for addin g a C function to the*//* Runtime version of UniData. *//* C function declaration format:function-name:return-type:number-of-argument:arg1,arg2,...argn */$$FUN /* beginning of C function */c_example:string:1:string$$OBJ /* object files or .o file comes here *//usr/ud51/work/c_example.o$$LIB /* library comes here */

D. Add the function definition to cfuncdef_user.

The function definition line follows $$FUN.

Syntax:

fun_name:rtn_data_type:num_arg:arg_data_type

A colon separates each element, and a comma separates multiple arguments. You can entethan one function definition, each on a separate line.

The following table lists the function definition arguments.

Argument Description Value inExample

fun_name The name of the C program as itwill be called from UniBasicprograms.

c_example

rtn_data_type The data type of the return value. string

cfuncdef Function Definition

224 Developing UniBasic Applications

Page 225: Basd_52

Linking C Programs (UNIX Only)

The following table lists valid data types for arguments and return values.

num_arg The number of arguments. 1

arg_data_type The data type of the arguments. string

Data Type Description

int An integer. A 32-bit signed long word.

short A 16-bit signed long word.

long A 32-bit signed long word (same as int).

double A 64-bit floating point value.

float A 32-bit floating point value.

char A signed byte.

string A pointer to a character string terminated by NULL (0)in a 34-K buffer. The buffer size cannot be changed.

Although memory reallocation is not supported, you canallocate memory for the variable in a UniBasic programbefore passing it in the parameter to the C program. Forexample:

...

var = SPACE(64000)

CALLC(var...)

The variable now has been allocated a size of

64 KB.

Data Types for UNIX C Definition

Argument DescriptionValue inExample

cfuncdef Function Definition (continued)

Developing UniBasic Applications 225

Page 226: Basd_52

Chapter 8 - Linking Programs with UniData

it in

E. Add the object code path and file name.

Enter the object code path and file name on the line that follows $$OBJ. You can putany directory as long as you specify the absolute path here.

F. Add the library path to cfuncdef_user.

If your function does not reside inudtlib, enter the library path on the line that follows$$LIB, preceded by -L. Do not use the environment variable (udtlib) in the path name, butinstead list the absolute path. The function in the example does not link any alternatelibraries.

bstring A pointer to a structure (struc ) in a buffer that is aminimum of 34 KB in size. You can reallocate thisbuffer. Also, you can pass data contain the NULL (0)character by using bstring. Defined as:

typedef struct (char *str;int len

} bstring;

Warning - To prevent a memory leak, you must free theoriginal buffer assignment before reallocating it. If thestring is changed, the length must also be reassigned.

pointer A 32-bit signed long word.

Data Type Description

Data Types for UNIX C Definition (continued)

226 Developing UniBasic Applications

Page 227: Basd_52

Linking C Programs (UNIX Only)

iatthat

eequent

rite

n

cess,

itstablet-

4. Rebuild the UniData Executable

The system-level makeudt command builds a new UniData executable (udt). The makeudapcommand also builds a new UniData executable (udapi_slave) with links to C programs so ththey are accessible through InterCall, UniObjects, or UniObjects for Java. Use the commandis appropriate for your situation to build the executable.

WarningIf you are upgrading from a version of UniData before Release 3.3, you will need to install thmakefile for Release 5.2 because the format for this file has changed more than once in subsreleases. If you use a pre-3.3 version of the file, makeudt or makeudapi will fail.

It is best to be logged in as root to execute makeudt or makeudapi because you must have waccess toudthome/work. Also, you must be in theudthome/work directory, but execute the utilityfrom udtbin, as in the following examples:udtbin/makeudt orudtbin/makeudapi.

These utilities use cfuncdef_user and base.mk to create the file new.mk. For more informatioabout these utilities, see“More on make, makeudt, and makeudapi”in this chapter. Forinformation about error messages and common problems you could encounter during this prosee“Troubleshooting CALLC”later in this chapter.

TipIf users are logged in to UniData, the makeudt or makeudapi utility might not finish becausemight not be able to overwrite the production udt or udapi_slave. If an error message displayindicating an unsuccessful completion, you need to locate the new udt or udapi_slave execuin theudthome/work directory. Later on, when UniData is no longer busy, move the new execuable toudtbin.

makeudt

Syntax:

• makeudt [-n nfa]

Developing UniBasic Applications 227

Page 228: Basd_52

Chapter 8 - Linking Programs with UniData

ll

on,

The following table describes each parameter of the syntax.

For more information about using the makeudt utility, seeAdministering UniData on UNIX.

makeudapi

Syntax:

• makeudapi

For more information about using the makeudapi utility, seeAdministering UniData on UNIX.

5. Write and Compile the UniBasic Program

A. Write the UniBasic program.

Next, you will write the UniBasic program that uses the UniBasic CALLC function to cathe C function.

UniBasic Program Example

In the following example, the UniBasic program CDEMO performs the following tasks:

1. Prompts for the name of the environment variable for which to display the value.

2. Calls the C program c_example you created.

3. Returns the value of the environment variable requested in the prompt.

Parameter Description

-n nfa Use this option only if you are not using UniData OFS/NFA. This option uses“dummy” libraries rather than network libraries required by NFA. Softwaredevelopment environments may or may not include the network libraries. Ifyour environment does not include these, and you do not use the -n nfa optimakeudt fails.

makeudt Parameters

228 Developing UniBasic Applications

Page 229: Basd_52

Linking C Programs (UNIX Only)

Program Example

* CDEMO*PROMPT ''PRINT 'Enter an environment variable (such as PATH or TERM)':INPUT VARNAMEEVAL = CALLC c_example(VARNAME)PRINTPRINT 'Value of ":VARNAME:" is ':EVALPRINTSTOPEND

B. Compile the UniBasic program.

Enter the BASIC command at the ECL prompt, as in the following example. Forinstructions about compiling and cataloging UniBasic programs, see“Chapter 3 - Creatingand Running a Program.”

Screen Example

: BASIC BP CDEMO

6. Execute the UniBasic Program

Execute the UniBasic program using the UniData ECL RUN command.

The following example demonstrates running the UniBasic program CDEMO:

Screen Example

: RUN BP CDEMOEnter an environment variable name (such as PATH or TERM)

Developing UniBasic Applications 229

Page 230: Basd_52

Chapter 8 - Linking Programs with UniData

iness the

by thens aasic

, and

To continue the example, the user enters TERM. The program calls the C function that determthe value of the environmental variable and returns it to the UniBasic program, which displayvalue.

Screen Example

?TERMValue of TERM is vt100

Passing bstring-Type Data

This example demonstrates passing bstring-type data. Notice that the original bstring passedUniBasic program is shorter than the minimum buffer size of 34 KB. Therefore, UniData assig34-KB buffer to it. Within the C program, however, the size of the variable passed by the UniBprogram is changed. To avoid a memory leak resulting from assigning a larger buffer, the Cprogram checks the size of the string to be passed back, frees up the original 34-KB allocationreassigns a buffer of adequate size.

The following UniBasic program prompts the user for the length of buffer to assign (seelength inthe INPUT statement), then passes this length to the C program (seelength in the CALLCstatement):

Program Example

PROGRAM trycallc

** Input a length to indicate that the length of the 2nd IO string* and bstring will be changed in C routine.*PRINT "Input length of new IO strings ":INPUT length <— INPUT statement

instr = "THE FIRST INPUT STRING"iostr1 = "THE FIRST IO STRING"iostr2 = "THE SECOND IO STRING"bstring = "THE BSTRING”

PRINT "Before calling C function str_arg()"

230 Developing UniBasic Applications

Page 231: Basd_52

Linking C Programs (UNIX Only)

m.anis

PRINT

CALLC str_arg( length , instr, iostr1, iostr2, bstring) <— CALLC statement

PRINTPRINT "After called C function str_arg()"PRINTPRINT "The 1st input string >> ":instrPRINT "The 1st IO string >> ":iostr1PRINT "The length of the 2nd IO string >> ":LEN(iostr2)PRINT "The length of the bstring is >> ":LEN(bstring)PRINT "The 1st 20 char of the 2nd string >> ":iostr2[1,20]PRINT "The 1st 20 char of the bstring is >> ":bstring[1,20]PRINT

The following C program is called by the CALLC statement in the preceding UniBasic prograThe buffer size assigned to the arguments IOstr2 and bstring are tested. If either is greater th34KB, the memory allocation for that variable must be freed and reallocated. Because IOstr21KB in size, the memory allocation is freed and reallocated before passing it to the UniBasicprogram.

Program Example

#include <stdio.h>#include <string.h>#include "/usr/ud51/include/callc_bstr.h"

#define ONEK 1024extern int U_unit;

intstr_arg(len, InStr, IOstr1, IOstr2, Bstr)int len; *length of the 2nd IO string and Bstring after updating */char *InStr; /* an input string, read only */char *IOstr1; /* an IO string, length of which is lessthan 34K */char *IOstr2; * an IO string whose length will be greater

* than 34K.*/

bstring *Bstr; /* an IO bstring struct pointer */{

Developing UniBasic Applications 231

Page 232: Basd_52

Chapter 8 - Linking Programs with UniData

char buf1[30], buf2[30];int memsize;

/** What the input strings are*/

U_preprint(U_unit, "The 1st input string (%s)\n", InStr);U_preprint(U_unit, "The 1st IO string (%s)\n", IOstr1);U_preprint(U_unit, "The 2nd IO string (%s)\n", IOstr2);U_preprint(U_unit, "The binary string (%s)\n", Bstr->str);U_preprint(U_unit, "Length of the bstring (%d)\n", Bstr->len);

/** For an IO string, the memory size is either 34 KB

* or the length of the original string in the basic* program. Memory reallocation

* is not supported for string-type parameters.* Allocate memory in the UniBasic program. (Assign* a long string to the variable as

* a work around if the size is known.)*/

strcpy(IOstr1, "The 1st IO string is changed");

len *= ONEK;memsize = strlen(IOstr2);memsize = (memsize > 34*ONEK ? memsize : 34*ONEK);

if ( len < memsize ) {memset(IOstr2, 'a', len);memcpy(IOstr2, "len < 34K ", 10);IOstr2[len] = '\0';

}else {

/* no memory reallocation is allowed here */memset(IOstr2, 'b', 100);IOstr2[30*ONEK] = '\0';memcpy(IOstr2, "len > 34K ", 10);

}

/** For bstring data, the initial memory size is the

* same as for string data, and memory reallocation* is supported. To avoid a memory leak, the buffer

232 Developing UniBasic Applications

Page 233: Basd_52

Linking C Programs (UNIX Only)

* size for the bstring needs to be freed* before allocating a larger buffer.

*/

memsize = Bstr->len;memsize = (memsize > 34*ONEK ? memsize : 34*ONEK);

if ( len < memsize ) {Bstr->len = len;memset(Bstr->str, 'c', len);memcpy(Bstr->str, "len < 34K ", 10);

}else {

/* memory re-allocation is allowed here */free(Bstr->str);Bstr->str = malloc(len);Bstr->len = len;memset(Bstr->str, 'd', len);memcpy(Bstr->str, "len > 34K ", 10);

}

/** print out changed strings*/

memcpy(buf1, IOstr2, 20);memcpy(buf2, Bstr->str, 20);buf1[20] = buf2[20] = '\0';

U_preprint(U_unit, "\nAfter modification:\n");U_preprint(U_unit, "The 1st IO string (%s)\n", IOstr1);U_preprint(U_unit, "Length of the 2nd IO string (%d)\n",strlen(IOstr2));U_preprint(U_unit, "Length of the bstring (%d)\n", Bstr->len);U_preprint(U_unit, "The 1st 20 char of IO str2 (%s)\n", buf1);U_preprint(U_unit, "The 1st 20 char of Bstring (%s)\n", buf2);

return 0;}

Developing UniBasic Applications 233

Page 234: Basd_52

Chapter 8 - Linking Programs with UniData

the

ingr thebe

The following cfuncdef_user file contains the function and argument definitions needed to linkpreceding C program with UniData:

Screen Example

/* comment lines come here. *//* C function declaration format:

* function-name:return-type:number-of-argument:arg1,arg2,...,argn*/

$$FUN /* beginning of C function */str_arg:int:5:int,string,string,string,bstring <— argument definitions$$OBJ /* *.o come here */str_arg.o <— function definition$$LIB /* library comes here

The following shows the output produced by executing the UniBasic program trycallc after linkthe C program str_arg with UniData. Notice that the user responded to the prompt of length fooutput string with a number less than 34; this will require that the memory allocation for IOstr2freed and reallocated to pass back a variable of 1 KB in size.

Screen Example

: run BP trycallcInput length of new IO strings ? 30

Before calling C function str_arg()

The 1st input string (THE FIRST INPUT STRING)The 1st IO string (THE FIRST IO STRING)The 2nd IO string (THE SECOND IO STRING)The binary string (THE BSTRING)Length of the bstring (11)

After modification:The 1st IO string (The 1st IO string is changed)Length of the 2nd IO string (30720)Length of the bstring (30720)The 1st 20 char of IO str2 (len < 34K aaaaaaaaaa)The 1st 20 char of Bstring (len < 34K cccccccccc)

234 Developing UniBasic Applications

Page 235: Basd_52

Linking C Programs (UNIX Only)

pt.

nes.etrofit

ill

After called C function str_arg()

The 1st input string >> THE FIRST INPUT STRINGThe 1st IO string >> The 1st IO string is changedThe length of the 2nd IO string >> 30720The length of the bstring is >> 30720The 1st 20 char of the 2nd string >> len < 34K aaaaaaaaaaThe 1st 20 char of the bstring is >> len < 34K ccccccccccEnter <New line> to continue...

Calling a UniBasic Subroutine from a C Programwith CallBasicYou can link a C program with UniData so that it executes a UniBasic subroutine by using theUniData CallBasic application programming interface (API). When you use CallBasic, yourUniBasic routine is called from a C program that is executed from the operating system promBoth UniBasic and UniData are invisible to the user.

CallBasic lets you combine the power of C with the advantages offered by UniBasic subroutiFor example, you can write an application in C to access the UniData database, or you can rexisting C applications to incorporate UniBasic subroutines to access the UniData database.

TipTo save time and frustration, read“Before You Begin”earlier in this chapter.

Procedure Summary

Here is a summary of the steps you must follow to link a C program with UniData so that it wcall a UniBasic subroutine:

1. Write, compile, and catalog the UniBasic subroutine.

2. Write the C program.

3. Create a makefile.

4. Compile and link the C program.

Developing UniBasic Applications 235

Page 236: Basd_52

Chapter 8 - Linking Programs with UniData

.

to

am:

ram.

5. Execute the C program.

Requirements

You must have the following components to use the CallBasic API:

• Development environment

Your system must have a full software development kit. (A base compiler is not suffi-cient). You also will need network libraries (for example, TCP/IP) if you are using NFA

TipConsult your host operating system documentation and your hardware vendor if you havequestions about your C development environment.

• C programs

You will need to code and compile the C application that calls UniBasic.

• Function definitions and makefiles

When you install UniData, the file callbas.mk is installed in theudthome/work directory.You will use this makefile as a template to build your application with UniData linked init.

The Procedure

You are now ready to link a C program that will call a UniBasic subroutine.

1. Write, Compile, and Catalog the UniBasic Subroutine

Perform the following steps to create a UniBasic subroutine that will be called from a C progr

A. Write the UniBasic subroutine.

Write a UniBasic subroutine that includes a RETURN statement. You cannot use aUniBasic mainline program, because the subroutine must return control to the C prog

236 Developing UniBasic Applications

Page 237: Basd_52

Linking C Programs (UNIX Only)

LE

ion

For example, the following subroutine (EXAMPLE) returns a value in RTNVAL. Theremaining arguments, ARG1 and ARG2, pass data from the C program to the EXAMPsubroutine.

Program Example

SUBROUTINEEXAMPLE(RTNVAL, ARG1, ARG2)PRINT ARG1PRINT ARG2RTNVAL = "val1"RETURNEND

B. Compile the UniBasic subroutine.

Use the ECL command BASIC to compile the UniBasic subroutine. For more informatabout this command, see“Chapter 3 - Creating and Running a Program,”or theUniDataCommands Reference.

In this example, we compile the EXAMPLE subroutine:

Screen Example

: BASIC BP EXAMPLE

C. Catalog the UniBasic subroutine.

Use the ECL command CATALOG to catalog the UniBasic subroutine.

Here we catalog the EXAMPLE subroutine:

Screen Example

: CATALOGBP EXAMPLE

Developing UniBasic Applications 237

Page 238: Basd_52

Chapter 8 - Linking Programs with UniData

ther

fore

2. Write the C Program

Write the C program that calls your UniBasic subroutine.

NoteA transaction started in a UniBasic subroutine invoked by a C program can continue into anosubroutine called by the same C program:

udtcallbasic_init( )

U_callbas(subroutineA) * this subroutine starts a transaction

U_callbas(subroutineB) * this subroutine commits the transaction

udtcallbasic_done( )

However, a transaction started in a UniBasic program executed from ECL must complete bethe process returns to ECL.

Sample Program

The following example (mypgm.c) illustrates a C program that calls a UniBasic subroutine:

Program Example

/* call a UniBasic subroutine EXAMPLE from mypgm.c */#include <stdio.h>#include <setjmp.h>

#include "/usr/ud51/include/share.h"#endif

main(){

/* declare variables */char arg0[BUFSIZ];char arg1[BUFSIZ];char *args[2];char *rtn;int sts;

/* initialize UniData environment */

238 Developing UniBasic Applications

Page 239: Basd_52

Linking C Programs (UNIX Only)

ta,d the

inite call.

/* first, set up an error handler */int jmpret, sat;U_SET_JMP(jmpret, sat);if (!jmpret) {

udtcallbasic_done(1);exit(-1);

}udtcallbasic_init(0,0);

/* assign arguments to be passed to the subroutine */strcpy(arg0, "1ST ARGUMENT");strcpy(arg1, "2ND ARGUMENT");args[0] = arg0;args[1] = arg1;

/* call the subroutine */sts = U_callbas(&rtn, "EXAMPLE", 2, args);if (sts = = 0){

printf("Return: %s\n", rtn);free(rtn);

}printf("Status: %d\n", sts);/* shut down UniData environment */udtcallbasic_done(sts);

}

Include Required Functions

Three functions must be included in the C program: udtcallbasic_init, which initializes UniDaU_callbas, which calls the UniBasic subroutine, and udtcallbasic_done, which closes files anUniData session.

Required Functions: Start UniData

Your C program must execute this function once and only once. The C function udtcallbasic_initializes the UniData environment, starting a udt process to execute the CallBasic subroutin

Developing UniBasic Applications 239

Page 240: Basd_52

Chapter 8 - Linking Programs with UniData

ce,

Syntax:

udtcallbasic_init(value1, value2)

int — value1;int — value2;

NoteYou must initialize the UniData environment with udtcallbasic_init before calling a UniBasicsubroutine.

WarningYou can call udtcallbasic_init only once in your program. If you attempt to call it more than onyour program could cause a core dump.

240 Developing UniBasic Applications

Page 241: Basd_52

Linking C Programs (UNIX Only)

value.all a

The following table describes each parameter of the syntax.

Required Functions: Call the UniBasic Subroutine

This function calls a UniBasic subroutine, passes arguments, and sets a pointer to the returnYou can execute this function numerous times in your C application, each time you want to cUniBasic subroutine.

Syntax:

int U_callbas(rtn, progname, argc, argv)

Parameters Description

value1 Names the type of UniData process that will be started. The default is 0.Values for each parameter are in the share.h file in the /usr/ud52/includedirectory.

Valid parameters include the following:

• 01 – U_PHANTOM – This parameter behaves like the ECL PHANTOMcommand.

• 0100 – U_REDIRECT – Use this parameter to override the terminalattributes that UniData sets by default; it sends UniData output to a fileinstead of the terminal screen.

• 0400 – U_UDT_SERVER – Sets a flag that, when a fatal error occurs,returns control to the calling UniBasic program rather than aborting(same as UDT.OPTIONS 41).

Note - When UDT.OPTION 41 is used, errors are returned in EXECUTEinstead of longjmp.

value2 Enter one of the following values to clear or not clear the screen whenCALLBASIC is initialized:

• 0 – Do not clear the screen.

• 1 – Clear the screen.

udtcallbasic_init Arguments

Developing UniBasic Applications 241

Page 242: Basd_52

Chapter 8 - Linking Programs with UniData

e them.

The following table describes each parameter of the syntax.

NoteUniData allocates memory every time you execute U_callbas. In the C program, you must frestorage space pointed to by the first argument or the memory will be unavailable to the systeHowever, you must free memory only if the function completes successfully.

Parameter DataType Description

rtn char The address of the pointer to the value returned from theUniBasic subroutine; you cannot use this argument to passanything to the subroutine. The return values include thefollowing:

• 0 – The function executed successfully.

• -1 – A UniBasic program error occurred in the RUNprocess, you are out of memory, or the system isperforming a CHAIN.

• -2 – A fatal error occurred or a STOP was encounteredin a UniBasic program.

progname char The pointer to the name of the subroutine.

argc int The number of arguments passed to the subroutine.

argv char The address of an array of pointers to arguments. Youcannot use these arguments to pass anything to thesubroutine.

U_callbas Function Arguments

242 Developing UniBasic Applications

Page 243: Basd_52

Linking C Programs (UNIX Only)

rface

be

wanter

Required Functions: Close Files and UniData

This function clears all UniData-related temporary files and other resources and ends the intebetween the C application and UniData. You must execute this function once in your Capplication. You must also include this function in any error exits in your application that couldtaken after udtcallbasic_init.

Syntax:

udtcallbasic_done(status)

int status;

statusis returned, but it is currently not interpreted.

3. Create a makefile

Perform the following steps to create or modify amakefileto specify to UniData the linkedprogram name and location.

A. Copy callbas.mk.

Copy the callbas.mk file fromudthome/work to your work directory. You will need tomake a backup copy of this file in case you need to start this process over. You mightto give the copy a name similar to that of your C function to make it easier to rememblater which makefile was used to link which C function.

A sample of this file is displayed in“File Examples”later in this chapter.

B. Enter the library path.

Change the libpath in yourmakefilefile to yourudthome/lib directory, using the absolutepath instead ofudthome. Here is an example of a libpath line:

libpath = -L/usr/ud52/lib

Also, if you find a line like the following in the file, remove it:

libpath = -L$$UDTLIB

This ensures that the make process will execute regardless of the definition of theenvironment variableudtlib.

Developing UniBasic Applications 243

Page 244: Basd_52

Chapter 8 - Linking Programs with UniData

ed

le.c,

el

C. Find NEWOBJS.

Look for the statement that defines NEWOBJS. It looks like this:

NEWOBJS = callbas.o

TipDoes your NEWOBJS line differ from this? If it refers to a previously linked C function, you neto reinitialize the files UniData uses to create the link. For more instructions, see“If This Is Notthe First Time”later in this chapter.

D. Change callbas.o.

NEWOBJS must refer to your object file. Because our sample C program is c_exampthe object name is c_example.o:

NEWOBJS = c_example.o

E. Enter object name again.

Modify the executable name again in a line that looks like this before modification:

callbas: $(NEWOBJS) $OBJS)

To link our sample C program, this line must be:

c_example: $(NEWOBJS) $(OBJS)

4. Compile and Link the C Program

NoteBefore you execute make, you need to know if anyone has executed the UniData system-levcommand makeudt or makeudapi since UniData was installed or upgraded. If they have, youMUST restore the files modified by this utility. For more information, see“If This Is Not the FirstTime” later in this chapter.

244 Developing UniBasic Applications

Page 245: Basd_52

Linking C Programs (UNIX Only)

Data

ahich

From the UNIX prompt, enter the make command to compile the C program and link it toUniData. The -f option tells UNIX to use the file specified inmakefile_namerather than thedefault, callbas.mk.

make

Syntax:

make -f makefile_name

For example, the following command compiles the C program named c_example.c into anexecutable named c_example and links the executable to UniData:

Screen Example

%make -f c_example.mk

5. Execute the C Program

Run the C program from the operating system prompt.

Syntax:

[path]executable_name[arg1] [args2...]

If the UniBasic subroutine is globally cataloged, you can execute the C program from any Uniaccount or directory.

If the UniBasic subroutine is locally or directly cataloged, you must execute the C program inUniData account that has an entry for the program in the VOC file. This is the account from wthe make utility was executed or one in which you manually create a VOC record for the Cprogram.

You must setudthome, udtbin, and your path. For information about setting these environmentvariables, seeAdministering UniData on UNIX.

Developing UniBasic Applications 245

Page 246: Basd_52

Chapter 8 - Linking Programs with UniData

the

ke,

r

ith

The following command invokes the program named c_example from the /usr/ud52/workdirectory:

Screen Example

%/usr/ud52/work/c_example

The sample C program, c_example, which calls the UniBasic program EXAMPLE, producesfollowing output:

Screen Example

1ST ARGUMENT2ND ARGUMENTStatus: 0Return: val1

If This Is Not the First TimePerform the following steps to reinitialize the files inudthome/work if someone has already linkedC functions to UniData. You need to perform this procedure before you try to execute the mamakeudt, or makeudapi utility.

1. Find cfuncdef_user

Look in theudthome/work directory for a file named cfuncdef_user. If you do not find it, look focfuncdef.

Here is why: When UniData is installed, the files required for the UNIX make utility to link Cprograms with UniData are provided inudthome/work. The instructions in the preceding section(for CallBasic) direct the user to copy cfuncdef to cfuncdef_user, then modify this template winformation required by the UNIX make utility.

246 Developing UniBasic Applications

Page 247: Basd_52

Linking C Programs (UNIX Only)

ctileink

ead,

2. Take a Look Inside

Use the UNIX more command to look at the contents. Does the file look like this template?

Program Example

/* this is a test for adding C function to the RUN Machine *//* comment lines come here. *//* C function declaration format:function-name:return-type:number-of-argument:arg1,arg2,...,argn*/$$FUN /* beginning of C function */$$OBJ /* *.o come here */$$LIB /* library comes here */

3. Look for Modifications

If you have linked one or more C functions to UniData for the purpose of CALLC, cfuncdef orcfuncdef_user will contain references to C functions on the line that follows $$FUN, and objenames in the line following $$OBJ. It could also list site-specific libraries under $$LIB. If the fhas been modified, you need to reinitialize the files the UNIX make utility uses to create the lbetween C programs and UniData. (These are the other files placed inudthome/work whenUniData is installed: funchead.c, interfunc.c, and so forth.)

4. Log In as root

Before you proceed to the next step, you must log in as root.

5. Reinitialize

Execute the UniData system-level commands genefs, gencdef, and genfunc to update funchinterfunc, and other C functions used by the makeudt or makeudapi utility.

Developing UniBasic Applications 247

Page 248: Basd_52

Chapter 8 - Linking Programs with UniData

order

Enter the following commands, in the indicated order, from the UNIX prompt:

Screen Example

# $UDTBIN/genefs# $UDTBIN/gencdef# $UDTBIN/genfunc# ls -tl |pgtotal 26-r--r--r-- 1 root sys 2735 Jun 10 16:08 interfunc.c-r--r--r-- 1 root sys 738 Jun 10 16:08 funchead.c-r--r--r-- 1 root sys 760 Jun 10 16:08 callcf.c-rw-rw-rw- 1 root sys 97 Jun 10 16:08 ndef-rw-rw-rw- 1 root sys 422 Jun 10 16:08 cdef-r--r--r-- 1 root sys 1006 Jun 10 16:08 efs_init.c-r--r--r-- 1 root sys 155 Jun 10 16:04 efsdef-rw-rw-rw- 1 root sys 985 Jun 10 16:04 callbas.mk-r--r--r-- 1 root sys 292 Jun 10 16:04 cfuncdef-rw-rw-rw- 1 root sys 1424 Jun 10 16:04 base.mk

PermissionsYou must be logged in as root to execute these commands, and you must execute them in theshown in the example.

After you reinitialize, return to the procedure for linking C programs with UniData.

248 Developing UniBasic Applications

Page 249: Basd_52

Linking C Programs (UNIX Only)

le

File ExamplesThe base.mk file and the cfuncdef file are platform-specific.

base.mk Example

WarningDo not copy the sample makefile onto your system, and do not copy a makefile from anotherplatform. If you do, makeudt or makeudapi will probably fail. Always start with the base.mk fireleased with UniData.

The following example shows a base.mk file for UniData on an HP system:

Screen Example

# pg base.mk## The Porting Date : Jun. 11, 99# The System to Be Ported : HPUX10#

CC = ccCFLAGS = -q -z +ESsfcLDFLAGS = -Wl,-a,archiveOPTFLAGS = -O +OvolatileDBFLAGS =libpath = -L/disk1/srcman/alpha/ud_51_990611_2025/bin/libaddlib = -lm -Wl,-a,shared -lcurses -lsecaddlibpath =odslib = -lududlib = -lndbm -lcl -lBSDlicnlib = -llicndclcnlib =nfalib = -lnfaclntdfslib =

libs_clt = -lshare -ludsql -ludmach -lbasic -lret1 -lperf -lides -lpipe

Developing UniBasic Applications 249

Page 250: Basd_52

Chapter 8 - Linking Programs with UniData

-lfunc -lndx $(dfslib) -lshm -lmglm -lglm -lulc -lcmn -llicn-ludus -lunix $(nfalib)$(odslib)

libs_svr = -lnfasvr -lshare -ludsql -ludmach -lbasic -lret1 -lperf -lides-lpipe -lfunc -lndx $(dfslib) -lshm -lmglm -lglm -lulc -lcmn -llicn \

-ludus -lunix $(odslib)

libs_srv = -lushare -lusql -lumach -lbasic -lret1 -lperf -lides -lpipe-lfunc -lndx -lshm -lmglm -lglm -lulc -lcmn -llicn-ludus -lunix -lunirpc $(nfalib) $(odslib)

OBJS = funchead.o interfunc.o callcf.o efs_init.o

UDOBJS = funchead.o interfunc.o callcf.o efs_init.o

udt: $(OBJS)$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy $(libs_clt)$(addlibpath) $(addlib)-o $@

udapi_slave: $(OBJS)$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy -licapi $(libs_clt) -lunirpc$(addlibpath) $(addlib)-o $@

udtsvr: $(OBJS)$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy $(libs_svr)$(addlibpath) $(addlib)-o $@

udsrvd: unirpc_srv.o $(OBJS)$(CC) unirpc_srv.o $(OBJS)$(libpath) -lapidummy $(libs_srv)$(addlibpath) $(addlib)-o $@

uniapisvr: $(OBJS)$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapisvr $(libs_clt) -lmsg$(udlib) $(addlibpath) $(addlib) \

250 Developing UniBasic Applications

Page 251: Basd_52

Linking C Programs (UNIX Only)

o

-o $@

.c.o:$(CC) $(CFLAGS) $(IDIR) $(OPTFLAGS) $(DBFLAGS) -c $<

cfuncdef Example

Some earlier releases of UniData included some UniData functions in cfuncdef. If someoneupgraded UniData and chose not to overlay this file, the wrong version could reside inudthome/work. The cfuncdef file must look similar to the following example, which contains n

reference to C functions:

Screen Example

# pg cfuncdef/* this is a test for adding C function to the RUN Machine *//* comment lines come here. *//* C function declaration format:function-name:return-type:number-of-argument:arg1,arg2,...,argn*/$$FUN /* beginning of C function */$$OBJ /* *.o come here */$$LIB /* library comes here */

Developing UniBasic Applications 251

Page 252: Basd_52

Chapter 8 - Linking Programs with UniData

callbas.mk Example

The following is an example of what the callbas.mk template might look like.

NoteDo not copy this example. Use the template provided in your udthome/work directory for theplatform on which you are linking C programs with UniData. This example shows link optionsthat might not be valid on some platforms.

Program Example

## The Porting Date : Dec. 11, 96# The System to Be Ported : HPUX10.debug#

CC = ccCFLAGS = -q -z +ESsfc -DNULL_OK -DSQLTP -DUDMS -DNEW_INTERLDFLAGS = -Wl,-a,archiveOPTFLAGS =DBFLAGS = -glibpath = -L/disk2/srcman/alpha/ud_pkqa4/bin/libaddlib = -lm -Wl,-a,shared -lcursesaddlibpath =odslib = -lududlib = -lndbm -lcl -lBSDlicnlib = -llicndclcnlib =nfalib = -lnfaclntdfslib =

OBJS = funchead.o interfunc.o callcf.o efs_init.o

NEWOBJS = callbas.o

newlibpath =newlibs =

libpath = -L$$UDTLIB

252 Developing UniBasic Applications

Page 253: Basd_52

Linking C Programs (UNIX Only)

hiss /0

libs = -lshare -ludsql -ludmach -lbasic -lperf -lret1 -lides -lpipe \-lfunc -lndx $(dfslib) -lshm -lcmn $(licnlib) -ludus $(nfalib) \

$(odslib) $(udlib)

callbas:$(NEWOBJS) $(OBJS)$(CC) $(LDFLAGS) $(NEWOBJS) $(OBJS) \

$(libpath) -lapidummy $(libs) $(newlibpath) $(newlibs) \$(addlibpath) $(addlib) -o $@

.c.o:$(CC) $(CFLAGS) $(IDIR) $(OPTFLAGS) $(DBFLAGS) -c $<

bstring Definition File

callc_bstr.h, which is located in /usr/ud52/include, contains the definition of bstring. Include theader in a C function when you need to pass binary data, especially when that data contain(called NULL in C), which is interpreted by C as a line terminator.

Screen Example

typedef struct {char *str;int len;

} bstring;

Developing UniBasic Applications 253

Page 254: Basd_52

Chapter 8 - Linking Programs with UniData

orms.

utes

:

More on make, makeudt, and makeudapiThe utilities make, makeudt, and makeudapi create new UniData executables. However, themakeudt and makeudapi commands perform more operations than the make command perf

makeudt and makeudapi

Use the makeudt utility to create a new executable udt, or use makeudapi to create a newexecutable udapi_slave, inudthome. Using one of these utilities forces udt or udapi_slave to becreated inudtbin.

1. First, makeudt or makeudapi reads cfuncef and cfuncdef_user to obtain the followinginformation:

...$$FUN /* beginning of C function */

str_arg:int:5:int,string,string,string,bstring <— function and argument$$OBJ /* *.o come here */ definitionsstr_arg.o <— C program object file name$$LIB /* library comes here */

/disk2/ud52/our_lib <— site-specific library path,if different from udtlib

2. Using information gained from cfuncdef and cfuncdef_user, makeudt or makeudapi execthe following three functions:

• genefs – Needed for NFA (Network File Access) only.

• gencdef – Creates a definition file (called cdef) for the following UniData functions

callcf.c

funchead.c

interfunc.c

• genfunc – Uses the definitions in cdef to create the following UniData functions:

callcf.c

funchead.c

interfunc.c

254 Developing UniBasic Applications

Page 255: Basd_52

Linking C Programs (UNIX Only)

and

file,

and

don,

3. Next, makeudt or makeudapi copies the base.mk file to new.mk and writes the C programlibrary path, which it obtained from cfuncdef_user:

NEWOBJS = str_arg.o

NEWLIBS =/disk2/ud52/our_lib

4. UniData overlays new.mk if it already exists.

Notemakeudt or makeudapi always writes the udt or udapi_slave executable toudtbin. If UniData isexecuting when it tries to overwrite the file, it notifies you. You must then copy the executableudt or udapi_slave, intoudtbinwhen all users are signed out of UniData.

5. Finally, makeudt or makeudapi deletes the cdef file.

make

By default, the makeudt or makeudapi utility makes a new UniData executable and replacesudtbin/udt (or, in the case of makeudapi,udtbin/udapi_slave) with the new one.

The make utility performs functions similar to makeudt and makeudapi with the followingexceptions:

• The make utility does not automatically execute the three functions genefs, gencdef,genfunc.

• The make utility lets you place the udt or udapi_slave executable in any directory. Toso, change the output path for the targets from -o $@ to -o path. For more informatiosee the UNIX man page for make.

Developing UniBasic Applications 255

Page 256: Basd_52

Chapter 8 - Linking Programs with UniData

The following example shows a sample base.mk with the output destinations indicated:

Screen Example

# pg base.mk...udt: $(OBJS) <— udt target

$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy $(libs_clt)$(addlibpath) $(addlib)-o $@ <— change to -o path

udapi_slave: $(OBJS) <— udapi_slave target$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy -licapi $(libs_clt) -lunirpc$(addlibpath) $(addlib)-o $@ <—change to -o path

udtsvr: $(OBJS) <— udtsvr target$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapidummy $(libs_svr)$(addlibpath) $(addlib)-o $@ <—change to -o path

udsrvd: unirpc_srv.o $(OBJS) <— udsrvd target$(CC) unirpc_srv.o $(OBJS)$(libpath) -lapidummy $(libs_srv)$(addlibpath) $(addlib)-o $@ <—change to -o path

uniapisvr: $(OBJS) <— uniapi.svr target$(CC) $(LDFLAGS) $(OBJS) $(NEWOBJS) $(NEWLIBS)$(libpath) -lapisvr $(libs_clt) -lmsg$(udlib) $(addlibpath) $(addlib) \-o $@ <—change to -o path

256 Developing UniBasic Applications

Page 257: Basd_52

Linking C Programs (UNIX Only)

empt

Troubleshooting CALLCThe following table contains solutions for some common problems encountered when you attto link C programs with UniData.

Problem Solution

makeudt or makeudapi aborts with a mes-sage indicating that UniData cannot find alibrary. For example:/usr/ccs/bin/ld:

Can't find library for -lapidummy

*** Error exit code 1

Add the full path to the C program in thecfuncdef_user file that follows $$OBJ.

Check the libpath line in your makefile (the oneyou created by copying base.mk). It should listthe absolute path to the UniData libraries. This isstored in the environment variableudtlib. To findout the path forudtlib, at the UNIX prompt, enterenv.

After completing, makeudt displays themessage:'udt' is up to date ormakeudapi displays the message:'udapi_slave' is up to date

This is not an error message. The new udt orudapi_slave has been built successfully.

makeudt or makeudapi aborts with anerror message such as:unsatisfied sym-

bol: str_arg

wherestr_arg is the object file for yourC program.

References to libraries are incorrect. Check thecfuncdef_user file. Enter the full path to theobject file for the C program after the line thatcontains $$OBJ.

Tip - To find out where the makeudt or makeu-dapi utility thinks the libraries are, look in yourmakefile at the line beginning with “libpath = -L”. If it is correct, it lists the absolute path toudtlib. To find out the path forudtlib, at theUNIX prompt, enter env.

Troubleshooting Tips

Developing UniBasic Applications 257

Page 258: Basd_52

Chapter 8 - Linking Programs with UniData

e

When you try to copy your C program toudthome, UNIX returns an error messagelike the following:cp: cannot create

/disk1/ud52/str_arg.o: Permission

denied

Unless the permissions have been changed for thdirectoryudthomesince UniData was installed,you must be logged in as root to copy files intothis directory.

When you execute the UniBasic programthat calls the C program you linked toUniData, a memory leak results.

To prevent a memory leak, you must free theoriginal buffer assignment in the C programbefore reallocating it. If the string is changed, thelength must also be reassigned. For moreinformation, see“Passing bstring-Type Data”earlier in this chapter.

makeudt or makeudapi aborts with anerror message similar to the following (formakeudapi, replace “udt” with“udapi_slave” in this example):

mv: /disk1/ud52/bin/udt: cannotwrite: Text file busy

Execute "mv udt/disk1/ud52/bin/udt" error, errno =0

The udt make failed.

Users are currently executing UniData sessions.(Execute the command LISTUSER from the ECLprompt to determine who those users are.)

The new executable has been created, butUniData was unable to overlay the currentexecutable. With all users signed off, copy the udtor udapi_slave executable fromudthome/work toudtbin.

When you log in as root, UniData cannotfind udthomeor other files or directories.

The setting for the UNIX environment variablePATH is lost. Reset your path as it is in your.login or .profile file (if you have one), or seeyour system administrator or the UNIX manpages for instructions on setting PATH.

Reset the environment variablesudthomeandudtbin. For instructions, seeAdministeringUniData on UNIXor the UNIX man pages.

Problem Solution

Troubleshooting Tips (continued)

258 Developing UniBasic Applications

Page 259: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

T

king

s

Cto

LL

LL

n

Linking C Programs (Windows NT or Windows2000 Only)

The information in this section applies to the Windows NT or Windows 2000 operating systemonly.

NoteFor more information about CALLC, seeAdministering UniData on Windows NT or Windows2000.

Dynamic Link Libraries (DLLs) and UniDataBoth the CALLC implementation and the CallBasic implementation in UniData for Windows Nor Windows 2000 use the Microsoft Windows Dynamic Link Library (DLL) facility. This facilitylets separate pieces of code call one another without being permanently bound together. Linbetween the separate pieces is accomplished at runtime (rather than compile time) through aDynamic Link Library (DLL) interface. Both the CALLC interface (for calling external functionfrom UniData) and the CallBasic interface (calling UniData functions from external code) areimplemented as DLLs.

• For CALLC, developers create a DLL and then call that DLL from UniData. Special VOentries for each function that is called from a DLL communicate interface informationUniData.

• For CallBasic, developers link their code with UniData.LIB (located in the UniDatabindirectory) and then make calls into the UniData DLL. The .LIB file supplies interfaceinformation.

Because linking between caller and DLL is accomplished at runtime, either the caller or the Dcan be modified independently. For UniData, this means that you can upgrade your UniDataversion without the need to relink with external routines, and you can update your external Dwithout the need to relink UniData.

A DLL is language-independent. Many software development environments for Windows caproduce a DLL.

Developing UniBasic Applications 259

Page 260: Basd_52

Chapter 8 - Linking Programs with UniData

tures

s.re

NoteFor information about linking code into a DLL, see the documentation for your softwaredevelopment environment.

CALLC Features and ComponentsCALLC enables users to execute external functions from within a UniBasic application. Theexternal functions can be written in C, C++, or Borland Delphi. This section describes the feaof CALLC.

NoteUniData includes a series of CALLC examples, both external functions and UniBasic programThe examples are in the CALLC_DEMO folder located in the UniData demo account. For moinformation, seeAdministering UniData on Windows NT or Windows 2000.

CALLC Syntax and Data Types

The UniBasic CALLC command has the following syntax:

rtn = CALLC function(arg1,arg2,...argn)

The following table lists the parameters of the syntax.

Parameter Description

rtn Return value from CALLC. Must be a valid data type.

function The name of the external function being called.

arg1,....argn Arguments to the external function. Each must be avalid data type.

CALLC Parameters

260 Developing UniBasic Applications

Page 261: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

ng

Valid data types for return values and arguments are listed in the following table.

E Type VOC Entries

An E (executable) type VOC entry identifies the DLL for an external function being called usiCALLC, and identifies the data types for its arguments and return value.

Data Type Description

CHAR A signed byte.

INT An integer (32-bit signed).

POINTER A 32-bit signed long word.

SHORT A short (16-bit) integer.

LONG A long integer.

STRING A pointer to a null-terminated character stringin a 34K buffer.

CHAR_PTR A pointer to a null-terminated characterstring.

INT_PTR A pointer to a 32-bit signed long word.

SHORT_PTR A pointer to a 16-bit integer.

LONG_PTR A pointer to a 32-bit integer.

DESCRIPTOR A pointer to a string descriptor.

NONE Use for functions that do not return anything(for instance, VOID).

Data Types for CALLC

Developing UniBasic Applications 261

Page 262: Basd_52

Chapter 8 - Linking Programs with UniData

The following table defines the attributes required for an E type VOC entry.

The following screen shows the VOC entry for a function named callcpp_subr1:

Screen Example

: CT VOC callcpp_subr1VOC:

callcpp_subr1:ECALLC_DEMO\CALLC_CPP\callcpp_test.dllcallcpp_subr1INTINTSHORTLONGCHARSTRING

Attribute Description

@ID The function name.

Attribute 1 The VOC entry type. You must specify E.

Attribute 2 The location of the DLL. It must be a fullyqualified path, a path relative to the currentworking directory, or a name that can belocated by way of the user’s path environmentvariable.

Attribute 3 The function name in the DLL.

Attribute 4 The data type for the return value.

Attribute 5 The data type for the first argument.

Attributes 6 -n The data types for the second throughntharguments.

Attributes of E Type VOC Entry

262 Developing UniBasic Applications

Page 263: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

from

ur

ate

tionntionur

POINTER:

Notice that this function expects six arguments, and returns an INT. The function is accesseda dynamic linked library called callcpp_test.dll.

WarningInformix recommends that you keep your development environment clearly separate from yoproduction environment when developing a CALLC application. Separating environments isuseful in any case, but can be critical because difficulties in the external functions can terminudt sessions and potentially damage data.

CALLC and UDT.OPTIONS 88

One function can call another in a stack-based architecture by using one of the followingconventions:

• Pascal calling convention.

• _cdecl calling convention.

The Pascal calling convention is the default for UniData.

NoteFor C and C++, the default calling convention is _cdecl. For Delphi, the default calling convenis Pascal. You can use the Pascal convention in C or C++, and you can use the _cdecl convein Delphi. For information about choosing a calling convention, see the documentation for yodevelopment environment.

Developing UniBasic Applications 263

Page 264: Basd_52

Chapter 8 - Linking Programs with UniData

tle

mited

A new UDT option has been introduced into UniData for Windows NT or Windows 2000 to leCALLC function correctly with both _cdecl and Pascal calling conventions. The following tabdescribes the behavior of CALLC commands with this option turned on or off.

WarningAs the preceding table indicates, calling a function with the wrong UDT.OPTIONS 88 settingalmost certainly terminates a udt session and could produce other undesirable results.

Using CALLCTo call an external function from UniBasic, perform the following procedure.

1. Write and Compile the External Function

You can code the external function in C, C++, or Delphi.

Guidelines for Writing C Functions

You might find the following guidelines helpful when writing external functions in C:

• Naming Variables – Avoid naming variables or functions with the prefix U and anunderscore (U_), such as U_unit and U_errout; UniData uses U_ as an identifier forvariable names and functions.

• Passing Arguments – You cannot pass more than 22 arguments. Each argument is lito 255 characters.

UDT.OPTIONS88 _cdecl Convention Pascal Convention

OFF (default) CALLC fails,terminating the UDT.

CALLC executes.

ON CALLC executes. CALLC fails,terminating the udt.

UDT.OPTIONS 88

264 Developing UniBasic Applications

Page 265: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

t is

en,x

ous

to

y the

• Displaying Error Messages – To display error messages, use the UniData C functionU_errout. U_errout() has the same syntax as U_preprint(), except the variable U_unireplaced by 0. U_errout() output goes to errout whereas U_preprint() output goes tostdout.

Syntax:

U_errout(0,"error message from the routine, value is %d",value);

• Printing – To maintain screen integrity and I/O redirection, use the UniData C functionU_preprint instead of the C function printf. The U_preprint function refreshes the screenabling the C subroutine to properly manage screen I/O. This function follows syntasimilar to printf().

Syntax:

U_preprint pattern,arg1,arg2...

• Ending the C Program – Do not use exit(). Instead, use U_done, which performs varicleanup tasks, and then causes the C program to terminate.

Steps for Developing the Function

A. Code the function using C, C++, or Borland Delphi. Make certain that all the functionsbe called from outside the program are exported in one of the following ways:

• A _declspec( dllexport ) statement.

• An EXPORTS statement. The EXPORTS statement lists the names and optionallordinal values of the functions exported by the DLL. When ordinal values arespecified, they must be in the range 1 throughn wheren is the number of functionsexported by the DLL.

NoteThe maximum number of bytes allowed in a function return is 256.

B. Compile the function or functions and link the code into a DLL.

Developing UniBasic Applications 265

Page 266: Basd_52

Chapter 8 - Linking Programs with UniData

he

to

ate

m

l

WarningUniData for Windows NT or Windows 2000 takes full advantage of the Win32 environment. TUniData DLL is a 32-bit DLL, and any DLLs you call by way of CALLC must also be 32-bitDLLs. You cannot call a 16-bit DLL from UniData.

C. Create the VOC entry for every function that you can call from the DLL. You will needcreate an E type record in the VOC file in every UniData account where you will becalling the functions. The VOC entry contains information that enables UniData to locand execute the called function.

After the DLL and the E type VOC entry are created, the function can be accessed froUniBasic via CALLC.

2. Write and Compile the UniBasic Program

The following example shows a portion of the sample UniBasic program that calls an externafunction named ps:

Program Example

.

.

.PRINT "TURNING ON UDT.OPTIONS 88; REQUIRED FOR C"PERFORM "UDT.OPTIONS 88 ON"

PRINT "THE ID OF MY CURRENT UNIDATA PROCESS IS: ":@USERNOPRINT "PASSING THE ID TO THE C ROUTINE."pid = @USERNOpname = ''cname = ''ptime = ''virt_mem = 0

RESULT = CALLC ps(pid, pname, cname, ptime, virt_mem)PRINT "THE C ROUTINE RETURNED: ":RESULTIF RESULT >= 0 THEN

PRINT

266 Developing UniBasic Applications

Page 267: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

try.

,

fif

mple

e

d

.

.

.END ELSEPRINT "AN ERROR HAS OCCURRED IN THE C ROUTINE."ENDPRINT "TURNING OFF UDT.OPTIONS 88 BEFORE CLOSING"PERFORM "UDT.OPTIONS 88 OFF"

STOPEND

Notice the following points:

• The function name in the CALLC statement matches the name in the E type VOC en

• By default, the calling convention for a C program is the _cdecl convention. ThereforeUDT.OPTIONS 88 must be turned on.

• Error handling is based on the RESULT from the C function rather than the STATUS othe CALLC statement. The statement can complete successfully (STATUS of 0) eventhe C function has encountered an error.

ReminderThe external function examples and UniBasic examples in this section are taken from the saprograms installed with the current release of UniData on Windows NT.

CallBasic Features and ComponentsYou can write programs that execute UniBasic subroutines by using the UniData CallBasicapplication programming interface (API). When you use CallBasic, your UniBasic routines arcalled from an external program, and UniBasic and UniData are invisible to the user.

CallBasic enables you to combine the power of programming languages such as C, C++, anDelphi with the advantages offered by UniBasic subroutines. For example, you can write anapplication in C to access the UniData database, or you can retrofit existing applications toincorporate UniBasic subroutines that let you access the database.

Developing UniBasic Applications 267

Page 268: Basd_52

Chapter 8 - Linking Programs with UniData

o

ce,

NoteUniData includes two CallBasic examples: both the external programs and the UniBasicsubroutines. The examples are in the CALLBASIC_DEMO folder located in the UniData demaccount. The UniBasic subroutines are in the BP file in the UniData demo account. For moreinformation, seeAdministering UniData on Windows NT or Windows 2000.

Functions of the CallBasic API

udtcallbasic_init

The C function udtcallbasic_init initializes the UniData environment, starting a udt process toexecute the CallBasic subroutine call.

Syntax:

udtcallbasic_init(value1, value2)

int — value1;int — value2;

NoteYou must initialize the UniData environment with udtcallbasic_init before calling a UniBasicsubroutine.

WarningYou can call udtcallbasic_init only once in your program. If you attempt to call it more than onyour program could cause a core dump.

268 Developing UniBasic Applications

Page 269: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

to the

The following table describes each parameter of the syntax.

U_callbas

The C function U_callbas calls a UniBasic subroutine, passes arguments, and sets a pointerreturn value.

Syntax:

int U_callbas(rtn, progname, argc, argv)

Parameters Description

value1 Names the type of UniData process that will be started. The default is 0.Valid parameters include the following:

• 0 or 01 – U_PHANTOM – This parameter behaves like the ECLPHANTOM command.

• 010 – U_PHANTOMHUSH – This parameter behaves likeU_PHANTOM, except that it suppresses the “Phantom process startedand “Phantom process completed” messages.

• 0100 – U_REDIRECT – Use this parameter to override the terminalattributes that UniData sets by default; it sends UniData output to a fileinstead of the terminal screen.

• 0400 – U_UDT_SERVER – Sets a flag that, when a fatal error occurs,returns control to the calling UniBasic program rather than aborting(same as UDT.OPTIONS 41).

Note - When UDT.OPTION 41 is used, an error will be returned inEXECUTE instead of longjmp.

value2 Enter one of the following values to clear or not clear the screen whenCALLBASIC is initialized:

• 0 – Do not clear the screen

• 1 – Clear the screen

udtcallbasic_init Arguments

Developing UniBasic Applications 269

Page 270: Basd_52

Chapter 8 - Linking Programs with UniData

r, you

The following table describes each parameter of the syntax.

NoteUniData allocates memory from the process heap every time you execute U_callbas. In the Cprogram, you must free the memory pointed to by the first argument or the memory will beunavailable to the system. You must use the HeapFree API call to free the memory. Howevemust free memory only if the function completes successfully.

Parameter DataType Description

rtn char The address of the buffer containing results from theUniBasic subroutine. You cannot use this argument to passanything to the subroutine. The return values include thefollowing:

• 0 – The function executed successfully.

• -1 – A UniBasic program error occurred in the RUNprocess, you are out of memory, or the system isperforming a CHAIN.

• -2 – A fatal error occurred or a STOP was encounteredin a UniBasic program.

progname char The pointer to the name of the subroutine.

argc int The number of arguments passed to the subroutine.

argv char The address of an array of pointers to arguments. Youcannot use these arguments to pass anything to thesubroutine.

U_callbas Function Arguments

270 Developing UniBasic Applications

Page 271: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

sults.

f theser isn

udtcallbasic

This function calls a UniBasic subroutine, passing arguments, and returns a pointer to the re

Syntax:

int udtcallbasic(rtn, progname, argc, arg[0], ..., arg[n])

The syntax of this function is required if the calling language is not C because the definition oreturn buffer is consistent between the external program and the call with udtcallbasic. The uresponsible for allocating memory for the buffer to store results. You can execute this functionumerous times in your application when you want to call a UniBasic subroutine.

The following table describes each parameter of the syntax.

Parameter DataType Description

rtn char The address of the pointer to the value returned from theUniBasic subroutine. You cannot use this argument to passanything to the subroutine. The return values include thefollowing:

• 0 – The function executed successfully.

• -1 – A UniBasic program error occurred in the RUNprocess, you are out of memory, or the system isperforming a CHAIN.

• -2 – A fatal error occurred or a STOP was encounteredin a UniBasic program.

progname char The pointer to the name of the subroutine.

argc int The number of arguments passed to the subroutine.

arg[0] ...arg[n]

char The pointers to arguments passed to the subroutine.

U_callbas Function Arguments

Developing UniBasic Applications 271

Page 272: Basd_52

Chapter 8 - Linking Programs with UniData

ce,

. (A

udtcallbasic_done

The UniData udtcallbasic_done C function clears all UniData-related temporary files and spaand shuts down the UniData environment.

Syntax:

udtcallbasic_done(status)

int status;

statusis returned, but it currently is not interpreted.

Using CallBasicYou must have the following components to use the CallBasic API:

• Development environment – Your system should have a full software development kitbase compiler is not sufficient.)

• UniData.LIB file – You must link your external program with the UniData.LIB file whenyou build the executable. Interface information is contained in UniData.LIB.

TipConsult your host operating system documentation and your hardware vendor if you havequestions about your development environment.

272 Developing UniBasic Applications

Page 273: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

al

t

1. Write, Compile, and Catalog the UniBasic Subroutine

Perform the following steps to create a UniBasic subroutine that will be called from an externprogram:

A. Write the UniBasic subroutine.

Write a UniBasic subroutine that includes a RETURN statement. The subroutine musreturn control to the external program. For example, the following subroutine,EXAMPLE, returns a value in RTNVAL. The remaining arguments, ARG1 and ARG2,pass data from the C program to the EXAMPLE subroutine.

Screen Example

SUBROUTINE EXAMPLE(RETNVAL,ARG1,ARG2)PRINT "THE FIRST ARG IS ":ARG1PRINT "THE SECOND ARG IS ":ARG2RETNVAL="RETURN"RETURNEND

NoteThis subroutine is included in the BP file of the UniData demo account.

B. Compile the UniBasic subroutine.

To compile the UniBasic subroutine, use the ECL command BASIC. For moreinformation about this command, see“Chapter 3 - Creating and Running a Program,”ortheUniData Commands Reference.

Developing UniBasic Applications 273

Page 274: Basd_52

Chapter 8 - Linking Programs with UniData

you

ine:

ation

ing

In the following example, we compile the EXAMPLE subroutine:

Screen Example

: WHERED:\UniData\demo

: BASIC BP EXAMPLE

Compiling Unibasic: BP\EXAMPLE in mode 'u'.compilation finished:

C. Catalog the UniBasic subroutine.

To catalog the UniBasic subroutine, use the ECL command CATALOG. Depending ifwant to access the subroutine from one account or many, you can catalog it directly,locally, or globally.

In the following example, we demonstrate globally cataloging the EXAMPLE subrout

Screen Example

: CATALOG BP EXAMPLED:\UniData\sys\CTLG\e\EXAMPLE has been cataloged, do you want to over-write?(y/n) Y:

2. Code, Compile, and Link the External Program

For information about compiling the external program, see the documentation for your applicdevelopment environment. Make certain that:

• Your declarations for the UniBasic functions use the correct syntax for your programmlanguage.

• You link your code with the UniData.LIB file.

274 Developing UniBasic Applications

Page 275: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

the

me

tine:

Write the external program that calls your UniBasic subroutine. Use the CallBasic functions inprogram as follows:

• udtcallbasic_init() – Your program must execute this function once and only once.

• U_callbas() – You can execute this function numerous times in your program, each tiyou want to call a UniBasic subroutine. The syntax for U_callbas is supported if thecalling language is C.

• udtcallbasic() – Remember to allocate memory for the buffer to store results. You canexecute this function numerous times in your program, each time you want to call aUniBasic subroutine.

• udtcallbasic_done() – Your program must execute this function once. You must alsoinclude this function in any error exits in your application that could be taken afterudtcallbasic_init().

The following example (callbasic_example1.c) shows a program that calls a UniBasic subrou

Program Example

#include <stdio.h>

#define NT

#ifdef NT#include <windows.h>#endif /* NT */

/* Declare UniData callbasic functions */

#ifdef CPP /* for c++ */extern "C" int udtcallbasic_init(int i, int j);extern "C" int udtcallbasic(char *xbuf, char *ybuf, int i, char *arg, ...);extern "C" int udtcallbasic_done(int k);extern "C" int U_callbas(char **xbuf, char *ybuf, int i, char **zbuf);#else /* for c */extern int udtcallbasic_init();extern int udtcallbasic_done();extern int U_callbas();#endif /* CPP */

Developing UniBasic Applications 275

Page 276: Basd_52

Chapter 8 - Linking Programs with UniData

#ifdef NTextern int udtcallbasic();#endif /* NT */

void main(){

/* Declare variables */char *rtn;char arg0[BUFSIZ];char arg1[BUFSIZ];char *args[2]; int sts;

/* Initialize the UniData environment */

udtcallbasic_init(0,0);

/* Assign arguments for the UniBasic routine */strcpy(arg0, "Plants");strcpy(arg1, "Animals");args[0] = arg0;args[1] = arg1;printf("Executing UniBasic subroutine using U_callbas()...\n");

/* Call the UniBasic routine */sts = U_callbas(&rtn, "EXAMPLE", 2, args);

if (sts == 0){printf("Return value from UniBasic subroutine is %s\n", rtn);

#ifdef NT/* Variable rtn returned by UniData come

from the process heap, not the C-RuntimeThey must be free'd with HeapFree().

*/HeapFree(GetProcessHeap(), 0, rtn);

#elsefree(rtn);

#endif /* NT */}

#ifdef NT/* Allocate memory for return variable */

rtn = (char *)malloc(256);

printf("\nExecuting UniBasic subroutine using udtcallbasic()...\n");

276 Developing UniBasic Applications

Page 277: Basd_52

Linking C Programs (Windows NT or Windows 2000 Only)

/* Call the UniBasic subroutine using udtcallbasic. */

sts = udtcallbasic(rtn, "EXAMPLE", 2, args[0], args[1]);

if (sts == 0){printf("Return value from UniBasic subroutine is %s\n", rtn);

}free(rtn);#endif /* NT */

/* Close everything properly */udtcallbasic_done(sts);

}

The following segment from the makefile for callbasic_example1.c shows linking with theUniData.LIB file:

Program Example

LINK32=link.exe# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib a\dvapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib\

/nologo /subsystem:console /machine:I386# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi\32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib c:\u\nidata\bin\unidata.lib /nologo /subsystem:console /machine:I386LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\

advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\odbccp32.lib c:\unidata\bin\unidata.lib /nologo /subsystem:console\/incremental:no /pdb:"$(OUTDIR)/callbasic_example1.pdb" /machine:I386\/out:"$(OUTDIR)/callbasic_example1.exe"

:

ReminderThe sample program and makefile are included in the CALLBASIC_DEMO folder in yourUniData demo account.

Developing UniBasic Applications 277

Page 278: Basd_52

Chapter 8 - Linking Programs with UniData

a

3. Use the New Executable

To run the new executable and call the UniBasic subroutine, your working directory must beUniData account where the subroutine is cataloged. You can execute your routine from theMS-DOS Command prompt, and you will need to be sure to specify the full path name of theexecutable, or include its location in your PATH. The following screen shows the results ofexecuting the callbasic_example1 executable from the demo directory:

Screen Example

:!callbasic_example1UniData is running under a temporary license!This license will expire in 6 days.

Executing UniBasic subroutine using U_callbas()...THE FIRST ARG IS PlantsTHE SECOND ARG IS AnimalsReturn value from UniBasic subroutine is RETURN

Executing UniBasic subroutine using udtcallbasic()...THE FIRST ARG IS PlantsTHE SECOND ARG IS AnimalsReturn value from UniBasic subroutine is RETURN:

ReminderIf your UniBasic subroutine is globally cataloged, you can use CallBasic from any UniDataaccount. You do not need to be in the UniData account where the subroutine was written.

278 Developing UniBasic Applications

Page 279: Basd_52

Chapter 9 - UniBasicTransaction Processing

thetem

ndsence

only

ons

NoteThis chapter applies to UniData for UNIX systems only. UniData for Windows NT or Windows2000 does not support transaction processing.

Transaction processing (TP) combines a set of operations in a single logical function so thatdatabase is maintained in a consistent state throughout an update, even in the event of a sysfailure.

Two UniData products support transaction processing: the Recoverable File System (RFS) aJournaling. One of these products must be in use for transaction processing to work. In the abof RFS or Journaling, UniData ignores TP commands.

NoteRFS and Journaling are purchased separately from the bundled UniData RDBMS. TP workswith recoverable files or files associated with Journaling. For more information about theseproducts, seeUsing JournalingandAdministering the Recoverable File System.

To learn more about creating new recoverable files or converting existing files, seeAdministeringthe Recoverable File System.

To create a UniBasic transaction, you bind the operations by TRANSACTION START andTRANSACTION COMMIT statements. If the transaction is unsuccessful, none of the operatiwithin the transaction take place. After the transaction is initiated, UniData can recover theupdated files.

Developing UniBasic Applications 279

Page 280: Basd_52

Chapter 9 - UniBasic Transaction Processing

ncy,

This chapter introduces the UniBasic transaction processing commands.“Appendix B - UniBasicTransaction Processing Concepts”explains the basic concepts on which UniData transactionprocessing is based. For information about using UniData locks to ensure database consistesee“Chapter 5 - Using UniData Locks.”

280 Developing UniBasic Applications

Page 281: Basd_52

In This Chapter

In This Chapter

This chapter consists of the following sections:

• “Transaction Processing Commands”

• “Creating or Converting to a Recoverable File”

• “Transaction Processing Programming Problems”

Developing UniBasic Applications 281

Page 282: Basd_52

Chapter 9 - UniBasic Transaction Processing

ic

To

seot

niDataica-

Transaction Processing Commands

The following UniBasic commands and the variable @TRANSACTION let you create UniBasprograms with transaction processing safeguards:

• TRANSACTION START

• TRANSACTION COMMIT

• TRANSACTION ABORT

• @TRANSACTION

NoteTransaction processing works only with recoverable files or the UniData Journaling product.learn more about creating new recoverable files or converting existing files, see theAdministeringthe Recoverable File System.

WarningWhen including WRITE statements within a transaction, you must code an ON ERROR clauthat takes appropriate action to notify the user and stop the transaction. If the transaction is naborted by the ON ERROR clause, processing continues, and the transaction commitsinappropriately.

Executing TP and Non-TP TransactionsInformix recommends that you NOT execute at the same time applications that performtransactions and those that do not. If both types of applications make updates to the same Ufile at the same time, indexes based on virtual fields might not be updated, and the only notiftion you will receive will be a warning recorded in the sm.log file.

282 Developing UniBasic Applications

Page 283: Basd_52

Transaction Processing Commands

g

RT

he

e

ngess aretted.dex

r an

ion, the

The following demonstrates a scenario that results in indexes based on virtual fields not beinupdated because TP and non-TP applications are running simultaneously:

1. The TP application initiates a transaction by executing the UniBasic TRANSACTION STAcommand or by executing any UniData SQL transaction-initiating command.

2. The TP transaction writes a new record to a recoverable file. (The write is held pending ttransaction commit.)

3. The non-TP application executes a write, creating a record with the same @ID as the oncreated in Step 2.

4. When the TP transaction commits, UniData discovers that the record now exists, so it chaits insert operation to an update. However, virtual fields are resolved and their index entriecreated when a write is executed within a transaction, not when the transaction is commiBecause the operation has become an update rather than insert, no new alternate key inentry is made for the new record.

Starting a TransactionUse the UniBasic TRANSACTION START command to initiate a transaction.

Syntax:

TRANSACTION START {THEN statement(s) | ELSEstatement(s)}

The UniBasic TRANSACTION START command initiates a new transaction and temporarilystores all updates until a the transaction is committed or aborted. You must specify a THEN oELSE clause, but can specify both.

NoteUniBasic does not support nested transactions. When UniData encounters a nested transactELSE clause executes.

Developing UniBasic Applications 283

Page 284: Basd_52

Chapter 9 - UniBasic Transaction Processing

STATUS Function Values

After you execute TRANSACTION START, the STATUS function returns one of the valuesdescribed in the following table.

For information about the UniBasic STATUS function, see theUniBasic Commands Reference.

Example

In the following example, which is taken from the sample program in“Appendix B - UniBasicTransaction Processing Concepts,”the TRANSACTION START command starts the transactionprocess:

Program Example

TRANSACTION START ELSEIF STATUS() = 1 THEN

DISPLAY "A Transaction had already been started, NESTED Transactions"DISPLAY "are NOT Allowed. (Contact System Administrator)"INPUT PAUSE,1_

END ELSEDISPLAY "The Recoverable File System is not enabled."

ENDEND

Value Description

0 Successful transaction start.

1 Indicates a nested start.

errno Indicates an error message.

STATUS Values

284 Developing UniBasic Applications

Page 285: Basd_52

Transaction Processing Commands

ase,

ing

Committing a TransactionUse the UniBasic TRANSACTION COMMIT command to commit a transaction.

Syntax:

TRANSACTION COMMIT {THEN statement(s)| ELSEstatement(s)}

The UniBasic TRANSACTION COMMIT command concludes the active transaction. UniDatwrites all pending updates to the appropriate files. You must specify a THEN or an ELSE clauor both. If a TRANSACTION COMMIT statement executes in the absence of an activetransaction, UniData executes the ELSE clause.

Successful Commit

UniData performs the following steps during a transaction commit:

1. Disables the break key.

2. Writes all updates.

3. Releases all records locked by this process.

4. Executes the THEN clause, if included.

5. Enables the break key.

Unsuccessful Commit

If the transaction cannot commit and the ELSE clause executes, UniData performs the followsteps:

1. Aborts the transaction without writing records.

2. Releases all records locked inside the transaction.

Developing UniBasic Applications 285

Page 286: Basd_52

Chapter 9 - UniBasic Transaction Processing

nd

STATUS Function Values

After you execute TRANSACTION COMMIT, the STATUS function returns one of the valuesdescribed in the following table.

Example

In the following example, taken from the sample program in“Appendix B - UniBasic TransactionProcessing Concepts,”the TRANSACTION COMMIT command ends the transaction process awrites the new record to the database:

Program Example

TRANSACTION COMMIT ELSEIF STATUS() = 1 THEN

DISPLAY "The TRANSACTION was not started"END ELSE

DISPLAY "The TRANSACTION could not be committed."END

Value Description

0 Transaction committed.

1 Transaction not started.

3 Transaction cannot com-mit.

STATUS Values

286 Developing UniBasic Applications

Page 287: Basd_52

Transaction Processing Commands

the

e to

ion

.

ithined in

Aborting a TransactionUse the UniBasic TRANSACTION ABORT command to abort active transactions.

Syntax:

TRANSACTION ABORT

The UniBasic TRANSACTION ABORT command cancels the active transaction, discardingpending writes. As a result, none of the updates associated with the transaction occur.

In addition to encountering a TRANSACTION ABORT statement, a transaction could abort duany of several conditions, including:

• A program finishes before a transaction commit is issued (STOP or END).

• The program CHAINs to another program.

• An error terminates the program before a transaction commit is issued.

• A user breaks out of the program before a transaction commit is issued. This can beprevented programmatically by disabling the interrupt key during the transaction byexecuting the ECL command PTERM -BREAK OFF.

• The user running the program is logged out, or the process is killed before a transactcommit is issued.

The system handles these abort conditions in the same way it does TRANSACTION ABORT

NoteYou should be aware of these various abort conditions and control the resulting action from wthe program where possible and appropriate. For example, if no ON ERROR clause is includa write statement and the write fails, the program aborts, terminating the transaction.

Developing UniBasic Applications 287

Page 288: Basd_52

Chapter 9 - UniBasic Transaction Processing

Example

In the following example, the transaction process aborts ifvar is 10:

Program Example

TRANSACTION STARTTHEN PRINT "Transaction started."ELSE PRINT "Transaction start failed, STATUS = ":STATUS(); STOP

READU var FROM file.var, record1var += 2IF var = 10 THEN TRANSACTION ABORT; GOTO ERR:WRITE var TO file.var, record1

TRANSACTION COMMITTHEN PRINT "Transaction committed."ELSE PRINT "Transaction Aborted, STATUS = ":STATUS(); STOP

Testing for an Active TransactionThe variable @TRANSACTION lets you test for an active transaction. The following tabledescribes the possible values for @TRANSACTION.

Value Description

1 A transaction is active.

0 A transaction is not active.

@TRANSACTION Values

288 Developing UniBasic Applications

Page 289: Basd_52

Transaction Processing Commands

on,

Transaction Processing Programming ExampleThe following program segment is taken from the sample program in“Appendix B - UniBasicTransaction Processing Concepts.”Note that the WRITE commands are enclosed in a transactiand that both or neither are committed.

Program Example

WRITE_RECORD:* The record(s) have been updated. Make sure that if the RECOVERABLE* FILE System is operational that either BOTH records are updated, or that* None are (using Transaction processing commands).

TRANSACTION START ELSEIF STATUS() = 1 THEN

DISPLAY "A Transaction had already been started, NESTED Transactions"DISPLAY "are NOT Allowed. (Contact System Administrator)"INPUT PAUSE,1_

END ELSEDISPLAY "The Recoverable File System is not enabled."

ENDEND

WRITE CLIENT.REC ON CLIENT_FILE,CLIENT_NUMBERWRITE ORDER.REC ON ORDERS_FILE,ORDER_NUMBER

TRANSACTION COMMIT ELSEIF STATUS() = 1 THEN

DISPLAY "The TRANSACTION was not started"END ELSE

DISPLAY "The TRANSACTION could not be committed."END

ENDRETURN

Developing UniBasic Applications 289

Page 290: Basd_52

Chapter 9 - UniBasic Transaction Processing

to be

ify

does

e

Creating or Converting to a Recoverable File

You can make a file recoverable when you create it, or you can convert a nonrecoverable filerecoverable. UniData supports recovery of the following file types:

• DATA

• DICT

• MULTIFILE

• DYNAMIC

NoteThe recoverable file system does not protect DIR and MULTIDIR type files. You cannot specthe DIR or MULTIDIR options with the recoverable options.

WarningThe operating system–level acctrestore command, which restores accounts in CPIO format,not work with the UniData Recoverable File System (RFS).

Creating a Recoverable FileUse the ECL CREATE.FILE command with the RECOVERABLE option to create a file for uswith RFS. For more information about RFS, seeAdministering the Recoverable File System.

Syntax:

CREATE.FILE [DICT | DATA] [DIR | MULTIFILE | MULTIDIR]filename[,subfile] [modulo[,block.size.multiplier]][TYPE hashtype] [DYNAMIC [KEYONLY | KEYDATA] [PARTTBL part_tbl]][RECOVERABLE] [OVERFLOW]

For more information about the ECL CREATE.FILE command, see theUniData CommandsReference.

290 Developing UniBasic Applications

Page 291: Basd_52

Creating or Converting to a Recoverable File

,xt

ore

to a

s

Example

In the following example, the CREATE.FILE command creates the recoverable file MASTERwith a modulo of 4. Because 4 is not a prime number, UniData changes the modulo to the nehighest prime number, which is 5:

Screen Example

: CREATE.FILE MASTER 4 RECOVERABLE4 is not a prime number, modulo changed to 5.Create file D_MASTER, modulo/1,blocksize/1024Hash type = 0Create file MASTER, modulo/5,blocksize/1024Hash type = 0Added "@ID", the default record for UniData to DICT MASTER.

Converting to a Recoverable FileTo convert an existing file to a recoverable file, use the UniData udfile command. To learn mabout creating new recoverable files or converting existing files, seeAdministering UniData onUNIX.

Syntax:

udfile [-r | -s] file.name

PermissionsThe UniData operating system–level udfile command converts a nonrecoverable UniData filerecoverable file or a recoverable file to a nonrecoverable UniData file. You must have rootprivileges to convert a file using this command. If you do not specify an option,UniData returnthe type of file (that is, recoverable or nonrecoverable). You cannot convert a file using udfilewhile UniData is running.

Developing UniBasic Applications 291

Page 292: Basd_52

Chapter 9 - UniBasic Transaction Processing

tryust

Parameters

The following table describes the valid udfile options.

NoteThe udfile command does not convert files that were created in one-half kilobyte blocks. If youto do so, UniData issues an error message indicating that the file cannot be converted. You mresize the file to at least a 1K block size, using the ECL RESIZE or system-level memresizecommand. For information about ECL commands, see theUniData Commands Reference.

Option Description

-r Converts a nonrecoverable file to a recoverable file.

-s Converts a recoverable file to a nonrecoverable file.

udfile Options

292 Developing UniBasic Applications

Page 293: Basd_52

Transaction Processing Programming Problems

seways

a

bortse thebeg.

user

.

hernone

,

Transaction Processing Programming Problems

Programming problems could, in some cases, degrade performance and, in other cases, cauUniData to abort transactions. This section points out some of these problems and suggestsof overcoming them. Many problems are caused or compounded by improper use of UniDatlocks. For more information, see“Chapter 5 - Using UniData Locks.”

Transaction AbortThe following problems cause UniData to abort transactions:

• Deadlocks

When two or more programs are waiting for each other to release records, UniData aone of the transactions to unlock its records and remove the deadlock. You can reduclikelihood of deadlocks occurring by imposing a protocol on the order data items canupdated. For example, the protocol might let programs lock record B only after lockinrecord A. If all programs on the system follow this protocol, deadlocks will be avoided

• Upgrading Locks

If two users share a lock on a record, and one or both tries to upgrade to a U lock, onereceives the upgraded lock, and UniData aborts the other transaction. Execute theLOCKED clause in the locking statement to abort the transaction, but not the program

• Nested Transactions

UniData does not support nested transactions. A TRANSACTION START within anotactive transaction executes the ELSE clause, if specified, and aborts the transaction ifis specified. Use the @TRANSACTION variable to find out if a transaction is activebefore calling an external subroutine. For more information about @TRANSACTIONsee“Testing for an Active Transaction”earlier in this chapter.

Developing UniBasic Applications 293

Page 294: Basd_52

Chapter 9 - UniBasic Transaction Processing

topstill

QL.cute

ersults

• Called Programs and Subroutines

If a you start a transaction within a called program or subroutine, and the subroutine sabnormally, UniData could return control to the calling program with the transaction sactive. To avoid this, include the ON.ABORT clause in the subroutine to stop programexecution in the event of a problem affecting a subroutine.

• Transaction Processing Limitations

UniData does not support transaction processing outside of UniBasic and UniData SAlthough you can include EXECUTE statements within a transaction, you cannot exeany of the following types of operations with the EXECUTE:

• UniData SQL (use EXECUTESQL)

• UEntry/UReport

• File-level operations on recoverable files (for example, the UniBasic CLEARFILEcommands and the following ECL commands: CLEAR.FILE, DELETE.FILE,RESIZE, CREATE.FILE, CREATE.INDEX, BUILD.INDEX, DELETE.INDEX,CNAME).

UDT.OPTIONSIf UDT.OPTION 35 is on when you issue an EXECUTE statement, UniData creates a new usand processes it independently from the original UniBasic program, causing unpredictable rein TP. Make sure UDT.OPTION 35 is off when using TP.

294 Developing UniBasic Applications

Page 295: Basd_52

Transaction Processing Programming Problems

n 2 to

s

Examples

Recovering from a deadlock– In this example, a deadlock results because two programs arewaiting for each other to release the same record (steps 3 and 4). UniBasic aborts Transactiobreak the deadlock when this transaction tries to upgrade to an exclusive lock. However, theLOCKED clause (LOCKED TRANSACTION ABORT) in the RECORDLOCKU statement tellUniBasic to abort the transaction only, thus preventing the program from aborting.

Step Transaction 1 Transaction 2

1 TRAN1:TRANSACTION STARTTHEN PRINT "Transaction started."READL var1 FROM file.var, record1ELSE PRINT "File not found."

TRAN2:TRANSACTION STARTTHEN PRINT "Transaction started."

2 READL var1 FROM file.var, record1ELSE PRINT "File not found."

3 RECORDLOCKU var1LOCKED TRANSACTION ABORT; GOSUBTRAN1

4var += 2WRITE var TO file.var, record1TRANSACTION COMMITTHEN PRINT "Transaction commit-ted."

RECORDLOCKU var1LOCKED TRANSACTION ABORT; GOTOTRAN2var += 2WRITE var TO file.var, record1TRANSACTION COMMITTHEN PRINT "Transaction commit-ted."

Avoiding Program Abort on Deadlock

Developing UniBasic Applications 295

Page 296: Basd_52

Chapter 9 - UniBasic Transaction Processing

ansac-brou-

on.

Nested transactions – The next three examples demonstrate creating and avoiding nested trtions. In this first program segment, the main routine starts a transaction, and then calls a sutine that contains a TRANSACTION START. This always results in an aborted transactionbecause transactions cannot be nested.

Program Example

TRANSACTION START ELSE PRINT "Transaction error.";STOPREADU var FROM file.var, record1 ELSE PRINT "File not found."IF var = "" THEN CALL SUBRZWRITE var TO file.var, record1

TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

SUBROUTINE SUBRZTRANSACTION START ELSE PRINT "Transaction error.";STOP

READU var1 FROM file.var, record2 ELSE PRINT "File not found."var1 += 2WRITE var1 TO file.var, record2

TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

The next program segment avoids the problem demonstrated in the previous example. Thesubroutine tests @TRANSACTION for an active transaction before starting its own transacti

Program Example

TRANSACTION START ELSE PRINT "Transaction error.";STOPREADU var FROM file.var, record1IF var = "" THEN CALL SUBRZWRITE var TO file.var, record1

TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

SUBROUTINE SUBRZIF @TRANSACTION= 1 THEN RETURNTRANSACTION START ELSE PRINT "Transaction error.";STOP

READU var1 FROM file.var, record2var1 += 2WRITE var1 TO file.var, record2

TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

296 Developing UniBasic Applications

Page 297: Basd_52

Transaction Processing Programming Problems

N

t or

theseRT.

cerove

In the following program, the subroutine tests for an active transaction with @TRANSACTIObefore an EXECUTE statement:

Program Example

TRANSACTION STARTELSE PRINT "Transaction not started."; STOP

READU var FROM file.var, record1IF var = "" THEN CALL SUBRZWRITE var TO file.var, record1

TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

SUBROUTINE SUBRZIF @TRANSACTION= 0 THEN EXECUTE "CLEAR.FILE file.var" ELSE RETURN

RETURN

Degraded PerformanceThis section discussed causes and solutions of degraded performance.

• Locked Records

If you lock records within a transaction, those records remain locked until you commiabort the transaction. If your program performs a number of operations, especiallyrequesting user input, you increase the waiting period for other users trying to accessrecords. To avoid this problem, put input statements before the TRANSACTION STAIf you must include requests for user interaction within a transaction, include theWAITING clause in the INPUT statement to time out if the user does not respond in areasonable amount of time.

• Long Transactions

Performing a number of operations inside a transaction also contributes to performandegradation. By minimizing the number of operations in the transaction, you can impperformance.

Developing UniBasic Applications 297

Page 298: Basd_52

Chapter 9 - UniBasic Transaction Processing

d

:

NoteProtecting data by locking records and using transaction processing can contribute to reduceefficiency and system performance.

Example

In the following example, the INPUT times out after five minutes if the user does not respond

Program Example

READU var FROM file.var, record1 ELSE PRINT "File not found."INPUT var WAITING 300TRANSACTION START ELSE PRINT "Transaction not started." STOP

WRITE var TO file.var, record1TRANSACTION COMMIT ELSE PRINT "Transaction aborted."

298 Developing UniBasic Applications

Page 299: Basd_52

Chapter 10 - Null ValueHandling

lingng,‘92.

This chapter introduces the null value handling in UniBasic. UniData supports null value handon both UNIX and Windows NT or Windows 2000 systems. You can turn on null value handliwhich makes the UniData RDBMS more compliant with the standards defined by ANSI SQLCompliance improves compatibility with client and desktop tools.

Developing UniBasic Applications 299

Page 300: Basd_52

Chapter 10 - Null Value Handling

rrou

sure

uwith

Representing Unknown Values

If you turn null value handling on, and you have accepted the default language group wheninstalling UniData, the null value is represented by the ASCII character 129. If you changelanguage groups, a different character could be assigned to represent the null value. For thisreason, Informix recommends that you use the @NULL variable to represent the null value inUniBasic.

TipTo determine which ASCII value represents the null value on your system, use the UniBasiccommand SEQ(@NULL).

Turning Null Value Handling OffWhen you install UniData, null value handling is turned off by default (the udtconfig parameteNULL_FLAG = 0). With null value handling turned off, an empty string represents unknown omissing values, and UniBasic programs that contain the variable @NULL will not compile. If ytry to execute object code containing @NULL, the program terminates with a fatal error.

After turning null value handling on, Informix recommends that you not turn it off, as the nullcharacter could have been introduced to your data. If you must turn null value handling off, beto check your data and convert the null value to another string (using a UniBasic program orvirtual attribute) before trying to execute queries, virtual attributes, or UniBasic programs. Yowill also need to regenerate any indexes that could contain null values; if you do not, recordsnull alternate key values cannot be retrieved.

300 Developing UniBasic Applications

Page 301: Basd_52

Null Value Handling in UniBasic

erdingcter

ble

n

ore

all

, by

Null Value Handling in UniBasic

The presence of the null value in data or function/command arguments profoundly affects thresults of UniBasic commands, functions, and arithmetic operators. These effects differ accoto whether null value handling is turned on or off, and range from UniBasic ignoring the charato generating a runtime error.

Printing and DisplayingThe ASCII character that represents the null value is nonprinting, and the environment variaNVLMARK, which specifies an alternative character to represent the null value for display orprinting in UniData and UniQuery, has no effect in UniBasic. Although no comparable functioexists in UniBasic, you can use the UniBasic conversion commands, such as SWAP andCONVERT, or the UniData SQL command NVL to convert the null value to another string befprinting.

Sorting and IndexingNull Value Handling On – The null character is always sorted as the lowest value, lower thannegative numbers.

TipUse the UniBasic command SETINDEX with therop operator NULL_VAL_ALT_KEY to set thealternate key index pointer to the null value (the beginning of the index). Therop operatorFIRST_ALT_KEY sets the pointer to the first non-null key.

Null Value Handling off – The character that would represent the null value is sorted normallyASCII value.

Developing UniBasic Applications 301

Page 302: Basd_52

Chapter 10 - Null Value Handling

Summary of Effects on Commands and FunctionsThe following table summarizes the effects of the null value in data and function or commandarguments. Details are provided in the sections that follow.

Type ofOperation Null Value Handling On Null Value Handling Off

Numericcalculations

Result is the null value. Original value is returned.UniBasic returns the message“ Non-numeric found when

numeric required .”

Relationaloperations

Follow the ANSI SQL3-way logic rules.

No special handling of the nullvalue. Follow the ANSI SQL 2-way logic rules.

Conversions Result is the null value; invalidfor format code.

No special handling of the nullvalue; invalid for format code.

Stringfunctions

No special handling of the nullvalue. In a parameter, if numericis required, displays a warningmessage and uses 0.

No special handling of the nullvalue. In a parameter, if numeric isrequired, generates runtime error.

Sorting andindexing

Null value is lowest (smaller thanall negative numbers).

No special handling of the nullvalue. Sorting is based on ASCIIvalues.

Null Value Handling Summary

302 Developing UniBasic Applications

Page 303: Basd_52

Null Value Handling in UniBasic

on or

.

ent

sues

The Null Value in Numeric FunctionsThe presence of the null character in data affects numeric functions whether nulls are turnedoff. The following table lists the UniBasic numeric operators and functions.

Null Value Handling On

In Data – The result of any numeric function on data containing the null value is the null value

In Arguments – Any time UniBasic encounters a null value as a command or function argumwhen a number is required, UniBasic prints a warning message and uses 0 as the functionargument.

ReminderWhen a UniBasic numeric function encounters a non-null, nonnumeric character, UniBasic isa warning message:Non-numeric found when numeric required ; the command or functionprocesses, using 0 in place of the invalid character.

Numeric Operators and Functions

+ - * /

^ ABS ACOS ASIN

ATAN BITAND BITNOT BITOR

BITXOR COS DROUND EXP

INT LN MOD NEG

POWER PWR RND SADD

SCMP SDIV SIN SMUL

SQRT SSUB TAN

Numeric Operators and Functions Affected by the Null Value

Developing UniBasic Applications 303

Page 304: Basd_52

Chapter 10 - Null Value Handling

Examples

The following program demonstrates the principle that any arithmetic operation on data thatcontains the null value results in the null value:

Program Example

A = 100 + @NULLGOSUB PRINTNULLPRINT "100 + @NULL = ":A

A = 0A = SIN(@NULL)GOSUB PRINTNULLPRINT "SIN(@NULL) = ":A

A = 0A = 99/@NULLGOSUB PRINTNULLPRINT "99/@NULL = ":A

A = 0A = 33/99GOSUB PRINTNULLPRINT "33/99 = ":A

STOP

PRINTNULL:IF ISNV(A) THEN SWAP @NULL WITH "null value" IN ARETURN

304 Developing UniBasic Applications

Page 305: Basd_52

Null Value Handling in UniBasic

f.

rnedg

The preceding program prints the following:

Screen Example

100 + @NULL = null valueSIN(@NULL) = null value99/@NULL = null value33/99 = 0.3333

Null Value Handling Off

The null value is invalid. When a numeric function encounters the null value as data or anargument, UniBasic displays a warning message and uses 0.

NoteUniBasic programs containing @NULL will not compile when null value handling is turned of

The Null Value in Conditional TestsThe presence of the null value in data affects conditional tests only if null value handling is tuon; then it is evaluated to false (0). You perform conditional tests in UniBasic with the followinstatements:

• IF/THEN/ELSE

• CASE

Within these statements, you can nest additional conditions using the following keywords:

• WHILE

• UNTIL

Developing UniBasic Applications 305

Page 306: Basd_52

Chapter 10 - Null Value Handling

the

m

Examples

The following examples demonstrate the effect of the null value in IF/THEN/ELSE and CASEstatements.

In this first example, COUNT.TO.TEN does not execute because X is the null value. Instead,program prints@NULL evaluates to 'false' .

Program Example

X=@NULLIF X THEN GOSUB COUNT.TO.TEN ELSE GOSUB NO.COUNT

STOP

COUNT.TO.TEN:FOR X = 1 TO 10

PRINT XNEXT XRETURN

NO.COUNT:PRINT "@NULL evaluates to 'false'"RETURN

In the following program segment, CASE 1 executes because X is the null value. The prograsegment printsDeleting corrupt record; @ID is null.

Program Example

X = @NULLBEGIN CASE

CASE X = 1GOSUB ADD_RECORD

CASE X = 2GOSUB UPDATE_RECORD

CASE X = 3FINISHED = 1

CASE 1GOSUB DELETE_RECORD

306 Developing UniBasic Applications

Page 307: Basd_52

Null Value Handling in UniBasic

END CASE

STOP

ADD_RECORD:PRINT "Adding a record."

RETURN

UPDATE_RECORD:PRINT "Updating a record."

RETURN

DELETE_RECORD:PRINT "Deleting corrupt record; @ID is null."

RETURN

Comparison Operators Used in Conditional Tests

The following table lists the UniBasic comparison operators.

NoteThe logical operators NULL and NOT @NULL are both evaluated to the null value, whichproduces a result of false in a conditional test.

Comparison Operators

NOT NOTS LE, <=, =< LES LT, <

LTS EQ, = EQS NE, #, <>, >< NES

GE, >=, => GES GT, > GTS AND

OR #> #<

Comparison Operators

Developing UniBasic Applications 307

Page 308: Basd_52

Chapter 10 - Null Value Handling

T, F,

use

Null Value Handling On

The results of comparisons using the logical operator AND are provided in the following truthtable (T, F, and N represent TRUE, FALSE, and @NULL, respectively).

The results of comparisons using the logical operator OR are provided in the following table (and N represent TRUE, FALSE, and @NULL, respectively).

You can use the following sample program to test comparisons of the logical operator OR. Tothe program to test the logical operator AND, substitute AND for OR in this program.

Program Example

PROMPT @(-1)PROMPT''PRINT "First value: Enter true, false, or null: ":INPUT answeranswer = UPCASE(answer)GOSUB SET.VALval.one=value

T F N

T T F N

F F F F

N N F N

Null in Conditional Statements with AND

T F N

T T T T

F T F N

N T N N

Null in Conditional Statements with OR

308 Developing UniBasic Applications

Page 309: Basd_52

Null Value Handling in UniBasic

ison

PRINT "Second value: Enter true, false, or null: ":INPUT answeranswer = UPCASE(answer)GOSUB SET.VALval.two=value

BEGIN CASECASE (val.one OR val.tw o ) = 1PRINT "Condition is true."CASE ISNV(val.one OR val.two) = 1PRINT "Condition is null"CASE 1PRINT "Condition is false."

END CASE

SET.VAL:IF answer = "NULL" THEN value = @NULLIF answer = "TRUE" THEN value = 1IF answer = "FALSE" THEN value = 0RETURN

The following example shows a sample run of this program. It demonstrates that the compar‘true OR null’ produces a result of ‘true’.

Screen Example

: RUN BP null.compareFirst value: Enter true, false, or null: trueSecond value: Enter true, false, or null: nullCondition is true.

Developing UniBasic Applications 309

Page 310: Basd_52

Chapter 10 - Null Value Handling

Examples

The following program segments demonstrate the effect of the null value on comparisons.

ReminderIn a comparison test, the null value is interpreted by UniBasic as false.

A comparison with the null value produces a result of null:

Program Example

X = @NULLIF NOT(X) THEN

PRINT "1a. NOT(NULL) is TRUE"END ELSE

Y = NOT(X)PRINT "1b. NOT(NULL) IS FALSE"

END

This program segment prints the following:

Screen Example

1b. NOT(NULL) IS FALSE

Any number is greater than the null value:

Program Example

X = @NULLIF (100 LE X) THEN

PRINT "2a. 100 LE NULL is TRUE"END ELSE

PRINT "2b. 100 LE NULL IS FALSE"

310 Developing UniBasic Applications

Page 311: Basd_52

Null Value Handling in UniBasic

ENDPRINT " 100 LE NULL evaluates to ":(100 LE @NULL)

This program segment prints:

Screen Example

2b. 100 LE NULL IS FALSE100 LE NULL evaluates to 0

The null value compared to the null value yields a result of false:

Program Example

X = @NULLIF (X EQ X) THEN

PRINT "3a. NULL EQ NULL IS TRUE"END ELSE

PRINT "3b. NULL EQ NULL IS FALSE"ENDPRINT " NULL EQ NULL evaluates to ":(@NULL EQ @NULL)

This program segment prints:

Screen Example

3b. NULL EQ NULL IS FALSENULL EQ NULL evaluates to 0

Anything AND the null value yields a result of false:

Program Example

X = @NULLIF (1 AND X) THEN

Developing UniBasic Applications 311

Page 312: Basd_52

Chapter 10 - Null Value Handling

PRINT "4a. 1 AND NULL IS TRUE"END ELSE

PRINT "4b. 1 AND NULL IS FALSE"ENDPRINT " 1 AND NULL evaluates to ":(1 AND @NULL)

This program segment prints:

Screen Example

4b. 1 AND NULL IS FALSE1 AND NULL evaluates to

Anything OR the null value yields a result of true:

Program Example

X = @NULLIF (1 OR X) THEN

PRINT "5a. 1 OR NULL IS TRUE"END ELSE

PRINT "5b. 1 OR NULL IS FALSE"ENDPRINT ' 1 OR NULL evaluates to ":(1 OR @NULL)

This program segment prints:

Screen Example

5a. 1 OR NULL IS TRUE1 OR NULL evaluates to 1

312 Developing UniBasic Applications

Page 313: Basd_52

Null Value Handling in UniBasic

llto 5.

n,turns

.hen atring.

Null Value Handling Off

The UniBasic comparison operations followANSI2-way logic, with the null value beingcompared as its ASCII value (ASCII character 129 in the English language group).

The Null Value in Conversion FunctionsThe following table lists the UniBasic conversion functions.

Null Value Handling On

In Data – For conversion functions ICONV/S, OCONV/S, and FMT/S, the presence of the nuvalue in data produces a result of the null value, and the STATUS function return value is set

In Parameters – If a UniBasic program tries to use the null value as a conversion specificatioUniBasic generates a runtime error and returns the input string. The STATUS function then re2, indicating an invalid conversion specification.

TipSome string functions also perform conversions of various kinds while ignoring the null valueUse the conversion functions in the preceding table when you want to produce a null value wnull value is input; use the string functions to convert between the null value and some other s

Conversion Functions

ICONV OCONV FMT

ICONVS OCONVS FMTS

Conversion Functions Affected by the Null Value

Developing UniBasic Applications 313

Page 314: Basd_52

Chapter 10 - Null Value Handling

alue

e is

ATUS

Examples

The following example demonstrates that an ICONV conversion on data containing the null vproduces a result of the null value:

Program Example

X = ICONV(@NULL,"D2/")PRINT "STATUS FOR ICONV IS ":STATUS()IF ISNV(X) THEN PRINT "ICONV on the null value produces the null value."

This program produces the following results:

Screen Example

STATUS FOR ICONV IS 5ICONV on the null value produces the null value.

NoteIf the null value is found in a string to be converted, the UniBasic STATUS function return valuset to 5.

This example demonstrates that @NULL in an argument produces no result, but sets the STreturn code to 2:

Program Example

PRINT = ICONV(1234,"@NULL")PRINT "STATUS FOR ICONV IS ":STATUS()

314 Developing UniBasic Applications

Page 315: Basd_52

Null Value Handling in UniBasic

ata.racter.

if a

0

This program produces the following results:

Screen Example

STATUS FOR ICONV IS 2

Null Value Handling Off

In Data – The ASCII character that would represent the null value in data has no effect onconversion functions.

In Parameters – The result is the null value; invalid format code.

The Null Value in String FunctionsThe following general guidelines apply to all string functions:

Null Value Handling On

In Data – The UniBasic string commands and functions are not affected by the null value in dTherefore, you can use them to manipulate the null character just as you would any other chaExceptions to this rule are listed in the following sections.

The following list highlights some points to remember about the null value in string functions:

• ISNV and ISNVS test for the null value as a string or dynamic array element.

• SEQ(@NULL) returns the ASCII code representing @NULL on your system.

• You cannot use an expression like “IF CUSTOMER = @NULL” to search for the nullvalue. You must instead test for a return value of 1 from ISNV or ISNVS to determinevariable or element is the null value.

• You cannot use NOT(@NULL) to test for the absence of the null value becauseNOT(@NULL) evaluates to the null value. You must instead test for a return value offrom ISNV or ISNVS.

• You can assign the null value to a variable in the following way:X=@NULL

Developing UniBasic Applications 315

Page 316: Basd_52

Chapter 10 - Null Value Handling

d,

nSCII

d,

r

In Parameters – Whenever a numeric parameter is required, and the null value is encountereUniBasic displays the warning message “Null value found when numeric required ”;UniBasic then continues processing using 0 as the parameter.

Null Value Handling Off

In Data – The ASCII character that would represent the null value has no effect on conversiofunctions when encountered in data. You can use these functions to locate and change any Avalue, including nulls.

In Parameters – Whenever a numeric parameter is required, and the null value is encountereUniBasic displays the warning message “Non-numeric found when numeric required ”;UniBasic continues processing using 0 as the function parameter.

Summary

The null value receives no special handling in string functions. It is processed as any othercharacter. If UniBasic encounters the null value in a command parameter when a number isexpected, it displays a warning message and uses 0.

Type Commands/Functions

String conversion ASCII, CHANGE, CHAR, CHARS, CONVERT, EBCDIC,REPLACE, SEQ, SEQS

DOWNCASE, UPCASE,SOUNDEX

Note - Special characters, including the null value, are ignored. Theyremain unchanged in function output.

Testing for datatype

ALPHA (alphabetic)NUM, NUMS (numeric)ISNV, ISNVS (null value)

Note -Special characters, including the null value, are not alphabetic onumeric.

UniBasic String Function Types

316 Developing UniBasic Applications

Page 317: Basd_52

Null Value Handling in UniBasic

Conditional tests IF/THEN/ELSE, CASE, WHILE, UNTIL

Note - For more information see“The Null Value in Conditional Tests”earlier in this chapter.

Concatenation : (colon), CAT, CATS, SPLICE

Insertion [], FIELDSTORE, GROUPSTORE, INS, INSERT

Deletion DEL, DELETE

Location GROUP, MATCHFIELD, XLATE

FIND, FINDSTR, LOCATE, MATCH, MATCHES

Extraction [ ], EXTRACT, FIELD, FIELDS, REMOVE, SUBSTRINGS, TRIM,TRIMB, TRIMF, TRIMS

Counting COUNT, COUNTS, DCOUNT

Returning System,File, Printer, andUser Information

DIR, SYSTEM, GETPTR, GETPU, GETUSERGROUP, GETUSER-NAME

Measuring Length LEN, LENS

Note - The null value has a length of 1 byte.

Repeating STR, STRS

SPACE, SPACES

Note - These functions produce a string or array elements made up ofspaces.

Type Commands/Functions

UniBasic String Function Types (continued)

Developing UniBasic Applications 317

Page 318: Basd_52

Chapter 10 - Null Value Handling

rs:

lue:

Examples

The following subroutine converts UniData delimiters and the null value to printable characte

Program Example

* externally cataloged subroutine to convert the null value* and UniData delimiters for printingSUBROUTINE null.swap(A)SWAP @NULL WITH "null value" IN ASWAP @AM WITH "AM" IN ASWAP @VM WITH "VM" IN ASWAP @SM WITH "SM" IN ARETURN

Testing for Data Type

The following program uses the function ISNV to test a string to see if it consists of the null va

Program Example

A = 0

PRINT "1.a ISNV(0) = ":ISNV(A)PRINT "2.a NOT(ISNV(0)) = ":NOT(ISNV(0))

A = "abc":@NULL:"def"PRINT "1.b ISNV('abc':@NULL:'def') = ":ISNV(A)PRINT "2.b NOT(ISNV('abc':@NULL:'def')) = ":NOT(ISNV(A))

A = @NULLPRINT "1.c ISNV(@NULL) = ":ISNV(A)PRINT "2.c NOT(ISNV(@NULL)) = ":NOT(ISNV(A))

318 Developing UniBasic Applications

Page 319: Basd_52

Null Value Handling in UniBasic

ains

se

This program produces the following results. Notice that ISNV executed on a string that contthe null valueand other charactersproduces a negative result (0).

Screen Example

1.a ISNV(0) = 02.a NOT(ISNV(0)) = 11.b ISNV('abc':@NULL:'def') = 02.b NOT(ISNV('abc':@NULL:'def')) = 11.c ISNV(@NULL) = 12.c NOT(ISNV(@NULL)) = 0

The following program segment inserts the null value into or deletes the null value from amultivalue in the QUANTITY attribute for a selected record in the INVENTORY demo databafile:

Program Example

OPEN 'INVENTORY' TO INV_FILE ELSEPRINT "OPEN error"STOP

END

PRINT "Enter record to be modified: ":INPUT recREADU REC_ARRAY FROM INV_FILE,rec LOCKED PRINT "Record locked."

ELSE PRINT "Record not found."

LOCATE @NULL IN REC_ARRAY<6,1,0> SETTING POINT THENPRINT "The null value already exists in the array at position ":PRINT POINTPRINT "Deleting the null value."DEL REC_ARRAY<6,POINT>PRINT "@NULL deleted from the array at position ":POINTPRT_ARRAY = CHANGE(REC_ARRAY,@NULL,"@NULL")FOR X = 1 TO POINT

PRINT PRT_ARRAY<6,X>NEXT XWRITE REC_ARRAY TO INV_FILE,rec ON ERROR PRINT "WRITEerror."

END ELSE

Developing UniBasic Applications 319

Page 320: Basd_52

Chapter 10 - Null Value Handling

REC_ARRAY<6,POINT> = @NULLPRINT "@NULL placed in the array at position ":POINTPRT_ARRAY = CHANGE(REC_ARRAY,@NULL,"@NULL")FOR X = 1 TO POINT

PRINT PRT_ARRAY<6,X>NEXT XWRITE REC_ARRAY TO INV_FILE,rec ON ERROR PRINT "WRITEerror."

ENDSTOP

The following example shows a a sample run of the preceding program:

Screen Example

: RUN BP null.del.insEnter record to be modified: ? 56070

@NULL placed in the array at position 5400500394399@NULL

A second execution of this program produces the following results:

Screen Example

:RUN BP null.del.insEnter record to be modified: ?56070

The null value already exists in the array at position 5Deleting the null value.@NULL deleted from the array at position 5400500394399

320 Developing UniBasic Applications

Page 321: Basd_52

Null Value Handling in UniBasic

the

er to

dex:

ReminderWhen a numeric parameter is required, and the null value is encountered, UniBasic displayswarning message “Null value found when numeric required ”; UniBasic continues processingusing 0 as the function parameter.

Sorting and Indexing

The following series of examples demonstrates the use of SETINDEX to set the record pointthe first null key in the PROD_NAME alternate key index:

Program Example

OPEN 'INVENTORY' TO inventory ELSE PRINT "Open error"SETINDEX 'PROD_NAME', NULLVAL_ALT_KEY inventory

FOR X = 1 TO 5READFWD rec FROM inventory THEN

PRINT rec<0>:", ":rec<3>:", ":rec<4>END ELSE NULL

NEXT XSTOP

This program produces the following result when no null values exist in the PROD_NAME in

Screen Example

: RUN BP set.idx10020, Adapter, A/C Adapter for notebook computers10086, Adapter, Ethernet LC Card10092, Adapter, Workgroup Hub10082, CD Player, Portable Model10104, CD Player, Personal Model, Bass Boost

Developing UniBasic Applications 321

Page 322: Basd_52

Chapter 10 - Null Value Handling

the

After the null value is inserted into the PROD_NAME attribute for records 10008 and 56060,same program produces the following results:

Screen Example

: RUN BP set.idx10015, , Portable, B/W, 6 ppm10238, , Super Deluxe Model10020, Adapter, A/C Adapter for notebook computers10086, Adapter, Ethernet LC Card10092, Adapter, Workgroup Hub

322 Developing UniBasic Applications

Page 323: Basd_52

Chapter 11 - ManagingNamed Pipes

s to

SEQTE

readwrite

lly.

The UniBasic OSOPEN, OSBREAD, and OSBWRITE commands enable UniBasic programinterface, through named pipes, with RedBack (UniData’s web application development soft-ware), other UniBasic programs, or other non-UniData processes.

NoteYou cannot use the READSEQ command to read a named pipe, nor can you use the WRITEor WRITESEQF command to write to a named pipe. You must use OSBREAD and OSBWRIto perform these tasks.

Three factors affect the operation of these commands:

• Is the target of the command a named pipe or a file?

• For a named pipe – Is it open for a complementary operation on the other end? (Whenaccess is requested, is the pipe open for writing on the other end? Conversely, whenaccess is requested, is the pipe open for reading on the other end?)

• For a named pipe – Is data stored in the pipe, and is it of the length specified in thecommand?

Processing can be modified to accommodate different circumstances. For example, a singleprocess can open the pipe for read-write access, and then coordinate access programmaticaAlso, a process can force the requested access by executing the NODELAY option.

Developing UniBasic Applications 323

Page 324: Basd_52

Chapter 11 - Managing Named Pipes

e:

r openthe

nd the

s not

hen

For UNIX, use the UNIX mkfifo command to create a named pipe, as in the following exampl

ReminderTo execute a UNIX command from the ECL prompt, precede it with the UniData bang (!)command.

Screen Example

: !mkfifo pipe_file: ls -l pipe_fileprw-rw-rw- 1 carolw unisrc 0 Jul 28 09:55 pipe_file

For Windows NT or Windows 2000, use the following Win32 APIs to create a named pipe:

• CreateNamedPipe() – Creates an instance of a named pipe on the local machine. Fomode, specify PIPE_ACCESS_DUPLEX. You also can specify a timeout value, whichUniBasic OSOPEN command uses to wait for an available instance.

• ConnectNamedPipe() – Establishes a connection between the server pipe instance aclient side.

• DisconnectNamedPipe() – Returns the server pipe instance to a listening state. It doedestroy the pipe. Use this API if your server uses multiple pipe instances.

• CloseHandle() – Destroys the pipe when the last pipe instance closes. Use this API wyou no longer need the pipe.

324 Developing UniBasic Applications

Page 325: Basd_52

m a

orpe toof amuste

o open

heusts

Points to RememberKeep in mind the following points when accessing named pipes:

• When a process reads from a pipe, the data is removed from the pipe. This differs froprocess reading from a file, in which case the data is copied into a variable, but alsoremains in the file.

• If the NODELAY keyword is not specified, and a process tries to access (open, read,write) a pipe that is not already open in the opposite mode, the process waits for the pibe accessed in the opposite mode before proceeding. This can give the appearancehung process. (Opposite mode means that if you try to open a pipe for reading, it alsobe open for writing on the other end. If you try to open a pipe for writing, it also must bopen for reading on the other end.)

• UniData cannot temporarily close named pipes to manage the operating system’slimitation on the maximum number of files allowed to be opened at a time. Therefore,opening a large number of named pipes at the same time can cause a process to try tmore than the maximum number of files allowed by the operating system.

• For UniData for UNIX only, the PIPE_BUF system variable determines the length of tnamed pipe. For a write (OSBWRITE) to be atomic, the length of data to be written mbe less than or equal to the value of the PIPE_BUF. Maximum length for PIPE_BUF idetermined by the operating system. For information about system variables, seeAdministering UniData on UNIX.

The sections that follow describe the syntax and processing for OSOPEN, OSBREAD, andOSBWRITE for use with named pipes.

Developing UniBasic Applications 325

Page 326: Basd_52

Chapter 11 - Managing Named Pipes

s

ne,

nanagefrom

OSOPEN

Syntax:

OSOPEN filename[READONLY | WRITEONLY ] TO file.var [NODELAY ][ON ERRORstatements] {THEN statements[END] | ELSEstatements[END]}

NoteIf filenameis not a named pipe, the NODELAY keyword has no effect.

On UniData for UNIX,filenamein the UniBasicOSOPENcommand must include the entire pathunless the pipe or file resides in the current directory. On UniData for Windows NT or Window2000, use thefilenameformat

\\computername\PIPE\pipename

wherecomputernameis a valid computer name or a period (.), which specifies the local machiandpipenameis the name of a pipe.

The keywords READONLY, WRITEONLY, and NODELAY are used with named pipes:

• READONLY opens the pipe or file for read access only.

• WRITEONLY opens the pipe or file for write access only.

NoteTo specify that a pipe be open for both read and write access, omit the READONLY andWRITEONLY keywords from the OSOPEN statement.

• NODELAY forces a pipe to be opened immediately. This lets a process continue evewhen the pipe is not open in the opposite access mode. The application then must maccess to the pipe to ensure that it is opened for the opposite process before readingor writing to it.

326 Developing UniBasic Applications

Page 327: Basd_52

OSOPEN

file.

ic

ReminderIf OSOPEN against a named pipe is successful, the file pointer is set to the beginning of the

Opening Named PipesThe following table, which applies to UniData for UNIX only, summarizes the actions UniBastakes when OSOPEN is executed against a named pipe.

1Is the pipe open in the opposite mode?

2What is the UniBasic STATUS function setting after this operation?

Mode Open 1 NODELAY Action STATUS2

read-write noeffect

no effect Depends on whether the operatingsystem supports read-write access mode:

• OS supports read-write mode – opens.

• OS does not support read-write mode– executes ON ERROR or aborts.

0

2

read-only yes no effect Opens. 0

no no The process waits until the pipe isopened in write-only mode or read-writemode on the other end.

0after open

no yes Opens. 0

write-only yes no effect Opens. 0

no no The process waits until the pipe isopened in read-only mode or read-writemode on the other end.

0after open

no yes ELSE clause executes. 3

Summary of OSOPEN Functionality with Named Pipes (UniData for UNIX Only)

Developing UniBasic Applications 327

Page 328: Basd_52

Chapter 11 - Managing Named Pipes

.

d

y

Opening a Pipe in Read-Write Access Mode

Processing depends on whether the operating system supports this access mode.

• OS supports read-write access mode – UniBasic forces the pipe to open immediately

• OS does not support read-write access mode – The ON ERROR clause executes ifspecified, or the program aborts; the UniBasic STATUS function is set to 2.

Opening a Pipe in Read-Only Access Mode

Processing depends on whether the pipe is open for writing on the other end:

• If the pipe is open for writing on the other end, UniBasic opens the pipe for read-onlyaccess.

• If the pipe is NOT open for writing on the other end:

• NODELAY specified – UniBasic forces the pipe open immediately in the requestemode.

• NODELAY not specified – The process waits until the pipe is opened in write-onlymode on the other end.

Opening a Pipe in Write-Only Access Mode

Processing depends on whether the pipe is open for reading on the other end:

• If the pipe is open for reading on the other end, UniBasic opens the pipe for write-onlaccess.

• If the pipe is NOT open for reading on the other end:

• NODELAY specified – The ELSE clause executes; STATUS is set to 3.

• NODELAY not specified – The process waits until the pipe is opened in read-onlymode on the other end.

328 Developing UniBasic Applications

Page 329: Basd_52

OSOPEN

pt

s the

ble,

the

SE

More about Opening Named Pipes (Windows NT or Windows2000)

On UniData for Windows NT or Windows 2000, the following behavior occurs when you attemto open a named pipe:

• If the named pipe exists, and if an instance is available, the OSOPEN command openpipe immediately.

• If NODELAY is specified, and if the named pipe does not exist or no instance is availathe ELSE clause executes, and STATUS is set to 4.

• If NODELAY is not specified:

• If all instances are busy, the process waits until an instance is available, and thenpipe opens. If the timeout period expires, the ELSE statement executes and theUniBasic STATUS function is set to 4.

• If the named pipe does not exist, the process waits for five minutes before the ELstatement executes.

Developing UniBasic Applications 329

Page 330: Basd_52

Chapter 11 - Managing Named Pipes

they

n the

oe

e-

and it

y.

OSBREAD

OSBREAD var FROM file.var [AT byte.expr] LENGTH length.expr[NODELAY ][ON ERRORstatements]

The UniBasicOSBREAD command accommodates reading from named pipes:

• TheAT clause is not allowed. AT is not appropriate for use with named pipes becauseare always read with no offset.

• TheNODELAY keyword forces UniData to read the pipe immediately, which lets areading process continue even when the pipe is not open for writing or no data exists ipipe.

NoteIf you do not specify NODELAY on an OSBREAD against a named pipe, the process trying tread waits until the pipe is opened for writing, and data is written to it, before reading from thpipe.

Reading from a Named PipeKeep these points in mind when writing programs that read from named pipes:

• Unlike a typical read, reading a named pipe removes the data.

• Your application should check the length ofvar after reading a pipe. The value returnedcould be shorter thanlength.expr.

• Data is truncated if it is longer thanlength.expr.

• On UniData for Windows NT or Windows 2000, you can set a named pipe to messagread mode by indicating -1 forlength.expr. To set a named pipe to byte-read mode, setlength.exprto a value greater than -1. Data in message mode always has a boundary,can be obtained in its entirety. Data in byte mode has no boundary. The reader mustspecify a length and have some kind of protocol with the server to interpret it correctl

330 Developing UniBasic Applications

Page 331: Basd_52

OSBREAD

n by

Summary for Reading Named Pipes

The combination of the following conditions and command options determine the action takeUniBasic when OSBREAD is executed against a named pipe:

• Presence or absence of data in the pipe.

• Open/closed status of the pipe.

• Presence or absence of the AT and NODELAY command options.

The following table, which applies to UniData for UNIX only, summarizes actions taken byUniBasic for each possible combination of these factors.

1Does the pipe contain data of the length requested?

AT Data1 Open 2 NODELAY Action STATUS3

yes noeffect

noeffect

no effect ON ERROR executes; if no ONERROR clause, the program aborts.

Note -ON ERROR executes regardlessof other conditions (presence of data;open/closed status; NODELAY).

2

no yes noeffect

no effect UniBasic returns data, of the lengthrequested, from the pipe.

0

no no no no effect UniBasic returns actual content of thepipe regardless of its length. Can be anempty string.

0

no no yes no The process waits for data to be writtento the pipe, or for the pipe to be closed;if closed with no data written, returnsan empty string.

0after read

no no yes yes UniBasic returns actual content of thepipe regardless of its length. Can be anempty string.

0

Summary of OSBREAD Functionality with Named Pipes (UniData for UNIX Only)

Developing UniBasic Applications 331

Page 332: Basd_52

Chapter 11 - Managing Named Pipes

on

tualno

lessn for

gth.

ttenata

urn

f its

2Is the pipe open in the opposite mode?

3What is the UniBasic STATUS function setting after this operation?

Reading from a Named Pipe

When a process executes a read against a named pipe, the actions UniBasic takes dependwhether the pipe contains data of the length requested in the read statement.

Data of the Required Length

When the named pipe contains data of at least the length requested, UniBasic returns the accontents of the pipe, even if the pipe contains more data than that requested. NODELAY haseffect in this case.

Data of Insufficient Length

When the named pipe contains insufficient data (the pipe is empty or the length of the data isthan specified in the OSBREAD statement), processing depends on whether the pipe is opewriting on the other end.

If the pipe is open for writing on the other end:

• NODELAY specified – UniBasic returns actual content of the pipe regardless of its lenCan be an empty string. The STATUS function return value is set to 0.

• NODELAY not specified – The process waits for data of the length requested to be writo the pipe or for the pipe to be closed. If the pipe is closed with no data or insufficient dwritten to it, UniBasic returns the actual contents of the pipe. The STATUS function retvalue is set to 0 in either case.

If the pipe is not open for writing, UniBasic returns the actual content of the pipe regardless olength. It can be an empty string. NODELAY has no effect.

332 Developing UniBasic Applications

Page 333: Basd_52

OSBREAD

pt

tual

epipe,

a hasth

d. If

se,

More about Reading from a Named Pipe (Windows NT orWindows 2000)

For UniData for Windows NT or Windows 2000, the following behavior occurs when you attemto read message-type or byte-type named pipes.

Message-Type Pipes

• If NODELAY is specified, and if a message exists in the pipe, UniBasic returns the accontents of the pipe regardless of its length. If a message does not exist in the pipe,UniData returns an empty string and the STATUS function return value is set to 5.

• If NODELAY is not specified, and if a message exists in the pipe, UniBasic returns thactual contents of the pipe regardless of its length. If a message does not exist in thethe process waits until a complete message is sent to the pipe.

Byte-Type Pipes

• If NODELAY is specified, and if the data has a length greater than or equal tolength.expr,UniBasic returns the contents of the pipe according to the length requested. If the data length less thanlength.expr, UniBasic returns the actual contents of the pipe (even wizero length) and the STATUS function return value is set to 5.

• If NODELAY is not specified, and if the data has a length greater than or equal tolength.expr, UniBasic returns the contents of the pipe according to the length requestethe data has a length less thanlength.expr, either the process waits until it receives datawith lengthlength.expr, or a server end closes the pipe. In the case of a server end cloUniBasic returns the contents of the pipe perhaps with length less thanlength.expr, and theSTATUS function return value is set to 5.

Developing UniBasic Applications 333

Page 334: Basd_52

Chapter 11 - Managing Named Pipes

.

n by

OSBWRITE

Syntax:

OSBWRITE expr [ON | TO] file.var [AT byte.expr] [NODELAY ] [ON ERRORstatements]

The UniBasicOSBWRITE command accommodates writing to a named pipe:

• TheAT clause is not allowed because named pipes are always read with no offset.

• The keywordNODELAY forces UniData to write when a pipe is full.

NoteIf you do not specify NODELAY, the writing process waits until the pipe is opened for reading

Writing to Named PipesThe combination of the following conditions and command options determine the action takeUniBasic when OSBWRITE is executed against a named pipe:

• Presence and length of data in the pipe

• Open/closed status of the pipe

• Presence or absence of the AT and NODELAY command options

The following table summarizes the actions taken by UniBasic when OSBWRITE is executedagainst a named pipe.

AT Empty 1 Open 2 NODELAY Action STATUS3

yes no effect noeffect

no effect ON ERROR executes; if no ONERROR clause, the program aborts.

Note - ON ERROR executes regard-less of other conditions (presence ofdata; open/closed status; NODELAY).

2

Summary of OSBWRITE Functionality with Named Pipes

334 Developing UniBasic Applications

Page 335: Basd_52

OSBWRITE

being

1Is enough space available in the pipe to receive the data?

2What is the UniBasic STATUS function return value after this operation?

Writing to a Closed Named Pipe

If the pipe is not open for reading, the ON ERROR clause executes. The program fails if ONERROR is not specified.

Writing to an Open Named Pipe

Processing depends on whether the pipe contains sufficient space to accommodate the datawritten:

• Sufficient space available

UniBasic writes to the pipe regardless of whether NODELAY is specified.

no no effect no no effect ON ERROR executes; if no ONERROR clause, the program aborts.

6

no yes yes no effect UniBasic writes to the pipe. 0

no no yes no The process waits for sufficient spaceto become available in the pipe tocontain the data being written.

0afterwriting

no no yes yes UniBasic first tries to write to thepipe; when it runs out of space, theON ERROR clause executes. Theprogram fails if ON ERROR is notspecified.

Tip - The INMAT function returns thelength of data written to the pipe.

3

AT Empty 1 Open 2 NODELAY Action STATUS3

Summary of OSBWRITE Functionality with Named Pipes

Developing UniBasic Applications 335

Page 336: Basd_52

Chapter 11 - Managing Named Pipes

hen

bleT

ee

• Sufficient space NOT available

Processing depends on whether NODELAY is specified:

• NODELAY specified – UniBasic first tries to write to the pipe; when it runs out ofspace, the ON ERROR clause executes. If the ON ERROR clause is not coded, tprogram aborts. The UniBasic STATUS function is set to 3, and the INMAT functioreturns the length of data written to the pipe.

• NODELAY not specified – The process waits for sufficient space to become availain the pipe to receive the data. When all the data is written successfully, the INMAfunction returns the length of data written to the pipe.

WarningOn UniData for UNIX only, the length of data inexprmust be less than or equal to the value of thPIPE_BUF system variable for the write to be atomic. PIPE_BUF determines the length of thnamed pipe. Maximum length is determined by the operating system.

336 Developing UniBasic Applications

Page 337: Basd_52

OSCLOSE

N

OSCLOSE

SyntaxOSCLOSE file.var [ON ERRORstatements]

DescriptionThe UniBasicOSCLOSE command closes a sequential file that was opened with the OSOPEstatement.

ParametersThe following table describes each parameter of the syntax.

Parameter Description

file.var Specifies the file to close.

ON ERRORstatements Specifies statements to execute if theOSCLOSE statement fails with a fatal errorbecause the file is not open, an I/O erroroccurs, or UniData cannot find the file.

If you do not specify the ON ERROR clauseand a fatal error occurs, the programterminates.

OSCLOSE Parameters

Developing UniBasic Applications 337

Page 338: Basd_52

Chapter 11 - Managing Named Pipes

e

STATUS Function Return Values

After you execute OSCLOSE, the STATUS function returns one of the values described in thfollowing table.

ExamplesIn the following example, the program statement closes the file UNDEF:

Program Example

OSCLOSE UNDEF

Related Topics

OSOPEN

The UniBasic OSOPEN command opens an operating system–level sequential file.

ReturnValue Meaning

0 The file is closed successfully.

5 The file did not close.

STATUS Function Values

338 Developing UniBasic Applications

Page 339: Basd_52

STATUS Function Return Values

STATUS Function Return Values

After you execute OSOPEN, OSCLOSE, OSBREAD, or OSBWRITE, the STATUS functionreturns one of the values described in the following table.

ReturnValue Description

0 Execution was successful.

1 Invalid file name or file variable.

2 User lacks permission to access the file or pipe (at operating systemlevel).

3 Execution against a named pipe:

• OSBWRITE was executed against a pipe that is open for reading,but is full; NODELAY was specified.

• OSOPEN with the WRITEONLY option was executed against apipe that was not open for reading.

4 The file does not exist.

5 Undefined error.

6 OSBWRITE was executed against a named pipe that is not open forreading.

UniBasic STATUS Function Return Values

Developing UniBasic Applications 339

Page 340: Basd_52

Chapter 11 - Managing Named Pipes

the

INMAT

SyntaxINMAT ()

DescriptionAfter you write to a named pipe, theINMAT function return value contains the number of byteswritten. This information can help you determine how much space was available in a pipe attime of an unsuccessful write.

NoteFor additional syntax and return values for INMAT, see INMAT in theUniBasic CommandsReference.

340 Developing UniBasic Applications

Page 341: Basd_52

Troubleshooting

Troubleshooting

The following information could be helpful in troubleshooting processes that manage namedpipes:

Symptom Probable Cause

Data is only partially written to afile or a named pipe.

On UniData for UNIX only, a process has tried towrite data to a named pipe whose length is greaterthan PIPE_BUF, and NODELAY was specified inthe write statement.

A named pipe is empty after aread.

Read operations work differently on named pipesversus other file types. Data read from a named pipeis removed from the pipe. Data read from othertypes of files is copied from the file.

A process that manages namedpipes appears to be hung.

If NODELAY is not specified, and a process tries toaccess (open, read or write) a pipe that is not alreadyopen in the opposite mode, the process waits for it tobe accessed in the opposite mode before proceeding.

A process executes the ELSEclause of OSOPEN executedagainst a named pipe.

UniData cannot temporarily close named pipes tomanage the operating system’s limitation on themaximum number of files allowed to be opened at atime. Therefore, opening a large number of namedpipes at the same time can cause a process to try toopen more than the maximum number of filesallowed by the operating system.

Data is only partially written to anamed pipe; and the ON ERRORclause executes, or the programaborts.

The pipe already contained some data when this pro-cess executed OSBWRITE. When UniBasic runsout of room in the pipe, the ON ERROR clauseexecutes, or the program aborts.

Tip - The UniBasic INMAT function returns thenumber of bytes written.

Troubleshooting Named Pipe Processes

Developing UniBasic Applications 341

Page 342: Basd_52

Chapter 11 - Managing Named Pipes

ing

Example

The following example demonstrates opening a named pipe, writing record IDs to it, and closit:

Screen Example

****************OPEN.NAMED.PIPES:****************

EOF = ''SELECT FILE.PRIORITY.MAPLOOP

READNEXT PRIORITY ELSE EOF = 1UNTIL EOF

PRIORITY.LIST<-1>=PRIORITYPIPE.NAME = 'SF.PIPE.':PRIORITYOSOPEN PIPE.NAME TO PIPE(PRIORITY) ELSE

MSG.TXT = 'Unable to open ':PIPE.NAMEGOSUB 9999STOP

ENDREPEAT

...************************2110 * Write ID to pipe************************

ID.LENGTH = LEN(OUT.ID)PIPE.ID = OUT.ID:STR(' ',PIPE.WIDTH-ID.LENGTH)OSBWRITE PIPE.ID TO PIPE(PRIORITY)RETURN

...***********CLOSE.PIPES:***********

FOR I = 1 TO DCOUNT(PRIORITY.LIST,@AM)PRIORITY = PRIORITY.LIST<I>OSBWRITE SHUTDOWN TO PIPE(PRIORITY)PRINT "'SHUTDOWN' ISSUED TO SF.PIPE.":PRIORITY

NEXT I

342 Developing UniBasic Applications

Page 343: Basd_52

Example

This next example reads the IDs from the other end of the pipe:

Screen Example

PIPE.WIDTH = 32

***************OPEN.NAMED.PIPE:***************

PIPE.NAME = 'SF.PIPE.':P.PRIORITYOSOPEN PIPE.NAME TO PIPE ELSE

MSG.TXT = 'Unable to open ':PIPE.NAMEGOSUB [email protected]=0STOP

END...************PROCESS.LOOP:************

LOOPOSBREAD IN.ID FROM PIPE LENGTH PIPE.WIDTHCONVERT ' ' TO '' IN IN.IDIF IN.ID = "SHUTDOWN" THEN

OSCLOSE [email protected] = 1EXIT

ENDREAD INBOX.REC FROM IN.FILE, IN.ID THEN

IF INBOX.REC<MB$COMPL_FLAG> = 0 THENGOSUB 2005; * Process INBOX.REC

ENDEND

REPEATMSG.TXT = '"SHUTDOWN" received from SF.PH.READ. Ending program.'GOSUB 9999; * Print Message

RETURN

Developing UniBasic Applications 343

Page 344: Basd_52

Chapter 11 - Managing Named Pipes

344 Developing UniBasic Applications

Page 345: Basd_52

Chapter 12 - UsingCallHTTP

sic

prisesany

-

nt tob-e web

irma-

r.

vel

CallHTTP provides customers with the capability of interacting with a web server from UniBathrough the standard HTTP protocol. In order to effectively use the CallHTTP functions, youshould have a working knowledge of the HTTP standard.

Internet and web technologies have rapidly changed the way business is conducted by enterof all categories. E-commerce is increasingly becoming an essential part of any business. Mcompanies desire the capability to “call out” to the web from UniBasic so that their now standalone applications can be integrated with other applications through the web.

There are many scenarios where this capability can be beneficial. For example, you may waintegrate a general ledger application with a third party application that has already been weenabled. When an account number is given, the general ledger application has to send it to thapplication through an HTTP request for validation. The web application then returns a conftion to the UniBasic application.

HTTP is a complex standard with a large number of components and methods. The goal forCallHTTP is to provide a basic yet general implementation that enables UniBasic to act as anHTTP client so that data can be exchanged between a UniBasic application and a web serveCallHTTP provides the “plumbing” for users to build a specific client, not make UniBasic abrowser of its own.

CallHTTP is implemented with the Socket Interface as its network transport, and this lower leAPI is also available for direct access by the user.

Developing UniBasic Applications 345

Page 346: Basd_52

Chapter 12 - Using CallHTTP

hese

r

Configuring the Default HTTP Settings

ThesetHTTPDefault function will configure the default HTTP settings, including proxy serverand port, buffer size, authentication credential, HTTP version, and request header values. Tsettings will be used with every HTTP request that follows.

SyntaxsetHTTPDefault(option, value)

If you require all outgoing network traffic to go through a proxy server,setHTTPDefault() shouldbe called withvaluecontaining the proxy server name or IP address as well as the port (if othethan the default of 80).

ParametersThe following table describes each parameter of the syntax.

The following table describes the available options forsetHTTPDefault.

Parameter Description

option A string containing an option name. See the table below for the optionscurrently defined.

value A string containing the appropriate option value.

setHTTPDefault Parameters

Option Description

PROXY_NAME Name or IP address of the proxy server.

PROXY_PORT The port number to be used on the proxy server. This only needs to bespecified if the port is other than the default of 80.

setHTTPDefault Options

346 Developing UniBasic Applications

Page 347: Basd_52

Configuring the Default HTTP Settings

g

edor

r-est-

is

ic

.

The following table describes the status of each return code.

VERSION The version of HTTP to be used. The default version is 1.0, but it can beset to 1.1 for web servers that understand the newer protocol. The strinshould be ”1.0” or “1.1”.

BUFSIZE The size of the buffer for HTTP data transfer between UniData and theweb server. The default is 4096 however, the buffer size can be increasto improve performance. It should be entered as an integer greater thanequal to 4096.

AUTHENTI-CATE

The user name and password to gain access. The string should be “usename:password”. Default Basic authentication can also be set. If a requis denied (HTTP staus 401/407), UniBasic will search for the default credential to automatically re-submit the request.

HEADERS The header to be sent with the HTTP request. Ifdefault_headerscontainsan empty string, then any current user-specified default header will becleared. Currently, the only default header UniBasic sets automatically“User-Agent” UniData 5.2”. If you do not want to send out this header youshould overwrite it withsetHTTPDefault(). Per RFC 2616, for “netpoliteness”, an HTTP client should always send out this header. UniBaswill also send a date/time stamp with every HTTP request. According toRFC 2616, the stamp will represent time in Universal Time (UT) format.A header should be entered as a dynamic array in the form of <Header-Name>@VM<HeaderValue>@Fm<HeaderName>@VM<HeaderValue>

Return Code Status

0 Success.

1 Invalid option.

2 Invalid Value.

Option Description

setHTTPDefault Options

Developing UniBasic Applications 347

Page 348: Basd_52

Chapter 12 - Using CallHTTP

fore-

r

NoteAll defaults set bysetHTTPDefault() will be in effect until the end of the current UniData ses-sion. If you do not want the setting to affect subsequent programs, you will need to clear it beexiting the current program. If the user wishes to set the “Authorization” or “Proxy-Authorization” header as defualts, see the description undersetRequestHeader(). To clear the default set-tings, pass an empty string with PROXY_NAME, AUTHENTICATE and HEADERS, and 0 foPROXY_PORT and BUFSIZE.

348 Developing UniBasic Applications

Page 349: Basd_52

Getting the Current HTTP Default Settings

ion

Getting the Current HTTP Default Settings

ThegetHTTPDefault function will return the default values of the HTTP settings. See the sectundersetHTTPDefault for additional information.

SyntaxgetHTTPDefault(option, value)

ParametersThe following table describes each parameter of the syntax:

The following table describes the status of each return code.

Parameter Desription

option Currently, the following options are defined:PROXY_NAMEPROXY_PORTVERSIONBUFSIZEAUTHENTICATEHEADERS

value A string containing the appropriate option value.

getHTTPDefault Parameters

Return Code Status

0 Success.

1 Invalid option.

Return Code Status

Developing UniBasic Applications 349

Page 350: Basd_52

Chapter 12 - Using CallHTTP

dl

ct

d to

ee

Creating an HTTP Request

ThecreateRequestfunction creates an HTTP request and returns a handle to the request.

SyntaxcreateRequest(URL, http_method, request_handle)

ParametersThe following table describes each parameter of the syntax.

The following table describes the available methods forhttp_method.

Parameter Option

URL A string containing the URL for a resource on a web server. An accepteURL must follow the specified syntax defined in RFC 1738. The generaformat is: http://<host>:<port>/<path>?<searchpart>. The host can beeither a name string or IP address. The port is the port number to conneto, which usually defaults to 80 and is often omitted, along with the pre-ceding colon. The path tells the web server which file you want, and, ifomitted, means “home page” for the system. The searchpart can be usesend additional information to a web server.

http_method A string which indicates the method to be performed on the resource. Sthe table below for the available (case-sensitive) methods.

request_handle A handle to the request object.

createRequest Parameters

Method Description

GET

createRequest Methods

350 Developing UniBasic Applications

Page 351: Basd_52

Creating an HTTP Request

, and

r-

The following table describes the status of each return code.

NoteIf URL does include a searchpart, it must be in its encoded format (space is converted into +other non-alphanumeric characters are converted into %HH format. SeeaddRequestParameter()

POST [:<MIME-type>] For this method, it can also have an optional MIME-typeto indicate the content type of the data the request intends to send. If noMIME-type is given, the default content type will be “application/x-www-form-urlencoded”. Currently, only “multipart/form-data” is internally sup-ported, as described in functionaddRequestParameter() andsubmitRe-quest(), although other “multipart/* data can also be sent if the user canassemble it on his/her own. (The multipart/form-data format itself is thooughly described in RFC 2388).

HEAD

OPTIONS /* HTTP/1.1 and later*/

DELETE /* HTTP/1.1 and later*/

TRACE /* HTTP/1.1 and later*/

PUT /* HTTP/1.1 and later but not supported */

CONNECT /* HTTP/1.1 and later but not supported */

Return Code Status

0 Success.

1 Invalid URL (Syntactically).

2 Invalid method (For HTTP 1.0, only GET/POST/HEAD)

Method Description

createRequest Methods

Developing UniBasic Applications 351

Page 352: Basd_52

Chapter 12 - Using CallHTTP

iBasic

RL

for more details). However, host and path are allowed to have these “unsafe” characters. Unwill encode them before communicating with the web server.

NoteThis function can also be used later to support other protocols (like FTP, in which case the Usupplied would be in the form of:ftp://<user>:<pswd>@<host>:<port>/cwd1/.../cwdN>/<name>;type=<typecode> . Thehttp_methodoption would be ignored for an FTP request.

352 Developing UniBasic Applications

Page 353: Basd_52

Setting Additional Headers for a Req uest

ity ofe

6 for

Setting Additional Headers for a Request

ThesetRequestHeaderfunction allows the user to set additional headers for a request.

SyntaxsetRequestHeader(request_handle, header_name, header_value)

ParametersThe following table describes each parameter of the syntax.

The following table describes the status of each return code.

NoteSince a user defined header or header value can be transferred, it is difficult to check the validparameters passed to the function. UniBasic currently will not perform syntax checking on thparameters, although it will reject setting a response header to a request. Refer to RFC 261

Parameter Description

request_handle The handle to the request returned bycreateRequest().

header_name The name of the header.

header_value The value of the header.

setRequestHeader Parameters

Return Code Status

0 Success.

1 Invalid request handle.

2 Invalid header (Incompatible with method).

3 Invalid header value.

Developing UniBasic Applications 353

Page 354: Basd_52

Chapter 12 - Using CallHTTP

eitherernc-

.ta.

valid request headers.

The header set by this function will overwrite settings bysetHTTPDefault().

NoteThis function supports Base64 encoding for Basic authentication. If header_name contains“Authorization” or “Proxy-Authorization”, the header_value should then contain ASCII text uscredential information in the format of “userid:password”, as specified by RFC 2617. This fution will then encode the text based on Base64 encoding.

NoteOnly Basic authentication is supported. Digest authentication may be supported in the futureBasic authentication is not safe and is not recommended for use with transferring secured da

354 Developing UniBasic Applications

Page 355: Basd_52

Adding a Parameter to the Request

Adding a Parameter to the Request

TheaddRequestParameterfunction adds a parameter to the request.

SyntaxaddRequestParameter(request_handle, parameter_name, parameter_value,content_handling)

ParametersThe following table describes each parameter of the syntax.

The following table describes the status of each return code.

Parameter Description

request_handle The handle to the request.

parameter_name The name of the parameter.

parameter_value The value of the parameter.

content_handling The dynamic MIME type for the parameter value.

addRequestParameter Parameters

Return Code Status

0 Success.

1 Invalid request handle.

2 Invalid parameter.

3 Bad content type.

Developing UniBasic Applications 355

Page 356: Basd_52

Chapter 12 - Using CallHTTP

-

n:

plica-

n-inon is

in

NoteFor a GET request, content_handling is ignored.

For a POST request with default content type, the default for content_handling is “Content-Type:text/plain” ifcontent_handlingis not specified. For a POST request with “Multipart/*” content-type,content_handlingis a dynamic array containing Content-* strings separated by fieldmarks (@FM). They will be included in the multipart message before the data contained inparameter_value is sent. An example ofcontent_handling:

Content-Type: application/XML @FMContent-Dispostion: attachment; file=”C:\drive\test.dat” @FMContent-Length: 1923

Specifically, for a POST request with content type “multipart/form-data”, a “Content-Dispostioform-data” header will be created (or, in the case of Content-Dispostion already incontent_handling, “form-data” will be added to it).

For both a GET and a POST request with either no content type specified or specified as “aption/x-www-form-urlencoded”, as described increateRequest(), URL encoding is performed ondata inparameter_valueautomatically. Basically, any character other than alpha-numeric is cosidered “unsafe” and will be replaced by %HH where HH is the ASCII value of the characterquestion. For example, ‘#’ is replaced by %23, and ‘/’ is replaced by %2F, etc.. One exceptithat by convention, spaces (‘ ‘) are converted into ‘+’.

For a POST method with other MIME-type specified, no encoding is done on data containedparameter_value.

356 Developing UniBasic Applications

Page 357: Basd_52

Submitting a Request

m-acter.

as is.

tent-e.

en

ataeader.

d cre-

onse is

ll beg,

to see ifund,

ser

n”noe

Submitting a Request

ThesubmitRequestfunction will submit a request and get a response.

The request is formed on the basis of default HTTP settings and previoussetRequestHeader()andaddRequestParameter()values. Specifically, for a GET method with parameters added, a praeter string (properly encoded) will be created and attached to the URL string after the ‘?’ char

For a POST request with non-empty post_data, the data is attached to the request messageNo encoding is performed, and any parameters added throughaddRequestParameter()will betotally ignored. Otherwise the following processing will be performed.

For a POST request with default content type, the parameter string will be assembled, a ConLength header created, and then the string is attached as the last part of the request messag

For a POST request with multipart/* content type, a unique boundary string is created and thmultiple parts will be generated in the sequence they were added through callingaddRequestPa-rameter(). Each will have a unique boundary, followed by optional Content-* headers, and dpart. The total lentgth is calculated and a Content-Length header is added to the message h

The request is then sent to the Web server identified by the URL supplied with the request anated throughcreateRequest() (maybe via a proxy server). UniBasic is then waiting for the webserver to respond. Once the response message is received, the status contained in the respanalyzed.

If the response status indicates that redirection is needed (status 301, 302, 305 or 307), it wiperformed automatically, up to five consecutive redirections (the limit is set to prevent loopinsuggested by RFC 2616).

If the response status is 401 or 407 (access denied), the response headers will be examinedthe server requires (or accepts) Basic authentication. If no Basic authentication request is fothe function will return with an error. Otherwise default Authentication (set bysetHTTPDefault)will be used to re-send the request. If no default authentication is set, and no other cached uauthentication is found, the function will return with an error.

If the user provides authentication information through “Authorization” or “Proxy-Authorizatioheader, the encoded information is cached. If later, a Basic authentication request is raised,default authentication is found, and only one user/password encoding is cached, then it will bused to re-send the request.

Developing UniBasic Applications 357

Page 358: Basd_52

Chapter 12 - Using CallHTTP

g(gzip,

ed.

The response from the HTTP server is disposed intoresponse_headerandresponse_data. It is theuser’s responsibility to parse the headers and data. UniBasic only performs transfer encodin(chunked encoding), and nothing else is done on the data. In other words, content-encodingcompress, deflate, etc.) are supposed to be handled by the user, as with all MIME types.

Also, if a response contains header “Content-type: multipart/*”, all the data (multiple bodiesenclosed in “boundary delimiters”, see RFC 2046) will be stored inresponse_data.It is the user’sresponsibility to parse it according to “boundary” parameter.

SyntaxsubmitRequest(request_handle, time_out, post_data, response_headers, response_data,http_status)

ParametersThe following table describes each parameter of the syntax.

The following table describes the status of each return code.

Parameter Description

request_handle The handle to the request.

time_out The timeout value (in milliseconds) before the wait response is abandon

post_data The data sent with the POST request.

response_headers A dynamic array to stre header/value pairs.

response_data The resultant data (may be in binary format).

http_status A dynamic array containing the status code and explanatory text.

submitRequest Parameters

Return Code Status

0 Success.

1 Invalid request handle.

358 Developing UniBasic Applications

Page 359: Basd_52

Submitting a Request

2 Timed out.

3 Network Error.

4 Other Errors.

Return Code Status

Developing UniBasic Applications 359

Page 360: Basd_52

Chapter 12 - Using CallHTTP

nt in

Getting a Response Header

This function gets a specific response header value from response headers returned bysubmitRe-quest(). It can be used to query if a specific header, for example, Content-encoding, is presethe response.

SyntaxgetResponseHeader(request_handle, header_name, header_value)

ParametersThe following table describes each parameter of the syntax.

The following table describes the status of each return code.

Parameter Description

request_handle The handle to the request.

header_name A string containing a response header name.

header_value The value of the header, if present. Otherwise, an empty string.

getResponseHeader Parameters

Return Code Status

0 Success.

1 Invalid request handle.

2 Header not found.

360 Developing UniBasic Applications

Page 361: Basd_52

Protocol Logging

e

Protocol Logging

This function will start or stop logging.

SyntaxprotocolLogging(log_file, log_action, log_level)

ParametersThe following table describes each parameter of the syntax.

The following table describes each log level and Detail.

Parameter Description

log_file The name of the file the logs will be recorded to. The default log file namis httplog and will be created under the current directory.

log_action Either “ON” or “OFF”. The default is “OFF”.

log_level The detail level of logging from 0 - 10. See table below.

protocolLogging Parameters

Level Detail

0 No logging.

1 Socket open/read/write/close action (no real data) HTTP request: hostinfo(URL)

2 Level 1 logging plus socket data statistics (size, etc.).

3 Level 2 logging plus all data actually transferred.

4-10 More detailed status data to assist debugging.

log_level Details

Developing UniBasic Applications 361

Page 362: Basd_52

Chapter 12 - Using CallHTTP

The following table describes the status of each return code.

Return Code Status

0 Success.

1 Failed to start logging.

Return Code Status

362 Developing UniBasic Applications

Page 363: Basd_52

Chapter 13 - Using theSocket Interface

ondis-etlientsppli-

The UniBasic Socket API provides the user with the capability of interacting with an applicatirunning on another machine via the sockets interface. The Socket API enables you to writetributed UniBasic applications. For example, one application, written in the server side sockinterface, can function as the server while others can function as clients. The server and the ccan cooperate on tasks through socket communication. This is an efficient way for UniBasic acations to communicate, and is easy to implement.

Developing UniBasic Applications 363

Page 364: Basd_52

Chapter 13 - Using the Socket Interface

t only

s func-

he user

ckign-

provider

s not, ancket withs zero or

scriptors

Socket Function Error Return Codes

These error return codes are used for all socket-related functions described below. Note thanumeric code should be used in Basic programs.

The table below describes each error code and its meaning.

Error Code Definition

0 - SCK_ENOERROR No error.

1 - SCK_ENOINITIALISED (NT) A successful WSAStartup() call must occur before using thition.

2 - SCK_ENETDOWN The network subsystem has failed.

3 - SCK_EFAULT The addrlen parameter is too small or addr is not a valid part of taddress space.

4 - SCK_ENOTCONN The socket is not connected.

5 - SCK_EINTR The (blocking) call was cancelled. (NT: through WSACancelBloCall).

6 - SCK_EINPROGRESS A blocking Windows Sockets 1.1 call is in progress, or the serviceis still processing a callback function.

7 - SCK_EINVAL This can be caused by several conditions. The listen function wainvoked prior to accept, the socket has not been bound with bindunknown flag was specified, or MSG_OOB was specified for a soSO_OOBINLINE enabled or (for byte stream sockets only) len wanegative.

8 - SCK_EMFILE The queue is nonempty upon entry to accept and there are no deavailable.

9 - SCK_ENOBUFS No buffer space is available.

10 - SCK_ENOTSOCK The descriptor is not a socket.

Error Code Definitions

364 Developing UniBasic Applications

Page 365: Basd_52

Socket Function Error Return Codes

ented ser-

n would

etecting a

a socketor

uffer andd the mes-nsport.

re. The

or because

r abortiveprevi-le” ICMP

r usable.

ate flag waso allow

or socket.

network

11 - SCK_EOPNOTSUPP The referenced socket is not a type that supports connection-orivice.

12 - SCK_EWOULDBLOCK The socket is marked as nonblocking and the requested operatioblock.

13 - SCK_ENETRESET The connection has been broken due to the keep-alive activity dfailure while the operation was in progress.

14 - SCK_ESHUTDOWN The socket has been shut down. It is not possible to receive onafter shutdown has been invoked with how set to SD_RECEIVESD_BOTH.

15 - SCK_EMSGSIZE (For recv()) The message was too large to fit into the specified bwas truncated, or (for send()) the socket is message oriented, ansage is larger than the maximum supported by the underlying tra

16 - SCK_ETIMEDOUT The virtual circuit was terminated due to a time-out or other failuapplication should close the socket as it is no longer usable.

17 - SCK_ECONNABORTED The connection has been dropped, because of a network failurethe system on the other end went down without notice.

18 - SCK_ECONNRESET The virtual circuit was reset by the remote side executing a hard oclose. For UPD sockets, the remote host was unable to deliver aously sent UDP datagram and responded with a “Port Unreachabpacket. The application should close the socket as it is no longe

19 - SCK_EACCES The requested address is a broadcast address, but the approprinot set. Call setsockopt with the SO_BROADCAST parameter tthe use of the broadcast address.

20 - SCK_EHOSTUNREACH The remote host cannot be reached from this host at this time.

21 - SCK_ENOPROTOOPT The option is unknown or unsupported for the specified provider

22 - SCK_ESYSNOTREADY Indicates that the underlying network subsystem is not ready forcommunication.

Error Code Definition

Error Code Definitions

Developing UniBasic Applications 365

Page 366: Basd_52

Chapter 13 - Using the Socket Interface

ed by this

imple-

.

busy.

because

lified-use withund in theetsockopt.)

t.

23 -SCK_EVERNOTSUPPORTED

The version of Windows Sockets support requested is not providparticular Windows Sockets implementation.

24 - SCK_EPROCLIM Limit on the number of tasks supported by the Windows Socketsmentation has been reached.

25 - SCK_EAFNOSUPPORT The specified address family is not supported.

26 - SCK_EPROTONOSUPPORTThe specifed protocol is not supported.

27 - SCK_EPROTOTYPE The specified protocol is the wrong type for this socket.

28 - SCK_ESOCKTNOSUPPORT The specified socket type is not supported in this address family

29 - SCK_EBADF For Windows CE AF_IRDA sockets only: the shared serial port is

30 - SCK_EHOST_NOT_FOUND Authoritative Answer Host not found.

31 - SCK_ETRY_AGAIN Nonauthoritative Host not found, or server failure.

32 - SCK_ENO_RECOVERY A nonrecoverable error occurred.

33 - SCK_ENO_RECOVERY Valid name, no data record of requested type.

34 - SCK_EACCESS Attempt to connect datagram socket to broadcast address failedsetsockopt option SO_BROADCAST is not enabled.

35 - SCK_EADDRINUSE A process on the machine is already bound to the same fully-quaaddress and the socket has not been marked to allow address reSO_REUSEADDR. For example, the IP address and port are boaf_inet case. (See the SO_REUSEADDR socket option under s

36 - SCK_EADDRNOTAVAIL The specified address is not a valid address for this machine.

37 - SCK_EISCONN The socket is already connected.

38 - SCK_EALREADY A nonblocking connect call is in progress on the specified socke

39 - SCK_ECONNREFUSED The attempt to connect was forcefully rejected.

40 - SCK_EMALLOC Memory allocation error.

Error Code Definition

Error Code Definitions

366 Developing UniBasic Applications

Page 367: Basd_52

Socket Function Error Return Codes

41 - SCK_EUNKNOWN Other unknown errors.

Error Code Definition

Error Code Definitions

Developing UniBasic Applications 367

Page 368: Basd_52

Chapter 13 - Using the Socket Interface

ta-

Opening a Socket

Use theopenSocketfunction to open a socket connection in a specified mode and return the stus.

SyntaxopenSocket(name_or_IP, port, mode, timeout, socket_handle)

ParametersThe following table describes each parameter of the syntax.

Parameter Description

name_or_IP DNS name (x.com) or IP address of a server.

port Port number. If the port number is specified as a value <= 0, CallHTTPdefaults to a port number of 40001.

mode 0:non-blocking mode1:blocking mode

timeout The timeout value expressed in milliseconds. If you specify mode as 0,timeout will be ignored.

socket_handle A handle to the open socket.

openSocket Parameters

368 Developing UniBasic Applications

Page 369: Basd_52

Opening a Socket

is

The following table describes the return status of each mode.

The following table describes the status of each return code.

Mode Return Status

0 - Non-blocking The function will return immediately regardless of whether or not thesocket is successfully opened. The return code inidcates if the operationsuccessful. Thetimeoutvalue is ignored.

1 - Blocking If a positivetimeoutis specified, the function will either return with a validsocket handle or will time out after the specifiedtimeoutperiod. If thetim-eoutvalue is 0, the function will block until either the socket is success-fully opened, the underlying TCP/IP connection times out or some othererror prevents the socket from opening.

Mode Return Status

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

Developing UniBasic Applications 369

Page 370: Basd_52

Chapter 13 - Using the Socket Interface

Closing a Socket

Use thecloseSocketfunction to close a socket connection.

SyntaxcloseSocket(socket_handle)

Wheresocket_handleis the handle to the socket you want to close.

The following table describes the status of each return code.

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

370 Developing UniBasic Applications

Page 371: Basd_52

Getting Information From a Socket

to

Getting Information From a Socket

Use thegetSocketInformation function to obtain information about a socket connection.

SyntaxgetSocketInformation(socket_handle, self_ or_ peer, socket_info)

ParametersThe following table describes each parameter of the syntax.

The following table describes each element of thesocket_infodynamic array.

Parameter Description

socket_handle The handle to the open socket.

self_ or_ peer Get information on the self end or the peer end of the socket. Specify 0return information from the peer end and non-zero for information fromthe self end.

socket_info Dynamic Array containing information about the socket connection. Forinformation about the elements of this dynamic array, see the followingtable.

Element Description

1 Open or closed

2 Name or IP

3 Port number

4 Secure or Non-secure

getSocketInformation Parameters

Developing UniBasic Applications 371

Page 372: Basd_52

Chapter 13 - Using the Socket Interface

The following table describes the status of each return code.

5 Blocking mode

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

Element Description

getSocketInformation Parameters

372 Developing UniBasic Applications

Page 373: Basd_52

Reading From a Socket

e

Reading From a Socket

Use thereadSocketfunction to read data in the socket buffer up tomax_read_sizecharacters.

SyntaxreadSocket(socket_handle, socket_data, max_read_size, time_out, blocking_mode,actual_read_size)

ParametersThe following table describes each parameter of the syntax.

Parameter Description

socket_handle The handle to the open socket.

socket_data The data to be read from the socket.

max_read_size The maximum mumber of characters to return. If this is 0, then the entirbuffer should be returned.

time_out The time (in milliseconds) before a return in blocking mode. This isignored for non-blocking read.

blocking_mode 0:using current mode1:blocking2:non-blocking

actual_read_size The number of characters actually read. -1 if error.

readSocket Parameters

Developing UniBasic Applications 373

Page 374: Basd_52

Chapter 13 - Using the Socket Interface

The following table describes the return status of each mode.

The following table describes the status of each return code.

Mode Return Status

0 - Non-Blocking The function will return immediately if there is no data in the socket. If themax_read_sizeparameter is greater than the socket buffer then just thesocket buffer will be returned.

1 - Blocking If there is no data in the socket, the function will block until data is put intothe socket on the other end. It will return up to themax_read_sizecharac-ter setting.

Mode Return Status

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

374 Developing UniBasic Applications

Page 375: Basd_52

Writing to a Socket

Writing to a Socket

Use thewriteSocket function to write data to a socket connection.

SyntaxwriteSocket(socket_handle, socket_data, time_out, blocking_mode, actual_write_size)

ParametersThe following table describes each parameter of the syntax.

The following table describes the return status of each mode.

Parameter Description

socket_handle The handle to the open socket.

socket_data The data to be written to the socket.

time_out The allowable time (in milliseconds) for blocking. This is ignored for anon-blocking write.

blocking_mode 0:using current mode1:blocking2:non-blocking

actual_write_size The number of characters actually written.

writeSocket Parameters

Mode Return Status

0 - Blocking The function will return only after all characters insocket_dataare writtento the socket.

Mode Return Status

Developing UniBasic Applications 375

Page 376: Basd_52

Chapter 13 - Using the Socket Interface

th

The following table describes the status of each return code.

1 - Non-Blocking The function may return with fewer character written than the actual leng(in the case that the socket is full).

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

Mode Return Status

Mode Return Status

376 Developing UniBasic Applications

Page 377: Basd_52

Setting the Value for a Socket Option

cket

r

d

Setting the Value for a Socket Option

ThesetSocketOptionsfunction sets the current value for a socket option associated with a soof any type.

SyntaxsetSocketOptions(socket_handle, options)

ParametersThe following table describes each parameter of the syntax.

Parameter Description

socket_handle The socket handle fromopenSocket(), acceptSocket(), or initServer-Socket().

options Dynamic Array containing information about the socket options and theicurrent settings. The dynamic array is configured as:

optName1<VM>optValue1a[<VM>optValue1b]<FM>optName2<VM>optValue2a[<VM>optValue2b]<FM>optName3...

Where optName is specified by the caller and must be an option namestring listed below. The first optValue specifies if the option is ON or OFFand must be one of two possible values: “1” for ON or “2” for OFF. Thesecond optValue is optional and may hold additional data for a specificoption. Currently, for the “LINGER” option it contains the delayed time(in milliseconds)before closing the socket. For all other options, it shoulnot be specified as it will be ignored.

setSocketOptions Parameters

Developing UniBasic Applications 377

Page 378: Basd_52

Chapter 13 - Using the Socket Interface

The following table describes the available options (case-sensitive) forsetSocketOptions.

The following table describes the status of each return code.

Option Description

DEBUG Enable/disable recording of debug information.

REUSEADDR Enable/disable the reuse of a location address (default)

KEEPALIVE Enable/disable keeping connections alive.

DONTROUTE Enable/disable routing bypass for outgoing messages.

LINGER Linger on close if data is present.

BROADCAST Enable/disable permission to transmit broadcast messages.

OOBINLINE Enable/disable reception of out-of-band data in band.

SNDBUF Set buffer size for output (default 4KB).

RCVBUF Set buffer size for input (default 4KB).

setSocketOptions Options

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

378 Developing UniBasic Applications

Page 379: Basd_52

Getting the Value of a Socket Option

ket

Getting the Value of a Socket Option

ThegetSocketOptionsfunction gets the current value for a socket option associated with a socof any type.

SyntaxgetSocketOptions(socket_handle, Options)

ParametersThe following table describes each parameter of the syntax..

Parameter Description

socket_handle The socket handle fromopenSocket(), acceptSocket(), or initServer-Socket().

Developing UniBasic Applications 379

Page 380: Basd_52

Chapter 13 - Using the Socket Interface

si-

getSocketOptions ParametersThe following table describes the available options (case-sensitive) forgetSocketOptions().

options A Dynamic Array containing information about the socket options andtheir current settings. When querying for options, the dynamic array isconfigured as:optName1<FM>optName2<FM>optName...

When the options are returned, the dynamic array is configured as:

optName1<VM>optValue1a[<VM>optValue1b]<FM>optName2<VM>optValue2a[<VM>optValue2b]<FM>optName3...

Where optName contains an option name string listed below. The firstoptValue describes if the option is ON or Off and must be one of two posble values: “1” for ON or “2” for OFF. The second optValue is optionaland may hold additional data for a specific option. Currently, for option“LINGER”, it contains the delayed time (in milliseconds) before closingthe socket.

Option Description

DEBUG Enable/disable recording of debug information.

REUSEADDR Enable/disable the reuse of a location address (default).

KEEPALIVE Enable/disable keeping connections alive.

DONTROUTE Enable/disable routing bypass for outgoing messages.

LINGER Linger on close if data is present.

BROADCAST Enable/disable permission to transmit broadcast messages.

OOBINLINE Enable/disable reception of out-of-band data in band..

Parameter Description

380 Developing UniBasic Applications

Page 381: Basd_52

Getting the Value of a Socket Option

getSocketOptions Parameters

The following table describes the status of each return code.

SNDBUF Get buffer size for output (default 4KB).

RCVBUF Get buffer size for input (default 4KB).

TYPE Get the type of the socket.

ERROR Get and clear error on the socket.

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

Option Description

Developing UniBasic Applications 381

Page 382: Basd_52

Chapter 13 - Using the Socket Interface

this

nt-

nt

Initializing a Server Side Socket Connection

Use theinitServerSocketfunction to create a connection-oriented (stream) socket. Associatesocket with an address (name_or_IP) and port number (port), and specify the maximum length thequeue of pending connections may grow to.

SyntaxinitServerSocket(name_or_IP, port, backlog, svr_socket)

ParametersThe following table describes each parameter of the syntax.

The following table describes the status of each return code.

Parameter Description

name_or_IP DNS name (x.com) or IP address of a server or empty. Empty is equivaleto INADDR_ANY which means the system will choose one for you. Generally, this parameter should be left empty.

port Port number. If the port number is specified as a value <= 0, CallHTTPdefaults to a port number of 40001.

backlog The maximum length of the queue of pending connections (i.e. concurreclient-side connections).

svr_socket The handle to the server side socket.

initServerSocket Parameters

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

382 Developing UniBasic Applications

Page 383: Basd_52

Accepting an Incoming Connection Attempt on the Server Side

de

nt

L,

,

Accepting an Incoming Connection Attempt onthe Server Side

Use theacceptConnectionfunction to accept an incoming connection attempt on the server sisocket.

SyntaxacceptConnection(svr_socket, blocking_mode, timeout, in_addr, in_name)

ParametersThe following table describes each parameter of the syntax.

Parameter Description

svr_socket The handle to the server side socket which is returned byinitServer-Socket().

blocking_mode 0 - default (blocking)1 - blocking. In this mode and the current blocking mode ofsvr_socketisset to blocking,acceptConnection() blocks the caller until a connectionrequest is received or the specfiedtime_outhas expired.2 - non-blocking. In this mode if there are no pending connections preseon the queue,acceptConnection() returns an error status code. In thismode,time_outis ignored.

time_out Timeout in milliseconds.

in_addr The buffer that receives the address of the incoming connection. If NULit will return nothing.

in_name The variable that receives the name of the incoming connection. If NULLit will return nothing.

acceptConnection Parameters

Developing UniBasic Applications 383

Page 384: Basd_52

Chapter 13 - Using the Socket Interface

ill

The following table describes the status of each return code.

socket_handle The handle to the newly created socket on which the actual connection wbe made. The server will usereadSocket(), writeSocket(), etc. with thishandle to commuinicate with the client.

Return Code Status

0 Success.

Non-zero SeeSocket Function Error Return Codes.

Parameter Description

acceptConnection Parameters

384 Developing UniBasic Applications

Page 385: Basd_52

Protocol Logging

e

Protocol Logging

This function will start or stop logging.

SyntaxprotocolLogging(log_file, log_action, log_level)

ParametersThe following table describes each parameter of the syntax.

Parameter Description

log_file The name of the file the logs will be recorded to. The default log file namis httplog and will be created under the current directory.

log_action Either “ON” or “OFF”. The default is “OFF”.

log_level The detail level of logging from 0 - 10. See table below.

protocolLogging Parameters

Level Detail

0 No logging

1 Socket open/read/write/close action (no real data) HTTP request: hostinfo(URL)

2 Level 1 logging plus socket data statistics (size, etc.).

3 Level 2 logging plus all data actually transferred.

4-10 More detailed status data to assist debugging.

log_level Details

Developing UniBasic Applications 385

Page 386: Basd_52

Chapter 13 - Using the Socket Interface

The following table describes the status of each return code.

Return Code Status

0 Success.

1 Failed to start logging.

386 Developing UniBasic Applications

Page 387: Basd_52

Appendix A - SampleProgram

arech

The following sample program, UPDATE_ORDER, demonstrates the use of some UniBasiccommands in a simple application. This program uses the demonstration database files thatincluded with UniData. The program calls an external subroutine, DISPLAY_MESSAGE, whiis included at the end of this appendix.

Developing UniBasic Applications 387

Page 388: Basd_52

Appendix A - Sample Program

UPDATE_ORDER

Program Example

** Program : UPDATE_ORDERS** Programmer : Todd Roemmich** Created : 04/02/1996** Description: Check and/or alter Order records** : Display Screen and ask for Order #** : Read record (if it exists) and display fields** : Prompt for a command (Alter, Delete, or Quit)** : A) Allow the user to change price or address** : D) Delete the record** : Q) Exit the program

*-------------- Include/Commons ------------------------

* Normally OPEN commands, EQUATEs, and DIMensions done* with INCLUDE files. --TER

EQU CLS TO @(-1)

GOSUB OPEN_FILES

*-------------- Main Logic -----------------------------

GOSUB INITIALIZE

LOOPGOSUB DISPLAY_SCREENGOSUB GET_ORDER_NUMBER

UNTIL ORDER_NUMBER[1,1] = 'Q'GOSUB DISPLAY_DATAIF RECORD_FOUND THEN GOSUB GET_RECORD_COMMANDRELEASE

REPEAT

GOSUB EXIT

388 Developing UniBasic Applications

Page 389: Basd_52

UPDATE_ORDER

*------------ Subroutines --------------------------

ALTER_RECORD:* Create a new screen, and allow PRICE and ADDRESS to be changed.

* Initialize variables and draw the screenNEED.TO.WRITE = 0DISPLAY CLS:@(15,5):"Alter ORDER":DISPLAY @(10,8):"(Press RETURN to leave unchanged)"DISPLAY @(8,9):"Old Price":@(42,9):"New Price (Enter 2 decimal places)"

* Change the PRICE field (if desired)FOR ENTRY = 1 TO NUM_ENTRIES

NEW.PRICE = ""DISPLAY @(10,9+ENTRY):OCONV(ORDER.REC<7,ENTRY>,"MR2$,"):INPUT @(45,9+ENTRY):NEW.PRICENEW.PRICE = OCONV(NEW.PRICE,"MCN")IF NEW.PRICE # '' AND NUM(NEW.PRICE) THEN

ORDER.REC<7,ENTRY> = NEW.PRICENEED.TO.WRITE = 1

ENDNEXT ENTRY

* Display the current ADDRESS informationDISPLAY @(21,12):"Change Address to: ":DISPLAY @(21,13):"Street Line1: ":@(40,13):ADDRESS<2>DISPLAY @(21,14):"Street Line2:"DISPLAY @(40,14):ADDRESS<3>:@(21,15):"City:":@(40,15):CLIENT.REC<6>DISPLAY @(21,16):"State:":DISPLAY @(40,16):CLIENT.REC<7>:@(21,17):"Zip:":@(40,17):CLIENT.REC<8>

* Accept INPUT to change values of addressINPUT @(40,13):STREET1IF STREET1 = '' THEN STREET1 = CLIENT.REC<4>INPUT @(40,14):STREET2IF STREET2 = '' THEN STREET2 = CLIENT.REC<5>INPUT @(40,15):CITYIF CITY = '' THEN CITY = CLIENT.REC<6>INPUT @(40,16):STATEIF STATE = '' THEN STATE = CLIENT.REC<7>INPUT @(40,17):ZIPIF ZIP = '' THEN ZIP = CLIENT.REC<8>

Developing UniBasic Applications 389

Page 390: Basd_52

Appendix A - Sample Program

* Compare Old and New values (Write out new record if needed)NEW_CLIENT = STREET1:STREET2:CITY:STATE:ZIPOLD_CLIENT = CLIENT.REC<4>:CLIENT.REC<5>:CLIENT.REC<6>:CLIENT.REC<7>:CLI-

ENT.REC<8>

IF (NEW_CLIENT # OLD_CLIENT) OR NEED.TO.WRITE THEN* Re-assign values to CLIENT.REC

CLIENT.REC<4> = STREET1CLIENT.REC<5> = STREET2CLIENT.REC<6> = CITYCLIENT.REC<7> = STATECLIENT.REC<8> = ZIP

GOSUB WRITE_RECORDEND

RETURN

DELETE_RECORD:* (Assuming the order #'s are on line 12)

READVU ORDER_LINE FROM CLIENT_FILE,CLIENT_NUMBER,12 THENLOCATE ORDER_NUMBER IN ORDER_LINE<1> SETTING POSITION THEN

DEL ORDER_LINE<1,POSITION>ENDWRITEV ORDER_LINE ON CLIENT_FILE, CLIENT_NUMBER, 12

END*

DELETE ORDERS_FILE, ORDER_NUMBERRELEASE CLIENT_FILE,CLIENT_NUMBER

RETURN

DISPLAY_DATA:* Display the current information in the desired record. This is* determined by the number the user entered (ORDER_NUMBER).

READU ORDER.REC FROM ORDERS_FILE,ORDER_NUMBER THEN* Read with a lock so that no one else can modify it at the same time.

RECORD_FOUND = 1ORDER_DATE = OCONV(ORDER.REC<1>,"D4/")ORDER_TIME = OCONV(ORDER.REC<2>,"MT")CLIENT_NUMBER = ORDER.REC<3>

390 Developing UniBasic Applications

Page 391: Basd_52

UPDATE_ORDER

ADDRESS = ''READU CLIENT.REC FROM CLIENT_FILE,CLIENT_NUMBER THEN

ADDRESS<1> = CLIENT.REC<3>ADDRESS<2> = CLIENT.REC<4>ADDRESS<3> = CLIENT.REC<5>ADDRESS<4> = CLIENT.REC<6>:", ":CLIENT.REC<7>:" ":CLIENT.REC<8>

ENDDISPLAY @(45,7):ADDRESS<1>DISPLAY @(45,8):ADDRESS<2>DISPLAY @(45,9):ADDRESS<3>DISPLAY @(45,10):ADDRESS<4>DISPLAY @(45,11):ADDRESS<5>PRODUCT_LINE = ''COLOR_LINE = ''QUANTITY_LINE = ''PRICE_LINE = ''

NUM_ENTRIES = DCOUNT(ORDER.REC<4>,@VM)FOR ENTRY = 1 TO NUM_ENTRIES

PRODUCT_NUMBER = ORDER.REC<4,ENTRY>COLOR = ORDER.REC<5,ENTRY>QUANTITY = ORDER.REC<6,ENTRY>PRICE = OCONV(ORDER.REC<7,ENTRY>,"MD2$,")IF PRODUCT_LINE = '' THEN

PRODUCT_LINE = PRODUCT_NUMBER "R#10"COLOR_LINE = COLOR "R#10"QUANTITY_LINE = QUANTITY "R#10"PRICE_LINE = PRICE "R#10"

END ELSEPRODUCT_LINE := " ":PRODUCT_NUMBER "R#10"COLOR_LINE := " ":COLOR "R#10"QUANTITY_LINE := " ":QUANTITY "R#10"PRICE_LINE := " ":PRICE "R#10"

ENDNEXT ENTRY

ORDER_DATA = @(13,7):ORDER_DATE:@(13,8):ORDER_TIMEORDER_DATA := @(13,10):CLIENT_NUMBER "R#5"ORDER_DATA := @(13,11):PRODUCT_LINE:@(13,13):COLOR_LINEORDER_DATA := @(13,14):QUANTITY_LINE:@(13,15):PRICE_LINEDISPLAY ORDER_DATA

END ELSEMESSAGE ="**(Record Does Not Exist)**"RECORD_FOUND = 0

Developing UniBasic Applications 391

Page 392: Basd_52

Appendix A - Sample Program

CALL DISPLAY_MESSAGE(MESSAGE)ENDRETURN

DISPLAY_SCREEN:* Display the starting screen

SCREEN = CLS:@(25,1):"ORDER MAINTENANCE":@(16,5):"(Enter Q to quit)"SCREEN := @(5,6):"Order #: "SCREEN := @(5,7):"Date: ":@(5,8):"Time: ":@(5,10):"Client #:"SCREEN := @(5,11):"Product #: ":@(5,13):"Color: ":@(5,14):"Qty: "SCREEN := @(5,15):"Price: "

DISPLAY SCREENRETURN

GET_ORDER_NUMBER:* Have the user enter a valid key to a record in the ORDERS file.

LOOPDISPLAY @(15,6):INPUT ORDER_NUMBERORDER_NUMBER = OCONV(ORDER_NUMBER,"MCU")IF NUM(ORDER_NUMBER) OR ORDER_NUMBER[1,1] = "Q" THEN

VALID_ORDER_NUMBER = 1END ELSE

VALID_ORDER_NUMBER = 0MESSAGE = "Order # must be a Number, or the letter 'Q'"CALL DISPLAY_MESSAGE(MESSAGE)

ENDUNTIL VALID_ORDER_NUMBERREPEAT

RETURN

GET_RECORD_COMMAND:* Enter a valid command to act upon (the Desired record is already shown).

DISPLAY @(7,22):"Enter A)lter, D)elete, or Q)uit: ":INPUT COMMAND,1COMMAND = OCONV(COMMAND[1,1],"MCU")

BEGIN CASE

392 Developing UniBasic Applications

Page 393: Basd_52

UPDATE_ORDER

CASE COMMAND = "A"GOSUB ALTER_RECORD

CASE COMMAND = "D"GOSUB DELETE_RECORD

CASE COMMAND = "Q"FINISHED = 1

CASE 1MESSAGE = "Valid options are A, D, or Q. Please try again"CALL DISPLAY_MESSAGE(MESSAGE)

END CASERETURN

WRITE_RECORD:* The record(s) have been updated. Make sure that if the RECOVERABLE* FILE System is operational that either BOTH records are updated, or that* None are (using Transaction processing commands).

TRANSACTION START ELSEIF STATUS() = 1 THEN

DISPLAY "A Transaction had already been started, NESTED Transactions"DISPLAY "are NOT Allowed. (Contact System Administrator)"INPUT PAUSE,1_

END ELSENULL

ENDEND

WRITE CLIENT.REC ON CLIENT_FILE,CLIENT_NUMBERWRITE ORDER.REC ON ORDERS_FILE,ORDER_NUMBER

TRANSACTION COMMIT ELSEIF STATUS() = 1 THEN

DISPLAY "The TRANSACTION was not started"END ELSE

DISPLAY "The TRANSACTION could not be committed."END

ENDRETURN

OPEN_FILES:OPEN "CLIENTS" TO CLIENT_FILE ELSE

MESSAGE = "The CLIENT file could not be opened."

Developing UniBasic Applications 393

Page 394: Basd_52

Appendix A - Sample Program

CALL DISPLAY_MESSAGE(MESSAGE)STOP

END

OPEN "ORDERS" TO ORDERS_FILE ELSEMESSAGE = "The ORDERS file could not be opened."CALL DISPLAY_MESSAGE(MESSAGE)STOP

END

RETURN

INITIALIZE:DISPLAY CLSPROMPT ''RETURN

EXIT:DISPLAY CLSSTOPRETURN

394 Developing UniBasic Applications

Page 395: Basd_52

DISPLAY_MESSAGE

DISPLAY_MESSAGE

The following example shows the external subroutine that is called by UPDATE_ORDERS:

Program Example

SUBROUTINE DISPLAY_MESSAGE(MESSAGE)DISPLAY @(5,20):MESSAGEDISPLAY @(5,21):"Press the (Return) key.":INPUT PAUSE,1_RETURN

Developing UniBasic Applications 395

Page 396: Basd_52

Appendix A - Sample Program

396 Developing UniBasic Applications

Page 397: Basd_52

Appendix B - UniBasicTransaction ProcessingConcepts

is

and

is in an theION

ilure.

NoteThis appendix applies to UniData for UNIX only. UniData for Windows NT or Windows 2000does not support transaction processing.

This chapter describes some basic concepts on which UniData transaction processing (TP)based.“Chapter 9 - UniBasic Transaction Processing”introduces the UniData TP commands,including how to create and convert to files, and describes some TP programming problemsproposes solutions for those problems. To learn more about recoverable files, seeAdministeringUniData on UNIX.

TP executes a set of statements as a single logical function. This ensures that if a databaseconsistent state before a transaction starts, the database maintains that consistent state whetransaction completes. To create a transaction, you must bind the operations by TRANSACTSTART and TRANSACTION COMMIT statements. When the transaction commits, all of theoperations take place as one, and UniData can recover the updated file in the event of any faIf a transaction is aborted, none of the operations within the transaction take place.

Developing UniBasic Applications 397

Page 398: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

ased.

In This Appendix

This appendix explains some of the concepts on which UniData Transaction Processing is bThe following sections are included:

• “Transaction Processing Rules: The ACID Properties”

• “Transaction Isolation”

• “Transaction Processing Errors”

• “What Are Isolation Levels?”

• “Programming to Isolation Levels”

• “Updating Nonrecoverable Files in Transactions”

398 Developing UniBasic Applications

Page 399: Basd_52

Transaction Processing Rules: The ACID Properties

tes:

cceed

tate

rd

iate

Transaction Processing Rules: The ACIDProperties

The ACID properties in the following list distinguish transactions from non-TP database upda

• Atomicity

• Consistency

• Isolation

• Durability

AtomicityLogical operations grouped by transaction semantics are treated as one unit. They will all suor all fail.

ConsistencyThe components of a logical operation all succeed or all fail. If a database is in a consistent sbefore you apply a logical operation, it will be in a consistent state afterwards. For example,writing a new record will guarantee that the record and the indexes are both written. The recowill not be written without its associated indexes.

IsolationIsolation means that operations are based on a consistent database rather than on intermedresults from other operations. Isolation is controlled within UniBasic applications. If locks areproperly set and checked, all transactions are properly isolated. In UniData SQL, a desiredisolation level is set by specifying the isolation level with the set transaction command. If noisolation level is specified, a default isolation level is handled by the database engine.

Developing UniBasic Applications 399

Page 400: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

. Ifstart.

DurabilityDurability means that completed transactions are preserved in the database despite failuresUniData stops running, the database recovers to the last committed transaction when you reUniData. Recovery techniques are available to provide durability in the case of media failure

400 Developing UniBasic Applications

Page 401: Basd_52

Transaction Isolation

g to

fthe

s.

ns

s

Transaction Isolation

Even though transactions appear to process sequentially and atomically, they actually occurserially. Isolation is determined by the degree to which transaction errors are prevented. Thissection identifies transaction errors, isolation levels, and provides templates for programmineach isolation level.

NoteUniData SQL follows ANSI '92 standards, but UniBasic does not. For this reason, the types otransaction errors that can occur and the isolation levels that can be achieved differ betweentwo products. UniBasic and UniSQL TP differ in the following ways:

• UniData SQL always protects against lost updates and dirty reads, but could allow phantom• UniBasic always protects against dirty reads and phantoms, but could allow lost updates.

Transaction Processing ErrorsYou can get unexpected results when transactions process concurrently. The following sectiodescribe these errors:

• “Lost Updates”

• “Dirty Reads”

• “Unrepeatable Reads”

Lost updates, dirty reads, and unrepeatable reads can be prevented by designing applicationappropriately, as in the examples provided later in this chapter.

Lost Updates

In a lost update, the updates from one transaction are overwritten by those of another.

ReminderUniData SQL protects against lost updates in all transactions.

Developing UniBasic Applications 401

Page 402: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

ouldtee in

y ad, this

cord;rent

Consider the following example:

ReminderUniData SQL protects against lost updates in all transactions.

Program Segment 1 and Transaction Segment 2 are run concurrently. Program Segment 1 close updates because the record is not locked between its READ and WRITE. In two separawrite operations, Transaction Segment 2 changes Record1’s value to 2, then to 3. The updatProgram Segment 1, made between the two writes, is lost.

Dirty Reads

A dirty read occurs when one of two scenarios takes place:

• Within a transaction, a process reads an attribute value between two updates made bsecond transaction. Because the second transaction changes the value after the rearead is considered dirty.

• Within a transaction, a record is changed; a second transaction process reads the rethen the first transaction process aborts and rolls back, changing the record to a diffevalue. The value obtained by the second transaction is dirty.

READ var FROM file.var, record1ELSE PRINT “Record not found.”

var += 1

WRITE var TO file.var, record1

TRANSACTION STARTTHEN PRINT “Transaction started.”

READ var FROM file.var, record1ELSE PRINT “Record not found”

var += 2

WRITE var TO file.var, record1TRANSACTION COMMITTHEN PRINT “Transaction committed.”

Program Segment 1 Transaction Segment 2

402 Developing UniBasic Applications

Page 403: Basd_52

Transaction Isolation

2itionalt.

result,is an

ReminderUniBasic protects against dirty reads in all transactions.

Consider the following example:

Program Segment 1 and Transaction Segment 2 are run concurrently. Transaction Segmentwrites a record; then Program Segment 1 reads it; finally, Transaction Segment 2 makes addchanges to the record. The record value obtained by Program Segment 1 is no longer curren

Unrepeatable Reads

Between two reads of a record in a transaction, another transaction updates the record. As athe first transaction obtains a different value for the same attribute on the second read. Thisunrepeatable read.

READ var FROM file.var, record1ELSE PRINT “Record not found.”

Program Segment 1 Transaction Segment 2

TRANSACTION STARTTHEN PRINT “Transaction started.” ELSE STOPvar = 1WRITE var TO file.var, record1

var += 2WRITE var TO file.var, record1TRANSACTION COMMITTHEN PRINT “Transaction committed.”

Developing UniBasic Applications 403

Page 404: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

s aurn

ds,

eng:n are

thesee

evel,

Consider the following example:

Program Segment 1 and Transaction Segment 2 run concurrently. Program Segment 1 readrecord twice before and after Transaction Segment 2 updates it. The two read operations retdifferent values for the record.

What Are Isolation Levels?The isolation level determines the type of transaction errors (including lost updates, dirty reaand unrepeatable reads) that are allowed or not allowed.

UniBasic TP does not implicitly enforce isolation levels. The application program must providprotection from transaction errors by setting shared locks on records being read and by settiexclusive locks on records being updated. UniBasic TP does provide the following protectionrecords are automatically locked during write operations, and all locks set during a transactioretained until the transaction is committed or aborted.

Unlike UniBasic, UniData SQL automatically initiates and commits transactions and provideslevel of isolation appropriate for the type of operation being executed. For more information,Using UniData SQL.

The following list describes fourtheoreticalisolation levels:

• Isolation level 0 exposes transactions to any type of TP error, but cannot overwrite thupdates from transactions at isolation level 1 or higher. To achieve atomicity at this lethe application must set exclusive locks on records being updated.

READ var FROM file.var, record1ELSE PRINT “Record not found.”

READ var FROM file.var, record1ELSE PRINT “Record not found.”

TRANSACTION STARTTHEN PRINT “Transaction started.”

var = 2WRITE var TO file.var, record1

TRANSACTION COMMITTHEN PRINT “Transaction committed.”

Program Segment 1 Transaction Segment 2

404 Developing UniBasic Applications

Page 405: Basd_52

Transaction Isolation

cks

re, if

s,

of

hieve

orata

• Isolation level 1 protects transactions against lost updates but allows dirty reads andunrepeatable reads. When you execute a read operation, the system automatically lorecords being updated.

• Isolation level 2 protects transactions against lost updates and dirty reads, but allowsunrepeatable reads. Note: UniBasic automatically protects against dirty reads; therefoyou program to protect against lost updates, you achieve isolation level 2.

• Isolation level 3 protects transactions against all three types of TP errors: lost updatedirty reads, and unrepeatable reads.

NoteThe ANSI-standard isolation levels available through UniData SQL differ from these becausethe differences in product design described at the beginning of this section.

Programming to Isolation LevelsThis section provides program templates that demonstrate how to program in UniBasic to acdifferent levels of isolation.

Example: Programming to Isolation Level 0

The following program template provides no protection against TP errors. It is programmed fisolation level 0. Unlike the theoretical situation depicted by this example, UniBasic and UniDSQL provide some protection against TP errors.

Program Example

TRANSACTION STARTTHEN PRINT "Transaction started."ELSE PRINT "Transaction start failed, STATUS = ":STATUS()

READ var FROM file.var, record1 ELSE PRINT "Record not found."var += 2WRITE var TO file.var, record1

TRANSACTION COMMITTHEN PRINT "Transaction committed."ELSE PRINT "Transaction aborted, STATUS = ":STATUS()

Developing UniBasic Applications 405

Page 406: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

, the

Example: Programming to Isolation Level 2The following program template illustrates programming for isolation level 2, which protectsagainst lost updates and dirty reads. After the record is locked by the second read (READU)transaction is protected against lost updates.

Program Example

TRANSACTION STARTTHEN PRINT "Transaction started."ELSE PRINT "Transaction start failed, STATUS = ":STATUS()

READ var FROM file.var, record1...REM "If another transaction changes record1 here, its updates arelost"...READU var FROM file.var, record1 ELSE PRINT "Record not found."var += 2WRITE var TO file.var, record1

TRANSACTION COMMITTHEN PRINT "Transaction committed."ELSE PRINT "Transaction aborted, STATUS = ":STATUS()

406 Developing UniBasic Applications

Page 407: Basd_52

Transaction Isolation

fd.

Example: Programming to Isolation Level 3The following program template illustrates programming for isolation level 3. All three types otransaction error are prevented because the record is locked by READU the first time it is rea

Program Example

TRANSACTION STARTTHEN PRINT "Transaction started."ELSE PRINT "Transaction start failed, STATUS = ":STATUS()

READU var FROM file.var, record1 ELSE PRINT "Record not found."var += 2WRITE var TO file.var, record1

TRANSACTION COMMITTHEN PRINT "Transaction committed."ELSE PRINT "Transaction aborted, STATUS = ":STATUS()

Developing UniBasic Applications 407

Page 408: Basd_52

Appendix B - UniBasic Transaction Processing Concepts

partthe

nge a

Updating Nonrecoverable Files in Transactions

UniData TP is effective only on recoverable files. An update to a nonrecoverable file is neverof a transaction, even when executed within a transaction. UniBasic updates the file, but withfollowing conditions:

• The write operation takes place immediately, even before the transaction commits.

• The write is not rolled back in the event of a transaction abort or restart after a systemcrash.

WarningUniData records only updates made while a file is recoverable. Remember this when you chafile to or from the recoverable state.

408 Developing UniBasic Applications

Page 409: Basd_52

Index

Symbols!, 70-, 159, 46, 303#, 47, 307#<, 45, 307#>, 45, 307$, 70$$FUN heading, cfuncdef file, 224$$LIB heading, cfuncdef file, 226$$OBJ heading, cfuncdef file, 226$BASICTYPE, 62, 196$DEFINE, 62$ELSE, 63$IFDEF, 63$IFNDEF, 63$INCLUDE, 63$INSERT, 63$UNDEFINE, 62*

commenting a program, 18multiplication, 159null value and, 303

**

exponentiation, 46, 159*=, multiplication, 160+, 159, 303+=, increment variable, 160/, division, 46, 159/=, division, 160:

concatenation, 159null value and, 317

:=, concatenation, 160<, 45, 307<=, 45, 307<>

EXTRACT function, 158not equal to, 45null value and, 307

=equal to, 45, 47in cross reference report, 70null value and, 307

–=, decrement variable, 160=<, 45, 47, 307=>, 45, 47, 307>, 45, 47, 307><, 45, 47

Developing UniBasic Applications 409

Page 410: Basd_52

Index

>=, 45, 47, 307@ in cross reference report, 70@AM, 24@FM, 24@NULL, 24@RM, 24@SM, 24@TM, 24@TRANSACTION, 288@USERNO, 84, 84@variable

@TRANSACTION, 288introduction to UniBasic, 27

@VM, 24[ ]

EXTRACT, 157null value and, 317replace, 168

^exponentiation, 46, 159null value and, 303

{, delimiter, 150{}, calculate, 195|, delimiter, 150}, delimiter, 150~

converting nonprinting characters, 169delimiter, 150

AABORT

program control commands, 49ABS, 164, 303absolute value, 164ACID properties, 399ACOS, 164, 303

active transaction, testing for, 288add

see also WRITEaddition, 46, 159advisory lock, 136AE

compiling in, 59creating a program with, 53help, 56introduction, 59running a program from, 82unable to find file, 54

ALPHA, 156null value and, 316

alphabeticcharacter in array, 158

alternate indexcreating and managing, 109

alternative editorcompiling in, 59introduction, 53

AND, 47arc cosine, 164arc sine, 164arc tangent, 164argument

command or function and the null value, 303arithmetic operation

introduction, 159on dates, 176

arithmetic operations and data type, 161array

converting data in, 168dimensioned, 149dynamic, 149finding elements in, 156left-justifying elements, 169

410 Developing UniBasic Applications

Page 411: Basd_52

Index

summary of commands, 151, 154types, 26, 149

array elementtesting for null value, 316, 318

ASCIIcharacter, converting, 168, 172converting from numeric to, 170function, 168null value and, 316

ASIN, 164, 303assigning

null value, 315value to variables, 25

AT, 330, 334ATAN, 164, 303atomicity, 399attribute

virtual, 195attribute mark

in UniBasic, 24

Bbase logarithm, 164BASIC

compiling programs, 59options, 60

BASICTYPE, 61, 196binary

data, converting, 172data, maintaining, 112

BITAND, 303BITNOT, 303BITOR, 303BITXOR, 303Boolean operator, 44

null value in, 307

bottleneck, 142BP file, 53branching, 48BREAK, 206break key

in transaction processing, 287BUILD.INDEX

transaction processing and, 294business rules, 96

CC program

calling UniBasic subroutine, 235writing, 219

CALCULATE, 195calculations

and data type, 161CALL

executing programs, 193extending statements over multiple lines, 20introduced, 33program control commands, 49

callbas.mk, 218, 236CallBasic

compiling and linking the C program, 235, 243U_callbas function, 275udtcallbasic function, 271, 275udtcallbasic_done function, 275udtcallbasic_done( ) function, 238udtcallbasic_init function, 275writing the UniBasic subroutine, 235, 236, 273

CALLC_cdecl calling convention, 264data types, 261PASCAL calling convention, 264program control commands, 49

Developing UniBasic Applications 411

Page 412: Basd_52

Index

syntax, 260called program

starting a transaction in, 294calling

C functions from UniBasic, 219external functions from UniBasic, 264UniBasic subroutines from C, 235UniBasic subroutines from external program, 272

CASEconditional tests, 38introduced, 41null value in, 305program control commands, 49

CAT, 317CATALOG

examples, 79options, 77

cataloged programdetermining version, 74

catalogingdirect, 74global, 75local, 75programs, 73

CATS, 317cfuncdef, 224CHAIN

in transaction processing, 287program call commands, 194program control commands, 49

CHANGE, 181, 316CHAR, 168, 181, 316character

conversion, 168lower case, 169nonprinting, 169upper case, 169

CHARS, 181, 316CLEAR.FILE

transaction processing and, 294CLEAR.LOCKS, 136CLEARDATA, 193clearing

data stacks, 193select lists, 118

CLEARINPUT, 204CLEARSQL, 197CLOSE, 128CLOSESEQ, 113closing

files in programs, 128non-UniData files, 114sequential files, 337

CNAMEtransaction processing and, 294

codeinterpretive/object, 59

COL1, 157, 181COL2, 157, 181colon

null value and, 317command

udtcallbasic_done, 272udtcallbasic_init, 268

command argument and the null value, 303commands, UniBasic, 17comments, adding to a program, 18COMMIT, 285committing transactions inappropriately, 282COMMON, 189, 189comparison

null value in, 302, 307compiler

directive commands, 62

412 Developing UniBasic Applications

Page 413: Basd_52

Index

directive, defined, 16UniBasic, 16

compilingprograms, 59, 61

concatenationintroduction, 159operator precendence, 46operators, 160

conditional operator, 44conditional test

see also logical operatordefined, 16null value in, 305order of precedence, 47types, 38

consistency, 399constant

representing data, 25constraint violation, 98, 105CONTINUE

loop commands, 36program control commands, 49

control statement, defined, 16controlling

looping, 49program execution, 29

conversion functions, null value in, 313CONVERT, 169, 316

command, 181converting

characters, 168data, 166files to transaction processing, 279nonprinting characters, 169null values, 302numbers, 170

copying

array elements to variable, 158COS, 164, 303cosine, 164COUNT, 156, 181, 317COUNTS, 156, 182, 317CPIO format in transaction processing, 290CREATE.FILE

transaction processing, 290transaction processing and, 294

CREATE.INDEXtransaction processing and, 294

creatingdimensioned array, 154recoverable file, 279, 290UniBasic program, 51

cross reference report, 68CRT, 205

DDATA, 20data

binary, updating, 112converting numbers, 172determining type, 155file types, 23formatting, 166in UniBasic programs, 93relational, 44representing in programs, 147stack, 191writing to a file, 123

DATA stack, 203data type

calculations and, 161character, 168date and time, 176

Developing UniBasic Applications 413

Page 414: Basd_52

Index

numeric, 172UNIX C definitions, 225

databasemaintaining consistency, 142triggers, 96

dateconverting and formatting, 175internal and display format, 175rules for entering, 177

DCOUNT, 156, 182, 317deadlock

avoiding, 293causes, 142

debuggercross referencing in UniBasic, 68

decimalconverting data, 172

decrement value in variable, 160default file, 115DEFAULT.LOCKED.ACTION BELL, 135degraded performance, 297DEL, 317DELETE, 317

invoking triggers with, 98non-UniData files, 114trigger subroutine, 102

DELETE.FILEtransaction processing and, 294

DELETE.INDEXtransaction processing and, 294

DELETEUtriggers, 98

deletingrecords, 126

delimiterdefining, 158in dynamic arrays, 150

representing in UniBasic, 24UniBasic, 150

demonstration databaseUniBasic program using, 387

device, output, 203DIM, DIMENSION, 154dimensioned array

defined, 26using, 153

DIR, 317DIRECT, 78direct catalog, 74directing the compiler, 59directory

file (BP), 53dirty read, 142, 402DISPLAY, 205display format, data and time, 176display terminal commands, 205DISPLAY_MESSAGE

sample program, 395displaying

null value in UniBasic, 301statements and variables in the debugger, 69

divisionarithmetic operators, 159combined operators, 160operator precedence, 46

DLLCallBasic implementation, 259CALLC implementation, 259UniData NT and DLL, 259

double spacing, suppressing, 210DOWNCASE, 169, 316DROUND, 303durability, 400dynamic array

414 Developing UniBasic Applications

Page 415: Basd_52

Index

converting data in, 168defined, 26using, 149

dynamic link library (DLL), 259

EE type VOC entry, 262, 266EBCDIC, 168, 316ECHO, 206ED (editor), 53efficiency

transaction processing, 298ELSE

transaction processing, 283empty strings

selected attributes in a file, 211UDT.OPTIONS and, 211

ENDprogram control commands, 49

ENTER, 194EQ

comparison operator, 307conditional tests, 47

EQS, 307error message, 203

in C function, 220in external function, 265

EX, 56exclusive lock, 133EXECUTE

program control commands, 49EXECUTE SELECT, 117EXECUTESQL

example, 197program control commands, 49

executing

UniBasic programs, 82execution time

reporting, 60, 84EXIT

loop commands, 36program control commands, 49

exit, 265exit( ), 221exiting

CallBasic, 243, 272EXP, 164, 303exponentiation, 46, 159external

date and time format, 176interaction, 195subroutines, 33

external interactiongetting system information, 27

external programcalling UniBasic subroutine, 272writing, 264

external subroutinesample program, 395

EXTRACT, 158, 317extracting

commands, 155data from arrays, 157

FFI, 56FIB, 59FIBR, 57, 82FIELD, 158, 182, 317field length, exceeding during data entry, 205FIELDS, 317FIELDSTORE, 317

Developing UniBasic Applications 415

Page 416: Basd_52

Index

fileaccessing unopened, 129closing, 128default, 115deleting records from, 126locks, 133maintaining binary, 112maintaining non-UniData, 112maintaining through programs, 107opening, 115recoverable, 279recoverable, creating or converting, 290sequential, closing, 337type, UniData, 23UniData.LIB, 259, 274writing to, 123

FILEINFOwriting programs, 110

file-level operation, 294filing

programs, 56FIND, 152, 157, 317FINDSTR, 182, 317FIR, 57FLOAT.PRECISION, 160floating point, 160FMT, 171, 313FMTS, 168FOOTING, 209FOR/NEXT

example, 20loop commands, 36program control commands, 49

FORCE, 78formatting

arrays and strings, 168dates, 176

functions for, 166numbers, 171

FUNCTIONwriting trigger, 99

functionconversion, 166defined, 17mathematic, 164null value in, 303U_callbas, 275udtcallbasic, 275udtcallbasic_done, 275udtcallbasic_init, 275

GGE

conditional tests, 47null value and, 307

GES, 307GET, 182GETPTR, 317GETPU, 317GETREADU, 137GETUSERGROUP, 317GETUSERNAM, 317GLOBAL, 77global catalog, 75GOSUB

executing subroutines, 31program control commands, 49

greater thanconditional tests, 47

GROUPSTORE, 317GT

conditional tests, 45null value and, 307

416 Developing UniBasic Applications

Page 417: Basd_52

Index

GTS, 307

Hhashed file

maintaining through programs, 107HEADING, 209HELP for AE, 57hexadecimal

converting data, 173hung process

named pipes and, 341HUSH, 205

II/O function, 205ICONV, 182

converting and formatting, 166null value and, 313

IF/THEN/ELSEconditional tests, 38formatting long statements, 20null value and, 305program control commands, 49

INCLUDE, 63increment variable, 160INDEX, 157, 182index

alternate, 109indexing

null values, 301, 302initial caps

converting to, 169INMAT

dimentioned arrays and, 154

named pipes and, 340INPUT, 182input

device, 203into variables, 25

INPUT @, 182INPUT@, 203INPUTCLEAR, 204INPUTERR, 203INPUTIF, 204INPUTNULL, 203INPUTTRAP, 204INS, 317INSERT

compiler directive, 63null value and, 317

insert mode in AE, 57INT, 164, 303integer

converting, 171obtaining a random, 164value, 164

interfacing with Cinvoking C programs, 236, 245makefile command, 243U_callbas function, 241udtcallbasic_done function, 243UniBasic program, 228

interfacing with external programU_callbas function, 269udtcallbasic_done function, 272udtcallbasic_init function, 268

internal formatdate and time, 175

internationalformat for dates, 176

interpretive code, 59

Developing UniBasic Applications 417

Page 418: Basd_52

Index

interrupt keyin transaction processing, 287

introduction to UniBasic, 13inverse cosine, sine, tangent, 164ISNV, ISNVS, 155, 319isolation

defined, 399dirty reads, 402levels, 404lost update, 401preventing errors, 401programming to level 0, 405programming to level 2, 406programming to level 3, 407unrepeatable reads, 403

Kkey

break, in transaction processing, 287

LL lock, 134label

in program subroutines, 32layout, statement, 19LE

comparison operator, 307conditional tests, 47

LEN, 156, 182, 317length

string or array, 156LENS, 182, 317LES

comparison operator, 307

less thanconditional tests, 47

limitationfile-level operations, 294report generator, 294screen generator, 294UniData SQL, 294

line editor, 53Linking programs with UniData, 215LIST, 69LIST.QUEUE, 137LIST.READU, 137, 196LN

null value and, 303numeric function, 164

LOCAL, 77local catalog, 75LOCATE, 152, 157, 317locating

data in array, 157lock

checking status, 137commands, when to use, 140obtaining user number, 137released by TRANSACTION COMMIT, 285transaction processing, 297types, 133UniBasic commands, 137using UniData, 131

LOCKED clause, 138logarithm, 164logical condition, 44

see also conditional testlogical operator

null value and, 307long transaction

performance, 297

418 Developing UniBasic Applications

Page 419: Basd_52

Index

LOOP/REPEATprogram control commands, 50

looping commands, 36lost update, 401lost updates, 142lowercase

converting to, 169LT, 307LTS, 307

Mmaintaining

dimensioned arrays, 154dynamic arrays, 150files, 107

make command, 245makefile, 218, 236, 243makeudapi, 228makeudt, 227MAT, 154MATBUILD , 155MATCH, 182, 182, 317

conditional tests, 45MATCHES, 317

in conditional tests, 45MATCHFIELD, 182, 317math functions, 164MATPARSE, 155MAXIMUM , 156McDonnell Douglas, 62MDPERFORM, 196MINIMUM , 156minus

operator precedence, 46MOD

null value and, 303

numeric function, 164modify

see also WRITEmodifying

data, 166numbers, 171

multiplication, 160arithmetic operators, 159operator precedence, 46

multivalued attributeformatting for output, 168

Nnamed pipes

introduction, 323opening, 326, 327troubleshooting, 341write access, 326writing to, 334

namingvariables in C function, 219variables in external function, 264

NEconditional tests, 45null value and, 307

NES, 307nested

statement, 21transaction, 283transaction in transaction processing, 293

NEWPCODE, 74NEWVERSION, 78NODELAY, 326, 330, 334nonprinting character, converting, 169NOT, 307

conditional tests, 43

Developing UniBasic Applications 419

Page 420: Basd_52

Index

not equal toconditional tests, 47

not greater thanconditional tests, 47

not less thanconditional tests, 47

NOTS, 307null value

ASCII value for, 300assigning to a variable, 315CASE, 41converting, 316determining ASCII code, 315effects on conditional tests, 308found when numeric required, 316in IF/THEN/ELSE, 38introduction to UniBasic, 299NOT, 43numeric calculations, 161representing in UniBasic, 24testing for, 36, 155, 315

NULL_VAL_ALT_KEY , 301NUM

null value and, 316testing for data type, 156

numberarithmetic operations, 159converting and formatting, 170locating data in array, 158random, 164rounding, 171scaling, 171

numbering system, converting, 170numeric calculation

null value in, 302numeric data

conditional tests of, 44

numeric functions and the null value, 303NUMS

null value and, 316

Oobject code, 59, 226OCONV, 158, 166, 169, 182, 313octal

converting data, 173ON ERROR

triggers, 98ON/GOSUB

program control, 50opeining a named pipe, 326OPEN

file commands, 115non-UniData files, 114

OPENSEQ, 113operation

file-level, 294operator

arithmetic, 17, 159Boolean, 44precedence, 46

OR, 307OSBREAD, 113, 323, 330OSBWRITE, 113, 323

writing to a named pipe, 334OSCLOSE, 113, 337OSDELETE, 113OSOPEN, 113, 323, 326OSREAD, 113OSWRITE, 113output device, 203

420 Developing UniBasic Applications

Page 421: Basd_52

Index

PP, AE command, 57packed decimal, 171PAGE

printer control, 209terminal control commands, 205

passingarguments to C functions, 220arguments to external functions, 264data through a stack, 191

PCPERFORMprogram control commands, 50

PERFORMprogram control commands, 50

performanceimproving in transaction processing, 297

phonetic code, converting to, 169Pick® Basic, 62PIPE_BUF, 325, 341position, determining in array, 155POWER

null value and, 303precision

setting in UniBasic, 161PRINT, 205, 208, 209PRINT @, 205PRINT ON, 209printer

output, 209PRINTER CLOSE, 209PRINTER OFF, 209PRINTER ON, 209printing

in a C function, 220in an external function, 265page feeds, 210

report with break line, 210right-justified data, 211

Proc user exit, 201profile

program, 84program

call interface, 223cataloging, 73compiling, 59executing a transaction start within, 294profile, 84stopping with ABORT, 49UniBasic called from C, 235writing, 147

program control, 29, 49programming in UniBasic, 51PROMPT, 206PWR

null value and, 303numeric function, 164

QQ, quitting AE, 56

Rrandom integer, returning, 164range, locating data in array, 158READ, 114READBCK, 110READBCKL, 110READBCKU, 110READFWD, 110READFWDL, 110READFWDU, 111

Developing UniBasic Applications 421

Page 422: Basd_52

Index

readingnamed pipe, 330records, commands for, 119unopened files, 129

READSEQ, 113READT, 212Reality® Basic, 62record

lock, 133, 137selecting, 116

record ID list, 116record mark, 24RECORDLOCKED, 137recoverable file system

see also transaction processingCPIO format, 290creating or converting a file, 290introduction, 279operation limitations, 294

RECOVERABLE keyword, 290RedBack, 323relational operator, 45relational operators

null value and, 302remainder, 164REMOVE, 158, 183, 317

command, 183REPEAT, 36REPLACE, 316replacing

characters in a string, 169string value, 168

RESIZEtransaction processing and, 294

RESIZET, 212RETURN

in internal subroutines, 31

introduced, 33program control commands, 50

return codefrom STATUS function, 27

REWIND, 212RND

null value and, 303numeric function, 164

rounding numbers, 171RUN

from ECL, 82running

UniBasic programs, 82runtime version of UniData, 227

SSADD, 303sample program

UniBasic, 387saving

select list, 116scaling numbers, 171SCMP

null value and, 303SDIV

null value and, 303searching

dynamic array or string, 158for data in a string or array, 157

SELECT, 117select list

clearing, 118creating, 116reading records from, 119saving and retrieving, 116

SELECTINDEX, 111, 117

422 Developing UniBasic Applications

Page 423: Basd_52

Index

selectingrecords, 116

SEQ, 183and null value, 315character conversion, 168

SEQS, 183null value and, 316

sequential fileclosing, 337commands for maintaining, 112

SETINDEX, 111, 301null value and, 321

SETTAPE, 212setting

uninitialized variables, 84shared lock, 134significance, 160SIN, 164

null value and, 303SMUL

null value and, 303sorting

null value, 301SOUNDEX, 169

null value and, 316SPACE, 317space

removing from a string, 169SPACES, 317SPLICE

null value and, 317SPOOLHELP, 58SQRT, 164

null value and, 303square root, 164SSUB

null value and, 303

stackclearing, 193data, 191

startingtransaction within a subroutine, 294

statementconditional, 38label, 32layout, 19multiline, 20multiple, 19nested, 21

STATUSnamed pipes and, 339RECORDLOCKED, 137return value for nulls, 313TRANSACTION COMMIT, 286TRANSACTION START, 284values returned from triggers, 105

STOPprogram control commands, 50

STR, 317string

converting, 168converting data in, 168counting substrings in, 156determining length, 156extracting a substring, 157left justifying, 169locating in array, 157, 158replacing value, 168value as constant, 25

string functionnull value and, 302, 315

STRSnull value and, 317

structured programming style, 29

Developing UniBasic Applications 423

Page 424: Basd_52

Index

subroutineCallBasic, 241, 269executing a transaction start within, 294program control commands, 49types, 31writing trigger, 99

substringconverting, 169locating in array, 157occurrence in array elements, 156

SUBSTRINGS, 183, 317subtraction, 159

operator precedence, 46subvalue mark, 24

delimiters, 150SUM, 164SUPERCLEAR.LOCKS, 136suppressing

double spacing, 210zero, 171

SWAP, 183SYSTEM, 317system information, 27system time and date, 176

TT.ATT, 212TAN, 165

null value and, 303tape drive commands, 212terminal

beeping for locked record, 135display commands, 205

testing for active transaction, 288testing for null value, 315text mark, 24, 150

THENTRANSACTION COMMIT, 285

tilde, converting nonprinting characters to, 169time

converting and formatting, 175reporting program execution, 84

transactionnested, in transaction processing, 283, 293

TRANSACTION ABORTintroduction, 287locks, 135

TRANSACTION COMMITinappropriate, 282locks, 135STATUS values, 286

transaction processing, 397atomicity, 399break key in, 287called programs and subroutines, 294consistency, 399defining isolation levels, 404dirty reads, 402durability, 400EXECUTE and, 294file-level operations, 294introduction, 282isolation, 399limitations, 294lost update, 401programming example, 289programming problems, 293report generator, 294screen generator, 294TRANSACTION ABORT, 287udfile, 291UDT.OPTIONS 35, 294UniData SQL, 294

424 Developing UniBasic Applications

Page 425: Basd_52

Index

unrepeatable reads, 403with nonrecoverable files, 408

TRANSACTION STARTwithin a subroutine, 294

triggerdefined, 96return value, 100STATUS return values, 105troubleshooting, 106writing UniBasic subroutines, 99, 102

TRIM, 169, 317TRIMB, 169, 317TRIMF, 169, 317TRIMS, 317troubleshooting

processing named pipes, 341transaction processing, 293

UU lock, 133U.S. date format, 176U_callbas, 241, 269, 275U_done, 221, 265U_errout, 220, 265U_PHANTOM, 241, 269U_preprint, 220, 265U_REDIRECT, 241, 269udfile, 291UDT.OPTIONS 12, 204UDT.OPTIONS 18, 204UDT.OPTIONS 35, 294UDT.OPTIONS 4, 210UDT.OPTIONS 5, 210UDT.OPTIONS 65, 204UDT.OPTIONS 7, 210UDT.OPTIONS 88, 263

udtcallbasic, 271, 275udtcallbasic_done, 243, 272, 275udtcallbasic_init, 268, 275UDTEXECUTE, 196Uni, 181, 182UniBasic, 183

@variables, 27CHANGE, 181CHAR, 181CHARS, 181COL1, 181CONVERT command, 181COUNT, 181COUNTS, 182DCOUNT, 182features and program components, 15FIELD, 182FINDSTR, 182GET, 182ICONV, 182INDEX, 182INPUT, 182INPUT @, 182LEN, 182LENS, 182MATCH, 182MATCHFIELD, 182OCONV, 182SEQ, 183SEQS, 183subroutine, U_callbas function, 241, 269SUBSTRINGS, 183SWAP, 183

UniDatalocking system, 133runtime version, 227

UniData SQL

Developing UniBasic Applications 425

Page 426: Basd_52

Index

executing from UniBasic, 197executing in transaction processing, 294

UniData.LIB, 259, 274UniQuery

user exits, 200unknown values, representing, 300UNLOCK, 136unrepeatable read, 403unrepeatable reads, 142UPCASE, 169

null value and, 316UPDATE

trigger, 99update

see also WRITEUPDATE_ORDER, UniBasic program, 387upper case

converting to, 169user exit

writing, 199user number

for locked records, 137using

UniBasic, sample program for, 387

Vvalidating

database changes, 96value

integer, 164mark, 150

value mark, 24variable

@variables in UniBasic, 27converting, 168defined, 25

naming in C function, 219naming in external function, 264naming in UniBasic, 25numeric, 44testing for null value, 316, 318uninitialized, setting, 84

VCATALOG, 74virtual attribute, 195VOC file

CALLC requirements, 266E type entry, 266

Wweb application development, 323WEOF, 212WEOFSEQ, 113WRITE

commands, 119non-UniData files, 114triggers, 98

WRITEONLY, 326WRITESEQ, 113WRITESEQF, 113WRITET, 212writing

C program from UniBasic, 228data to files, 123trigger subroutines, 102UniBasic subroutine in CallBasic, 236, 273user exits, 199

XXLATE, 317XREF, 69

426 Developing UniBasic Applications

Page 427: Basd_52

Index

Zzero, suppressing, 171

Developing UniBasic Applications 427

Page 428: Basd_52

Index

428 Developing UniBasic Applications