Jak stworzyć moduł bazy danych

W tym artykule opisana została konstrukcja modułu bazy danych wykorzystywanego w eStats 4.9.

^ Wprowadzenie

Moduły baz danych zawierają funkcje (ściślej, metody klas / obiektów) wymagane do zbierania i obróbki danych w celu ich prezentacji. Jeden moduł jest przeznaczony do obsługi jednego typu baz danych (chyba, że inne są z nią w pełni kompatybilne, lub przynajmniej wystarczająco dla potrzeb prawidłowego działania modułu), mogą jednak wykorzystywać różne metody łączenia się z nimi (np. moduł obsługi bazy MySQL obsługuje ją przy użyciu jednego z rozszerzeń PHP, MySQL lub MySQLi, gdy dostępne).

Przyjmuje się, że moduły przeznaczone dla serii 4.0 posiadały numer wersji 1.x.xx, te dla serii 4.5 używają numeracji 2.x.xx. Moduły przeznaczone dla wersji 4.9 powinny używać numeracji 3.x.xx.

Jeśli chcesz stworzyć własny moduł, to zaleca się bazowanie na jednym z już istniejących, dołączonych do pakietu ze skryptem.

Nie zaleca się używania modułów z niesprawdzonych źródeł.

Moduły przechowywane są w katalogu lib/db/, nazwa katalogu jest identyfikatorem modułu, powinna wskazywać na typ używanej bazy danych. Moduł wybierany jest tylko w czasie instalacji, usunięcie aktualnie używanego modułu dezaktywuje zbieranie danych i uniemożliwi ich wyświetlenie.

^ Budowa

^ Struktura

Każdy moduł musi zawierać niżej wymienione pliki (dodatkowe są dozwolone), na przykładzie modułu MySQL:

  • MySQL/ [wymagany - główny katalog modułu, nazwa taka jak jego identyfikator]
    • common.php [wymagany - plik wspólnych metod oraz tych używanych do zbierania danych]
    • db.ini [wymagany - plik konfiguracyjny]
    • gui.php [wymagany - plik metod używanych do wyświetlania danych]
    • install.php [wymagany - plik instalacyjny]
    • schema.php [wymagany - plik schematu bazy]

Plik common.php zawiera klasę bazową estats_db, natomiast gui.php klasę estats_db_gui, która rozszerza tę pierwszą. Zawierają one odpowiednio, metody wspólne oraz wymagane do zbierania danych oraz wspomagające wyświetlanie i obróbkę zebranych danych.

Poza metodami, obiekt zawiera definicje zmiennej $About (tablica zawierające opis modułu w różnych językach - identyfikatory języków są kluczami, wymagany jest przynajmniej język angielski) oraz zwykle definicję liku połączenia z bazą danych ($Link) oraz prefiks tabel, o ile jest wymagany ($Prefix).

Poza niżej opisanymi, każdy moduł może zawierać zmienne, metody czy nawet funkcje pomocnicze, pod warunkiem, że nie będę one kolidowały z wymaganymi.

^ Metody wymagane do zbierania danych

