Reviving DatabaseLayer

Talk here about issues with one of the components hosted at wxCode, or suggest features for it.
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

I nearly forgot that the TDS code also needs to link libTDS.lib.

I decided early on that wxDatabase should use an implementation of TDS common to both Windows and Linux.

I've attached my copy of the freetds-0.91 source (NB: I had to remove the "doc" folder to be under the upload limit).

I've added VC++ 2008 and VC++ 2010 solutions and projects to the win32/msvc6 folder.
Attachments
freetds-0.91.rar
(1.5 MiB) Downloaded 185 times
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 340
Joined: Mon Oct 06, 2008 12:55 pm

Re: Reviving DatabaseLayer

Post by samsam598 »

Sorry for my stepping in~~

May I ask whether it works on the situation that I posted here before,regarding Asian/Chinese font or character sets or code page whatever caused the problem I mentioned before.I am really eager to know and find a solution.In my previuse post,I mentioned that either Chinese record been inserted back to MS Access is not recoganizable,or the modification version won't pass the unit test,no complete solution yet.

I did tried the library you've uploaded here,but when encountered my situation,new record is not recognizable in Access.

Regards,
Sam
Regards,
Sam
-------------------------------------------------------------------
Windows 10 64bit
VS Community 2019
msys2-mingw13.2.0 C::B character set: UTF-8/GBK(Chinese)
wxWidgets 3.3/3.2.4 Unicode Mono Static gcc static build
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: Reviving DatabaseLayer

Post by evstevemd »

manyleaves wrote:Hi evstevmd

Not quite sure I understand your last post. "I'm now working with wxDatabase" and "I do not use it at all" seem contradictory!
Niche! You catch me!
I was all shouting about ODBC, Seeing that I have Dropped TDS.
manyleaves wrote:Anyway, yesterday I downloaded your latest wxDatabase and merged my TDS and ODBC fixes and all the tests back into your code. In what I've put together we have MySql, PostGreSQL, Sqlite3, ODBC and TDS. I've run the tests for ODBC and TDS and they both pass all 65.

As I mentioned in an earlier post, I'm exclusively a VC++ developer on Windows so I've also added VC++ 2008 and VC++ 2010 solutions and projects to the code.

I organise my development code a little closer still to (to what I think is) the wxWidgets standard; so to fit in with my other code (particularly wxDatabaseConfig) I have to restructure wxDatabase further again. I will upload the restructured code shortly.
Cool! Its sounds great.
I exclusively work with SQLite, MySQL and PGS so thats the reason ODBC was a burden to me.
I will be happy if you will take maintainance of the two. I have roughly added one new method in API, which gets array of primary key columns (I needed it) and I was planning to revamp the code to release version 1 so I will wait your restructuring so that I merge it with my code and release it!

Again thanks for your code and sorry for contradiction!
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

samsam598

It's a long time since I used ODBC to connect to MS Access ... however I have connected to MS Access via TDS using the OPENROWSET function

SELECT * From OpenRowset
(
'Microsoft.Jet.OLEDB.4.0',
';Database=c:\windows\temp\whatever.mdb;',
'SELECT * from table1'
)

but this will need at least SQL Server Express Edition installed on the calling machine. Not sure if this is possible in your situation.

I will have a look at your asian character issue when I can find the time ... what version of MS Access are you using and what OS is this all running on?

estevemd

I saw your PK addition and I added support for it in TDS. I've also added

Code: Select all

static wxDatabase* GetDatabase(wxConfigBase& config, const wxString& warning)
in the restructured code that returns the correct type of wxDatabase* based on the contents of the config. The reason for this is that it saves having to propogate all the specific #includes in the consuming code.

I'm testing my restructured code right now and it fits in well with the other projects especially wxDatabaseConfig. All I need to do now is to merge the old tests into some sort of "sample".

I have a further extension to wxDatabaseConfig in one of my other projects "composite" which supports a concept similar to #include within config files so you chain them eg you can install a simple wxFileConfig that includes the wxDatabaseConfig. This is useful if you have many clients pointing to a single config on a server.

Andrew
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 340
Joined: Mon Oct 06, 2008 12:55 pm

Re: Reviving DatabaseLayer

Post by samsam598 »

Thanks for the reply.I have MS Access 2003 in my Windows XP in this laptop;also I tried the same code in MS Access 2010+Win7 in my desktop,but no luck either.

Sorry I have no SQL Server Express Edition installed.I realized maybe using sqlite3 is more convenient and cross-platform,I just want to work out and clear my confusion on ODBC+MS Aceess +WX under windows.

