Thread Meldeliste auf Website erstellen (23 answers)
Opened by seemann at 2011-07-14 18:45

rosti
 2011-07-15 23:37
#150451 #150451
User since
2011-03-19
3472 Artikel
BenutzerIn
[Homepage]
user image
Bitte mal testen und feedback. Ich wollte es als PM schicken, es sah jedoch so aus, als wollte die Einrückung kaputt gehen... deswegen hier.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
###########################################################################
#
# Dateiname: Kladde.pm
# Einfache Klasse für eine Tabelle
# Rolf Rost, 15.7.2011
#
###########################################################################
package Kladde;

use strict;
use warnings;
use DBI;

# Object beeinhaltet die Definition der Felder und
# die Definition des Primary Key
sub new{
        my $class = shift;
        my %opts = @_;
        # Definiere die erforderlichen Felder
        # [0]-> Attribute DB, Feldtype
        # Achtung, es kommt noch ein Feld für das Einfügedatum hinzu
        # fest codiert: Feldname 'datime'
        my $self = bless{
                FIELDS => {
                        name =>  ["varchar(100) NOT NULL DEFAULT ''", 'Familienname'],
                        vorname => ["varchar(100) NOT NULL DEFAULT ''", 'Vorname'],
                        wohnort => ["varchar(100) NOT NULL DEFAULT ''", 'Wohnort'],
                        email => ["varchar(100) NOT NULL DEFAULT ''", 'Email'],
                        homepage => ["varchar(255) NOT NULL DEFAULT ''", 'Website'],
                        typ =>  ["varchar(100) NOT NULL DEFAULT ''", 'Schiffstyp'],
                        descr => ["text", 'Angaben zur Person'],
                        dienstzeit => ["varchar(100) NOT NULL DEFAULT ''", 'Dienstzeit von bis'],
                        dienstgrad => ["varchar(100) NOT NULL DEFAULT ''", 'Dienstgrad'],
                        dienststellung => ["varchar(100) NOT NULL DEFAULT ''", 'Dienststellung'],
                        einheit => ["varchar(100) NOT NULL DEFAULT ''", 'Name der Einheit'],
                        nummer => ["varchar(100) NOT NULL DEFAULT ''", 'Schiffsnummer'],
                },
                PKEY => q(name, vorname, email),
                DBH => undef,
        }, $class;
        
        $self->_handle(%opts) or return;    # Fehler in $@
        return $self;
}

