PDA

View Full Version : QODBC for Postgresql on Windows



AlbertoN
23rd January 2014, 13:50
Hi all,

I tried to run an app with QPSQL, but I found that it doesn't support UNICODE:

9966

and from psql shell:

9967

I inserted first row with psql shell therefore you can see unicode is supported inside postgresql.
As postgresql docs says (link (http://wiki.postgresql.org/wiki/Running_%26_Installing_PostgreSQL_On_Native_Window s#Why_can.27t_I_select_Unicode_as_an_encoding.3F)) :


"Programs using libpq directly need to be aware of this, but not much else does."

So I'm trying to run a test app with QODBC, even if qt docs says that it's better to use specific driver (QPSQL) link (http://qt-project.org/doc/qt-4.8/sql-driver.html#qodbc):

Note: You should use native drivers in preference to the ODBC driver where they are available. ODBC support can be used as a fallback for compliant databases if no native drivers are available.

I installed driver manager too (following this thread (http://stackoverflow.com/questions/6796252/setting-up-postgresql-odbc-on-windows) instructions):
9962

then compiled and installed qt odbc wrapper:
9963

this is my code:




//main.cpp:
#include <QCoreApplication>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlDriver>
#include <QDebug>

class Database
{
public:
explicit Database();
~Database();
bool connection();
private:
QString driverName;
QSqlDatabase db;
};

Database::~Database()
{
db.close();
}

Database::Database() :
db(QSqlDatabase::addDatabase("QODBC"))
//db(QSqlDatabase::addDatabase("QODBC3"))//tried even with this
{
driverName = QString("QODBC");
db.setDatabaseName("Driver={PostgreSQL};Server=localhost;Port=5432;Dat abase=prova;Uid=postgres;Pwd=*******;");
//db.setConnectOptions("SQL_ATTR_ODBC_VERSION=SQL_OV_ODBC3");//tried even with this
}

bool Database::connection()
{
if (!db.open()) {
qDebug() << QString("Unable to establish a database connection.\n"
"This example needs %1 support. Please read "
"the Qt SQL driver documentation for information how "
"to build it.\n\n"
"Click Cancel to exit.").arg(driverName);
return false;
}
return true;
}

bool insertTest()
{
QSqlQuery q;
q.prepare("INSERT INTO p(d) VALUES(:d)");
q.bindValue(":d",QString("Questa è un altra prova"));
return q.exec();
}

int main(int argc, char **argv)
{
QCoreApplication app(argc,argv);
const QScopedPointer<Database> database(new Database());
database->connection();
if(insertTest())
{
qDebug() << "query executed successfully";
}else{
qDebug() << "insert query error";
}
QSqlQuery q;
q.exec("SELECT * FROM p");
while(q.next())
{
QSqlRecord r = q.record();
qDebug() << "id=" << r.value("id").toInt();
qDebug() << "d=" << r.value("d").toString() << '\n';
}
return app.exec();
}


and this is my .pro file:


QT += core gui sql widgets
TARGET = ScopedPointer
CONFIG += console
TEMPLATE = app

sql-plugins += odbc

SOURCES += main3.cpp

OBJECTS_DIR = build/o
MOC_DIR = build/moc
UI_DIR = build/ui
RCC_DIR = build/rcc
DESTDIR = bin

I added sql-plugins directive following this thread (http://www.qtcentre.org/archive/index.php/t-31873.html)

Anyway i get this error message:


"QODBCResult::exec: No statement handle available" Error: "[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified"


as you can see here:
9969

I'm using Qt 5.2.0. If you need any other information please ask.
Any help would be appreciated, thanks!
Alberto

Lesiok
23rd January 2014, 14:42
Hi all,
I tried to run an app with QPSQL, but I found that it doesn't support UNICODE:
Nonsense.
The problem is that qDebug converts Unicode to the local code page. Often, Windows uses a different code page for character session and another code page for GUI session. For applications always be notified the GUI code page.
PS.
psql warns You about this, look at second picture.

AlbertoN
23rd January 2014, 18:49
Nonsense.
The problem is that qDebug converts Unicode to the local code page. Often, Windows uses a different code page for character session and another code page for GUI session. For applications always be notified the GUI code page.
PS.
psql warns You about this, look at second picture.

yes, you're right. After a whole day spent fighting against Windows I found how to fix that.

I'm going to write it down here for other users with same issue:

1. change windows' console codepage:
you can set it up with prompt command: "chcp 1252" but it works just for current session. To make it default codepage, you have to open regedit, locate AutoRun in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\ subdirectory. If it doesn't exists, as in my case, you'll create an entry as "string" and put "chcp 1252" as value in it.

2. after previous change you shouldn't be able to see any accents in console due to the fact that windows default font is a "Raster Font". To change it, you have to open a psql shell-> right click -> properties -> Fonts and switch to "Lucida Console". Do the same on a common console (I don't know why. They should be the same... maybe my mistake i'm a bit tired).

3. after that you have to set up postgresql shell config to WIN1252 encoding. To do that open as admin your runpsql.bat file. In my case there's a psql shell link on desktop -> right click->Shortcut->"open file location" button. It opens a path like this: C:\Program Files (x86)\PostgreSQL\9.3\scripts\runpsql.bat. And change it as follows (to save changes you have to open it as Admin):



[....]
for /f "delims=" %%a in ('chcp ^|find /c "932"') do @ SET CLIENTENCODING_JP=%%a
SET PGCLIENTENCODING=WIN1252
if "%CLIENTENCODING_JP%"=="1" SET /P PGCLIENTENCODING="Client Encoding [%PGCLIENTENCODING%]: "
[...]


4. create a db with right encoding inside psql shell: create database test with encoding 'UTF8';

That's all.

I hope this could be useful to someone else.
Thanks Lesiok for your support.
Alberto

P.S.: Anyway I can't run that code with QODBC driver and I can't understand why...