Russian Qt Forum

Qt => Базы данных => Тема начата: JamS007 от Апрель 18, 2011, 22:14



Название: Не стандартное название подключения к БД
Отправлено: JamS007 от Апрель 18, 2011, 22:14
Доброго времени суток,

Ситуация такая: я пишу сервер, и у меня часто подключаються/отключаються клиенты. Каждый из них практически всегда работает со своей БД, а так как клиентов много то и подключений много. Скажу еще, что приложение многопоточное, и может быть такое, что клиенты работают в разных потоках.

Для обслуживания клиентов я написал специальний класс. Предполагаеться создание по одному его экземпляру на каждого клиента. Так как клиентов много, то я решил создавать все QSqlDatabase на хипе, чтобы лишний раз не перегружать стэк, (я правильно решил?) но с удивлением обнаружил, что в созданной на хипе БД я не могу (не умею/не нашел как) поменять имя подключения и драйвер. Все конструкторы QSqlDatabase или не принимают параметров, или принимают ссылки на БД, созданные на стеке.

Покопавшись в интернете не нашел ничего лучше чем это:
Код
C++ (Qt)
mDatabase = new QSqlDatabase(QSqlDatabase::addDatabase(GDatabase::driverType));

Но в ходе работы программы в лог сыпались такие сообщения:
QSqlDatabasePrivate::addDatabase: duplicate connection name "Имя подключения", old connection removed.

Я не нашел ничего лучше чем задавать имя подключения для каждого клиента отдельно, а так как, я создаю по экземпляру класса-обработчика на каждого клиента, то соотвественно в памяти они не могут находиться по одному и тому же адресу, и я решил сделать так:
Код
C++ (Qt)
mDatabase = new QSqlDatabase(QSqlDatabase::addDatabase(GDatabase::driverType,QString::number(long(this))));
где - this - указатель на класс-обработчик.

Чесно скажу, мне такой способ не оч. нравиться, но это лучше чем то, что было.

А теперь вопросы:
1. В ходе работы я заметил, что после уничтожения одного клиента и создания другого (и инициализации его БД) я получаю:
QSqlDatabasePrivate::addDatabase: duplicate connection name '147141264', old connection removed.
Тоесть используеться адрес отключившегося клиента, не понятно лишь почему БД не отключаеться, в деструкторе вызываю:
Код
C++ (Qt)
if (mDatabase){
       mDatabase->close();
       delete mDatabase;
   }

2. Что скажете о моем способе именования подключений? Я не смахиваю на шизофреника?  :D Любая критика принимаеться, оч. желательно с поучениями и обьяснениями.

P.S. Простите за ошибки. Как граматические так и стилистические, рус. язык мне не родной  ;)


Название: Re: Не стандартное название подключения к БД
Отправлено: lit-uriy от Апрель 19, 2011, 07:25
Для класса QSqlDatabase нет смысла делать указатель, т.к. соединения всегда можно получить по его имени.
Класс QSqlDatabase работает как "именованный одиночка", т.е. само соединение всегда создаётся в куче, а не на стеке.

посмотри внимательно на примеры работы, в описании класса QSqlDatabase.

Код
C++ (Qt)
void connect()
{
   QSqlDatabase db = QSqlDatabase::addDatabase("first");
   ...
}// Из функции вышли, объект db  уничтожен, но не соединение, т.к. оно было создано статической функцией
 
void use()
{
   QSqlDatabase db = QSqlDatabase::database("first"); // используем соединения с именем "first" (оно уже существует)
   ...
}
 


Название: Re: Не стандартное название подключения к БД
Отправлено: JamS007 от Апрель 20, 2011, 20:10
lit-uriy , спасибо.
А как быть с именем соединения?


Название: Re: Не стандартное название подключения к БД
Отправлено: lit-uriy от Апрель 21, 2011, 08:16
>>А как быть с именем соединения?
Ну задавай его по шаблону, с помощью QString::arg()

Код
C++ (Qt)
int connectionId = ...;
 
...
 
QString name = QString("connection%1").arg(connectionId);