Every now and then we'll add a Progress« 4GL code snippet or sample program here. You can use our stuff, but please don't remove the copyright notice.


Dump/export a complete Progress« database

This program dumps all table contents to text files. [Shrink]

Get the absolute OS path

This routine returns the temp directory or converts relative paths to absolute OS paths. [Shrink]

Get a unique file name

This routine creates a unique file name. Properly implemented, the file name is unique across all computers on this planet. [Shrink]

Convert special characters to lower ASCII strings

This routine converts special characters like '─' or 'Ă' to lower ASCII strings like 'Ae'. [Shrink]

Create a UUID (Unified Unique IDentifier)

This routine creates UUIDs. Use it to assign unique values to primary keys, message IDs, file names or whatever. [Shrink]

Dump/export a complete Progress« database


This program dumps all table contents to text files. It's meant to export data when you need special delimiters and do not plan to reload the data into another Progress« database. If you can live with comma delimited export files, better use the Progress« Data Administration tool. I wrote it with Progress 9.1E, but it should run with earlier versions too.

1. Download the source code: dump-progress-database.zip

2. Edit config.i:

     cDbName         = "sports":U
     cDbFile         = "c:/cl/test/sports/db/sports.db":U
     cDbConnectString = "-1":U
     cProgDir         = "c:/cl/test/sports/db/temp/":U
     cDumpDir         = "c:/cl/test/sports/db/dump/":U
     cDumpExt         = ".txt":U
     cDelimiter     = ",":U

cDbName is the logical database name.
cDbFile is the database location.
cDbConnectString is populated with all connect parameters except ldb.
cProgDir is the directory used for generated source code.
cDumpDir is the target directory for data files.
cDumpExt is the extension used in data file names.
cDelimiter is a single character used as delimiter like '|', ';' or '~t' (TAB), default is comma.

3. Create the directories, then run dumpDB.p and wait.

dumpDB.p connects to the database and calls dumpTables.p. dumpTables.p loops for all application tables in the database schema, creates a dump program in cProgDir and writes the table contents to cDumpDir.

Get the absolute OS path


getOsPath.p returns a fully qualified path including a trailing slash or backslash, depending on the operating system. It can return UNC1 paths, but don't use UNC paths in Windows« .cmd/.bat files or with Windows« command line utilities, because those won't handle them properly.