Plik common.php zawiera definicję klasy estats_db, o następujących metodach (wymaganych):

  • estats_db ([BOOLEAN czy_połączyć_z_bazą = 1]) (konstruktor) - ustawia zmienną $About oraz ewentualnie wywołuje metodę connect () w celu nawiązania połączenia z bazą danych;
  • connect (BOOLEAN czy_połączenie_testowe, STRING prefiks_tabel, BOOLEAN czy_stałe_połączenie[, dodatkowe argumenty]) - używa danych konfiguracyjnych (conf/config.php) stosownych dla każdego modułu w celu nawiązania połączenia z bazą danych. W przypadku nieudanej próby połączenia wywoływana jest funkcja e_error;
  • update (STRING nazwa_tabeli, STRING argument) - zwiększa liczbę wystąpień o jeden w podanej tabeli dla podanego argumentu;
  • update_software (STRING nazwa_tabeli, ARRAY argument) - zwiększa liczbę wystąpień o jeden w podanej tabeli dla podanego argumentu (dla tabel przeglądarek i systemów operacyjnych);
  • update_sites (ARRAY argument) - zwiększa liczbę wystąpień o jeden w tabeli stron dla podanego argumentu;
  • update_geoip (ARRAY argument) - zwiększa liczbę wystąpień o jeden w tabeli geolokalizacji dla podanego argumentu;
  • update_time (STRING typ_odwiedzin) - aktualizuje tabelę czasowych dla obecnej daty oraz dla podanego typu odwiedzin;
  • update_visit_details (INT id_gościa, STRING adres_strony) - dodaje informację o wizycie na stronie o podanym adresie gościa o podanym id;
  • update_visits_ignored (STRING adres_ip[, BOOLEAN czy_zablokowana = 0]) - zwiększa liczbę wystąpień o jeden w podanej tabeli dla podanego argumentu;
  • update_info (INT id_gościa, ARRAY argument) - aktualizuje dodatkowe informacje dla gościa o podanym id;
  • time_clause ([INT od[, INT do]]) - generuje fragment zapytania do bazy wyszczególniający okres, dla którego zapytanie jest adekwatne, dla argumentów od i do - uniksowych znaczników czasu (jeśli drugi jest równy 0, to zapytanie obejmie okres tylko od, jeśli pusty będzie pierwszy argument, to zwrócony zostanie pusty ciąg);
  • visits_amount (STRING typ[, INT od[, INT do]]) - zwraca liczbę odwiedzin podanego typu dla opcjonalnego zakresu czasu (uniksowe znaczniki czasu);
  • visitor_id_exists (INT id_gościa) - sprawdza czy w bazie znajduje się wpis z danymi gościa o podanym id;
  • visitor_id_get (STRING adres_ip) - sprawdza (i ewentualnie zwraca) czy istnieje identyfikator gościa o podanym adresie IP z czasem odwiedzin mniejszym niż połowa czasu trwania wizyty ($VisitTime);
  • visitor_id_max () - zwraca maksymalną wartość identyfikatora gościa zapisaną w bazie;
  • visitor_add (INT id_gościa, ARRAY argument) - dodaje do bazy dane gościa (zapisane w tablicy argument) o podanym id;
  • visitor_info_exists (INT id_gościa) - sprawdza czy dla gościa o podanym id znajdują się w bazie dodatkowe dane (zbierane z użyciem JS);
  • backup_create (ARRAY tabele, BOOLEAN czy_zachować_strukturę_tabel, BOOLEAN czy_zastępować_dane, BOOLEAN czy_użyć_formatu_sql) - generuje kopię zapasową według podanych parametrów, zwraca ciąg tekstowy zawierający kopię zapasową;
  • log (INT kod_logu[, STRING dodatkowa_informacja]) - zapisuje do tabeli logów czas, kod_logu oraz ewentualną dodatkową informację;
  • config_get (INT tryb) - pobiera konfigurację dla wybranego trybu (0 / 1) i zwraca ją w formie tablicy;
  • config_set (ARRAY tablica[, powiadom = 1]) - ustawia (lub tworzy je z trybem 1, jeśli nie istnieją) przekazane opcje (w formie tablicy - klucz: nazwa opcji, wartość: wartość opcji), jeśli opcjonalny parametr powiadom ma wartość 1 (domyślną), to dodatkowo informacja o zmianie konfiguracji jest zapisywana oraz wyświetlany jest komunikat;
  • disconnect () - zamyka połączenie z bazą danych;

^ Metody wymagane do wyświetlania danych