########################## PRIVATE METHODS ################################
# Erstelle DataBaseHandle
sub _handle{
        my $self = shift;
        # Default Settings
        my %opts = (
                base => 'myweb',      # Name der Datenbank
                user => '',           # DB Benutzername
                pass => '',           # DB Passwort
                port => 3306,         # DB Port
                host => 'localhost',  # DB Host
                tabn => 'kladde',     # Name der Tabelle
                @_,                   # Parameter
        );

        # Alle Keys muessen definiert sein
        foreach my $k(keys %opts){ return if not defined $k } 

        # Data Source Name
        my $dsn = "DBI:mysql:database=$opts{base};host=$opts{host};port=$opts{port}";
        eval{
                $self->{DBH} = DBI->connect_cached(
                        $dsn, $opts{user}, $opts{pass}, {
                                RaiseError => 1, 
                                PrintError => 0,
                        }
                );
        };
        
        if($@){
                return;
        }
        else{
                $self->{TABN} = $self->{DBH}->quote_identifier($opts{tabn});
                return 1;
        }
}
########################## PUBLIC METHODS #################################
# Tabelle erstellen
sub create_table{
        my $self = shift;

        # Felder aufarbeiten, quote_identifier
        my @fields  = ();
        foreach my $f(keys %{$self->{FIELDS}}){
                my $qf = $self->{DBH}->quote_identifier($f);
                # Attribute hinzu
                push @fields, qq($qf $self->{FIELDS}->{$f}->[0]);
        }
        
        # Datum/Zeitfeld hinzu
        push @fields, qq(datime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00');

        # Falls ein Primary Key sein soll
        if(defined $self->{PKEY}){ push @fields, qq(PRIMARY KEY ($self->{PKEY})) }
        
        my $fields = join ",", @fields;

        # Statement
        my $q = qq(
                CREATE TABLE $self->{TABN} (
                        $fields
                ) ENGINE=MyISAM DEFAULT CHARSET=utf8 
        );

        eval{ $self->{DBH}->do($q) };
        return $@ ? undef : 1;
}
###########################################################################
# Tabelle entfernen
sub drop_table{
        my $self = shift;
        eval{ $self->{DBH}->do("DROP TABLE $self->{TABN}") };
        return $@ ? undef : 1;
}

# INSERT, nach dem ersten Aufruf liegt das prepared Statement im Objekt
# Damit werden mehrere aufeinanderfolgende Inserts performanter
sub insert{
        my $self = shift;
        my %vals = @_; # hash
        
        # Reihenfolge hier egal aber später beim Einbau genauso wie hier!!!
        my @fields = keys %{$self->{FIELDS}};
        
        # Achtung, das Feld 'datime' geht extra mit NOW()

        # erzeuge prepared Statement
        if(not defined($self->{STH_INSERT})){
                my @qms = ();     # Question Marks
                my @updates = (); # Falls ein Primary Key definiert ist
                for(@fields){
                        push @qms, "?";
                        push @updates, "$_=?";
                }
                my $q = "INSERT INTO $self->{TABN} (".join(",", @fields).", datime) VALUES(".join(",", @qms).", NOW() )";
                $q .= " ON DUPLICATE KEY UPDATE ".join(",", @updates).", datime=NOW()";

                $self->{STH_INSERT} = $self->{DBH}->prepare_cached($q); 
        }
        
        # Konsistenzprüfung der einzugebenden Werte
        my @input = ();
        foreach my $f(@fields){
                if(my $val = $vals{$f}){
                        push @input, $val;
                }
                else{
                        $@ = "Eingabefelder nicht korrekt mit Werten";
                        return;
                }
        }
        eval{ $self->{STH_INSERT}->execute(@input, @input) };

        return $@ ? undef : 1;
}
###########################################################################
# Löschen nach bestimmten Keys
sub delete{
        my $self = shift;
        my %keys = @_; 
        
        if(not keys %keys){
                $@ = "Keine Schluesselwerte definiert",
                return;
        }
        
        # Where Klause zusammenbauen
        my @where = ();
        foreach my $k(keys %keys){
                my $v = $self->{DBH}->quote($keys{$k});
                push @where, qq($k = $v);
        }
        my $where = "WHERE ".join(" AND ", @where);
        eval{ $self->{DBH}->do("DELETE FROM $self->{TABN} $where") };
        return $@ ? undef : 1;
}
1;#########################################################################


# Zum Testen entferne den END-Token und führe die Datei aus mit Perl
# Oder das Modul unter 'Kladde.pm' abspeichern und im Script mit 
# use Kladde;
# einbinden
__END__

package main;

use strict;
use warnings;

# Anwendung im CGI-Script
# Optionen für die Datenbank
my %myopts = (
        base => 'myweb',
        tabn => 'kladde',
        user => '',
        pass => '',
        host => 'localhost',
        port => 3306,
);

# Objekterstellung, DataBaseObject
# Zur Fehlerbehandlung immer $@ abfragen
# Jede Funktion liefert 1 bei Erfolg, undef bei NichtErfolg 
my $dbo = Kladde->new(%myopts) or die $@;;

# erklärt sich von selbst
# $dbo->create_table or die $@;
# $dbo->drop_table or die $@;



# Alle Felder müssen einen Wert bekommen
# Generalprobe mit einigen Inserts
for(1..2000){
        $dbo->insert(
                name => "Larson $_",
                vorname => "Holger $_",
                typ => 'Flaggschiff',
                descr => 'Meine Zeit bei Marina',
                wohnort => 'Buxtehude',
                email => "blonder_hans_$_\@example.com",
                dienstzeit => '1975-1978',
                dienstgrad => 'Vollmatrose',
                dienststellung => 'Klabautermann',
                einheit => 'Hannes Schinder',
                nummer => "abc/0815 $_",
                homepage => "http://example.com/$_",    
        ) or die $@;
}
# entsprechend der Keys wird gelöscht
#$dbo->delete(
#       name => 'Albers',
#       vorname => 'Hanns',
#) or die $@;

Last edited: 2011-07-16 11:46:48 +0200 (CEST)

View full thread Meldeliste auf Website erstellen