Webbasierte Adressdatenbank

AdressDB die Zweite
Das Script gibt es hier, einfach anklicken, und als adress_2.pl abspeichern.
Für die ganz Ungeduldigen jetzt eine Kurzanleitung zur Installation: Zuerst holt man sich die Module DBI, Text::CSV_XS, SQL::Statement und DBD::File entweder vom CPAN oder von ActiveState und installiert wie in Installation von Perl Modulen beschrieben. Dann Skript ins cgi-bin Verzeichnis des Webservers stellen und ausführbar machen (Linux Rechte 755). Beim ersten Mal mit adress_2.pl?init=1 aufrufen, damit das Datenbankfile erstellt wird.
Eine Darstellung der Bildschirmausgabe spare ich mir, da hier keine Veränderungen gegenüber der Version 1 entstanden sind. Mein Versprechen das Skript würde nur ca 150 Zeilen lang lies sich allerdings nicht halten. Jetzt liegen wir bei ca 270 Zeilen Code. Dafür ist das Programm auch für Ungeübte besser lesbar.

Wie funktioniert's?
Es haben sich nur dort Änderungen gegenüber adress_1.pl ergeben, wo auf die Daten zugegriffen wird. Wir benutzen das DBI Modul und den DBD für eine Flatfile Datenbank. Die dazu notwendigen Variablen werden in Zeile 24-30 definiert. in Zeile 36 verbinden wir uns mit der Datenbank. Alle Unterprogramme, die auf die Datenbank zugreifen, bekommen beim Aufruf das Datenbankhandle  $dbh  übergeben. In den Zeilen 40-62 verzweigen wir, je nach gesetzten Parametern in die entsprechenden Unterprogramme. Um Daten Einzufügen oder zu Ändern ( &Einfuegen ), verwenden wir die UPDATE bzw INSERT Anweisung. Sollen Daten gelöscht werden ( &Loeschen ) definieren wir eine entsprechende SQL Anweisung in Zeile 163 und führen sie in Zeile 165 aus. Das Suchen ( &Suchen ) ist jetz wesentlich einfacher, wir müssen nicht mehr das ganze Textfile einlesen, sondern können mit einer SELECT Anweisung auf die Daten zugreifen (Zeile 186ff). Vorher legen wir noch die Bedingung zum Suchen in der WHERE Anweisung fest (Zeile 178ff). Auch die Routine zum Füllen der Eingabemaske mit Daten, wenn eine Änderung ansteht, läßt sich mit einer SELECT Anweisung (Zeile 236ff) durchführen. Die notwendigen Parameter füllen wir aus eine Hashreferenz (Zeilen 243-245), die wir mit der  $row=$sth->fetchrow_hashref  Anweisung aus der Datenbank mit Daten belegen. Neu hinzugekommen ist die Routine  &init_db . Hier erzeugen wir ein Verzeichnis  addressbook  unterhalb des  cgi-bin  Verzeichnises, in dem unser Perl Programm liegt. Dies hat den Vorteil, daß die, den Webserver ausführende Instanz dort auch Schreibrechte hat. Allerdings vom Standpunkt der Sicherheit aus gesehen ist dies eher bedenklich, da wir aber erst einmal grundsätzlich verstehen wollen, wie das Skript arbeitet, soll uns die Sicherheit im Moment weniger belasten.

