Categories: Database

Работа с базами данных в wxWidgets – DatabaseLayer – Минимальное приложение

Вслед за анонсом новой версии DatabaseLayer, кросс-платформенной библиотеки для работы с базами данных, решил выложить небольшой туториал с примером использования DatabaseLayer.

В этот раз мы рассмотрим пример создания простейшего консольного приложения, использующего эту библиотеку для работы с базами данных.

В качестве среды разработки будем использовать Visual Studio. Это самый простой способ добиться желаемого результата. Бесплатная версия Visual Studio Express Edition тоже вполне подойдет для создания приложений на С++/wxWidgets.

Для начала создадим консольное приложение и назовем его DatabaseLayerMinimal.

В настройках проекта указываем тип приложение Console Application и стамим маркер на Empty Project.

После того как мы создали проект, распаковываем DatabaseLayer рядом с папкой, в которой находится .sln-файл решения.

Затем добавляем в решение проект databaselayer_databaselayer_sqlite.dsp – это проект SqliteDatabaseLayer, который позволяет получить доступ к базам данных SQLite в приложении.

После этого необходимо настроить конфигурации сборки. Открываем Configuration Manager (Build -> Configuration Manager) и устанавливаем для проекта databaselayer_sqlite нужную отладочную и финальную конфигурацию. В нашем примере это Static Unicode Debug Multilib Static и Static Unicode Release Multilib Static.

После этого в нашем проекте приложения необходимо настроить пути для поиска заголовочных файлов, файлов библиотек, а также список дополнительных библиотек для сборки проекта.

Для этого в свойствах проекта в разделе C/C++ -> General в свойстве Additional Include Directories прописываем:

$(SolutionDir)..\databaselayer\include

В разделе Linker -> General в свойстве Additional Library Directories прописываем:

$(SolutionDir)..\databaselayer\lib\vc_lib

В разделе Linker -> Input в свойстве Additional Dependencies указываем список необходимых библиоек:

Все, настройку проекта мы закончили, теперь можно заняться написанием кода.

Для каждого сервера баз данных в библиотеке DatabaseLayer существует соответствующий класс соединения. В нашем примере мы будем работать с базой данных SQLite. Для этого будем использовать класс SqliteDatabaseLayer.

Для того чтобы открыть базу данных можно использовать два пути:

  • Вызвать конструктор с параметрами и скормить ему путь к базе данных.
  • Использовать конструктор без параметров и метод Open().

В нашем примере будет использоваться первый способ.

Для разрыва соединения с базой данных (или для закрытия файла базы данных) используется метод Close().

В библиотеке DatabaseLayer для обработки ошибок используется механизм исключений. Для обработки ошибок необходимо отлавливать исключение DatabaseLayerException.

Итак, минимальное приложение, способное открыть базу данных выглядит так:

#include <wx/wx.h>
#include <DatabaseLayer.h>
#include <SqliteDatabaseLayer.h>
#include <DatabaseLayerException.h>

int main()
{
 int returnCode(0);
 DatabaseLayer * connection(NULL);
 do
 {
  try
  {
   connection = new SqliteDatabaseLayer(wxT("Minimal.sqlite"), false);
  }
  catch(DatabaseLayerException & e)
  {
   returnCode = 2;
   wxPrintf(wxT("%d %s"), e.GetErrorCode(), e.GetErrorMessage().GetData());
  }
 }
 while(false);
 wxDELETE(connection);
 getchar();
 return returnCode;
}

Необходимо помнить, что все ресурсы нужно освобождать руками.

Для выборки данных из таблицы используется метод RunQueryWithResults(), который возвращает указатель но объект DatabaseResultSet. После работы с результатми запроса, объект DatabaseResultSet необходимо обязательно закрыть во избежание утечек памяти. Сделать это можно, вызывав метод DatabaseLayer::CloseResultSet().

Для обхода записей, возвращенных с помощью метода RunQueryWithResults() используется метод DatabaseResultSet::Next().

Для получения значения поля в классе DatabaseResultSet существует соответствующий набор методов – GetResultInt(), GetResultString(), GetResultBool() и т.д. Каждый из этих методов может принимать как имя поля, так и порядковый номер (zero-based).

Для запросов, которые не возвращают список записей (INSERT, DELETE) используется метод RunQuery().

И вот со всем, описанным выше, мы подошли к рассмотрению более сложного примера – приложение открывает базу данных SQLite, проверяет ее на наличие таблиц. Если таблицы не найдены, то приложение создает одну таблицу и заполняет ее данными. После этого происходит выборка данных и отображение результатов выборки в консоли.

#include <wx/wx.h>
#include <DatabaseLayer.h>
#include <SqliteDatabaseLayer.h>
#include <DatabaseLayerException.h>