W pliku gui.php zdefiniowana jest klasa estats_db_gui rozszerzająca klasę estats_db, dodaje ona poniższe metody (wymagane):

  • data (STRING grupa, INT ilość[, INT od = 0[, INT do = 0]]) - zwraca tablicę z danymi z tabeli przypisanej do grupy dla podanego, opcjonalnego, zakresu czasu (od i do - liczby całkowite, uniksowe znaczniki czasu, 0 aby wyświetlić wszystkie dane), liczba pozycji jest limitowana przez ilość. Zwracana jest trzy elementowa tablica asocjacyjna, klucz data zawiera tablicę z danymi, sum sumę wartości wszystkich danych, a amount liczbę dostępnych danych;
  • data_countries () - zwraca tablicę z listą krajów, dla których znajdują się w bazie zebrane dane;
  • visit_details (INT identyfikator, INT numer_strony) - zwraca tablicę danych dla szczegółów wizyty dla użytkownika o podanym identyfikatorze, dla podanego numeru strony (jeśli nie istnieje, to jest ustawiana na 1). Tablica składa się z trzech elementów: data zawiera dane użytkownika, sites zawiera listę stron dla wybranego numeru strony, a page ostateczny numer strony. Jeśli nie ma danych użytkownika w bazie, to zwracane jest 0;
  • visits (BOOLEAN czy_wyświetlać_roboty, INT numer_strony) - zwraca tablicę danych dla szczegółowych, w zależności od czy wyświetlać roboty uwzględnia roboty sieciowe. Tablica składa się z trzech elementów: data zawiera dane dla wybranego numeru strony (jeśli nie istnieje, to jest ustawiana na 1), page ostateczny numer strony, a amount liczbę elementów w tabeli;
  • visits_previous (INT id_gościa[, INT poziom_zagłębienia = 0]) - rekurencyjnie generuje tablicę danych z listą poprzednich wizyt gościa o podanym identyfikatorze;
  • visits_next (INT id_gościa[, INT poziom_zagłębienia = 0]) - rekurencyjnie generuje tablicę danych z listą następnych wizyt gościa o podanym identyfikatorze;
  • visits_online () - zwraca liczbę gości on - line;
  • visits_most (STRING typ[, INT od = 0[, INT do = 0[, STRING jednostka = day]]]) - zwraca maksymalną liczbę wizyt danego typu, dla opcjonalnego zakresu czasu (uniksowe znaczniki czasu, od, do) oraz ewentualnej jednostki;
  • visits_excluded ([INT od = 0[, INT do = 0]]) - zwraca liczbę wykluczonych wizyt, dla opcjonalnego zakresu czasu (uniksowe znaczniki czasu, od, do);
  • visits_ignored (INT ilość, INT od_którego_wiersza) - zwraca tablicę danych dla listy zignorowanych i zablokowanych wizyt, dla podanej ilości rozpoczynając od podanego wiersza;
  • time (STRING jednostka[, INT od = 0[, INT do = 0[, ARRAY typy_wizyt = array (views, unique, returns)]]]) - zwraca tablicę danych dla czasowych, dla podanej jednostki, opcjonalnego zakresu czasu (uniksowe znaczniki czasu, od, do), z ewentualnym zawężeniem listy typów wizyt;
  • logs (INT ilość, INT od_którego_wiersza[, STRING warunek = '']) - zwraca tablicę danych dla podglądu logów, dla podanej ilości rozpoczynając od podanego wiersza, opcjonalny parametr warunek zawiera fragment zapytania limitującego wyniki;
  • logs_search_clause (ARRAY parametr) - generuje warunek zapytania ograniczający liczbę wyświetlanych logów, według danych w tablicy parametr, zwraca ciąg z fragmentem zapytania;
  • backup_restore (STRING identyfikator) - przywraca kopię zapasową o podanym identyfikatorze, zwraca logiczną prawdę jeśli operacja się powiedzie, w przeciwnym wypadku zwraca fałsz;
  • clean () - oczyszcza tabele odwiedzin szczegółowych, w zależności od ustawień;
  • verify (ARRAY schemat_tabel) - weryfikuje istnienie tabel dla podanego schematu oraz zleca weryfikację zawartości tabeli konfiguracji, zwraca logiczną prawdę, gdy są poprawne, w przeciwnym razie zwraca fałsz;
  • verify_configuration_option (STRING nazwa_opcji, INT tryb_opcji) - sprawdza, czy istnieje w tabeli konfiguracji opcja o podanej nazwie i wskazanym trybie, jeśli opcja istnieje, to zwraca logiczną prawdę, w przeciwnym wypadku zwraca fałsz;
  • table_reset (ARRAY tabele) - dokonuje resetu (usunięcia danych) z listy tabel podanych jako argument;
  • table_row_delete (STRING tabela, STRING wiersz) - usuwa z tabeli wiersz, który ma pole name o wartości wiersz;
  • table_rows_amount (STRING tabela[, STRING warunek = '']) - zwraca liczbę wierszy w tabeli, ewentualnie spełniających warunek, jeśli podany;
  • db_size () - zwraca wielkość bazy w bajtach, jeśli nie można jej pobrać, to zwraca ? (znak zapytania);

^ Plik instalacyjny

Zawiera kod wspomagający utworzenie struktury bazy danych i wprowadzenie wartości początkowych, w tym domyślnej konfiguracji.

