Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RDDADS Problem #354

Open
VarenL opened this issue Apr 2, 2024 · 6 comments
Open

RDDADS Problem #354

VarenL opened this issue Apr 2, 2024 · 6 comments

Comments

@VarenL
Copy link

VarenL commented Apr 2, 2024

Hi,

I have a problem with rddads:

  • ADS server: 12.02 Linux (stmped with NTXPL852 and Polish)
  • client: Linux 12.02
  • database: DBFCDX, OEM, PL852
    With this configuration I cannot save the record correctly if there are national characters in the index key. In ANSI mode (AdsSetCharset(1)), data is written correctly, but the index is corrupted. In OEM mode (AdsSetCharset(2)), data is written and read incorrectly (ADS incorrectly converts characters from ANSI to OEM, according to CP437, not CP852). Everything works fine in OEM mode after modifying the AdsGetValue and AdsPutValue functions in rddads to use the AdsGetFieldRaw and AdsSetFieldRaw functions.
@alcz
Copy link
Contributor

alcz commented Apr 2, 2024

BTW, what's your HB_CdpSelect()?
AdsGet*, AdsPut* ACE API on Windows really do prefer ANSI, maybe they are the same on Linux - but there are no translations active, see rddads.h ADS_USE_OEM_TRANSLATION is only defined on Windows.
Does Linux ADS server have ANSI setting at all?

@VarenL
Copy link
Author

VarenL commented Apr 3, 2024

I am using code page PL852. According to the documentation, the Linux ADS server performs automatic conversion from OEM to ANSI if the table is opened in OEM mode. In the case of the Linux client, code pages stamped in the server (in libadsd.so) are used. I have CP852 and CP1250 sides stamped in, and still the conversion takes place using CP437 and CP1252. In my opinion, this is a bug in ADS that can be bypassed by reading and writing in raw mode.

From ADS documentation:

"· This information applies only to tables opened with the OEM character set type.

When using DBF (ADS_CDX or ADS_NTX) tables with the OEM character set type, Advantage must perform translations between ANSI and OEM character values. If a DBF table is opened with the OEM character set type, then the character data in the table is expected to have OEM values. Advantage converts the values to ANSI before returning it to client applications and performs the reverse conversion when storing data in the tables. The conversions must be done at various times in processing. When reading data, for example, the conversions are performed at the client. When performing SQL operations, some of the conversions must occur at the server.

The Advantage Database Server for Linux has translation tables built into it for converting characters between ANSI and OEM character sets. The existing tables are for converting from OEM character set 437 to the ANSI character set 1252 (the common character sets used in the United States). If you use different character sets, then it is possible you may need different conversion tables. For example, ANSI character 165 (in code page 1252) gets converted to OEM character 190 when using OEM code page 850 and to OEM character 157 when using OEM code page 437.

If you use different code pages, you must stamp the corresponding translation tables into the ADS daemon. The utility stampansioem.exe is provided for this purpose. It must be run from a Windows client. When you run it, provide the adsd binary as the command line parameter. The utility will generate the ANSI/OEM translation tables based on the current operating system settings and stamp those tables into the adds binary.

The Advantage Client Engine for Linux reads the ANSI/OEM translation tables from the server when it connects, so it does not require the tables to be stamped into the client. Win32 clients use the translation functions that are built into the Windows operating systems."

@alcz
Copy link
Contributor

alcz commented Apr 3, 2024

OK, though you seem to miss one information. ACE API functions (as far as i used them and skipping any ...Raw ...UTF8 flavours) always speak ANSI, doesn't matter what the underlying database is. That may need HB_CdpSelect("PLWIN") app(?).

A Windows app speaking OEM internally (may be not common apart from Harbour and Xbase++) to OEM databases on disk encounters double conversion. 1st conv to-ANSI before it reaches ACE lib, 2nd to-OEM before it reaches the disk.

Linux build of Harbour's RDDADS as i pointed before, doesn't have the automatic 1st stage, there goes my speculation.

@VarenL
Copy link
Author

VarenL commented Apr 3, 2024

HB_CdpSelect() does not matter, both PLWIN and PL852 give the same, incorrect results. Sample read:

ADS_ANSI,PLWIN: ŁĄCZNIKÓ - ok
ADS_ANSI,PL852: ŁĄCZNIKÓ - ok
ADS_OEM, PLWIN: ą˝CZNIKa
ADS_OEM, PL852: ą˝CZNIKa
ADS_OEM, PL852, translate from ESMWIN to EN: ŁĄCZNIKa - partly ok

@alcz
Copy link
Contributor

alcz commented Apr 3, 2024

Can you paste here a sample source code for your simple failing tests?
I don't have a Linux ADS installation at hand, but maybe someone else will take a look at this too.

@VarenL
Copy link
Author

VarenL commented Apr 3, 2024

Sample code and table in the attachment.
test.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants