|
|
![]() |
||
![]() |
|||
| Version
www.capesoft.com |
|
||
| Contents | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Driver | Pros | Cons |
| BTrieve | Limited to a 4K record size, Does not return helpful error information for FM3. | |
| Clarion | Free | Prone to corrupt, unbuilt keys and data files. |
| Topspeed | Free, Good Performance | Prone to corrupt files. |
| MsSQL | Good performance, Stored Procedures and Triggers, Good name, Tried and tested | Fairly Expensive, Regular security patches |
| Oracle | Good performance, Stored Procedures and Triggers, Good name | Very Expensive, Needs a qualified DBA, i.e. a bit difficult for the untrained to manage. |
| MySQL | Good performance | Not Free |
| Firebird | Good Performance, Optionally Embedded, Stored Procedures and Triggers, Free | Key size limitation of 254K under default characterset, Keys cannot have mixed sort orders, but this can be easily worked around. |
| Sybase/ASA | Good performance, Stored Procedures and Triggers, Good name, Tried and tested | Fairly Expensive (although cheaper than MSS) |
| PostgreSQL | Good performance, Stored Procedures and Triggers, Free | Text based variables don't handle non-printable characters. Requires binary strings to be set to BINARY in the dct. |
You need to turn this dictionary key option off for all your unique keys. This is good practice in flat-files as well.
This option in the dictionary editor is such a bad idea. Seriously. It causes so much heartache when converting TPS data to SQL. In SQL nullability is on the _field_ not the key. In tps, blank fields (no such thing as null in TPS) are excluded from the key table (which is like a separate file within the tps file). In SQL, there is no option to exclude elements of a key from that key if they are blank or null. So nulls/blanks are included in the key. If it is a single element key, then you can only have one null and one blank (or zero - not the same as null in SQL) value in a key.
So when you come to exporting your data into SQL, you need to either: Make the key non-unique, or remove records that cause a duplicate key error (preferably before exporting to SQL). The easiest way is to make the key non-unique - as there are essentially (because of that confounded "Exclude Empty Keys" switch in the dct) duplicates in the key - although these "duplicates" were permitted in TPS.
In the clarion dct, case-senstivity is defined in the key - but (depending on the default collation of your SQL database) - sort orders are on the field. This is called the field collation. In order to maintain an efficient sort order (or to maintain uniqueness across a key that is case sensitive) you need to tell FM3 which fields you need to collate in case-sensitive order. See the CaseSensitive field user option in the main FM3 docs for details on how to do this.
| Customers | file,pre(CUS),driver('MSSQL') | ||||
| PK_Customers | key(CustomerID),primary,nocase | ||||
| FK_Countries | key(CountryID),nocase | ! Links to Countries PK_Countries | |||
| record | record | ||||
| CustomerID | long | ||||
| CountryID | long | ||||
| LastName | string(40) | ||||
| FirstName | string(60) | ||||
| end | |||||
| end | |||||
| Countries | file,pre(COU),driver('MSSQL') | ||||
| PK_Countries | key(CountryID),primary,nocase | ! Links to Customers FK_Countries | |||
| record | record | ||||
| CountryID | long | ||||
| Country | string(100) | ||||
| end | |||||
| end | |||||
You don't need to worry about this next bit as it's now taken care of in the DLL - unless you don't want your application to use a sysadmin login. If you don't want your application to use SysAdmin rights, then you must create the linked server manually, and then login with a user with dbOwner rights.
For
complete automation of FM3 administration, the user should also be a member
of the SysAdmin role (MsSQL). This is, however, not necessary if you can
create the linkedserver manually as follows:
| FM3 needs to perform administrative tasks on the SQL backend. It therefore needs some level of administration rights. These rights can be limited to dbowner by completing the following configuration of the MsSQL Server. Two tasks must be completed on your MsSQL Server for FM3 to continue it's job. The server must be a linked server, and the server option DATA ACCESS must be set to true. |
Dates and Times
Memos
Reals
Arrays (Dimensioned fields)
Dynamic and Static Indexes
Oracle DataType Matching
Large String Data
MSSQL - UniqueIdentifier
Binary strings (see the PostgreSQL section of the docs)
MSSQL users: You'll only need to use this option if you find yourself in one (or more) of the following situations:
| Example Field Name | Data Type | UserOption to add | ||
| MyDateTime | string(8) | UnRealField | ||
| MyDateTime_Group | group,over(MyDateTime) | |||
| MyDateTime_Date | date | RealField | ||
| MyDateTime_Time | time | RealField | ||
| end | ||||
| MyDateTime | datetime |
Option
2: Use a DATE and a TIME datatype.
In MSSQL 2005 and up (have not tested all backends), you may match a DATE to a DATETIME,
and a TIME to a DATETIME. For DATE, it is happy to leave the time portion
= 0, but in TIME, the date portion defaults to today's date. This will
not make keys and indexes very useful! Other applications accessing your
data will also need some explanation.
Code example:
CLARION:
| MyDate | date | |
| MyTime | time |
| MyDate | datetime | |
| MyTime | datetime |
Important Note: This option should only be used for DATEs, not TIMEs. If used for TIME (without the DATE portion) - you will be plagued with the "Another user updated this record" error. If you have single TIMEs then rather create the group, over and an extra DATE field. You can then initialize the DATE portion to 0 so that all your local indexes (using the TIME field) will be consistent. This is not an FM3 issue, but a Clarion limitation.
Option
3: Use a LONG datatype.
Well, every Clarion programmer will jump for joy at this idea, ... BUT, is it
really a good solution? Well, you would have to analyse the situation completely,
and especially think of what may come up in the future! For example, if
you are building an app that uses it's own database, and no other frontend
apps or tools look at it, or care what's in it, then you have no problem.
But, what about those "likely-to-happen" scenarios, like building
a dynamic website from the data, or an intranet? Of course, if you're in
charge of it all you can build those with Clarion, and you have no problems!
But, if a VB guy ever came along and needed to use the data for his application,
oh boy - I guess at this point you could start a "Why Clarion is the
best RDA tool" argument! Otherwise, if you, and only you (or any other
Clarion programmer) are going to be using the data - joy joy and more joy
- keys are a breeze, date calculations are a breeze, formatting display
is a breeze, and it's only 4 bytes of data each! <sigh>I love Clarion!</sigh>
Code
example:
CLARION:
| MyDate | long | |
| MyTime | llong |
| MyDate/font> | int | |
| MyTime | int |
| MyDate | string(8) | ! or cstring(9) | |
| MyTime | string(6) | ! or cstring(7) |
| MyDate | char(8) | /* or varchar(8) */ | |
| MyTime | char(6) | /* or varchar(6) */ |
Either:
Or:
Convert all your MEMOs to STRINGs or CSTRINGs.| MyDim_Group | group | |||
| MyDim_1 | string(20) | |||
| MyDim_2 | string(20) | |||
| MyDim_3 | string(20) | |||
| MyDim | string(20),dim(3),over(MyDim_Group) | |||
| MyDim_1 | char(20) | ||
| MyDim_2 | char(20) | ||
| MyDim_3 | char(20) |
| Number(1) | byte | ||
| Number(2) | byte | ||
| Number(3) | short | ||
| Number(4) | short | ||
| Number(5) | long | ||
| Number(6) | long | ||
| Number(7) | long | ||
| Number(8) | long | ||
| Number(9) | long | ||
| Number(10) | pdecimal(11) | ||
| Number(11) | pdecimal(11) | ||
| Number(12) | pdecimal(13) |
| byte | number(3) | ||
| short | number(5) | ||
| long | number(10) | ||
| pdecimal(x) | number(x) | ||
| pdecimal(x,y) | number(x,y) |
| MyLargeString | cstring(10000) |
| MyLargeString | text | (mssql) | |
| MyLargeString | clob | (oracle) |
1. Your field must be a cstring 37 in your dictionary.
2. You need to enter the following in your user options for the ROWGUID field:
| ForceSQLDataType | uniqueidentifier ROWGUIDCOL NOT NULL DEFAULT NewID() |
| ForceSQLDataType | uniqueidentifier NULL ROWGUIDCOL DEFAULT NewID() |
3. You need to add the | READONLY attribute to the field's external name in the dictionary. If you do not do this, you will get a 22005 error when inserting a record into the SQL table.
NOTE: You must use a fully qualified external name as well as the READONLY attribute. You cannot simply add the | READONLY attribute to the external name field by itself. This will result in an error 47 when trying to use the file. You will then by unable to rename the ROWGUID field, as a ROWGUID field is not permitted to be altered.
In TPS files, all string data is stored as binary data. Each byte can contain any value from 0 to 255. In SQL though, all datatypes can be catagorized into either binary or text type data types. This means that strings can be correlated to chars 95% of the time, as they will contain valid text data (like addresses, names, descriptions, etc). However, in flat-files, strings can also be used to contain binary data (non-printable characters) – which makes them non-compatible with text based data types. Where strings are used in TPS files for storing binary data, these fields must be converted to binary based variable type in order to allow the SQL backend to store this data correctly.
You need to identify each variable that contains binary data and force the data type to convert to binary. On the Field User Options for those fields, enter:
ForceSQLDataType binary
A Caveat with this approach: Clarion does not handle binary data in browses very well. An alternative approach to this (depending on your backend - PostgreSQL supports this) - is to use a larger stringsize in your dictionary, because PostgreSQL will store non-printable characters in a text datatype using more than one byte (up to 3 bytes for some characters). If you have a string(20) in your dictionary, then restrict the data entry to 20, bump the size up to 60 and this will be a better working solution in PostgreSQL.Note: GUIDs will be handled later on – so leave these as they are at this stage.
This is normally not necessary (with FM3), as your file will not error 47 if
there are extra fields or fields with longer dimensions (like if you change a
string(200) to a string(100)) - but some folks like to keep it this way. The
downside with this is that if other parties use the database (or the clients
build in server side triggers for reporting or whatever) then those fields will
be used, and when you no longer need those fields and delete them from your dct,
then FM3 will delete them - making other applications not work (because the
fields have disappeared).
The difference with SQL as apposed to Topspeed, is that in Topspeed your
file structure in your dct had to match the file structure in the db otherwise
Error47. Extra fields are a no-no, different length fields, etc. But this rule
falls away with SQL as you can have fields on the backend that aren't in your
dct and your program will happily open them without knowing the difference (as
to whether they are there are not). The question you should be asking is Why do
I want DctMasterFields on, rather than why do I want it off. Obviously you
need the fields in the backend that are declared in your dictionary.
| Property | Value | |
| DctMasterFields | 1 |
For more information on how to use User Options in FM3, see the Dictionary User Option Reference.
Note: Even if you have set the DctMasterFields, FM3 will only do structure changes on the datatables if there is an error opening the tables. This means that if other fields are added to the backend, these won't be deleted, unless FM3 detects an error. If you would like to enforce a structure change, then on the FM3 connect window (at runtime), you can check the Force FM3 Full Data Structure Comparison checkbox.
| Property | Value | |
| DCTMasterKeys | 1 |
Note: Even if you have set the DCTMasterKeys, FM3 will only do structure changes on the datatables if there is an error opening the tables. This means that if other keys are added to the backend, these won't be deleted, unless FM3 detects an error. If you would like to enforce a structure change, then on the FM3 connect window (at runtime), you can check the Force FM3 Full Data Structure Comparison checkbox.
Note: For MSSQL backends - there is an issue with MSSQL2000, whereby it struggles to create statistics on large table structures (of a few hundred columns/fields). In this case, FM3 could struggle to create indices on the backend, which will result in only primary and unique keys being created (instead of all the indices, if DCTMasterKeys is set). Here's a note from Developer.* Blogs:
The scenario is that you have a gigantic SQL Server 2000 table--gigantic not necessarily because it has a lot of rows, but gigantic because it has a ton of columns. I've inherited a couple tables like this on different projects, tables with two or three hundred columns. (Don't look at me, I didn't create these tables.)
It's not uncommon to need to add a new index to these kinds of ridiculous tables to cover a query. So you go to try and add your new index and you get an error like this:
Cannot create more than 249 nonclustered indices or column statistics on one table.
You may be frustrated by this initially because you know for a fact that there are not 249 indices on this table (or maybe you do...but you've got bigger problems in that case). What's really blocking you, though, are not too many indices, but too many auto-computed statistics, which are like temporary indices created by SQL Server for columns that don't have indices. What you have to do to add your new index is get rid of one of these auto statistics. Here's how to do that:
For some reason, the "Manage Statistics" dialog box is in SQL Query Analyzer, not Enterprise Manager. Go to the Tools menu in Query Analyzer and choose Manage Statistics. Choose the database and the table, then scroll down to select a "statistic" from the list for a column you don't care about (that is, one that is seldom or never used in a WHERE clause). Use the Delete button to delete it.
Now try adding your new index again. It should work.
Note: one step in the above instructions that I may have skipped is to go to the Properties dialog for the database in Enterprise Manager and turn off Auto Compute Statistics and Auto Create Statistics. When I solved this for myself, I had turned these off, and then I turned them back on after I deleted a statistic and added the new index.
Solution for SQL Server Cannot create more than N nonclustered indices Error developer. Blogs
Note: PostgreSQL users, check out the section: PostgreSQL - Decrementing Indices
| Ensure that the owner variable that the file is set to use in the dictionary (or in your Multi-Proj Driver Substitution setup) is exactly the same as that set in the FM3 SQL_Connect control template. |
Before
changing your dictionary, follow the steps laid out in the
Adding FM3 to your Application section.
Compile
and run your TPS driven FM3 enabled program.
Now
the UPG.tps file exists, containing valid file structures for each file.
Send
out this update to all your clients to allow each client to build a upg.tps file.
If you have already been using FM2/3 in your application, or have completed the steps above, then a upg.tps file should already exist, and you can follow these instructions.
Make
your dictionary SQL compliant (see the Clarion / SQL Fundamentals
and SQL Data Types sections of this document).
Compile and run your application (you will need to ship this exe to your
clients, so that the TPS data is at the latest version before upgrading to SQL).
Either:
Generally
the best approach is to use Multi-Proj's driver substitution feature to use
the same application and dictionary - with multiple exe outputs to support
different database types. In this way you can keep supporting your TPS
application without leaving your TPS clients in the cold.
Or:
Alternatively,
in the Dictionary editor, change the driver to the relevant SQL driver - or you can
use the Bulk Dictionary Editor (BDE) to change the whole dictionary over.
Set
the Owner attribute with either your connection string, or a string variable. Read
about SQL Owner Strings.
Set
the Full Path Name for SQL (e.g.: owner.myfilename). Read about
SQL TableNames.
On
the Options tab, add the string user option OldName.
Increase
the Version Number (if using BDE - this will be done automatically)
Continued for both options:
If your
TPS file was encrypted with an owner string, then you need to use the
OldOwner user option to migrate the data to the SQL backend
If
you have had FM2 applied, follow these steps to Convert to FM3.
On
the Global Extension, select the SQL driver, and leave the the previously used
driver(s) also checked.
Run the 'Import the SQL Connect procedure'
template utility. You'll need
to set the Global Owner variable in the SQL_Connect window's "Connect To
SQL Backend" Control Template prompts. To do this, double click on the
SQL_Connect window and click on the "Connect To SQL Backend" control
template to bring up the prompts and enter the Global Owner variable in the
field provided on the General tab.
In your
FM3 global extension template, on the Auto Up tab, set the "SQL Connect
procedure" to 'SQL_Connect' (i.e. the new procedure that the template
utility just created).
Compile
and run your application.
| Driver | SQL Owner string | Example |
| MSSQL | Server, DatabaseName, UserName, Password | CRUNCHIE, CapeSoftDB, Scott, Tiger |
| SQL Express | Machine\Server, DatabaseName, UserName, Password | CRUNCHIE\CRUNCHIE, CapeSoftDB, Scott, Tiger |
| Oracle | UserName/Password@Protocol:DatabaseName | Scott/Tiger@2:CapeSoftDB |
| UserName@Protocol:DatabaseName,Password | Scott@2:CapeSoftDB,Tiger | |
| MySQL | DSN, UserName, Password (See DSN-less Connections below) | MyDSN,Scott,Tiger |
| Firebird | DSN, USERNAME, Password (See DSN-less Connections below) | MyDSN,SCOTT,Tiger (note UPPERCASE) |
| Sybase/ ASA | DatabaseName,UserName,Password;ENG=Server;tcpip={host=111.222.333.444:5555} | CapeSoftDB,Scott,Tiger;ENG=CapeSoftDB;TCPIP={host=127.0.0.1:49152} |
| PostgreSQL | DSN, UserName, Password (See DSN-less Connections below) | MyDSN,Scott,Tiger |
| Driver | Table name | Example |
| MsSQL | TableOwner.TableName | dbo.Customers |
| Oracle | UserName.TableName | Scott.Customers |
| Oracle XPress (10g) | TableName | Customers |
| MySQL | DatabaseName.TableName | CapeSoftDB.Customers |
| Firebird | TABLENAME (Case-sensitive - UPPERCASE recommended) | CUSTOMERS |
| Sybase / ASA | UserName.TableName | Scott.Customers |
| PostgreSQL | SchemaName.TableName | public.customers |
Check out the HotTips section for more Database specific topics.
| 1. | Start > Settings > Control Panel. |
| 2. | Administrative Tools. (2K, XP, 2003, Vista) |
| 3. | Double click on ODBC Data Sources. |
| 4. | Select the System tab. |

