Qt

Динамическое создание виджетов Qt. QGridLayout

В этом сообщении хотелось бы немного отредактировать предыдущий подобный пост Qt. Динамическое создание виджетов на форме.

Задача такая же: Есть объект QGroupBox groupBox, в него надо запихнуть виджеты (labels & lineEdits) в QGridLayout лэйауте. Данные берутся из запроса (он представлен в сообщении по ссылке выше).

Более универсальный способ будет выглядеть так:

if(ui->groupBox->layout()) {
	QLayoutItem *child;
    while ((child = ui->groupBox->layout()->takeAt(0)) != 0) {
    	delete child->widget();
        delete child;
    }
    delete ui->groupBox->layout();
}
QGridLayout *layout = new QGridLayout(ui->groupBox);
ui->groupBox->setLayout(layout);
int pos = 0; //устанавливаем позицию расположения виджетов в 0
int colsCount = 2; //Количество колонок в лэйауте
while (query.next()) { //берем результаты запроса
	QLabel *newLabel = new QLabel(this);
    newLabel->setText(query.value("caption").toString()+":");
    newLabel->setObjectName("label_"+query.value("name_").toString());
    layout->addWidget(newLabel,pos/colsCount,pos%colsCount);
    pos++; //сдвигаемся

    QLineEdit *newEdit = new QLineEdit(this);
    newEdit->setObjectName(query.value("name_").toString());
    layout->addWidget(newEdit,pos/colsCount,pos%colsCount);
    lineEdits.push_back(newEdit);
    pos++;
}

В данном случае мне необходимо было разместить объекты в бокс с двумя колонками. Поэтому colsCount = 2. Если их должно быть больше, то значение переменной нужно поменять. Очищение лэйаута позволяет при изменении результатов запроса все очистить и нарисовать все в соответствии с актуальными данными.

PostgreSQL, Qt, Портфолио

DBServerWizard — автоматизация работы с базами данных PostgreSQL

Сегодня хочу познакомить вас с утилитой DBServerWizard, написание которой закончила намедни. Если коротко, ее предназначение — самые базовые элементы управления базами данных PostgreSQL.

МенюУстановка сервераРезервное копирование/ восстановление из копииСоздание базы данных
Меню
Установка сервера
Бэкап/рестор
Создание БД

А если расписать немного подробнее, то перечень такой:

  • Установка сервера PostgreSQL (включает предварительную проверку наличия уже установленного сервера).
  • Создание и удаление баз данных. Есть некоторый обязательный набор баз данных; при подключении к серверу происходит проверка наличия этого минимального набора, если какие-либо БД из этого списка отсутствуют, то предлагается произвести создание БД и восстановление из бэкапа. Доступно принудительное удаление при наличии «застрявших» подключений, мешающих операции.
  • Резервное копирование и восстановление из копии. Перед восстановлением базы данных производится резервное копирование «на всякий случай».
  • Обновление баз данных из скриптов. Скрипт разделяется на отдельные инструкции, которые выполняются последовательно. Невыполненные инструкции записываются в отдельный файл.

Следующие сообщения были написаны в течение работы над утилитой:

Qt: Восстановление pg_restore БД PostgreSQL в Windows

Принудительное удаление базы данных в PostgreSQL

Qt: Резервная копия pg_dump БД PostgreSQL в Windows

Файл паролей PostgreSQL pgpass в Windows

Путь к каталогу bin PostgreSQL Windows

Чтобы заказать проект или получить консультацию, перейдите, пожалуйста, на страницу Контакты.

Моё портфолио

Инфо обо мне

PostgreSQL, Qt, Базы данных

Qt: Резервная копия pg_dump БД PostgreSQL в Windows

Пример того, как можно реализовать резервное копирование базы данных PostgreSQL в Qt. Создается batch-файл, где вызывается утилита pg_dump.

