Разработаем приложение которое в последствии должно взаимодействовать с базой данных PostgreSQL. Есть две официальных клиентских C++ API для работы с PostgreSQL:
libpq++, libpqxx и SOCI PostgreSQL backend, с поддержкой PostgreSQL >= 7.3, версии старше 8.0. Они распространяются свободно, с открытым исходным кодом и «хорошо документированы» на английском языке.
Работа с библиотекой libpq++
create table people (
id integer,
firstname varchar(20),
lastname varchar(20),
phonenumber char(10)
);
insert into people (id, firstname, lastname, phonenumber) values
(1, 'Вася', 'Пупкин', '5055551234');
insert into people (id, firstname, lastname, phonenumber) values
(2, 'Лена', 'Похер', '5055551234');
insert into people (id, firstname, lastname, phonenumber) values
(3, 'Серёжа', 'молодец', '5055554321');
Для этой программы для C++ использую библиотеку libpq что бы получить доступ в базу. Для C программиста лучше использовать родные С библиотеки через C++ libpq и эта библиотека очень доступна для на-С++ программита.
Компиляция:
g++ -lpq db.cpp -o db
Использование libpqxx
Вот несколько причин для выбора libpqxx:
- Согласованность с языком. Используются преимущества C++: шаблоны (templates), исключения (exceptions), различные итераторов.
По возможности внутри юзается стандартные вещи из STL. - Структура, позволяющая писать «хороший» код. В основном проблемы обнаруживаются
на этапе компиляции или тестирования. - Мощность. Встроенные фичи: автоматическое восстановление соединения и
управление транзакциями освобождают разработчика. - Гибкость. Код библиотеки живет в своем пространстве имен (pqxx)
и полностью прячет нативный C API.
Что нужно для libpqxx?Во-первых, необходима нативная libpq.so/libpq.dll.
Во-вторых, сама libpqxx.so/libpqxx.dll.
#include
#include
#include
#include
#include
void help()
{
std::cout << "Использовать: " << std::endl;
}
int main(int argc, char **argv)
{
if (argc < 5) {
help();
return 1;
}
// Prepare connection string
std::ostringstream conn_string("");
conn_string << "host=" << argv[1]
<< " user=" << argv[2]
<< " password=" << argv[3]
<< " dbname=" << argv[4];
do {
// Create connection
try {
pqxx::connection conn(conn_string.str());
pqxx::work xact(conn, "SampleSelect");
std::string query("SELECT * from people limit 3");
// Execute query
try {
pqxx::result res = xact.exec(query);
if (!res.size()) {
std::cout << "Пустой вывод." << std::endl;
break;
}
// Show results
for (pqxx::result::const_iterator i = res.begin(), r_end = res.end(); i != r_end; ++i) {
// Iterate fields
for (pqxx::result::const_fielditerator f = i->begin(), f_end = i->end(); f != f_end; ++f) {
std::cout << f->name() << " = '" << f->c_str() << "'" << std::endl;
}
std::cout << std::endl;
}
} catch (...) {
std::cout << "Запрос не был выполнен: " << query << std::endl;
break;
}
} catch (pqxx::broken_connection) {
std::cout << "Ошибка: establish connection." << std::endl;
break;
}
std::cout << "Запрос успешно выполнен." << std::endl;
return 0;
} while (false);
return 1;
}
Makefile:
SRC=pqxx_sample.cpp
PROG=pqxx_sample
all:
c++ ${SRC} -o ${PROG} `pkg-config --libs --cflags libpqxx`
clean:
rm -f *.o ${PROG}
- libpq++ – libpqplusplus.html
- libpqxx – libpqxx
- Справочная информация – Reference
- std::ostringstream – ostringstream
Библиотека SOCI PostgreSQL backend поддерживает:
- Oracle
- PostgreSQL >= 7.3, версии старше 8.0
- MySQL
- (unsupported) backends exist in the CVS repository: ODBC, SQLite and Firebird.
Тестированные платформы
| PostgreSQL версии | Операционная система | Компилятор |
|---|---|---|
| 8.3 | Mac OS X 10.5.3 | g++ 4.0.1 |
| 8.3 | Mac OS X 10.5.3 | g++ 4.4.0 |
| 8.3 | FreeBSD 7.0 | g++ 4.2.1 |
| 8.3 | Linux i686 2.6.9 (RedHat family) | g++ 3.4.6 |
| 8.2.7 | Linux i686 2.6.23 (Fedora release 7) | g++ 4.1.2 |
Поддерживаемые backend-ы и поддерживаемые платформы
| Oracle | PostgreSQL | MySQL | SQLite3 | Firebird | ODBC | |
|---|---|---|---|---|---|---|
| Binding by Name | YES | YES (>=8.0) | YES | YES | YES | YES |
| Dynamic Binding | YES | YES | YES | YES | YES | YES |
| Bulk Operations | YES | YES | YES | YES | YES | YES |
| Transactions | YES | YES | YES (with servers that support them, usually >= 4.0) | YES | YES | YES |
| BLOB Data Type | YES | YES | NO | NO | YES | NO |
| RowID Data Type | YES | YES | NO | NO | NO | NO |
| Nested Statements | YES | NO | NO | NO | NO | NO |
| Stored Procedures | YES | YES | NO (but stored functions, YES) | NO | YES | NO |
Какие требуются клиентские библиотеки
SOCI PostgreSQL backend требует PostgreSQL’slibpqклиентскую библиотеку.
Пример:
#include "soci.h"
#include "soci-oracle.h"
#include
#include
#include
#include
#include
using namespace soci;
using namespace std;
bool getName(string &name)
{
cout << "Введите имя: ";
return cin >> name;
}
int main()
{
try
{
session sql(postgresql, "service=mydb user=john password=secret");
int count;
sql << "select count(*) from phonebook", into(count);
cout << "У нас " << count << " записей в phonebook.\n";
string name;
while (getName(name))
{
string phone;
indicator ind;
sql << "select phone from phonebook where name = :name",
into(phone, ind), use(name);
if (ind == i_ok)
{
cout << "Телефонный номер: " << phone << '\n';
}
else
{
cout << "Нет телефонного номера: " << name << '\n';
}
}
}
catch (exception const &e)
{
cerr << "Ошибка: " << e.what() << '\n';
}
}
[:]