| 5. | Click on Add. |
| 6. | Select the driver you wish to use, and click Finish. |
| 7. | Type in a descriptive name eg: 'MyApp_dsn' , and follow the prompts for setting up your driver's DSN. |
DRIVER=SQL Server;SERVER=SQLBox;UID=Bill;PWD=micro$oft;DATABASE=Northwind;WSID=BillsWorkStation;APP=Microsoft Open Database Connectivity;
| TableSpace | MyTableSpace,C:\Oracle\OraData\MyTableSpace\MyTableSpace.ora,100M |
Here is an example of the code generated by FM3 to create the TableSpace:
| Create TableSpace "MyTableSpace" Logging Datafile 'MyTableSpace.dbf' Size 50M Extent Management Local |
Please note that the File definition overrides the Dictionary setting. i.e. If
you have a dictionary level TableSpace option set, and you have a file level
TableSpace option, the file level user option will be used for that file.
Please note too, that the directory for the datafile setting must exist!
We have also added the ability to create your indexes and keys in a separate
TableSpace. This is done in much the same way as the TableSpace option, although
this can be set at Key, File and Dictionary level. Again, the Key user option
has higher priority than the file, which has higher priority over the dictionary
level user option.
| IndexSpace | MyTableSpace,C:\Oracle\OraData\MyIndexSpace\MyIndexSpace.ora,100M |
General SQL
MSSQL
Firebird
PostgreSQL
Are you not sure whether you need to use NULLs or not? Check out this article:
http://www.sqlservercentral.com/columnists/mcoles/fourrulesfornulls.asp
In flat files, your application has to handle auto-numbering for your auto-incrementing keys. You can still use this in SQL, but there are some disadvantages to this approach - especially if multiple applications are writing to the database simultaneously.
In order to effectively implement Server-side auto-incrementing, you need to do the following to your table in your dictionary:

| SQL Backend | Driverstring to add |
| PostgreSQL | /AUTOINC='SELECT currval(''schemaname.tablename_fieldname_seq'')' |
| MySQL | /AUTOINC='SELECT LAST_INSERT_ID()' |
| MSSQL |
/AUTOINC=SCOPE_IDENTITY() |
A note for PostgreSQL users:
PostgreSQL handles auto-incrementing differently from other databases. A sequence is not automatically invoked. It is a default constraint which is used only if no value is passed. Clarion (bydefault) passes a value - other SQL backends ignore this value when inserting a record, whereas PostgreSQL will apply this passed value - thus not auto-incrementing the field.
There are 2 ways to handle this:
Call the nextval(Sequence) function before you insert the record, and assign that value to the field. The advantage of this is that you already know what the value is, so in the case of child tables you are set for good.
Make that field readonly in the dictionary, such that the query generator will not pass a value in the insert/update queries.
The first in this section is a MSSQL Stored Procedure for returning Clarion
date and time integer values in MSSQL's datetime datatype. For example,
it is in many ways nicer to store dates and times as a Clarion long (eg:
73838 = Feb 25, 2003 and 5400001 = 15:00), as it makes keys and mathematical
calculations much easier. But, this data would be useless to any non-Clarion
program, unless converted to meaningful data. This is what ds_ConvertClarionDateTime
does. It takes 2 input parameters, 1 output parameter, and a return status.
You can optionally convert on a date value or time value, but must pass
a value of 0 (zero) into the "unwanted" parameter.
Example: (Calling from SQL Query Analyser)
| declare @rs int --
return status declare @cd int -- clarion date - can be a field in a table declare @ct int -- clarion time - can be a field in a table declare @sdt datetime -- sql datetime set @cd = 73842 -- March 1, 2003 - 0 if "blank" set @ct = 5400001 -- 15:00 - 0 if "blank" exec @rs = ds_ConvertClarionDateTime @cd,@ct,@sdt output if @rs = -1 -- Both date and time parameters are zero print 'Zero Date and Time!' if @rs = 1 -- Integer value is greater than valid clarion date print 'Invalid Clarion Date!' if @rs = 2 -- Integer value is greater than valid clarion time print 'Invalid Clarion Time!' select @sdt as 'Returned DateTime' |
Importing a MSSQL database from an LDF and MDF file:
Exporting an MSSQL database to an LDF and MDF file:
If you're struggling with an aspect of FM3 - where FM3 is not maintaining your database correctly, then we could request a database dump - which consists of an MDF file and an LDF file, together with your dictionary and the UPG.tps file that corresponds with that dump. This is how it's done:
Open the SQL Management Studio.
Right-click on the Database that requires exporting and select Properties.
On the Files Properties window make a note of the mdf and ldf files used for the database.
Return to the main window - Right-click the database and select detach from the Tasks menu.
The files that you need to send are the mdf and ldf files indicated in step 3.
This is very simple, but if you don't know the couple of steps, it can be very frustrating.
You cannot do this directly using the Clarion MSSQL Driver, but you can do
this by creating an alias in the MSSQL Client manager. If you want to create a
registry entry in your app you can do with:
PUTREG(REG_LOCAL_MACHINE,'SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo','MyServer','DBMSSOCN,211.68.105.49,2433')
and then you can use the next owner attribute,
'MyServer,<database>,<uid>,<pwd><;LANGUAGE=language><;APP=name><;WSID=name>'
Schemas. At this stage you have to use the default schema 'dbo'.
Note: You cannot use Firebird embedded - because the embedded version requires the use of the fbclient.dll api (not the ODBC driver). FM3 does not support the fbclient.dll api driver.
These notes were created using Firebird v1.5.2 CR1 (which is Firebird version 1.5.2.4634).
There are two websites for the Firebird downloads, but the first is more useful:
You’ll need to download and install three items:
The default username and password is:
Username:
SYSDBA
Password:
masterkey
FM3 requires that you have already created a (blank) database in your SQL backend.
(FM3 will create all the tables and keys* for you, you just need to create the
database).
* Not all keys are created by FM3, just the ones it needs, but you can override this.
Make sure Firebird is running (you can start it from your Control Panel).
Using IB Expert create a database such as the one below (Database | Create Database):