//QString name - имя базы данных для создания копии
//file - "куда складывать" бэкап
bool myClass::backupDatabase(QString name, QString file)
{
    QString binDir = postgresBinDirectory();
    if (binDir.isEmpty()) {
        error(tr("Системный каталог bin сервера не найден. "
				 "Операция восстановления базы данных "
				 "%1 из резервной копии %2 прервана")
              .arg(name).arg(file));
        return false;
    }
    if (file.isEmpty()) {
        QDir dir(QCoreApplication::applicationDirPath()+
				 "/db_dumps/");
        if (!dir.exists())
            dir.mkpath(QCoreApplication::applicationDirPath()+
					   "/db_dumps/");
        file = QString("%1/%2-%3.dump")
                .arg(QCoreApplication::applicationDirPath()+
					 "/db_dumps")
                .arg(name)
                .arg(QDateTime::currentDateTime()
					 .toString("yyyyMMddhhmm"));
    }
    QString text = QString(
		"@ECHO OFF \n"
        "cd /d %1 \n"
        "pg_dump -Fc -U %4 -Z 9 -v %2 > \"%3\" \n"
        "set /p id=\"Press Enter to exit...\"\n")
            .arg(binDir)
            .arg(name)
            .arg(file)
            .arg(postgresUser);
    QString fileName = QString("%1-dump.bat")
            .arg(name);
	//запись Значения строки text в файл *.bat
    if (!writeBatFile(text, fileName, 
				 QCoreApplication::applicationDirPath()+"/temp"))
		return;
	//обновление файла паролей pgpass
    updatePgPassFile(QString("%1:%2:%3:%4:%5")
                     .arg(host,
                          ui->port->text(),
                          name,
                          postgresUser,
                          ui->password->text()));
	//вызов созданного batch файла
    system(qPrintable("cmd.exe /c \""+
                      QDir::toNativeSeparators(
                          QString("%1/%2")
                          .arg(QCoreApplication::applicationDirPath()+
							   "/temp")
                          .arg(fileName)+"\"")));
	//если файл бэкапа имеет ненулевой размер
    return QFileInfo(file).size() > 0;
}

Как узнать путь к каталогу bin сервера PostgreSQL, подробно написано здесь: Путь к каталогу bin PostgreSQL Windows. При условии известности имени пользователя и его пароля можно запустить утилиту pg_dump без необходимости авторизации пользователем при наличии соответствующей строки подключения в файле паролей pgpass, про что подробно писала в этой статье: Файл паролей PostgreSQL pgpass в Windows. В вышеприведенном коде используется функция updatePgPassFile(QString), код которой можно найти по обозначенной ссылке.

Более ранняя статья на схожую тему: Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL

PostgreSQL, Qt, Базы данных

Файл паролей PostgreSQL pgpass в Windows

Для восстановления базы данных из резервной копии используется исполняемый файл сервера pg_restore. Если в настройках сервера выставлена авторизация по имени и паролю, то при использовании утилиты необходимо вводить пароль при каждой операции восстановления БД из бэкапа. Что не подходит в случае пакетной операции, например, или когда операция должна производится без взаимодействия с пользователем в этом ключе. Тогда сервер использует файл паролей pgpass. Он может и отсутствовать. Что тогда делать? Создать и обновлять. Продолжить чтение «Файл паролей PostgreSQL pgpass в Windows»

PostgreSQL, Qt, Базы данных

Путь к каталогу bin PostgreSQL Windows

Задача: получить значение пути к каталогу бинарников сервера — к каталогу bin. Путь к каталогу data, как и прочие значения параметров времени выполнения, найти совершенно несложно: достаточно выполнить запрос show, воспользоваться функцией current_setting() или обратиться к представлению pg_settings:

show data_directory;
select current_setting('data_directory');
select setting from pg_settings 
   where name = 'data_directory';
Три равнозначных примера получения значения пути к каталогу data

Еще парочку примеров показывала вот в этой записи: Количество подключений к БД PostgreSQL.

С значением пути к каталогу bin не все так просто — запросом его не получишь. Но можно узнать из реестра. В реестре не хранится чистый ключ со значением пути к каталогу, к сожалению, но можно узнать путь к исполняемому файлу службы сервера.

Итак, интересующий нас ключ: Продолжить чтение «Путь к каталогу bin PostgreSQL Windows»

Qt, Базы данных

Добавление данных запроса в таблицу QTableWidget

Здесь: Добавление данных в таблицу QTableWidget. Очистка таблицы — я рассказала, как заполнить таблицу QTableWidget данными из объекта QMap. Можно сказать, через годы и расстояния :), я решила чуть больше развернуть эту тему и показать, как организовать добавление данных запроса в таблицу. Для тех, кому по какой-то причине нужно использовать объект QTableWidget вместо QTableView. Продолжить чтение «Добавление данных запроса в таблицу QTableWidget»

PostgreSQL, Qt

PostgreSQL: unnest(array)

Моя любимая функция PostgreSQL — unnest (ссылка на документацию)! Она такая простая, но такая классная 😀

