hk_classes to biblioteka C++ służąca do łączenia się z bazami danych (MySQL, PostgreSQL, SQlite, ODBC i inne) - główna zaleta - dotyczy wielu baz danych a nie tylko jednej...
strona projektu.
hk_classes mogą działać niejako w dwóch trybach - interaktywnym i pasywnym. Ten pierwszy pojawi się wtedy jeżeli nie określimy typu bazy danych ani danych połączenia - wtedy program poprosi o wprowadzenie odpowiednich danych. Oto najprostszy program w "wersji" interaktywnej:
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection();
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->connect();
delete mydrivermanager;
}
Kompilacja: musisz sprawdzić gdzie dokładnie znajdują się pliki hk_classes. Dla archa i innych dystrybucji instalujących wszystko z --prefix=/usr polecenie powinno wyglądać mniejwięcej tak:
g++ -o plik_wynikowy plik_zrodlowy.cpp -ldl -lhk_classes -L/usr/lib/hk_classes/ -I/usr/include/hk_classes/
Notka: jeżeli po udanej kompilacji program nie uruchamia się z powodu braku pliku libhk_classes.so.8 to trzeba skopiować albo lepiej zsymlinkować pliki z /usr/lib/hk_classes/ do /usr/lib/ (ln -sf /usr/lib/hk_classes/* /usr/lib/) albo poprawić coś w ścieżkach do bibliotek :P Po kompilacji i nadaniu praw wykonywalności (chmod 755 plik) wykonanie pliku w konsoli powinno dać generalnie taki efekt:
===========================================
The following database drivers were found:
===========================================
(1) mdb
(2) mysql
(3) odbc
(4) postgres
(5) sqlite3
(6) Select directory
===========================================
Please give me the following information:
=========================================
Host: localhost
User: piotr
Database name: test
Password (will not be displayed):
TCP Port: 5432
Najpierw wybieramy typ bazy danych a potem się z nią łączymy. Jeżeli program skończy działanie bez żadnych komunikatów to oznacza to iż połączenie zakończyło się sukcesem. Dostępne sterowniki znajdziemy w
/usr/lib/hk_classes/drivers/.
By wybrać typ bazy trzeba podać nazwę sterownika w
new_connection("STEROWNIK"); oraz ustawić host, login i hasło za pomocą odpowiednich metod:
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection("postgres");
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->set_host("localhost");
myconnection->set_user("user");
myconnection->set_password("haslo");
myconnection->connect();
}
Jeżeli program wykona się bez żadnych błędów to wszystko działa.
hk_classes umożliwia wykonywanie zapytań SQL. Oto przykładowy kod:
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection("postgres");
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->set_host("localhost");
myconnection->set_user("user");
myconnection->set_password("haslo");
myconnection->connect();
hk_database* mydatabase=myconnection->new_database("test");
if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
hk_datasource* mydatasource= mydatabase->new_resultquery();
mydatasource->set_sql("SELECT * FROM boo_rk_posts");
if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
mydatasource->enable();
mydatasource->dump_data(); // TYLKO DO TESTOWANIA
}
Nowy kod zaczyna się od
hk_database* mydatabase=myconnection->new_database("test"); gdzie łączymy się z określoną bazą danych na serwerze PostgreSQL a następnie pobieramy dane z tabeli boo_rk_posts (instalka RkCMF). Wykonanie programu zwróci coś takiego:
driverspecific DUMP
====
0: 2 news_1 2 NULLvalue NULLvalue Komentarze dla newsa [b]Pierwszy news[/b] 0 1126356179 NULLvalue NULLvalue 2
1: 3 root 2 ::1 NULLvalue ssssssssssss 0 1126356218 NULLvalue NULLvalue 2
2: 1 root 2 127.0.0.1 NULLvalue Jeżeli widzisz ten post to oznacza to że instalacja punBB i RkCMF udała się. 0 1126356152 NULLvalue NULLvalue 1
By pokazać dane z określonej kolumny mamy obiekt hk_column. By wyświetlić dane z obecnie "zaznaczonego" wiersza kolumny należy użyć
mycolumn->asstring(). Metoda hk_datasource::column_by_name pozwana natomiast na wybranie owej kolumny po jej nazwie. Po wybraniu kolumny zaznaczony jest pierwszy wiersz, by przejść do następnych trzeba skorzystać z metod:
bool goto_row (unsigned long r)
bool goto_first (void)
bool goto_last (void)
bool goto_next (void)
bool goto_previous (void)
A oto przykładowy kod
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection("postgres");
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->set_host("localhost");
myconnection->set_user("user");
myconnection->set_password("haslo");
myconnection->connect();
hk_database* mydatabase=myconnection->new_database("test");
if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
// Wybieramy tabelę
hk_datasource* mydatasource= mydatabase->new_table("boo_rk_posts");
if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
mydatasource->enable();
// Wybieramy wiersz
hk_column* mycolumn = mydatasource->column_by_name("message");
if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
// Wyświetlamy dwa wiersze
cout <<"Pierwszy wiersz: "<<mycolumn->asstring()<<endl;
mydatasource->goto_next();
cout <<"Drugi wiersz: "<<mycolumn->asstring()<<endl;
delete mydrivermanager;
}
Wyświetli pierwszy i drugi wpis... ale jak wyświetlić wszystkie? Zwróć uwagę że goto_next i koledzy to metody bool - zwrócą wartość prawda jeżeli uda im się przejść do wiersza... tak więc zastosujmy do while:
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection("postgres");
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->set_host("localhost");
myconnection->set_user("login");
myconnection->set_password("haslo");
myconnection->connect();
hk_database* mydatabase=myconnection->new_database("test");
if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
hk_datasource* mydatasource= mydatabase->new_table("boo_rk_cmf_global_lang");
if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
mydatasource->enable();
hk_column* mycolumn = mydatasource->column_by_name("lang_string");
if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
do
{
cout <<mycolumn->asstring()<<endl;
} while (mydatasource->goto_next());
delete mydrivermanager;
}
Pętla
do ... while ma tą zaletę że warunek sprawdzany jest po przejściu pętli, a w przypadku zwykłego while - przed jej przejściem, co spowodowałoby że dopiero drugi wiersz by się wyświetlił.
#define HAVE_SSTREAM 1
#include <hk_classes.h>
#include <iostream>
int main()
{
hk_drivermanager* mydrivermanager = new hk_drivermanager();
if (mydrivermanager==NULL) {cout <<"error creating mydrivermanager"<<endl;exit(1);}
hk_connection* myconnection = mydrivermanager->new_connection("postgres");
if (myconnection==NULL) {cout <<"error creating myconnection"<<endl;exit(1);}
myconnection->set_host("localhost");
myconnection->set_user("login");
myconnection->set_password("haslo");
myconnection->connect();
hk_database* mydatabase=myconnection->new_database("test");
if (mydatabase==NULL) {cout <<"error creating mydatabase"<<endl;exit(1);}
hk_datasource* mydatasource= mydatabase->new_table("boo_rk_cmf_global_lang");
if (mydatasource==NULL) {cout <<"error creating mydatasource"<<endl;exit(1);}
mydatasource->enable();
hk_column* mycolumn = mydatasource->column_by_name("lang_string");
if (mycolumn==NULL) {cout <<"error getting column"<<endl;exit(1);}
// Tutaj owy kod jest
// edytujemy dany wiersz
mycolumn->set_asstring("nowy wpis");
// zapisujemy
mydatasource->store_changed_data();
delete mydrivermanager;
}
hk_classes pozwala również na dodawanie i usuwanie wierszy jak i ich przeszukiwanie. Pełen opis znajduje się w dokumentacji klasy lecz np dodawanie pełnego wpisu do wieloelementowej tabeli najlepiej zrobić poprzez zwykłe zapytanie INSERT.
- Dodane: 14.07.2008 przez riklaunim