سؤال

There is a problem, the system is written in Clarion 5 came from the past and now it needs to be rewrite in Java.

To do this I need to deal with its current state and how it works.

I'm generate the executable file via Application Generator (\*.APP-> \*.CLW -> \*.EXE, \*.DLL).

But when I run it I get the message:

File(\...\...\DAT.TPS) could not be opened. Error: Path Not Found(3). Press OK to end this application

And then - halt, File Access Error

In what may be the problem? Is it possible in the Clarion 5 IDE to reconfigure the path to the data files?

هل كانت مفيدة؟

المحلول

Generally, Clarion uses a data dictionary (DCT) as the center of persistent data (files) that will be used by the program. There are other ways you can define a table, but since you mentioned you compile from the APP, I'm concluding that your APP is linked to a DCT.

In the DCT you have the declarations for every file your application will use. In the file declaration you can inform both logic and disk file name. The error message says you have a problem in the definition of the disk file name.

The Clarion language separates the logic data structure definition from its disk file. A "file" for a Clarion programm, is a complex data structure, which conforms to the following:

structName          FILE, DRIVER( 'driverType' ), NAME( 'diskFileName' )
key                   KEY( keyName )
index                 INDEX( indexName )
recordName            RECORD
field                   DATATYPE
 .
 .
                      END
                    END

The above is the basic declaration syntax, and a real example would be like:

orders              FILE, DRIVER( 'TopSpeed' ), NAME( 'sales.dat\orders' )
ordersPK              KEY( id ), PRIMARY
customerK             INDEX( customerID )
notes                 MEMO( 4096 )
RECORD                RECORD
id                      LONG
customerID              LONG
datePlaced              DATE
status                  STRING( 1 )
                      END
                    END

orderItems          FILE, DRIVER( 'TopSpeed' ), NAME( 'sales.dat\items' )
itemsPK               KEY( orderID, id ), PRIMARY
RECORD                RECORD
orderID                 LONG
id                      LONG
productID               LONG
quantityOrdered         DECIMAL( 10, 2 )
unitPrice               DECIMAL( 10, 2 )
                      END
                    END

Now, with the above two declarations, I have two logic files that reside in the same disk file. This is a capability offered for some file drivers, like the TopSpeed file driver. It is up to the system designer to decide if, and which files will reside in the same disk file, and I can talk about that on another post, if it is the case.

For now, the problem may be arising from the fact that you probably didn't change the NAME property of the file declaration, and the driver you're using doesn't support multi-file storage.

Here's a revised file definition for the same case above, but targeting a SQL database.

szDBConn            CSTRING( 1024 )               ! //Connection string to DB server

orders              FILE, DRIVER( 'ODBC' ), NAME( 'orders' ), OWNER( szDBconn )
ordersPK              KEY( id ), PRIMARY
customerK             INDEX( customerID )
notes                 MEMO( 4096 ), NAME( 'notes' )
RECORD                RECORD
id                      LONG, NAME( 'id | READONLY' )
customerID              LONG
datePlaced              DATE
status                  STRING( 1 )
                      END
                    END

orderItems          FILE, DRIVER( 'ODBC' ), NAME( 'order_items' ), OWNER( szDBconn )
itemsPK               KEY( orderID, id ), PRIMARY
RECORD                RECORD
orderID                 LONG
id                      LONG
productID               LONG
quantityOrdered         DECIMAL( 10, 2 )
unitPrice               DECIMAL( 10, 2 )
                      END
                    END

Now, if you pay attention, you'll notice the presence of a szDBconn variable declaration, which is referenced at the file declarations. This is necessary to inform the Clarion file driver system what to pass the ODBC manager in order to connect to the dabase. Check Connection Strings for plenty of connection strings examples.

Check the DCT definitions of your files to see if they reflect what the driver expects.

Also, be aware that Clarion does allow mixing different file drivers to be used by the same program. Thus, you can adapt an existing program to use an external data source if needed.

Here is a complete Clarion program to transfer information from an ISAM file to a DBMS.

PROGRAM

MAP
END

INCLUDE( 'equates.clw' )                 ! //Include common definitions

szDBconn              CSTRING( 1024 )

inputFile             FILE, DRIVER( 'dBase3' )
RECORD                  RECORD
id                        LONG
name                      STRING( 50 )
                        END
                      END

outuputFile           FILE, DRIVER( 'ODBC' ), NAME( 'import.newcustomers' ), |
                        OWNER( szDBconn )
RECORD                  RECORD
id                        LONG
name                      STRING( 50 )
backendImportedColumn     STRING( 8 )
imported                  GROUP, OVER( backendImportedColumn )
date                        DATE
time                        TIME
                          END
processed                 CHAR( 1 )
                        END
                      END

CODE

IF NOT EXISTS( COMMAND( 1 ) )
  MESSAGE( 'File ' & COMMAND( 1 ) & ' doesn''t exist' )
  RETURN
END

imputFile{ PROP:Name } = COMMAND( 1 )
OPEN( inputFile, 42h )
IF ERRORCODE()
  MESSAGE( 'Error openning file ' & inputFile{ PROP:Name } )
  RETURN
END

szDBconn = 'Driver={{PostgreSQL ANSI};Server=192.168.0.1;Database=test;' & |
  'Uid=me;Pwd=plaintextpassword'

OPEN( outputFile, 42h )
IF ERRORCODE()
  MESSAGE( 'Error openning import table: ' & FILEERROR() )
  RETURN
END

! // Lets stuff the information thatll be used for every record
outputFile.imported.date = TODAY()
outputFile.imported.time = CLOCK()
outputFile.processed = 'N'

! //arm sequential ISAM file scan
SET( inputFile, 1 )
LOOP UNTIL EOF( inputFile )
  NEXT( inputFile )

  outputFile.id = inputFile.id
  outputFile.name = input.name
  ADD( outputFile )
END

BEEP( BEEP:SystemExclamation )
MESSAGE( 'File importing completed' )

Well, this example program serves only the purpose of showing how the different elements of the program should be used. I didn't use a window to let the user track the progress, and used Clarion's primitives, like ADD(), which work for sure, but inside a loop can represent a drag in performance.

Much better would be to encapsulate the entire reading in a transaction opened with outputFile{ PROP:SQ } = 'BEGIN TRANSACTION' and at the end, issue a outputFile{ PROP:SQL } = 'COMMIT'.

Yes, trhough the PROP:SQL one can issue ANY command accepted by the server, including a DROP DATABASE, so it is very powerful. Use with care.

Gustavo

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top