Procedura instalacji i aktualizacji oparta jest o uniwersalny format kopii zapasowych (zawsze generowany jest odpowiedni plik w folderze kopii zapasowych).

Wymagane jest udostępnienie możliwości aktualizacji danych z poprzedniej wersji tego samego modułu, jeśli taka istniała.

Plik musi udostępniać zmienne:

  • $Available - determinuje czy dana baza danych jest obsługiwana na serwerze;
  • $OptionsInstall - tablica opcji dostępnych przy instalacji (z domyślnymi wartościami);
  • $OptionsUpgrade - tablica opcji dostępnych przy aktualizacji (z poprzednimi wartościami);
  • $OptionsUpgradeUnchanged - lista opcji, których wartości nie należy zmieniać przy aktualizacji;

Oraz funkcje (o przedrostku składającego się identyfikatora modułu, pisanego małymi literami, oraz znaku _, np. mysql_connection_test ()):

  • install_prepare (OBJECT obiekt_bazy, BOOLEAN czy_aktualizacja, RESOURCE uchwyt_pliku_kopii_zapasowej) - funkcja kończy generowanie kopii zapasowej i odpowiada za obróbkę i pobranie danych przy aktualizacji, zwraca logiczną prawdę, gdy zadanie zostało wykonane pomyślnie, fałsz w przeciwnym wypadku;
  • install_finish (OBJECT obiekt_bazy, BOOLEAN czy_aktualizacja) - funkcja zajmuje się "sprzątaniem" po instalacji lub aktualizacji (w przypadku tej drugiej może usuwać nieużywane już tabele);
  • connection_test () - opcjonalna funkcja do testowania połączenia z bazą danych, zwraca logiczną prawdę, gdy połączenie nawiązano pomyślnie, fałsz w przeciwnym wypadku;

Moduł może definiować także dodatkowe funkcje pomocnicze na własne potrzeby.

^ Plik schematu

Plik schema.php zawiera tablicę $Schema, w której znajdują się definicje tabel bazy danych, przykład (MySQL)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$Schema = array (
    'configuration' => '(`name` VARCHAR(50) NOT NULL, `value` VARCHAR(200) NOT NULL, `mode` TINYINT(1) NOT NULL, PRIMARY KEY(`name`))',
    'logs' => '(`time` TIMESTAMP NOT NULL, `log` SMALLINT(6) NOT NULL, `info` VARCHAR(100))',
    'time' => '(`time` TIMESTAMP NOT NULL, `views` INT(11) NOT NULL, `unique` INT(11) NOT NULL, `returns` INT(11) NOT NULL, PRIMARY KEY (`time`))',
    'visitors' => '(`id` INT(11) NOT NULL, `firstvisit` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', `lastvisit` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', `visitsamount` INT(5) NOT NULL, `ip` VARCHAR(20) NOT NULL, `useragent` VARCHAR(250), `host` VARCHAR(200), `referrer` VARCHAR(250), `language` VARCHAR(5), `javascript` TINYINT(1), `cookies` TINYINT(1), `flash` VARCHAR(5), `java` TINYINT(1), `screen` VARCHAR(12), `info` TINYINT(1), `robot` VARCHAR(20), `proxy` VARCHAR(100), `proxyip` VARCHAR(20), `previous` INTEGER, PRIMARY KEY(`id`))',
    'details' => '(`id` INT(11) NOT NULL, `address` VARCHAR(200) NOT NULL, `time` TIMESTAMP NOT NULL)',
    'ignored' => '(`lastview` TIMESTAMP NOT NULL, `lastvisit` TIMESTAMP NOT NULL, `firstvisit` TIMESTAMP NOT NULL, `ip` VARCHAR(20) NOT NULL, `unique` INT(11) NOT NULL, `views` INT(11) NOT NULL, `useragent` VARCHAR(250) NOT NULL, `type` TINYINT(1) NOT NULL, PRIMARY KEY(`ip`, `type`))',
    'geoip' => '(`time` TIMESTAMP NOT NULL, `city` VARCHAR(50) NOT NULL, `region` VARCHAR(50) NOT NULL, `country` VARCHAR(10) NOT NULL, `continent` VARCHAR(10) NOT NULL, `latitude` DOUBLE, `longitude` DOUBLE, `amount` INT(11), PRIMARY KEY(`city`, `country`))',
    'browsers' => '(`time` TIMESTAMP NOT NULL, `name` VARCHAR(50) NOT NULL, `amount` INT(11) NOT NULL, `version` VARCHAR(20) NOT NULL, PRIMARY KEY(`time`, `name`, `version`))',
    'oses' => '(`time` TIMESTAMP NOT NULL, `name` VARCHAR(50) NOT NULL, `amount` INT(11) NOT NULL, `version` VARCHAR(20) NOT NULL, PRIMARY KEY(`time`, `name`, `version`))',
    'sites' => '(`time` TIMESTAMP NOT NULL, `name` VARCHAR(50) NOT NULL, `amount` INT(11) NOT NULL, `address` VARCHAR(200) NOT NULL, PRIMARY KEY(`time`, `name`, `address`))'
    );