Она очень пригодится, если нужно вставить сразу несколько записей за один присест. Допустим, у одной фирмы есть несколько номеров телефонов и,чтобы не перечислять вставку этих данных через запятую, дублируя id фирмы, можно использовать unnest — элегантное решение! Продолжить чтение «PostgreSQL: unnest(array)»

Microsoft SQL Server, PostgreSQL, Qt, Базы данных

Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL

Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQLНе во всех СУБД есть возможность настроить Резервное копирование базы данных по расписанию штатными средствами. Например, в Microsoft SQL Server это делается без проблем, а вот в PostgreSQL такой возможности «из коробки» нет.

Но выход есть: создать файл сценария и добавить его исполнение в расписание задач в Windows.

В переменных database, host, port, userName, bin, backupDir будут храниться значения имени базы данных, сервера, порта, имени пользователя БД, путь к bin папке PostgreSQL и директории сохранения резервных копий соответственно.

Пусть значение driver = 0 будет отвечать за PostgreSQL, а 1 — за Microsoft SQL Server.

Определим текст *.bat-файла:

QString batText = "@ECHO OFF \n"
        "SET dmpfile="+database+"-FullBackup-%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2% \n"
        "IF \"%TIME:~0,1%\"==\" \" (SET dmpfile=%dmpfile%-0%TIME:~1,1%) ELSE (SET dmpfile=%dmpfile%-%TIME:~0,2%) \n"
        "SET dmpfile=%dmpfile%-%TIME:~3,2%-%TIME:~6,2%.backup \n"
        "set text = Begin to backup... \n"
        "echo %text% \n";
if (driver==0)
       batText += QString(
           "cd %1\ \n"
           "pg_dump.exe --host %2 --port %3 --username %4 --no-password --format" 
		   "custom --blobs --verbose --file \"%5\\%dmpfile%\" %6")
            .arg(bin, host, port, userName, 
				 backupDir.replace("/", "\\"), database);
 else
       batText += QString("SQLCMD -S %1 -E -Q \"BACKUP DATABASE %2 "
           "TO DISK = '%3/%dmpfile%' "
           "WITH INIT, NOFORMAT, SKIP, NOUNLOAD\"")
                .arg(host, database, backupDir);

Имя файла резервной копии будет иметь при этом подобный вид: DatabaseName-FullBackup-2018-08-07 -11-23-38.backup, то есть имя базы данных, FullBackup + таймстемп.

Далее запишем текст в файл: Продолжить чтение «Резервное копирование базы данных по расписанию: MS SQL Server и PostgreSQL»

Microsoft SQL Server, Qt

QSqlQuery::numRowsAffected(), QSqlQuery::size() и MS SQL Server

Для получения количества обработанных записей запросом (insert, update, delete) в Qt используют функцию numRowsAffected(), а для получения размера выборки — size() объекта QSqlQuery:

QSqlQuery query;
if (!query.exec("delete from people where age < 20")) {
	qDebug() << "error:" << query.lastError()->text();
	return;
}
qDebug() << "rows count" << query.numRowsAffected();
numRowsAffected()
QSqlQuery query;
if (!query.exec("select * from people where age < 35")) {
	qDebug() << "error:" << query.lastError()->text();
	return;
}
qDebug() << "rows count" << query.size();
size()

Но не все СУБД поддерживают эту функцию. Например, SQLite и, о Боже! — Microsoft SQL Server (как не стыдно!). Проверить поддержку данной функции (а заодно и функции QSqlQuery::size()) можно так:

qDebug() << database.driver()->hasFeature(QSqlDriver::QuerySize);

где database — объект подключения к базе данных QSqlDatabase. Если в выводе приложения вы увидите false, то прогноз пессимистичен.

Что делать в этом случае?

Продолжить чтение «QSqlQuery::numRowsAffected(), QSqlQuery::size() и MS SQL Server»

Microsoft SQL Server, Qt, Базы данных

Подключение к базе данных MS SQL Server в Qt

В записи Подключение к базе данных в Qt на примере СУБД PostgreSQL я показала, как произвести подключение к базе данных. С MS SQL Server немного запутанней получается (не привыкать).

MS SQL Server может использовать 2 вида аутентификации: аутентификация windows и аутентификация  SQL Server. Ниже рассмотрим оба способа подключения. Продолжить чтение «Подключение к базе данных MS SQL Server в Qt»