fyi.I am using CodeBlocks (source editor character set:UTF-8).

Regards,
Sam
Regards,
Sam
-------------------------------------------------------------------
Windows 10 64bit
VS Community 2019
msys2-mingw13.2.0 C::B character set: UTF-8/GBK(Chinese)
wxWidgets 3.3/3.2.4 Unicode Mono Static gcc static build
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: Reviving DatabaseLayer

Post by evstevemd »

samsam598 wrote:I realized maybe using sqlite3 is more convenient and cross-platform
Regards,
Sam
That is the best if there is nothing that stops you from doing it.
And if you use wxDatabase its even easier!
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: Reviving DatabaseLayer

Post by evstevemd »

Hi andrew,
manyleaves wrote: estevemd
I saw your PK addition and I added support for it in TDS.
Thanks. This is great news. I have zero understanding of TDS but I will read at least to know what it is :)

manyleaves wrote:I've also added

Code: Select all

static wxDatabase* GetDatabase(wxConfigBase& config, const wxString& warning)
in the restructured code that returns the correct type of wxDatabase* based on the contents of the config. The reason for this is that it saves having to propogate all the specific #includes in the consuming code.
Great also!
So it should be able to save in Config right?
There should be a setter somewhere right?
manyleaves wrote:I'm testing my restructured code right now and it fits in well with the other projects especially wxDatabaseConfig. All I need to do now is to merge the old tests into some sort of "sample".
Thats good waiting to hear from you!

One thing that I wanted always to add is copy constructor to wxDatabase!
manyleaves wrote:I have a further extension to wxDatabaseConfig in one of my other projects "composite" which supports a concept similar to #include within config files so you chain them eg you can install a simple wxFileConfig that includes the wxDatabaseConfig. This is useful if you have many clients pointing to a single config on a server.
Andrew
I would like in Future move my app to use wxDatabaseConfig than custom way I use now!
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

evstevemd

FYI: TDS stands for Tabular Data Stream and is the internal streaming format used by Sybase, MS SQL Server and its variants.

Please find attached my restructured wxDatabase and wxDatabaseConfig. In the samples folder you will find projects that run unit tests for both wxDatabase and wxDatabaseConfig. All you have to do is change the content of test.conf to reflect whatever DB you are testing. I've tested TDS and TDS via ODBC. NB: I've only tested DLL builds (ie DLL Debug and DLL Release).

You configure the databases you are supporting by editing setup.h in the database project. The static wxDatabase::GetDatabase() method returns a wxDatabase* for the first valid DB configuration it can find in the "config" parameter. How to use wxDatabaseConfig should be evident from the sample.

I'd appreciate your comments!

Andrew
Attachments
wxDatabase.rar
(178.13 KiB) Downloaded 211 times
User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2409
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania

Re: Reviving DatabaseLayer

Post by evstevemd »

Hi Andrew,
Great work indeed. Am in the final stages of finalizing the app we are coding here.
Soon after, I will have a look and integrate it and do a first release :p

Again thanks for the efforts!
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

After my previous upload I ran the "config" tests using a different ODBC connection string. The connection string in that upload fails. Because wxDatabaseConfig keeps open multiple prepared statements, the DRIVER used by ODBC must be able to support a MARS connection. So for a MS SQL Server 2008 database named "test" running on a named instance "sqlexpress" on server "manyleaves" the connection string is:

Code: Select all

[ODBC]
Connection=DRIVER={SQL Server Native Client 10.0};MARS_CONNECTION=Yes;SERVER=manyleaves\\sqlexpress;TRUSTED_CONNECTION=Yes;DATABASE=test
DSN=
DbType=TDS
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

samsam598

I've just spent several hours investigating your ODBC to MS Access problems.

I can certainly replicate the issues you described a few posts back. I haven't been able to fully fix the problem but I've gone some way towards understanding it ... it needs someone else more experienced with encodings/charsets to investigate!

MS Access's default encoding/charset seems to be some variant of UTF16. wxWidgets seems to be UTF8.

I've had the best (most readable) results so far with UTF16:

1. Edit odbc_resultset.cpp as follows

Code: Select all

void wxOdbcResultSet::RetrieveFieldData(int nField)
{
...
        //AML SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_CHAR, buff, col_size, &real_size );
        SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff, col_size, &real_size );
...
        //AML SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_CHAR, buff, col_size, &real_size );
        SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff, col_size, &real_size );
}
2. Add "CHARSET=UTF16;" to your odbc connection string
3. Changing wxWidgets default encoding:

Code: Select all

	 wxCSConv cs(wxFONTENCODING_UTF16);
	 wxConvCurrent = &cs;
Set up this way all the chinese strings in the access db are shown correctly in the result set but the western strings only show the first character.

However, I think we should be able to set it up all UTF8 but I've had no success.

Is there anyone else out there who could help with this?

Andrew
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 340
Joined: Mon Oct 06, 2008 12:55 pm

Re: Reviving DatabaseLayer

Post by samsam598 »

Code: Select all

// these functions should be used when the conversions really, really have
    // to succeed (usually because we pass their results to a standard C
    // function which would crash if we passed NULL to it), so these functions
    // always return a valid pointer if their argument is non-NULL

    // this function safety is achieved by trying wxConvLibc first, wxConvUTF8
    // next if it fails and, finally, wxConvISO8859_1 which always succeeds
    extern WXDLLIMPEXP_BASE wxWCharBuffer wxSafeConvertMB2WX(const char *s);

    // this function uses wxConvLibc and wxConvUTF8(MAP_INVALID_UTF8_TO_OCTAL)
    // if it fails
    extern WXDLLIMPEXP_BASE wxCharBuffer wxSafeConvertWX2MB(const wchar_t *ws);
wxConvertWX2MB(const wchar_t* ws) under UNICODE case works as well to make Asian characters put/retrieve properly to and from the table.