$DBTables = array ('cookies', 'flash', 'hosts', 'java', 'javascript', 'keywords', 'languages', 'proxy', 'referrers', 'robots', 'screens', 'websearchers');
for ($i = 0; $i < count ($DBTables); ++$i) $Schema[$DBTables[$i]] = '(`time` TIMESTAMP NOT NULL, `name` VARCHAR(200) NOT NULL, `amount` INT(11) NOT NULL, PRIMARY KEY(`time`, `name`))';
?>

Dane te używane są podczas instalacji oraz funkcje generujące i przywracające kopie zapasowe (do utworzenia lub regeneracji tabel).

^ Plik konfiguracyjny

Plik konfiguracyjny posiada format INI, zawiera podstawowe informacje na temat modułu (sekcja Information).

  • Name - nazwa modułu;
  • DB - typ bazy danych obsługiwany przez moduł;
  • Author - pseudonim lub imię i nazwisko autora;
  • URL - strona domowa;
  • Version - wersja (format x.x.xx);
  • Status - status modułu (stable / beta / RC / alfa / pre / inne);
  • Licence - licencja;
  • Time - czas ostatniej modyfikacji (uniksowy znacznik czasu);

Dane z tego pliku wczytywane są do tablicy $DBInfo, dodatkowo moduł ustawia klucz DBVersion z wersją bazy danych, jeśli można ją pobrać.

Przykład (moduł MySQL):

1
2
3
4
5
6
7
8
9
[Information]
Name = "eStats MySQL"
DB = "MySQL"
Author = "Emdek"
URL = "http://estats.emdek.cba.pl"
Version = "3.0.03"
Status = "RC"
Licence = "GPL"
Time = "1203079581"

^ Działanie

W przypadku zbierania danych pliki są dołączane w następującej kolejności: conf/config.php, lib/common.php, lib/db/identyfikator_modułu/common.php. Ładowany jest także plik konfiguracyjny lib/db/identyfikator_modułu/db.ini. Następnie tworzony jest obiekt $DB klasy estats_db (o ile nie wystąpił błąd przy ładowaniu plików). Potem pobierana jest konfiguracja w trybie 0 (o ile nawiązano połączenie z bazą danych) i skrypt przechodzi do zbierania danych (o ile statystyki są aktywne i nie wystąpiły żadne błędy krytyczne).

W trybie prezentacji danych dołączana jest także biblioteka lib/gui.php oraz plik lib/db/identyfikator_modułu/gui.php. Następnie tworzony jest obiekt $DB klasy estats_db_gui (rozszerzona klasa estats_db, o ile nie wystąpił błąd przy ładowaniu plików). Potem pobierana jest konfiguracja w trybie 0 i 1 (o ile nawiązano połączenie z bazą danych) i skrypt przechodzi do dalszych zadań (o ile nie wystąpiły żadne błędy krytyczne).

Opis poszczególnych metod znajduje się powyżej, w stosownych sekcjach.

^ Zakończenie

Napisanie modułu wymaga sporej ilości wiedzy i samozaparcia, więc jeśli stworzysz jakiś, to podziel się nim z innymi, aby Twoja praca nie została zmarnowana ;-). W przypadku pytań lub chęci pokazania efektów pracy pisz w odpowiednim dziale forum.

Ostatnia modyfikacja: 2008-02-17 21:08:52 CET

Mówienie bez myślenia to jak strzelanie bez celowania.

Zbigniew Herbert