Wstęp do baz danych: ćwiczenia 4 (2001/2002)

Pike to interpretowany, obiektowy język programowania o składni wyrażeń zbliżonej do C/C++/Java. Nie jest może zbyt szeroko spopularyzowany, ale jest łatwy, prosty i wygodny w użyciu, posiada dogodne złożone typy danych i dobrze współdziała z (niektórymi) serwerami relacyjnych baz danych (jak np. MySQL) oraz z serwerami WWW: Roxen i Caudium. Te ostatnie to główne aplikacje oparte na języku Pike. Umożliwia również programowanie graficzne (okienkowe) z wykorzystaniem bibliotek Gnome/GTK oraz OpenGL. Programy w Pike pisze się dość łatwo, wydajność (szybkość programów, wymagania pamięciowe) jest porównywalna z językiem Perl, przy bardziej przejrzystej składni i strukturze obiektowej.

Interpreter języka Pike jest zainstalowany na komputerze primus, w paru różnych wersjach; wersja najbardziej aktualna i z dostępem do bibliotek GTK występuje jako /usr/bin/pike7.2. NB. aby było możliwe uruchomienie programu takiego, jak stoper, tj. korzystającego z okieniek, najlepiej zdalną sesję na primus uruchomić przez slogin -X primus.okwf.fuw.edu.pl (dotyczy to dostępu z sal pracowni OKWF).

Materiały pomocnicze

Przykłady i zadania

  1. Przeszukanie zadanego poddrzewa katalogów w poszukiwaniu linków symbolicznych ,,wskazujących w próżnię''; program boguslinks.
    Zadanie: zmodyfikować ten programik tak, aby na koniec wypisywał jeszcze komunikat według wzorca
    Found nlink symlinks, nbogus bogus (percent%)
    oczywiście w miejsce nlink itd. powinny pojawić się odpowiednie liczby.
  2. Programik tworzący statystykę imion użytkowników systemu, tj. posortowaną alfabetycznie listę pozycji postaci Imię: częstość. Informacje o kontach pobieramy za pomocą funkcji getpwent().
    Funkcja ta to array(string|int) getpwent(); tzn. wywołuje się ją bez argumentów, a zwraca tablicę której elementami są napisy i liczby całkowite -- są to wartości zapisane w kolejnych polach jednego rekordu passwd. W kolejnych wywołaniach getpwent() zwracane będą kolejne rekordy passwd, w kolejności nieokreślonej lecz bez powtórzeń. W razie potrzeby, czytanie bazy passwd można zacząć od nowa wywołując setpwent(). Po zakończeniu odczytywania zawartości bazy warto ją zamknąć, wywołując endpwent() -- szczególnie jeżeli w dalszej pracy programu może powstać potrzeba by znów czytać dane z passwd.
    W jakiej kolejności pola passwd występują w tablicy zwracanej przez getpwent()? Najprościej sprawdzić to interakcyjnie:
    bash-2.05a$ pike
    Pike v7.2 release 236 running Hilfe v2.0 (Incremental Pike Frontend)
    > getpwent();
    Result: ({ /* 7 elements */
                "root",
                "x",
                0,
                0,
                "root",
                "/root",
                "/bin/bash"
            })
    >
    
    Inne pokrewne funkcje to array(int|string) getpwnam(string pw_name) oraz array(int|string) getpwuid(int pw_uid). Łatwo dojść co one robią, czytając dokumentację (man) ich imienniczek z biblioteki C, lub eksperymentując w trybie interakcyjnym.

    Zadanie: niech opcja -n powoduje wypisanie listy posortowanej wg. częstości wystąpień, z zachowaniem porządku alfabetycznego dla przypadków o równej częstości.
  3. Programik obliczający statystykę wielkości plików w zadanym poddrzewie katalogów, w postaci mogącej posłużyć do stworzenia histogramu rozkładu wielkości plików (tj. np. 10 plików wielkości 0-100 KB, 13 plików 100-200 KB, itd.). Uwzględniamy jedynie pliki ,,zwyczajne'', a szerokość przedziału (100 KB w tym przykładzie) lub liczba przedziałów histogramu powinny móc być wybrane przez opcje wywołania (z zadaniem pewnych wartości domyślnych na wypadek braku odp. opcji).
    Tutaj przyda się funkcja object file_stat(string filename, int|void follow_links). A oto jak poznać jakie są atrybuty zwracanego przez nią obiektu:
    bash-2.05a$ pike
    Pike v7.2 release 236 running Hilfe v2.0 (Incremental Pike Frontend)
    > indices(file_stat("."));
    Result: ({ /* 20 elements */
                "ctime",
                "islnk",
                "mtime",
                "atime",
                "size",
                "rdev",
                "gid",
                "uid",
                "nlink",
                "mode",
                "ino",
                "dev",
                "type",
                "mode_string",
                "issock",
                "isfifo",
                "isblk",
                "ischr",
                "isdir",
                "isreg"
            })
    > file_stat(".")->type;
    Result: "dir"
    >
        
    itd.
    Dla ambitnych: tworzyć histogram w postaci pliku graficznego zapisywanego na dysku lub bezpośrednio wyświetlanego w oknie.
  4. Program analizujący plik poczty w formacie mbox i tworzący posortowaną listę adresów nadawców.
  5. (Dodatkowo, dla chętnych) Stoper: prosty gadżet okienkowy z wykorzystaniem GTK (ew. Gnome). Program tworzy okienko z dwoma guzikami: Start/Stop oraz Reset (zerujący), oraz odczytem czasu w sekundach. Przykładowa realizacja.
    Uwaga: istotne jest, że w tym przykładzie funkcja main zwraca -1; chodzi o to, aby po stworzeniu elementów interfejsu, powiązaniu ich z funkcjami (signal_connect) i wywołaniu wypełnionego okienka program nie zakończył natychmiast działania, tylko czekał na zdarzenia (w tym wypadku związane z działaniami użytkownika); taki jest efekt powrotu funkcji main z wartością ujemną (w Pike!). Program zakończy działanie, gdy użytkownik zamknie jego okno -- to trzeba było zapewnić za pomocą signal_connect("destroy", exit, 0).

Wstęp do baz danych: ćwiczenia 4 (2001/2002)