Das Skript adress_2.pl

  1: #!/usr/bin/perl -w
  2: 
  3: use CGI qw/:standard :netscape/;
  4: use CGI::Carp qw/fatalsToBrowser/;
  5: use strict;
  6: use DBI;
  7: 
  8: ##################################################
  9: # adress_2.pl Copyright 1999 Dr. Thomas Wieland
 10: # wieland@k-town.de
 11: # fuer den Perl-Stammtisch im Rahmen des
 12: # 1. Pirmasenser Internetclubs
 13: ##################################################
 14: 
 15: 
 16: ##################################################
 17: # Variablendeklaration
 18: ##################################################
 19: 
 20: # Methode der Datenuebergabe im Formular GET oder POST
 21: # POST, wenn Daten in URL nicht auftauchen sollen
 22: my $method = 'GET';
 23: 
 24: my $DB_DIR      = "./addressbook";
 25: my $DB_DSN      = "DBI:CSV:f_dir=$DB_DIR";
 26: my $DB_USER     = "";
 27: my $DB_PASSWD   = "";
 28: 
 29: my @dbfields = qw/fname lname phone email street plz addr/;
 30: my $dbflist  = join(', ', @dbfields);
 31: 
 32: print header(), 
 33:       start_html(-BGCOLOR => 'white', 
 34:                  -title => 'Adress DB die Zweite');
 35: 
 36: my $dbh = DBI->connect($DB_DSN, $DB_USER, 
 37:                 $DB_PASSWD, { RaiseError => 1 });
 38: 
 39: 
 40: if (param('insert')) {
 41:     &Einfuegen($dbh, map { param($_) } @dbfields);
 42:     &Ueberschrift;
 43:     &Suchformular;
 44: } elsif (param('delete')) {
 45:     &Loeschen($dbh);
 46:     &Ueberschrift;
 47:     &Suchformular;
 48: } elsif (defined param('search')) {
 49:     &Ueberschrift;
 50:     &Suchen($dbh);
 51: } elsif (param('edit')) {
 52:     &Ueberschrift;
 53:     &get_data($dbh);
 54:     &Eingabeformular;
 55: } elsif(param('init')) {
 56:     &Ueberschrift;
 57:     &Suchformular;
 58:     init_db($dbh);
 59: } else {
 60:     &Ueberschrift;
 61:     &Suchformular;
 62: }
 63: 
 64: print end_html();
 65: 
 66: $dbh->disconnect;
 67: 
 68: ##################################################
 69: sub Ueberschrift {
 70: ##################################################
 71:     print center(h1("Adress DB die Zweite")),
 72:           hr;
 73: }
 74: 
 75: ##################################################
 76: sub Suchformular {
 77: ##################################################
 78:     print start_form(-method => $method),
 79:           p(a({href => url() .  "?search="},
 80:               " Alle Einträge")),
 81:           p("Suchbegriff: ", 
 82:             textfield(-name => 'lname')),
 83:           p(" Bitte Nachname oder Vorname oder ". 
 84:             "Anfangsbuchstabe eingeben (Groß und ".
 85:             "Kleinschreibung beachten)! "),
 86:           p(submit(-name => 'search',
 87:                    -value => 'Suche starten'),
 88:             submit(-name => 'edit',
 89:                    -value => 'Neuer Eintrag')),
 90:           end_form();
 91: }
 92: 
 93: ##################################################
 94: sub Eingabeformular {
 95: ##################################################
 96:     print start_form(-method => $method),
 97:           hidden(-name => 'id'),
 98:           table({"border" => 1},
 99:           TR(td("Vorname:"), 
100:              td(textfield(-name => 'fname', -size => 40))),
101:           TR(td("Nachname:"), 
102:              td(textfield(-name => 'lname', -size => 40))),
103:           TR(td("Telefon:"), 
104:              td(textfield(-name => 'phone', -size => 40))),
105:           TR(td("Email:"), 
106:              td(textfield(-name => 'email', -size => 40))),
107: 	      TR(td("Straße:"), 
108:              td(textfield(-name => 'street', -size => 40))),
109: 	      TR(td("PLZ:"), 
110:              td(textfield(-name => 'plz', -size => 10))),
111:           TR(td("Ort:"), 
112:              td(textfield(-name => 'addr', -size => 40))),
113:           ),
114:           p(submit(-name  => 'insert', 
115:                    -value => 'Speichern'), 
116:             submit(-name  => 'delete', 
117:                    -value => 'Eintrag löschen')), 
118:           end_form();
119: }
120: 
121: ##################################################
122: sub Einfuegen {
123: ##################################################
124:     my ($dbh, $fname, $lname, $phone, 
125:         $email, $street, $plz, $addr) = @_;
126: 
127:     # id existiert Eintrag aendern
128:     if (param('id')) {
129:         my $id = param('id');
130:      
131:         my $sql = qq[ 
132:           UPDATE addressbook
133:           SET id='$id', fname='$fname', 
134:               lname='$lname', phone='$phone', 
135:               email='$email', street='$street',
136:               plz='$plz', addr='$addr'
137:           WHERE id = '$id'];
138:         
139:         $dbh->do($sql);   
140: 
141:     # keine id vorhanden hinzufuegen	
142:     } else {
143:         my $id = time . $$;  # Generate ID
144:  
145:         my $sql = qq[
146:           INSERT INTO addressbook
147:           (id, $dbflist)
148:           VALUES ('$id', '$fname', '$lname', '$phone', 
149:                   '$email', '$street', '$plz', '$addr')];
150: 
151:         $dbh->do($sql);    
152:     }
153: 
154:     # alle Parameter param('..') loeschen
155:     Delete_all();
156: }
157: 
158: ##################################################
159: sub Loeschen {
160: ##################################################
161:     my $dbh = shift;
162:     my $id = $dbh->quote(param('id'));
163:     my $sql = qq[ DELETE FROM addressbook
164:                   WHERE id = $id];
165:     $dbh->do($sql);
166:     
167:     # alle Parameter param('..') loeschen
168:     Delete_all();
169: }
170: 
171: ##################################################
172: sub Suchen {
173: ##################################################
174:     my ($dbh) = shift; 
175:     my $where_clause = "";
176:     my ($sth, $row);
177: 
178:     # Wurde ein Suchparameter eingegeben
179:     if (param('lname')) {
180:         my $keyword  = $dbh->quote(param('lname')."%");
181:         $where_clause = qq[
182:             WHERE fname CLIKE $keyword OR
183:                   lname CLIKE $keyword];
184:     }
185:     
186:     my $sql = qq[ SELECT id, $dbflist
187:                   FROM addressbook
188:                   $where_clause
189:                   ORDER BY lname];
190:     
191:     $sth = $dbh->prepare($sql);
192: 
193:     $sth->execute();
194: 
195:     print "<center><TABLE BORDER=1>\n";
196:     print TR(map { th($_) } 
197:       qw/Name Telefon Email Straße PLZ Ort/);
198: 
199:     while ($row = $sth->fetchrow_arrayref) {
200:         print "\n<TR>",
201:               td(a({href => url() . "?id=$row->[0]&edit=1"}, 
202:                  "$row->[2], $row->[1]"));
203:         if ($row->[3]) { print td($row->[3]);
204:         } else { print td(" ")
205:         };
206:         if ($row->[4]) { print td(a({href => "mailto:$row->[4]"}, 
207:                                   "$row->[4]"));
208:         } else { print td(" ") 
209:         };
210:         if ($row->[5]) { print td($row->[5]);
211:         } else { print td(" ")
212:         };
213:         if ($row->[6]) { print td($row->[6]);
214:         } else { print td(" ")
215:         };
216:         if ($row->[7]) { print td($row->[7]);
217:         } else { print td(" ")
218:         };
219:     }
220:     print "</table>",
221:           hr, a({href => url()}, "Zurück zum Anfang"), 
222:           "</center>";
223:     
224:     $sth->finish();
225:     # alle Parameter param('..') loeschen
226:     Delete_all();
227: }
228: 
229: ##################################################
230: sub get_data {
231: ##################################################
232:     my $dbh = shift;
233:     my ($key, $row);
234:     if (defined(param('id'))) {
235:         my $id  = param('id');
236:         my $sql = qq[ SELECT id, $dbflist FROM addressbook 
237:                    WHERE id = '$id' ];
238: 
239:         my $sth = $dbh->prepare($sql);
240:         $sth->execute;
241:         
242:         while ($row = $sth->fetchrow_hashref) {
243:             foreach $key (keys %{$row}) {
244:                 param(-name => $key,  -value => $row->{$key});
245:             }
246:         }
247:     }
248: }
249: 
250: ##################################################
251: sub init_db {
252: ##################################################
253:     my $dbh = shift;
254: 
255:     if(! -d $DB_DIR) {
256:         mkdir($DB_DIR, 0755) || 
257:             die "Cannot create dir $DB_DIR";
258:     }
259: 
260:     my $sql=qq[CREATE TABLE addressbook (
261:             id     char(20),  fname  char(40),  
262:             lname  char(40),  phone  char(40),
263:             email  char(40),  street char(40),
264:             plz    char(10),  addr   char(100)
265:         )];
266: 
267:     $dbh->do($sql);
268: }

Literaturhinweise:

Zurück zum Anfang dieses Projekts.