Spis treści

Gabinet dentystyczny - dodanie wizyt

Ostatnie dwie drzemki mojej córki spędziłam na “rozszerzaniu”  prorgamu “Gabinet”.

W “Gabinecie” można już dodawać pacjentom wizyty. Oprócz notatki związanej z wizytą oraz daty i godziny nic więcej na temat wizyt nie zapisuję. Programik posiada więc podstawową funkcjonalność biednego, CRUD-owego prototypu.

Rzeczy do zrobienia (TODO)

Aby był on choć trochę używalny, koniecznie trzeba jeszcze dodać:

  • stronicowanie (w sensie: paginację) dla tabel
  • wyszukiwanie pacjentów
  • pokazywanie wizyt: dzisiejszych, w tym ygodniu, wszystkich
  • schemat zębowy dla pacjenta (to pewnie byłaby bardziej interaktywna część)

Ciekawe, czy starczy mi motywacji, żeby zaimplementować choć część z powyższych funkcji.

Czego się nauczyłam

  • Go: odpowiednikiem javowego toString() jest w go imlementacja String() string (z receiverem)
  • SQLite: foreign key constraint - ograniczenie klucza obcego - nie jest domyślnie włączone w sqlite3 (patrz foreign key):
1
2
3
sqlite> PRAGMA foreign_keys;
foreign_keys
0

i powinno być włączane jako opcja w napisie definiującym połączenie. W dokumentacji go-sqlite3 jest wyszczególniona opcja połączenia _fk=Boolean której mogę użyć:

1
2
connstr := fmt.Sprintf("%s?_fk=true", dbname)
db, err = sql.Open("sqlite3", connstr)
  • Definicja klucza obcego następuje po definicji kolumny i powinna zawierać klauzulę foreign key (a nie tylko references); dlatego zamiast:
1
2
3
4
5
6
create table if not exists visit (
  id integer primary key,
  vdatetime datetime not null default CURRENT_TIMESTAMP,
  patient_id integer references patient(id),
  note_id string references note(id)
);

powinno być

1
2
3
4
5
6
7
8
create table if not exists visit (
  id integer primary key,
  vdatetime datetime not null default CURRENT_TIMESTAMP,
  patient_id integer not null,
  note_id integer,
  foreign key(patient_id) references patient(id),
  foreign key(note_id) references note(id)
);

Screenshoty

Pusta baza

Po uruchomieniu programu bez wskazania żadnej bazy (lub po podaniu nazwy nieistniejącej bazy) zostanie utworzona nowa baza danych oraz uruchomiony serwer http z gotowym programem: Gabinet - bez pacjentów

Dodanie pacjenta

W zakładce “Pacjenci” można dodać nowego pacjenta: Gabinet - nowy pacjent

Zapisanie pacjenta

Zapisanie danych pacjenta powoduje dodanie go do tabelki pacjentów po lewej stronie.

  • dane każdego pacjenta można wyświetlić i zmieniać po wybraniu odnośnika “Dane”
  • listę wizyt pacjenta można zobaczyć wybierając odnośnik “Wizyty”
Gabinet - zapisany pacjent

Zapisanie kolejnego pacjenta

Oprócz Edwarda Nożycorękiego gabinet odwiedza również Papa Smerf:

Gabinet - zapisany pacjent

Wizyty

Oto wizyty Edwarda:

Gabinet - brak wizyt

Nowa wizyta

Jak widać, lista jest pusta, więc dodaję nową wizytę.

Gabinet - dodanie wizyty

Druga wizyta

Kolejne wizyty - podobnie jak kolejni pacjenci - widoczne są w tabelce z lewej strony ekranu. Po dodaniu drugiej wizyty Edwarda:

Gabinet - kolejna wizyta

Wizyty innego pacjenta

Drugi pacjent ma dodane dwie wizyty:

Gabinet - wizyty innego pacjenta

Wszystkie wizyty

Wszystkie wizyty (wszystkich pacjentów) widoczne są po wybraniu odnośnika “Wizyty” w głównym pasku “menu” programu:

Gabinet - wszystkie wizyty

Wnioski

  • praca z błędami w Go jest dziwna: funkcje “deferred” wydają mi się analogiczne do bloków finally, ale chyba jeszcze nie mam dobrego modelu mentalnego
  • łatwiejsza do testowania byłaby z pewnoścą aplikacja wystawiająca API REST-owe oparte o JSON-a, a nie taka, która renderuje htmla
  • kliencka aplikacja (Vue, React) wołająca backend mogłaby być rozwijana niezależnie od kodu serwera (wcześniej bądź później niż serwer)
  • konieczność przełączania się z kodu serwera do częśsci GUI-owej sprawia, że mam ochotę chodzić na skróty i nie chce mi się tworzyć warstw izolujących GUI od części backendowe
  • go-gin jest super szybki, cykl zmian od pomysłu i implementacji do ręcznego testowania zmian w działającej aplikacji to dosłownie sekunda (w czasie tej sekundy wciskam CTRL+C i UP żeby dostać wiersz z poleceniem uruchamiającym program, i Enter, i program się uruchamia)