int main()
{
 int returnCode(0);
 DatabaseLayer * connection(NULL);
 DatabaseResultSet * result(NULL);
 do
 {
  try
  {
   connection = new SqliteDatabaseLayer(wxT("Minimal.sqlite"), false);
   result = connection->RunQueryWithResults(
    wxT("SELECT * FROM sqlite_master WHERE type='table'"));
   if(!result || !result->Next())
   {
    connection->RunQuery(
     wxT("CREATE TABLE SampleTable \
      (ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, \
      Name VARCHAR(32))"));
    for(int i = 0; i < 5; i++)
    {
     connection->RunQuery(wxString::Format(
      wxT("INSERT INTO SampleTable (Name) VALUES ('%i')"), rand()));
    }
   }
   if(result)
   {
    connection->CloseResultSet(result);
    result = NULL;
   }
   result = connection->RunQueryWithResults(wxT("SELECT * FROM SampleTable"));
   if(!result)
   {
    returnCode = 1;
    break;
   }
   while (result->Next())
   {
    wxPrintf(wxT("%d - %s\r\n"),
     result->GetResultInt(wxT("ID")),
     result->GetResultString(wxT("Name")).GetData());
   }
  }
  catch(DatabaseLayerException & e)
  {
   returnCode = 2;
   wxPrintf(wxT("%d %s"), e.GetErrorCode(), e.GetErrorMessage().GetData());
  }
 }
 while(false);
 if(connection)
 {
  if(result) connection->CloseResultSet(result);
 }
 wxDELETE(connection);
 getchar();
 return returnCode;
}

Скачать исходный код примера.

T-Rex

View Comments

  • Все отлично, но откуда к примеру взять библиотеки comctl32.lib uuid.lib rpcrt4.lib advapi32.lib wxbase28ud.lib wxmsw28ud_core.lib wxcode_msw28ud_databaselayer_sqlite.lib. В архиве их нет.

  • comctl32.lib uuid.lib rpcrt4.lib advapi32.lib - стандартные, ставятся с Visual Studio
    wxbase28ud.lib wxmsw28ud_core.lib - при сборке wxWidgets появляются
    wxcode_msw28ud_databaselayer_sqlite.lib - создаются при сборке DatabaseLayer.

  • при компиляции mingw-ом я слегка помучался:) разработчики явно его не долюбливают. Чтобы скомпилировать только postgre_sql пришлось править makefile.gcc. В то же время gnumake и VisualStudio позволяют это делать.

    И почему то хидеры в архиве только для sqlite. И чтобы скомпилить всю либу под mingw приходится либо makefile править либо качать исходники всех поддерживаемых СУБД.

    Но в целом всё получилось неплохо и даже все тесты прошли.

  • насколько я понял Databaselayer без dll может работать только с SQLite или я заблуждаюсь?
    Я пытаюсь работать с postgres. Следуя доке я конвертнул libpq.dll в libpq.a, а как заставить mingw засунуть эту либу в исполняемый файл понять не могу. Databaselayer компилировал с опциями MONOLITHIC=1, DEBUG=1, WXSHARED=0, SHARED=0...

    p.s. а за что мой предыдущий пост удалили?

  • ибо качать исходники всех поддерживаемых СУБД.

    Какие такие исходники? Для всего есть заголовки/либы в дистрибутивах СУБД. Для Postgres, MySQL точно есть.

  • Следуя доке я конвертнул libpq.dll в libpq.a, а как заставить mingw засунуть эту либу в исполняемый файл понять не могу.

    Не конвертнул, а создал import library. Это не одно и тоже. import library просто говорит линкеру что некоторые функции лежат не в исполняемом файле а во внешней DLL. И таскать эту dll надо за собой всегда. Это нормально.
    Хочется распространять прогу одним файлом? Сделай инсталлятор. в NSIS/NISEdit это за минуту делается

  • p.s. а за что мой предыдущий пост удалили?

    Возможно мне показалось что ты бот :P

Share
Published by
T-Rex

Recent Posts

Разработка кроссплатформенных модульных приложений на C++ с библиотекой wxWidgets

Введение Уже долгое время не пишу статьи о разработке, хотя сам процесс написания мне очень…

11 years ago

wxWidgets App With Plugins (Windows/Linux/Mac) – Sample Source Code

I can see that there is still a lot of topics at wxWidgets forums related…

11 years ago

wxToolBox is Now Open-Source!

I've just published the source code of wxToolBox component and a couple of sample apps at…

11 years ago

Microsoft Kinect Helper Library and Sample for wxWidgets

Microsoft released their Kinect SDK several days ago. So, for those wxWidgets developers who are…

13 years ago

wxJSON 1.1.0 Released

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to…

15 years ago

wxRuby. Оно даже работает!

Вдохновленнный читаемой нынче книгой My Job Went to India: 52 Ways to Save Your Job…

15 years ago