I tried to build (with MinGW the only compiler I have ,and there is no makefile to use,and I don't know how to write one) and run the test case to check whether it will pass the test,but got an error:The compiler does not know _ASSERTE,nor _CrtCheckMemory(),where do they come from?

Thanks for the help.

Regards,
Sam
Regards,
Sam
-------------------------------------------------------------------
Windows 10 64bit
VS Community 2019
msys2-mingw13.2.0 C::B character set: UTF-8/GBK(Chinese)
wxWidgets 3.3/3.2.4 Unicode Mono Static gcc static build
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

Sam

_ASSERTE and _CrtCheckMemory() are defined in "crtdbg.h". Perhaps this is only supported by VC++.

In the "wxprec.h" include files I've enabled C-runtime memory checking. I suggest you change

Code: Select all

#ifdef _DEBUG
    #include <crtdbg.h>
	#define debug_normal_new new(_NORMAL_BLOCK ,__FILE__, __LINE__)
	#define debug_ignore_new new(_IGNORE_BLOCK ,__FILE__, __LINE__)
#else
    #define debug_normal_new new
    #define debug_ignore_new new
#endif
to

Code: Select all

#if defined(_DEBUG) && defined(_MSC_VER)
    #include <crtdbg.h>
	#define debug_normal_new new(_NORMAL_BLOCK ,__FILE__, __LINE__)
	#define debug_ignore_new new(_IGNORE_BLOCK ,__FILE__, __LINE__)
#else
    #define debug_normal_new new
    #define debug_ignore_new new
#endif
and then it should compile.

Andrew
samsam598
Super wx Problem Solver
Super wx Problem Solver
Posts: 340
Joined: Mon Oct 06, 2008 12:55 pm

Re: Reviving DatabaseLayer

Post by samsam598 »

Thanks for getting back to me.

I managed to get the test case compiled and run .The summary reported that all 65 tests have been passed.Please take note the wxDatabase library I tested on is the one I've modified to ensure the Chinese characters properly interact with MS Access(so ODBC part I myself tested only),the issue I mentioned in previous post.I tested the Chinese character issue based on my existing project.After that project works well,I tested the testcase in the wxDatabase tests folder.

I have one question here.In previous DatabaseLayer version,different database tests generate to different exe files(runner_odbc.exe,runner_sqlite.exe,etc).But in wxdatabase,it seems that only one runnercase exe file has been built.So if it reported all 65 tests have been passed,does that mean both ODBC and sqlite have been passed in my case only these two database are enabled?

If this is true that both ODBC and sqlite have passed the test,I am very excited that finally I managed to fix the asian(Chinese) characters save back and retrieve from MS Access issues mentioned in previous post!

But there is one exceptions need to mention as I don't know whether that does affect the final result or not.This is the vc++ _ASSERTE and _CrtCheckMemory() I take them out.Under MinGW I have to take them out,under VS.Net2003 since I have no wxprec.h in my project ,I am silly so I don't know how to make use them otherwise.Adding #ifdef __DEBUG etc as you mentioned to wx/include/wx/wxprec.h does not make any sense to my project.

Here goes what I did:

I installed VS.net 2003 today and tested under both VC and MinGW.Under MinGW,modified getchar() to std::cin.get() in MiniCppUnit.hxx,line 421.

1.The wxDatabase package I use is not the lasted one you've uploaded.The one (folder structure like:wxDabase/include/wx/base,wxDatabase/include/wx/database)I failed to make it compile,when I turn on wxUSE_DATABASE_ODBC=1,wxUSE_DATABASE_SQLITE=1,turned off wxUSE_DATABASE_TDS,still it complained wxSqliteDatabase can not be found bla.
I use the one you've uploaded earlier,which folder structure is like wxDatabase/include/odbc,wxDatabase/include/sqlite,etc;

2.Create new CodeBlocks wxWidgets project->Empty Project;

3.Change the build target from GUI to console app;

4.Added all sources and headers under the root folder and tests folder, and also ODBC/*.* and sqlte/*.*,change ODBC configurations in settings.conf according to my Access file;

5.Added sqlite3 include path,lib path and sqlite3.lib(*.a) to project;

5.Added USE_ODBC and USE_SQLITE to compiler #define option;

6.Commented out several places that _ASSERTE and _CrtCheckMemory() exists .The reason I've mentioned before.

7. Changes in wxDatabase sources and headers that fix the asian(Chinese)characters interact with MS Access issue:

affected 3 files:stringconverter.h,stringconverter.cpp,odb_cresultset.cpp

a. In stringconverter.h added :

Code: Select all

virtual wxString ConvertFromUnicodeStream(const wxChar* inputBuffer);
static wxString ConvertFromUnicodeStream(const wxChar* inputBuffer,const char* encoding);
b. In stringconverter.cpp added:

Code: Select all

wxString wxDatabaseStringConverter::ConvertFromUnicodeStream(const wxChar* inputBuffer)
{
    wxString strReturn( wxConvUTF8.cWC2WX(inputBuffer),*wxConvCurrent);
    if(strReturn==wxEmptyString)
        strReturn<<wxString(inputBuffer,*wxConvCurrent);
    return strReturn;
}

wxString wxDatabaseStringConverter::ConvertFromUnicodeStream(const wxChar* inputBuffer, const char* encoding)
{

    wxString strReturn( wxConvUTF8.cWC2WX(inputBuffer),*wxConvCurrent);
    if(strReturn==wxEmptyString)
        strReturn<<wxString(inputBuffer,*wxConvCurrent);
    return strReturn;
}
c. Same in stringconverter.cpp,modification made in two version of ConvertToUnicodeStream function:

Code: Select all

const wxCharBuffer wxDatabaseStringConverter::ConvertToUnicodeStream(const wxString& inputString)
{
#if wxUSE_UNICODE
  //return wxConvUTF8.cWC2MB(inputString.wc_str(*wxConvCurrent));//does not work for Chinese character issue
   // return wxConvUTF8.cWX2MB(inputString.wc_str(*wxConvCurrent));//does now work neither
  //return wxCharBuffer(wxConvCurrent->cWX2WC(inputString.wc_str()));//does not work neither


  return wxSafeConvertWX2MB(inputString.wc_str());
   
  
  //return inputString.c_str();//this works under some case;don't test any more this time
  
  //from docs for my easy reference only:
  //To print a wxChar buffer to a non-Unicode stdout:
  //printf("Data: %s\n", (const char*) wxConvCurrent->cWX2MB(unicode_data));

#else
  wxString str(inputString.wc_str(*wxConvCurrent), wxConvUTF8);
  return str.mb_str();
#endif
}
and:

Code: Select all

const wxCharBuffer wxDatabaseStringConverter::ConvertToUnicodeStream(const wxString& inputString, const char* WXUNUSED(encoding))
{
#if wxUSE_UNICODE
  //return wxConvUTF8.cWC2MB(inputString.wc_str(*wxConvCurrent));
   //return wxConvUTF8.cWX2MB(inputString.wc_str(*wxConvCurrent));
  //return inputString.c_str();

  return wxSafeConvertWX2MB(inputString.wc_str());

#else
  wxString str(inputString.wc_str(*wxConvCurrent), wxConvUTF8);
  return str.mb_str();
#endif
}
d. In odbc_resultset.cpp,RetrieveFieldData(int nField):

Two places you've mentioned in previous post,m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_CHAR, buff,...),change SQL_C_CHAR to SQL_C_TCHAR;

Two places in strValue+=ConvertFromUnicodeStream((const char*)buff),change (const char*)buff to (const wxChar*)buff:

Code: Select all

SQLRETURN nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff,
            col_size, &real_size );
        if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO )
        {
            InterpretErrorCodes(nRet, m_pOdbcStatement);
            ThrowDatabaseException();
            return;
        }
        strValue += ConvertFromUnicodeStream((const wxChar*)buff);//ori:char*

        // Mark this field as retrieved
        m_RetrievedValues.insert(nField);
        // Record whether this field is NULL
        if (real_size == SQL_NULL_DATA)
          m_NullValues.insert(nField);

        if ( real_size > col_size )
        {
            while ( nRet != SQL_NO_DATA )
            {
                nRet = m_pInterface->GetSQLGetData()( m_pOdbcStatement, nField, SQL_C_TCHAR, buff,
                    col_size, &real_size );
                if ( nRet != SQL_SUCCESS && nRet != SQL_SUCCESS_WITH_INFO && nRet != SQL_NO_DATA )
                {
                    InterpretErrorCodes(nRet, m_pOdbcStatement);
                    ThrowDatabaseException();
                    return;
                }
                strValue += ConvertFromUnicodeStream((const wxChar*)buff);//orignal char*
            }
        }
Remarks:The encoding of my C::B is UTF8;MS Access connection string is as below:

Code: Select all

wxString conn=wxT("Driver={microsoft access driver (*.mdb)};dbq=e:/pathToMyMdbFolder/my.mdb;");
With or without CHARSET=UCS-2 or CHASET=UTF16 in the connection string does not make any difference at all.

Tested ODBC and sqlite only under windows xp.Grateful if anyone would like to do a stricter test to other databases (string converter function) and other platforms.
Regards,
Sam
-------------------------------------------------------------------
Windows 10 64bit
VS Community 2019
msys2-mingw13.2.0 C::B character set: UTF-8/GBK(Chinese)
wxWidgets 3.3/3.2.4 Unicode Mono Static gcc static build
manyleaves
Earned a small fee
Earned a small fee
Posts: 21
Joined: Tue Mar 26, 2013 3:52 am

Re: Reviving DatabaseLayer

Post by manyleaves »

Sam

Many thanks for your help fixing up Asian character support.

I've attached an updated wxDatabase.rar which
1. Incorporates the stringconverter/odbc_resultset fixes you mentioned in your previous post. Please check I've done it correctly.
2. Properly supports SQLITE built via a $(SQLITE) environment variable in wx_vc10_database.vcxproj. I also had to do a few other fixes to get it to compile. FYI: this is the first time I've ever used SQLITE.
3. Improves the "testEncodingSupport" in the database "tests" project to support multiple lines in "test.dat" (This is where the Asian characters should be tested!)

The "wxprec.h" are pre-compiled headers for my code much like those used in wxWidgets themselves.

I wouldn't recommend using VS.net 2003 (I used it many years ago), rather I'd suggest you download the free VC++ Express 2010 from Microsoft (this is what I am using) and you'll have the same build environment as me. VC++ Express 2010 is the last VC++ that runs on Windows XP. (VC++ Express 2012 needs Windows 7.)

To answer your other question, there is only one "runner" exe in wxDatabase which works via GetDatabase() by connecting to the first valid connection info it can find via the "config" parameter. To run the tests on multiple databases you simply comment-in that part of the config you wish to connect to. The only "gotcha" here is that wxFileConfig internally sorts the groups so it will scan in alphabetic order (eg [ODBC] wil always be tested before [SQLITE] no matter what order they appear in the config file). To be able to force a particluar order I've improved GetDatabase() so that it scans recursively through sub-groups (eg [1] followed by [1/SQLITE] and [2] followed by [2/ODBC] will force SQLITE before ODBC).

The database project as uploaded is set up for SQLITE and ODBC. I've tested SQLITE directly and SQLITE via ODBC and MS Access via ODBC. SQLITE directly passed all the tests before I extended "testEncodingSupport" for your Chinese characters. SQLITE via ODBC has some issues with dates/times. MS Access via ODBC fails even more tests.

I've still been unable to get your Chinese characters into an MS Access or SQLITE database - I must be missing something obvious. Perhaps you could make the appropriate changes to "testEncodingSupport" (and wherever else necessary) so you can share your knowledge of how to do this. I've never had the need to work with different encodings so it's a big mystery to me.

I hope I've answered all your questions.

Thanks

Andrew
Attachments
wxDatabase.rar
(181.29 KiB) Downloaded 242 times
Post Reply