def var cWhat as char no-undo.                    
def var cPath as char no-undo.
run getOsPath.p(
        input cWhat,    /*
WorkDir         : Progress current directory
TempDir         : OS tempDir
AppTempDir     á: Progress tempDir
A relative path : relative path like "tools" "tools/temp" or "./tools"
        output cPath). /* ? on failure || OS-Path incl. trailing slash */

RUN getOsPath.p(input 'TempDir':U, output cPath). /* returns the tmpDir */

RUN getOsPath.p(input 'WorkDir':U, output cPath). /* returns the working directory of the current session */

RUN getOsPath.p(input 'tools/filesystem':U, output cPath). /* returns a fully qualified path like //server/.../progress/wrk/tools/filesystem/ */



Universal/Uniform Naming Convention

Get a unique file name


getUniqueFileName.p returns a unique file name with fully qualified path.

DEF var cExtension AS CHAR NO-UNDO. /* .txt .wmf .bmp ....*/
DEF var cTargetPath AS CHAR init ? NO-UNDO. /* ?=tempDir or relative path from workdir like /globtools */
DEF var cUniqueFileName AS CHAR INIT ? NO-UNDO. /* ? on error, see return value */
RUN getUniqueFileName.p(
    INPUT cExtension,
    INPUT cTargetPath,
    OUTPUT cUniqueFileName).

Download getUniqueFileName.p. getUniqueFileName.p calls other routines, you should download ">getOsPath.p and getUUID.p too.

Convert special characters to lower ASCII strings


Dealing with legacy systems, you need to convert your data all day long. For example, if you have to print UPS labels and send data to UPS via the PLD 0200 interface, you must not use any special characters you have within your international address data. This routine converts these characters to their best1 lower ASCII representation. For example '─' and 'Ă' get converted to 'Ae'. Usage:

ASSIGN cAnsiString = '─ń'.
RUN makeCleanAsciiString.p (INPUT cAnsiString, OUTPUT cAsciiString).
MESSAGE cAnsiString '==>' cAsciiString VIEW-AS ALERT-BOX.

Result: '─ń==>Aeae'



I'm by no means an expert on european languages. If you can improve my character conversions, please drop me a message using the contact link on this page.

Create a UUID (Unified Unique IDentifier)


UUID definition: A UUID is an identifier that is unique across both space and time1, with respect to the space of all UUIDs. A UUID can be used for multiple purposes, from tagging objects with an extremely short lifetime, to reliably identifying very persistent objects across a network.

Unfortunately, Progress« does not provide a build-in UUID generator. In DLC/bin you'll find genuuid, which uses a Java class to produce non-standard identifiers. You can't use genuuid to create unique primary key values, because this thing is incredible slow and the globally uniqueness is not guaranteed (KB#21175).

To populate primary keys, you could use sequence values instead of UUIDs, but there are disadvantages:
A Progress« sequence can produce 4 billion unique IDs, that is not enough if you need enterprise-wide unique object identifiers (OIDs).
Using integers to identify objects on the web (forms, links ...) enables hackers and bored users to update more stuff than they should have access to.
If you extend an environment where sequence values are used to identify tuples in tables, for example when you exchange data with vendors and customers, the (local) uniqueness is lost and you need to implement additional IDs.

Besides feeding of unique keys you can use UUIDs in file names, as instance identifier of transient objects, message identifier ...

getUUID.p is meant as a template demonstrating how UUIDs can be handled with Progress« 4GL. You can use getUUID.p to build a centralized UUID generator supplying unique IDs to all your databases, or within a session running as super procedure.

getUUID.p can supply Windows« GUIDs using either UuidCreate or UuidCreateSequential in rpcrt4.dll. It creates 'faked' UUIDs which should be unique when GUID creation fails. With 'faked' UUIDs you can pass strings like MAC addresses or table prefixes to replace the node part of the UUID. On UNIX boxes search for /usr/bin/uuidgen or another UUID generator and customize the internal procedure getUnixUUID.


def var cUUID as char no-undo.                    
def var lGUID as log init false no-undo.
def var cConstantNode as char init ? no-undo.
def var cMode as char init "String":U no-undo.
RUN getUUID.p(
        INPUT cMode,         /* String or Binary */
        INPUT lGUID,         /* create GUID yes/no */
        INPUT cConstantNode, /* replace the node part, ?=no */    
        OUTPUT cUUID).



To be precise, the UUID consists of a finite bit space. Thus the time value used for constructing a UUID is limited and will roll over in the future (approximately at A.D. 3400)

Author: Sebastian
Last Update: Friday, March 25, 2005   Web Feed

· Home

· Development

· P4GL Code

· Web Links

· Link to us

· Contact

· What's new

· Site map

· Get Help

Most popular:

· Site Feeds

· Database Design Guide

· Google Sitemaps

· smartDataPump

· Spider Support

· How To Link Properly

Free Tools:

· Sitemap Validator

· Simple Sitemaps

· Spider Spoofer

· Ad & Click Tracking

Search Google
Web Site

Add to My Yahoo!
Syndicate our Content via RSS FeedSyndicate our Content via RSS Feed

To eliminate unwanted email from ALL sources use SpamArrest!

Digg this · Add to del.icio.us · Add to Furl · We Can Help You!

Home · Categories · Articles & Tutorials · Syndicated News, Blogs & Knowledge Bases · Web Log Archives

Top of page

No Ads

Copyright © 2004, 2005 by Smart IT Consulting · Reprinting except quotes along with a link to this site is prohibited · Contact · Privacy