Note:
You must use Dialect 3.
Note: If you are running firebird as
a service, then the file path must be accessible to the service.
After creating the database (or if you have already created it), you can view the
database, with the following registration information:

You’ll then see your Database listed in the IB Expert database list. If you double
click on it, you’ll see the database properties:

Without this DLL your Firebird applications won’t work. After installation you should
find it in your Windows\System32 folder. It’s probably worth shipping a copy
of this DLL with your application.
Firebird Indices (keys) have a limit of 254 characters, depending on the character set,
so it may be less. You may have to shorten some of your keys or fields in order
for Firebird tables to be made.
Each Firebird Index can only contain either all ascending or all descending Key Sort Orders.
Firebird doesn’t like have two unique Indices with the same fields in them. For example
the following are not allowed:
DateKey: Date, Share
ShareKey: Share, Date
You’ll need to either add or remove fields from the keys or make one of the keys non-unique.
In the Connect window:

The char and varchar character types in Postgres are quite rigorous in the use of non-characters used. In Clarion, a string is basically a binary collection of ASCII bytes - which can normally be equated to a char type in Postgres because of the nature of data stored in strings (addresses, names, comments, etc). However, because of the potential that Clarion possesses in the Topspeed driver to store non-printable characters (or binary characters) in strings, this can mean that equating a string to a char in Postgres can have adverse effects - i.e. your TPS data string will not be converted into the Postgres database. This is particularly prevalent in GUIDs (used with Capesoft's Replicate) which will mostly contain binary data.
There're a few ways of working around this issue:
Use the ds_SetMakeGUIDsBinary(1) function before the FM3 init code runs. This will basically ensure that all GUIDs in all your tables will be created as type bytea (or the equivalent of a binary string in Clarion) - without making any changes to your dictionary. This will cater for the use of GUIDs in your dictionary. You only need this for existing applications that used Replicate v2.10 or less at any stage. Applications that only started using Replicate at Replicate version 2.11 or above, are generated with GUIDs that are legal text characters.
Use the | BINARY dictionary switch in the external name (see the dictionary help on External name options) to inform FM3 that this is a binary string and should be created as 'bytea' on the backend, as apposed to the default char type. This will cater for non-GUID fields that contain binary data.
The following characters are unusable in text based datatypes (like chars, varchars, etc) in PostgreSQL:
chr(0) - this is stored as chr(32)
chr(10) - this is stored as chr(13)
Range: chr(128) to chr(255) - these cannot be stored legally (in one byte) - some of these chars are stored in 2 or 3 bytes.
Why does FM3 only support Clarion6 and up? FM3 uses a generated maintenance file to connect to the database and query system tables. There is one for each driver supported (MSS, TPS, ODBC, etc) - the ODBC file is called gODBCFile. The ODBC generated file contains uppercase field names, which are necessary for FireBird support. In Clarion6, the external name is treated as case insensitive - thus ds_field1 is equated to DS_FIELD1, but in Clarion5.5 and below this is not the case. Field names are created as lower case, but when queried, the case is expected as upper, and so the field names don't match (hence error 47). This makes multiple ODBC backend support impossible in previous versions of Clarion.
PostgreSQL does not support decrementing Indices. For more discussion on this topic, please see:
http://archives.postgresql.org/pgsql-general/2002-03/msg00092.php
Turning off the CR/LF conversion (to LF only).
By default, PostgreSQL converts the CR/LF to LF character when inserting and upgrading records. This means that insertions into the database get added with just an LF. However, this can be problematic for fields with existing data (with CR/LF charset) - because the data is read and arrives at your clarion application with the CR/LF charset, but when it is added back, the record is encoded to just the LF and compared to a reget (which has the CR/LF character). This will then be marked as different from the original, and so a "This record was changed by another station. Those changes will now be displayed. Use the Ditto Button or Ctrl+H to recall your changes" error.
In order to bypass this error, you need to turn the CR/LF conversion off in the odbc driver.
If you are connecting via a normal connection (i.e. non-DSN) then you need to add the LFConversion=0 to the driver string (which you can insert on the AutoUp tab).
If you have a dsn connection, then you do this as follows:

What you'll need:
The PosgreSQL server ( http://www.postgresql.org/ftp/ )
A GUI interface to the server like pgAdmin ( http://www.postgresql.org/ftp/pgadmin3/release/ ) or EMS SQL Manager lite ( http://www.sqlmanager.net/ )
The ODBC driver (which you'll install on the client machine). You can get from: http://www.postgresql.org/ftp/odbc/versions/msi/
Some steps to get you going:
Install the server on the database machine (and run it, pretty straight forward)
Setup the accountname details on the server machine database.
On the client machine, install the GUI interface to the server.
The crucial thing is to grant access
on the Server side (for the client). You do this in the pg_hba.conf file
(which is in the C:\Program Files\PostgreSQL\8.1\data directory by
default, or wherever you installed the Server).
You need to put the following line in:
host all all 192.168.2.3/32 trust
for access for your local machine.
It seems like 0
works as a wildcard, so 192.168.2.0/0 would allow the same machine and
others to connect.
If you get a Can't Obtain databases error when running the Client
application, then you've set this up incorrectly.
The first time I did it, I didn't put the /32 in. It's really fussy
about that.
The next crucial thing to do on the server side (for the
client) in granting access to the client, is to modify the
postgresql.conf file to tell PostgreSQL which addresses to allow access
to the server.
Open the postgresql.conf file (which is in the C:\Program Files\PostgreSQL\8.1\data directory by
default, or wherever you installed the Server) with a text editor.
You need to put the following line in:
listen_addresses = '*'
Install the ODBC driver on the Client machine. For FM3 (at the writing of this) you'll need the PostgreSQL Unicode ODBC driver. Make sure that this one is installed when you install the ODBC driver. If you already have a PostgreSQL driver installed (but not the PostgreSQL Unicode driver) - then you'll need to run the upgrade.bat file that is included in the ODBC install zip. Otherwise, you can simply run the msi install file.
It's a good idea to setup a DSN on the client machine to test the connection (the first time you work with PostgreSQL): http://www.sevainc.com/access/PostgreSQL_ODBC_Configuration.html
Note: You may have some issues when connecting to a different machine (i.e. where the Server resides on a different machine to the client application). Anti-virus could be the culprit or your Firewall. The best solution would be to first try and allow the PostgreSQL port - by default 5432 - failing that, to disable the Firewall and/or Anti-Virus temporarily during your test.
If you
haven't already, read this document! To Top ^.
Dan
Pressnell of Toolwares has
written some excellent Articles entitled "The
Better SQL Series". These can
be found on the IceTips site.
ClarionMag is
an excellent resource containing many articles by many Clarion programmers.
Note: This is a paid for subscription based resource.
ClarionFoundry is
also an excellent resource for Clarion Programmers.
And,
one of the best places to find information are the SoftVelocity
newsgroups.
[End of document]