File Coverage

blib/lib/DBIx/Database.pm
Criterion Covered Total %
statement 27 653 4.1
branch 0 334 0.0
condition 0 178 0.0
subroutine 9 27 33.3
pod 0 12 0.0
total 36 1204 2.9


line stmt bran cond sub pod time code
1              
2             ###################################################################################
3             #
4             # DBIx::Recordset - Copyright (c) 1997-2000 Gerald Richter / ECOS
5             #
6             # You may distribute under the terms of either the GNU General Public
7             # License or the Artistic License, as specified in the Perl README file.
8             #
9             # THIS IS BETA SOFTWARE!
10             #
11             # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
12             # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
13             # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14             #
15             # $Id: Database.pm,v 1.18 2001/07/09 19:59:48 richter Exp $
16             #
17             ###################################################################################
18              
19              
20             package DBIx::Database::Base ;
21              
22 1     1   6 use strict 'vars' ;
  1         2  
  1         32  
23              
24 1     1   5 use vars qw{$LastErr $LastErrstr *LastErr *LastErrstr *LastError $PreserveCase} ;
  1         1  
  1         149  
25              
26             *LastErr = \$DBIx::Recordset::LastErr ;
27             *LastErrstr = \$DBIx::Recordset::LastErrstr ;
28             *LastError = \&DBIx::Recordset::LastError ;
29             *PreserveCase = \$DBIx::Recordset::PreserveCase;
30              
31              
32 1     1   6 use Carp qw(confess);
  1         2  
  1         53  
33              
34 1     1   5 use File::Spec ;
  1         2  
  1         32  
35 1     1   6 use DBIx::Recordset ;
  1         2  
  1         26  
36 1     1   927 use Text::ParseWords ;
  1         1327  
  1         2720  
37              
38              
39             ## ----------------------------------------------------------------------------
40             ##
41             ## savecroak
42             ##
43             ## croaks and save error
44             ##
45              
46              
47             sub savecroak
48              
49             {
50 0     0     my ($self, $msg, $code) = @_ ;
51              
52 0   0       $LastErr = $self->{'*LastErr'} = $code || $dbi::err || -1 ;
53 0   0       $LastErrstr = $self->{'*LastErrstr'} = $msg || $DBI::errstr || ("croak from " . caller) ;
54              
55             #$Carp::extra = 1 ;
56             #Carp::croak $msg ;
57 0           confess($msg);
58             }
59              
60             ## ----------------------------------------------------------------------------
61             ##
62             ## DoOnConnect
63             ##
64             ## in $cmd sql cmds
65             ##
66              
67             sub DoOnConnect
68              
69             {
70 0     0     my ($self, $cmd) = @_ ;
71            
72 0 0         if ($cmd)
73             {
74 0 0         if (ref ($cmd) eq 'ARRAY')
    0          
75             {
76 0           foreach (@$cmd)
77             {
78 0           $self -> do ($_) ;
79             }
80             }
81             elsif (ref ($cmd) eq 'HASH')
82             {
83 0           $self -> DoOnConnect ($cmd -> {'*'}) ;
84 0           $self -> DoOnConnect ($cmd -> {$self -> {'*Driver'}}) ;
85             }
86             else
87             {
88 0           $self -> do ($cmd) ;
89             }
90             }
91             }
92            
93              
94             ## ----------------------------------------------------------------------------
95             ##
96             ## DBHdl
97             ##
98             ## return DBI database handle
99             ##
100              
101             sub DBHdl ($)
102              
103             {
104 0     0     return $_[0] -> {'*DBHdl'} ;
105             }
106              
107              
108             ## ----------------------------------------------------------------------------
109             ##
110             ## do an non select statement
111             ##
112             ## $statement = statement to do
113             ## \%attr = attribs (optional)
114             ## @bind_valus= values to bind (optional)
115             ## or
116             ## \@bind_valus= values to bind (optional)
117             ## \@bind_types = data types of bind_values
118             ##
119              
120             sub do($$;$$$)
121              
122             {
123 0     0     my($self, $statement, $attribs, @params) = @_;
124            
125 0           $self -> {'*LastSQLStatement'} = $statement ;
126              
127 0           my $ret ;
128             my $bval ;
129 0           my $btype ;
130 0           my $dbh ;
131 0           my $sth ;
132              
133 0 0 0       if (@params > 1 && ref ($bval = $params[0]) eq 'ARRAY' && ref ($btype = $params[1]) eq 'ARRAY')
      0        
134             {
135 0 0         if ($self->{'*Debug'} > 1) { local $^W = 0 ; print DBIx::Recordset::LOG "DB: do '$statement' bind_values=<@$bval> bind_types=<@$btype>\n" } ;
  0            
  0            
136 0           $dbh = $self->{'*DBHdl'} ;
137 0           $sth = $dbh -> prepare ($statement, $attribs) ;
138 0   0       my $Numeric = $self->{'*NumericTypes'} || {} ;
139 0           local $^W = 0 ; # avoid warnings
140 0 0         if (defined ($sth))
141             {
142 0           for (my $i = 0 ; $i < @$bval; $i++)
143             {
144 0 0 0       $bval -> [$i] += 0 if (defined ($bval -> [$i]) && defined ($btype -> [$i]) && $Numeric -> {$btype -> [$i]}) ;
      0        
145             #$sth -> bind_param ($i+1, $bval -> [$i], $btype -> [$i]) ;
146             #$sth -> bind_param ($i+1, $bval -> [$i], $btype -> [$i] == DBI::SQL_CHAR()?DBI::SQL_CHAR():undef ) ;
147 0           my $bt = $btype -> [$i] ;
148 0 0 0       $sth -> bind_param ($i+1, $bval -> [$i], (defined ($bt) && $bt <= DBI::SQL_CHAR())?{TYPE=>$bt}:undef ) ;
149             }
150 0           $ret = $sth -> execute ;
151             }
152             }
153             else
154             {
155 0 0         print DBIx::Recordset::LOG "DB: do $statement <@params>\n" if ($self->{'*Debug'} > 1) ;
156            
157 0           $ret = $self->{'*DBHdl'} -> do ($statement, $attribs, @params) ;
158             }
159              
160 0 0         print DBIx::Recordset::LOG "DB: do returned " . (defined ($ret)?$ret:'') . "\n" if ($self->{'*Debug'} > 2) ;
    0          
161 0 0 0       print DBIx::Recordset::LOG "DB: ERROR $DBI::errstr\n" if (!$ret && $self->{'*Debug'}) ;
162 0 0 0       print DBIx::Recordset::LOG "DB: in do $statement <@params>\n" if (!$ret && $self->{'*Debug'} == 1) ;
163              
164 0           $LastErr = $self->{'*LastErr'} = $DBI::err ;
165 0           $LastErrstr = $self->{'*LastErrstr'} = $DBI::errstr ;
166            
167 0           return $ret ;
168             }
169              
170              
171             ## ----------------------------------------------------------------------------
172             ##
173             ## QueryMetaData
174             ##
175             ## $table = table (multiple tables must be comma separated)
176             ##
177              
178              
179             sub QueryMetaData($$)
180              
181             {
182 0     0     my ($self, $table) = @_ ;
183            
184 0 0         $table = lc($table) if (!$PreserveCase) ;
185              
186 0           my $meta ;
187 0           my $metakey = "$self->{'*DataSource'}//" . $table ;
188            
189 0 0         if (defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
190             {
191 0 0         print DBIx::Recordset::LOG "DB: use cached meta data for $table\n" if ($self->{'*Debug'} > 2) ;
192 0           return $meta
193             }
194              
195 0           my $hdl = $self->{'*DBHdl'} ;
196 0           my $drv = $self->{'*Driver'} ;
197 0           my $sth ;
198            
199 0           my $ListFields = DBIx::Compat::GetItem ($drv, 'ListFields') ;
200 0           my $QuoteTypes = DBIx::Compat::GetItem ($drv, 'QuoteTypes') ;
201 0           my $NumericTypes = DBIx::Compat::GetItem ($drv, 'NumericTypes') ;
202 0           my $HaveTypes = DBIx::Compat::GetItem ($drv, 'HaveTypes') ;
203             #my @tabs = split (/\s*\,\s*/, $table) ;
204 0           my @tabs = quotewords ('\s*,\s*', 1, $table) ;
205 0           my $tab ;
206             my $ltab ;
207 0           my %Quote ;
208 0           my %Numeric ;
209 0           my @Names ;
210 0           my @Types ;
211 0           my @FullNames ;
212 0           my %Table4Field ;
213 0           my %Type4Field ;
214 0           my $i ;
215              
216 0           foreach $tab (@tabs)
217              
218             {
219 0 0         next if ($tab =~ /^\s*$/) ;
220            
221 0           eval {
222 0 0         $sth = &{$ListFields}($hdl, $tab) or carp ("Cannot list fields for $tab ($DBI::errstr)") ;
  0            
223             } ;
224 0 0         next if ($@) ; # ignore any table for which we can't get fields
225              
226 0 0         if ($tab =~ /^"(.*?)"$/)
227 0           { $ltab = $1 ; }
228             else
229 0           { $ltab = $tab ; }
230            
231 0           my $types ;
232 0 0         my $fields = $sth?$sth -> FETCH ($PreserveCase?'NAME':'NAME_lc'):[] ;
    0          
233 0           my $num = $#{$fields} + 1 ;
  0            
234            
235 0 0 0       if ($HaveTypes && $sth)
236             {
237             #print DBIx::Recordset::LOG "DB: Have Types for driver\n" ;
238 0           $types = $sth -> FETCH ('TYPE') ;
239             }
240             else
241             {
242             #print DBIx::Recordset::LOG "DB: No Types for driver\n" ;
243             # Drivers does not have fields types -> give him SQL_VARCHAR
244 0           $types = [] ;
245 0           for ($i = 0; $i < $num; $i++)
246 0           { push @$types, DBI::SQL_VARCHAR (); }
247              
248             # Setup quoting for SQL_VARCHAR
249 0           $QuoteTypes = { DBI::SQL_VARCHAR() => 1 } ;
250 0           $NumericTypes = { } ;
251             }
252            
253 0           push @Names, @$fields ;
254 0           push @Types, @$types ;
255 0           $i = 0 ;
256 0           foreach (@$fields)
257             {
258 0           $Table4Field{$_} = $ltab ;
259 0           $Table4Field{"$ltab.$_"} = $ltab ;
260 0           $Type4Field{"$_"} = $types -> [$i] ;
261 0           $Type4Field{"$ltab.$_"} = $types -> [$i++] ;
262 0           push @FullNames, "$ltab.$_" ;
263             }
264              
265 0 0         $sth -> finish if ($sth) ;
266              
267             # Set up a hash which tells us which fields to quote and which not
268             # We setup two versions, one with tablename and one without
269 0           my $col ;
270             my $fieldname ;
271 0           for ($col = 0; $col < $num; $col++ )
272             {
273 0 0         if ($self->{'*Debug'} > 2)
274             {
275 0           my $n = $$fields[$col] ;
276 0           my $t = $$types[$col] ;
277 0           print DBIx::Recordset::LOG "DB: TAB = $tab, COL = $col, NAME = $n, TYPE = $t" ;
278             }
279 0           $fieldname = $$fields[$col] ;
280 0 0         if ($$QuoteTypes{$$types[$col]})
281             {
282             #print DBIx::Recordset::LOG " -> quote\n" if ($self->{'*Debug'} > 2) ;
283 0           $Quote {"$tab.$fieldname"} = 1 ;
284 0           $Quote {"$fieldname"} = 1 ;
285             }
286             else
287             {
288             #print DBIx::Recordset::LOG "\n" if ($self->{'*Debug'} > 2) ;
289 0           $Quote {"$tab.$fieldname"} = 0 ;
290 0           $Quote {"$fieldname"} = 0 ;
291             }
292 0 0         if ($$NumericTypes{$$types[$col]})
293             {
294 0 0         print DBIx::Recordset::LOG " -> numeric\n" if ($self->{'*Debug'} > 2) ;
295 0           $Numeric {"$tab.$fieldname"} = 1 ;
296 0           $Numeric {"$fieldname"} = 1 ;
297             }
298             else
299             {
300 0 0         print DBIx::Recordset::LOG "\n" if ($self->{'*Debug'} > 2) ;
301 0           $Numeric {"$tab.$fieldname"} = 0 ;
302 0           $Numeric {"$fieldname"} = 0 ;
303             }
304             }
305 0 0 0       print DBIx::Recordset::LOG "No Fields found for $tab\n" if ($num == 0 && $self->{'*Debug'} > 1) ;
306             }
307              
308 0 0 0       print DBIx::Recordset::LOG "No Tables specified\n" if ($#tabs < 0 && $self->{'*Debug'} > 1) ;
309              
310              
311 0           $meta = {} ;
312 0           $meta->{'*Table4Field'} = \%Table4Field ;
313 0           $meta->{'*Type4Field'} = \%Type4Field ;
314 0           $meta->{'*FullNames'} = \@FullNames ;
315 0           $meta->{'*Names'} = \@Names ;
316 0           $meta->{'*Types'} = \@Types ;
317 0           $meta->{'*Quote'} = \%Quote ;
318 0           $meta->{'*Numeric'} = \%Numeric ;
319 0           $meta->{'*NumericTypes'} = $NumericTypes ;
320              
321 0           $DBIx::Recordset::Metadata{$metakey} = $meta ;
322            
323              
324 0 0         if (!exists ($meta -> {'*Links'}))
325             {
326 0           my $ltab ;
327             my $lfield ;
328 0           my $metakey ;
329 0           my $subnames ;
330 0           my $n ;
331              
332 0           $meta -> {'*Links'} = {} ;
333              
334 0           my $metakeydsn = "$self->{'*DataSource'}//-" ;
335 0   0       my $metakeydsntf = "$self->{'*DataSource'}//-" . ($self->{'*TableFilter'}||'');
336 0   0       my $metadsn = $DBIx::Recordset::Metadata{$metakeydsn} || {} ;
337 0   0       my $tabmetadsn = $DBIx::Recordset::Metadata{$metakeydsntf} || {} ;
338 0           my $tables = $tabmetadsn -> {'*Tables'} ;
339              
340 0 0         if (!$tables)
341             { # Query the driver, which tables are available
342 0           my $ListTables = DBIx::Compat::GetItem ($drv, 'ListTables') ;
343              
344 0 0         if ($ListTables)
345             {
346 0 0         my @tabs = &{$ListTables}($hdl) or $self -> savecroak ("Cannot list tables for $self->{'*DataSource'} ($DBI::errstr)") ;
  0            
347 0           my @stab ;
348             my $stab ;
349 0   0       my $tabfilter = $self -> {'*TableFilter'} || '.' ;
350 0           foreach (@tabs)
351             {
352 0           s/^[^a-zA-Z0-9_.]// ;
353 0           s/[^a-zA-Z0-9_.]$// ;
354 0 0         if ($_ =~ /(^|\.)$tabfilter/i)
355             {
356 0           @stab = split (/\./);
357 0 0         $stab = $PreserveCase?(pop @stab):lc (pop @stab) ;
358 0           $tables -> {$stab} = $_ ;
359             }
360             }
361 0           $tabmetadsn -> {'*Tables'} = $tables ;
362 0 0         if ($self->{'*Debug'} > 3)
363             {
364 0           my $t ;
365 0           foreach $t (keys %$tables)
366 0           { print DBIx::Recordset::LOG "DB: Found table $t => $tables->{$t}\n" ; }
367             }
368             }
369             else
370             {
371 0           $tabmetadsn -> {'*Tables'} = {} ;
372             }
373            
374 0           $DBIx::Recordset::Metadata{$metakeydsn} = $metadsn ;
375 0 0         $DBIx::Recordset::Metadata{"$metakeydsn$self->{'*TableFilter'}"} = $tabmetadsn if ($self->{'*TableFilter'}) ;
376             }
377              
378 0 0         if ($#tabs <= 0)
379             {
380 0           my $fullname ;
381 0           my $tabfilter = $self -> {'*TableFilter'} ;
382 0           my $fullltab ;
383 0           my $tableshort = $table ;
384 0 0 0       if ($tabfilter && ($table =~ /^$tabfilter(.*?)$/))
385             {
386 0           $tableshort = $1 ;
387             }
388 0           foreach $fullname (@FullNames)
389             {
390 0           my ($ntab, $n) = split (/\./, $fullname) ;
391 0           my $prefix = '' ;
392 0           my $fullntab = $ntab ;
393            
394 0 0 0       if ($tabfilter && ($ntab =~ /^$tabfilter(.*?)$/))
395             {
396 0           $ntab = $1 ;
397             }
398              
399 0 0         if ($n =~ /^(.*?)__(.*?)$/)
400             {
401 0           $prefix = "$1__" ;
402 0           $n = $2 ;
403             }
404              
405 0           my @part = split (/_/, $n) ;
406 0   0       my $tf = $tabfilter || '' ;
407 0           for (my $i = 0; $i < $#part; $i++)
408             {
409 0           $ltab = join ('_', @part[0..$i]) ;
410 0           $lfield = join ('_', @part[$i + 1..$#part]) ;
411            
412 0 0         next if (!$ltab) ;
413            
414 0 0 0       if (!$tables -> {$ltab} && $tables -> {"$tf$ltab"})
415 0           { $fullltab = "$tabfilter$ltab" }
416             else
417 0           { $fullltab = $ltab }
418              
419 0 0         if ($tables -> {$fullltab})
420             {
421 0           $metakey = $self -> QueryMetaData ($fullltab) ;
422 0           $subnames = $metakey -> {'*Names'} ;
423 0 0         if (grep (/^$lfield$/i, @$subnames))
424             { # setup link
425 0           $meta -> {'*Links'}{"-$prefix$ltab"} = {'!Table' => $fullltab, '!LinkedField' => $lfield, '!MainField' => "$prefix$n", '!MainTable' => $fullntab} ;
426 0 0         print DBIx::Recordset::LOG "Link found for $ntab.$prefix$n to $ltab.$lfield\n" if ($self->{'*Debug'} > 2) ;
427            
428             #my $metakeyby = "$self->{'*DataSource'}//$ltab" ;
429             #my $linkedby = $DBIx::Recordset::Metadata{$metakeyby} -> {'*Links'} ;
430 0           my $linkedby = $metakey -> {'*Links'} ;
431 0           my $linkedbyname = "\*$prefix$tableshort" ;
432 0           $linkedby -> {$linkedbyname} = {'!Table' => $fullntab, '!MainField' => $lfield, '!LinkedField' => "$prefix$n", '!LinkedBy' => $fullltab, '!MainTable' => $fullltab} ;
433             #$linkedby -> {"-$tableshort"} = $linkedby -> {$linkedbyname} if (!exists ($linkedby -> {"-$tableshort"})) ;
434             }
435 0           last ;
436             }
437             }
438             }
439             }
440             else
441             {
442 0           foreach $ltab (@tabs)
443             {
444 0 0         next if (!$ltab) ;
445 0           $metakey = $self -> QueryMetaData ($ltab) ;
446              
447 0           my $k ;
448             my $v ;
449 0           my $lbtab ;
450 0           my $links = $metakey -> {'*Links'} ;
451 0           while (($k, $v) = each (%$links))
452             {
453 0 0         if (!$meta -> {'*Links'}{$k})
454             {
455 0           $meta -> {'*Links'}{$k} = { %$v } ;
456 0 0         print DBIx::Recordset::LOG "Link copied: $k\n" if ($self->{'*Debug'} > 2) ;
457             }
458            
459             }
460             }
461             }
462              
463             }
464              
465              
466 0           return $meta ;
467             }
468              
469              
470             ###################################################################################
471              
472             package DBIx::Database ;
473              
474 1     1   7 use strict 'vars' ;
  1         2  
  1         56  
475              
476             use vars (
477 1         142 '%DBDefault', # DB Shema default für alle Tabellen
478             '@DBSchema', # DB Shema definition
479             '$LastErr',
480             '$LastErrstr',
481             '*LastErr',
482             '*LastErrstr',
483             '*LastError',
484             '$PreserveCase',
485 1     1   5 '@ISA') ;
  1         2  
486              
487             @ISA = ('DBIx::Database::Base') ;
488              
489             *LastErr = \$DBIx::Recordset::LastErr ;
490             *LastErrstr = \$DBIx::Recordset::LastErrstr ;
491             *LastError = \&DBIx::Recordset::LastError ;
492             *PreserveCase = \$DBIx::Recordset::PreserveCase;
493              
494              
495 1     1   4 use Carp ;
  1         1  
  1         5872  
496              
497             ## ----------------------------------------------------------------------------
498             ##
499             ## connect
500             ##
501              
502             sub connect
503              
504             {
505 0     0 0   my ($self, $password) = @_ ;
506              
507 0 0         my $hdl = $self->{'*DBHdl'} = DBI->connect($self->{'*DataSource'}, $self->{'*Username'}, $password, $self->{'*DBIAttr'}) or $self -> savecroak ("Cannot connect to $self->{'*DataSource'} ($DBI::errstr)") ;
508              
509 0           $LastErr = $self->{'*LastErr'} = $DBI::err ;
510 0           $LastErrstr = $self->{'*LastErrstr'} = $DBI::errstr ;
511              
512 0           $self->{'*MainHdl'} = 1 ;
513 0           $self->{'*Driver'} = $hdl->{Driver}->{Name} ;
514 0 0         if ($self->{'*Driver'} eq 'Proxy')
515             {
516 0           $self->{'*DataSource'} =~ /dsn\s*=\s*dbi:(.*?):/i ;
517 0           $self->{'*Driver'} = $1 ;
518 0 0         print DBIx::Recordset::LOG "DB: Found DBD::Proxy, take compability entrys for driver $self->{'*Driver'}\n" if ($self->{'*Debug'} > 1) ;
519             }
520              
521 0 0         print DBIx::Recordset::LOG "DB: Successfull connect to $self->{'*DataSource'} \n" if ($self->{'*Debug'} > 1) ;
522              
523 0           my $cmd ;
524 0 0 0       if ($hdl && ($cmd = $self -> {'*DoOnConnect'}))
525             {
526 0           $self -> DoOnConnect ($cmd) ;
527             }
528            
529 0           return $hdl ;
530             }
531              
532              
533             ## ----------------------------------------------------------------------------
534             ##
535             ## new
536             ##
537             ## creates a new DBIx::Database object. This object fetches all necessary
538             ## meta information from the database for later use by DBIx::Recordset objects.
539             ## Also it builds a list of links between the tables.
540             ##
541             ##
542             ## $data_source = Driver/DB/Host
543             ## $username = Username (optional)
544             ## $password = Password (optional)
545             ## \%attr = Attributes (optional)
546             ## $saveas = Name for this DBIx::Database object to save
547             ## The name can be used in Get, or as !DataSource for DBIx::Recordset
548             ## $keepopen = keep connection open to use in further DBIx::Recordset setups
549             ## $tabfilter = regex which tables should be used
550             ##
551              
552             sub new
553              
554             {
555 0     0 0   my ($class, $data_source, $username, $password, $attr, $saveas, $keepopen, $tabfilter, $doonconnect, $reconnect) = @_ ;
556            
557 0 0         if (ref ($data_source) eq 'HASH')
558             {
559 0           my $p = $data_source ;
560 0           ($data_source, $username, $password, $attr, $saveas, $keepopen, $tabfilter, $doonconnect, $reconnect) =
561             @$p{('!DataSource', '!Username', '!Password', '!DBIAttr', '!SaveAs', '!KeepOpen', '!TableFilter', '!DoOnConnect', '!Reconnect')} ;
562             }
563            
564 0           $LastErr = undef ;
565 0           $LastErrstr = undef ;
566            
567 0           my $metakey ;
568             my $self ;
569              
570              
571              
572 0 0         if (!($data_source =~ /^dbi:/i))
573             {
574 0           $metakey = "-DATABASE//$1" ;
575 0           $self = $DBIx::Recordset::Metadata{$metakey} ;
576 0 0         $self->{'*DBHdl'} = undef if ($reconnect) ;
577 0 0 0       $self -> connect ($password) if ($keepopen && !defined ($self->{'*DBHdl'})) ;
578 0           return $self ;
579             }
580            
581 0 0         if ($saveas)
582             {
583 0           $metakey = "-DATABASE//$saveas" ;
584 0 0         if (defined ($self = $DBIx::Recordset::Metadata{$metakey}))
585             {
586 0 0         $self->{'*DBHdl'} = undef if ($reconnect) ;
587 0 0 0       $self -> connect ($password) if ($keepopen && !defined ($self->{'*DBHdl'})) ;
588 0           return $self ;
589             }
590             }
591              
592              
593             $self = {
594 0           '*Debug' => $DBIx::Recordset::Debug,
595             '*DataSource' => $data_source,
596             '*DBIAttr' => $attr,
597             '*Username' => $username,
598             '*TableFilter' => $tabfilter,
599             '*DoOnConnect' => $doonconnect,
600             } ;
601              
602 0           bless ($self, $class) ;
603              
604 0           my $hdl ;
605 0 0         $self->{'*DBHdl'} = undef if ($reconnect) ;
606              
607              
608 0 0 0       if (ref ($data_source) and eval { $data_source->isa('DBI::db') } )
  0            
609             {
610              
611 0           $self->{'*DBHdl'} = $data_source;
612             }
613             else
614             {
615              
616             }
617              
618 0 0         if (!defined ($self->{'*DBHdl'}))
619             {
620 0           $hdl = $self->connect ($password) ;
621             }
622             else
623             {
624 0           $LastErr = $self->{'*LastErr'} = undef ;
625 0           $LastErrstr = $self->{'*LastErrstr'} = undef ;
626            
627 0           $hdl = $self->{'*DBHdl'} ;
628 0 0         print DBIx::Recordset::LOG "DB: Use already open dbh for $self->{'*DataSource'}\n" if ($self->{'*Debug'} > 1) ;
629             }
630            
631 0   0       $DBIx::Recordset::Metadata{"$self->{'*DataSource'}//*"} ||= {} ; # make sure default table is defined
632              
633 0           my $drv = $self->{'*Driver'} ;
634 0           my $metakeydsn = "$self->{'*DataSource'}//-" ;
635 0   0       my $metakeydsntf = "$self->{'*DataSource'}//-" . ($self->{'*TableFilter'}||'');
636 0   0       my $metadsn = $DBIx::Recordset::Metadata{$metakeydsn} || {} ;
637 0   0       my $tabmetadsn = $DBIx::Recordset::Metadata{$metakeydsntf} || {} ;
638 0           my $tables = $tabmetadsn -> {'*Tables'} ;
639              
640 0 0         if (!$tables)
641             { # Query the driver, which tables are available
642 0           my $ListTables = DBIx::Compat::GetItem ($drv, 'ListTables') ;
643              
644            
645 0 0         if ($ListTables)
646             {
647 0           my @tabs = &{$ListTables}($hdl) ; # or $self -> savecroak ("Cannot list tables for $self->{'*DataSource'} ($DBI::errstr)") ;
  0            
648 0           my @stab ;
649             my $stab ;
650              
651 0   0       $tabfilter ||= '.' ;
652 0           foreach (@tabs)
653             {
654 0           s/^[^a-zA-Z0-9_.]// ;
655 0           s/[^a-zA-Z0-9_.]$// ;
656 0 0         if ($_ =~ /(^|\.)$tabfilter/i)
657             {
658 0           @stab = split (/\./);
659 0 0         $stab = $PreserveCase?(pop @stab):lc (pop @stab) ;
660 0           $tables -> {$stab} = $_ ;
661             }
662             }
663            
664 0           $tabmetadsn -> {'*Tables'} = $tables ;
665 0 0         if ($self->{'*Debug'} > 2)
666             {
667 0           my $t ;
668 0           foreach $t (keys %$tables)
669 0           { print DBIx::Recordset::LOG "DB: Found table $t => $tables->{$t}\n" ; }
670             }
671             }
672             else
673             {
674 0           $tabmetadsn -> {'*Tables'} = {} ;
675             }
676            
677 0           $DBIx::Recordset::Metadata{$metakeydsn} = $metadsn ;
678 0           $DBIx::Recordset::Metadata{$metakeydsntf} = $tabmetadsn ;
679             }
680              
681 0           my $tab ;
682             my $x ;
683              
684 0           while (($tab, $x) = each (%{$tables}))
  0            
685             {
686 0           $self -> QueryMetaData ($tab) ;
687             }
688              
689            
690 0 0         $DBIx::Recordset::Metadata{$metakey} = $self if ($metakey) ;
691              
692             # disconnect in case we are running in a Apache/mod_perl startup file
693            
694 0 0 0       if (defined ($self->{'*DBHdl'}) && !$keepopen)
695             {
696 0           $self->{'*DBHdl'} -> disconnect () ;
697 0           undef $self->{'*DBHdl'} ;
698 0 0         print DBIx::Recordset::LOG "DB: Disconnect from $self->{'*DataSource'} \n" if ($self->{'*Debug'} > 1) ;
699             }
700            
701 0           return $self ;
702             }
703              
704              
705             ## ----------------------------------------------------------------------------
706             ##
707             ## Get
708             ##
709             ## $name = Name of DBIx::Database obecjt you what to get
710             ##
711              
712             sub Get
713              
714             {
715 0     0 0   my ($class, $saveas) = @_ ;
716            
717 0           my $metakey ;
718            
719 0           $metakey = "-DATABASE//$saveas" ;
720 0           return $DBIx::Recordset::Metadata{$metakey} ;
721             }
722              
723              
724             ## ----------------------------------------------------------------------------
725             ##
726             ## TableAttr
727             ##
728             ## get and/or set and attribute for an specfic table
729             ##
730             ## $table = Name of table(s)
731             ## $key = key
732             ## $value = value
733             ##
734              
735             sub TableAttr
736              
737             {
738 0     0 0   my ($self, $table, $key, $value) = @_ ;
739              
740 0 0         $table = lc($table) if (!$PreserveCase) ;
741              
742 0           my $meta ;
743 0           my $metakey = "$self->{'*DataSource'}//$table" ;
744            
745 0 0         if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
746             {
747 0           $self -> savecroak ("Unknown table $table in $self->{'*DataSource'}") ;
748             }
749              
750             # set new value if wanted
751 0 0         return $meta -> {$key} = $value if (defined ($value)) ;
752              
753             # only return value
754 0 0         return $meta -> {$key} if (exists ($meta -> {$key})) ;
755              
756             # check if there is a default value
757 0           $metakey = "$self->{'*DataSource'}//*" ;
758            
759 0 0         return undef if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey})) ;
760              
761 0           return $meta -> {$key} ;
762             }
763              
764              
765             ## ----------------------------------------------------------------------------
766             ##
767             ## TableLink
768             ##
769             ## get and/or set an link description for an table
770             ##
771             ## $table = Name of table(s)
772             ## $key = linkname
773             ## $value = ref to hash with link description
774             ##
775              
776              
777             sub TableLink
778              
779             {
780 0     0 0   my ($self, $table, $key, $value) = @_ ;
781              
782 0 0         $table = lc($table) if (!$PreserveCase) ;
783              
784 0           my $meta ;
785 0           my $metakey = "$self->{'*DataSource'}//$table" ;
786            
787 0 0         if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
788             {
789 0           $self -> savecroak ("Unknown table $table in $self->{'*DataSource'}") ;
790             }
791              
792 0 0         return $meta -> {'*Links'} if (!defined ($key)) ;
793              
794 0 0         return $meta -> {'*Links'} -> {$key} = $value if (defined ($value)) ;
795              
796 0           return $meta -> {'*Links'} -> {$key} ;
797             }
798              
799              
800             ## ----------------------------------------------------------------------------
801             ##
802             ## MetaData
803             ##
804             ## get/set metadata for a given table
805             ##
806             ## $table = Name of table
807             ## $metadata = meta data to set
808             ##
809              
810              
811             sub MetaData
812              
813             {
814 0     0 0   my ($self, $table, $metadata, $clear) = @_ ;
815              
816 0 0         $table = lc($table) if (!$PreserveCase) ;
817              
818 0           my $meta ;
819 0           my $metakey = "$self->{'*DataSource'}//$table" ;
820            
821 0 0         if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
822             {
823 0           $self -> savecroak ("Unknown table $table in $self->{'*DataSource'}") ;
824             }
825              
826 0 0 0       return $meta if (!defined ($metadata) && !$clear) ;
827              
828 0           return $DBIx::Recordset::Metadata{$metakey} = $metadata ;
829             }
830              
831             ## ----------------------------------------------------------------------------
832             ##
833             ## AllTables
834             ##
835             ## return reference to hash which keys contains all tables of that datasource
836             ##
837              
838             sub AllTables
839              
840             {
841 0     0 0   my $self = shift ;
842 0   0       my $metakeydsn = "$self->{'*DataSource'}//-" . ($self->{'*TableFilter'} || '') ;
843 0   0       my $metadsn = $DBIx::Recordset::Metadata{$metakeydsn} || {} ;
844 0           return $metadsn -> {'*Tables'} ;
845             }
846              
847             ## ----------------------------------------------------------------------------
848             ##
849             ## AllNames
850             ##
851             ## return reference to array of all names in all tables
852             ##
853             ## $table = Name of table
854             ##
855              
856             sub AllNames
857              
858             {
859 0     0 0   my ($self, $table) = @_ ;
860              
861 0 0         $table = lc($table) if (!$PreserveCase) ;
862              
863 0           my $meta ;
864 0           my $metakey = "$self->{'*DataSource'}//$table" ;
865            
866 0 0         if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
867             {
868 0           $self -> savecroak ("Unknown table $table in $self->{'*DataSource'}") ;
869             }
870              
871 0           return $meta -> {'*Names'} ;
872             }
873              
874             ## ----------------------------------------------------------------------------
875             ##
876             ## AllTypes
877             ##
878             ## return reference to array of all types in all tables
879             ##
880             ## $table = Name of table
881             ##
882              
883             sub AllTypes
884              
885             {
886 0     0 0   my ($self, $table) = @_ ;
887              
888 0 0         $table = lc($table) if (!$PreserveCase) ;
889              
890 0           my $meta ;
891 0           my $metakey = "$self->{'*DataSource'}//$table" ;
892            
893 0 0         if (!defined ($meta = $DBIx::Recordset::Metadata{$metakey}))
894             {
895 0           $self -> savecroak ("Unknown table $table in $self->{'*DataSource'}") ;
896             }
897              
898 0           return $meta -> {'*Types'} ;
899             }
900              
901              
902              
903             ## ----------------------------------------------------------------------------
904             ##
905             ## DESTROY
906             ##
907             ## do cleanup
908             ##
909              
910              
911             sub DESTROY
912              
913             {
914 0     0     my $self = shift ;
915 0           my $orgerr = $@ ;
916 0           local $@ ;
917              
918             eval
919 0           {
920 0 0         if (defined ($self->{'*DBHdl'}))
921             {
922 0           $self->{'*DBHdl'} -> disconnect () ;
923 0           undef $self->{'*DBHdl'} ;
924             }
925             } ;
926 0 0 0       $self -> savecroak ($@) if (!$orgerr && $@) ;
927 0 0 0       warn $@ if ($orgerr && $@) ;
928             }
929              
930              
931             ## ---------------------------------------------------------------------------------
932             ##
933             ## Datenbank Erzeugen
934             ##
935             ## in $dbschema Schema file or ARRAY ref
936             ## in $shema schema name (Oracle)
937             ## in $user user to grant rights to
938             ## in $setpriv resetup privileges
939             ## in $alterconstraints resetup constraints (-1 to drop containts)
940             ##
941              
942            
943             sub CreateTables
944              
945             {
946             #my $DataSource = shift ;
947             #my $setupuser = shift ;
948             #my $setuppass = shift ;
949             #my $tabprefix = shift ;
950 0     0 0   my $db = shift ;
951 0           my $dbschema = shift ;
952 0           my $shema = shift ;
953 0           my $user = shift ;
954 0           my $setpriv = shift ;
955 0           my $alterconstraints = shift ;
956              
957 0           my $DBSchemaRef ;
958              
959 0           print "\nDatenbanktabellen anlegen/aktualisierien:\n" ;
960              
961 0 0         if (ref ($dbschema) eq 'ARRAY')
962             {
963 0           $DBSchemaRef = $dbschema ;
964             }
965             else
966             {
967 0 0         open FH, $dbschema or die "Schema nicht gefunden ($dbschema) ($!)" ;
968             {
969 0           local $/ = undef ;
  0            
970 0           my $shema = ;
971 0           $shema =~ /^(.*)$/s ; # untaint
972 0           $shema = $1 ;
973 0           eval $shema ;
974 0 0         die "Fehler in $dbschema: $@" if ($@) ;
975             }
976 0           close FH ;
977 0           $DBSchemaRef = \@DBSchema ;
978             }
979              
980              
981             #my $db = DBIx::Database -> new ({'!DataSource' => "$DataSource",
982             # '!Username' => $setupuser,
983             # '!Password' => $setuppass,
984             # '!KeepOpen' => 1,
985             # '!TableFilter' => $tabprefix}) ;
986             #
987             #die DBIx::Database->LastError . "; Datenbank muß bereits bestehen" if (DBIx::Database->LastError) ;
988             #
989            
990 0           my $dbh = $db -> DBHdl ;
991 0           local $dbh -> {RaiseError} = 0 ;
992 0           local $dbh -> {PrintError} = 0 ;
993            
994 0           my $tables = $db -> AllTables ;
995              
996            
997 0           my $tab ;
998             my $tabname ;
999 0           my $type ;
1000 0           my $typespec ;
1001 0           my $size ;
1002              
1003 0   0       my $public = defined ($user) && $db -> {'*Username'} ne $user ;
1004 0           my $drv = $db->{'*Driver'} ;
1005 0           my $tabprefix = $db -> {'*TableFilter'} ;
1006 0           my $trans = DBIx::Compat::GetItem ($drv, 'CreateTypes') ;
1007 0 0         $trans = {} if (!$trans) ;
1008 0           my $createseq = DBIx::Compat::GetItem ($drv, 'CreateSeq') ;
1009 0   0       my $createpublic = $public && DBIx::Compat::GetItem ($drv, 'CreatePublic') ;
1010 0           my $candropcolumn = DBIx::Compat::GetItem ($drv, 'CanDropColumn') ;
1011 0           my $i ;
1012             my $field ;
1013 0           my $cmd ;
1014              
1015              
1016 0           foreach $tab (@$DBSchemaRef)
1017             {
1018 0           my $newtab = 0 ;
1019 0           my $newseq = 0 ;
1020 0           my $hasseq = 0 ;
1021 0 0         my %tabdef = (%DBDefault, %$tab, %{$tab -> {'!For'} -> {$drv} || {}}) ;
  0            
1022 0           $tabname = "$tabprefix$tabdef{'!Table'}" ;
1023 0           my $init = $tabdef{'!Init'} ;
1024 0 0 0       my $grant = (defined ($user) && $db -> {'*Username'} ne $user)?$tabdef{'!Grant'}:undef ;
1025 0           my $constraint ;
1026 0           my $constraints = $tabdef{'!Constraints'} ;
1027 0           my $default = $tabdef{'!Default'} ;
1028 0           my $pk = $tabdef{'!PrimKey'} ;
1029 0           my $index= $tabdef{'!Index'} ;
1030 0           my $c ;
1031             my $ccmd ;
1032 0           my $cname ;
1033 0           my $cval ;
1034 0           my $ncnt ;
1035 0 0         if ($tables -> {$tabname})
1036             {
1037 0           printl ("$tabname", LL, "vorhanden\n") ;
1038              
1039 0           my $fields = $tabdef{'!Fields'} ;
1040 0           my $dbfields = $db -> AllNames ($tabname) ;
1041 0           my %dbfields = map { $_ => 1 } @$dbfields ;
  0            
1042 0           my $lastfield ;
1043 0           for ($i = 0; $i <= $#$fields; $i+= 2)
1044             {
1045 0           $field = lc ($fields -> [$i]) ;
1046 0           $typespec = $fields -> [$i+1] ;
1047 0 0 0       $hasseq = 1 if ($createseq && $typespec eq 'counter') ;
1048            
1049 0           $ccmd = '' ;
1050 0           $ncnt = 0 ;
1051 0 0 0       if ($constraints && ($constraint = $constraints -> {$field}))
1052             {
1053 0           $cname = "${tabname}_$field" ;
1054 0           for ($c = 0 ; $c < $#$constraint; $c+=2)
1055             {
1056 0 0         if ($constraint -> [$c] eq '!Name')
1057             {
1058 0           $cname = $tabprefix . $constraint -> [$c+1] ;
1059 0           $ncnt = 0 ;
1060 0           next ;
1061             }
1062 0           $ncnt++ ;
1063 0   0       $cval = $constraint -> [$c+1] || $constraint -> [$c] ;
1064 0           $cval =~ s#REFERENCES\s+(.*?)\s*\(#REFERENCES $tabprefix$1 (#i ;
1065 0 0         $ccmd .= " CONSTRAINT $cname" . ( $ncnt >1?$ncnt:'') . " $cval" ;
1066             }
1067             }
1068              
1069              
1070 0 0 0       if (!$dbfields{$field})
    0          
1071             {
1072 0           printl (" Add $field", LL) ;
1073 0 0 0       $newseq = 1 if ($createseq && $typespec eq 'counter') ;
1074            
1075 0 0         if ($typespec =~ /^(.*?)\s*\((.*?)\)(.*?)$/)
1076             {
1077 0 0         $type = $trans->{$1}?$trans->{$1}:$1 . "($2) $3" ;
1078             }
1079             else
1080             {
1081 0           $type = $typespec ;
1082 0 0         $type = $trans -> {$typespec} if ($trans -> {$typespec}) ;
1083             }
1084 0 0         $cmd = "ALTER TABLE $tabname ADD $field $type $ccmd" . ($lastfield?" AFTER $lastfield":'') ;
1085              
1086 0           $db -> do ($cmd) ;
1087              
1088 0 0         die "Fehler beim Erstellen des Feldes $tabname.$field:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1089            
1090 0           print "ok\n" ;
1091            
1092 0 0 0       if ($init || $default)
1093             {
1094 0           printl (" $field initialisieren", LL) ;
1095              
1096 0           $db -> MetaData ($tabname, undef, 1) ;
1097              
1098 0           my $rs = DBIx::Recordset -> Setup ({'!DataSource' => $db, '!Table' => $tabname, '!PrimKey' => $tabdef{'!PrimKey'}}) ;
1099 0 0         die "Fehler beim Setup von Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1100              
1101 0           my $rec ;
1102 0 0 0       if ($default && defined ($default -> {$field}))
1103             {
1104 0           $$rs -> Update ({$field, $default -> {$field}}, "$field is null") ;
1105 0 0         die "Fehler beim Update in Tabelle $tabname:\n" . $$rs -> LastSQLStatement . "\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1106             }
1107              
1108 0 0         if ($init)
1109             {
1110 0           foreach $rec (@$init)
1111             {
1112 0           $$rs -> Update ({$field, $rec -> {$field}}, {$pk => $rec -> {$pk}}) ;
1113 0 0         die "Fehler beim Update in Tabelle $tabname:\n" . $$rs -> LastSQLStatement . "\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1114             }
1115             }
1116 0           print "ok\n" ;
1117             }
1118             }
1119             elsif ($alterconstraints && $ccmd)
1120             {
1121 0           printl (" Alter Constraint $field", LL) ;
1122              
1123 0           $ccmd = '' ;
1124 0           $ncnt = 0 ;
1125 0 0 0       if ($constraints && ($constraint = $constraints -> {$field}))
1126             {
1127 0           $cname = "${tabname}_$field" ;
1128 0           for ($c = 0 ; $c < $#$constraint; $c+=2)
1129             {
1130 0 0         if ($constraint -> [$c] eq '!Name')
1131             {
1132 0           $cname = $tabprefix . $constraint -> [$c+1] ;
1133 0           $ncnt = 0 ;
1134 0           next ;
1135             }
1136 0           $ncnt++ ;
1137 0 0         $ccmd = " CONSTRAINT $cname" . ( $ncnt>1?$ncnt:'') ;
1138 0           $cmd = "ALTER TABLE $tabname DROP $ccmd" ;
1139              
1140 0           $db -> do ($cmd) ;
1141              
1142             #die "Fehler beim Erstellen des Feldes $tabname.$field:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1143              
1144 0 0         if ($alterconstraints > 0)
1145             {
1146 0           $cval = $constraint -> [$c] ;
1147 0 0 0       if (lc ($cval) eq 'null' || lc ($cval) eq 'not null')
1148             {
1149 0           $cmd = "ALTER TABLE $tabname MODIFY $field $ccmd $cval" ;
1150             }
1151             else
1152             {
1153 0           $cval .= " ($field) " . $constraint -> [$c+1] ;
1154 0           $cval =~ s#REFERENCES\s+(.*?)\s*\(#REFERENCES $tabprefix$1 (#i ;
1155              
1156 0           $cmd = "ALTER TABLE $tabname ADD $ccmd $cval" ;
1157             }
1158 0           $db -> do ($cmd) ;
1159 0 0         die "Fehler beim Ändern des Constraints des Feldes $tabname.$field:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1160             }
1161             }
1162             }
1163              
1164            
1165 0           print "ok\n" ;
1166             }
1167              
1168 0           $dbfields{$field} = 2 ;
1169             }
1170 0 0         if ($candropcolumn)
1171             {
1172 0           while (($field, $i) = each (%dbfields))
1173             {
1174 0 0         if ($i == 1)
1175             {
1176 0           printl (" Drop $field", LL) ;
1177            
1178 0           $cmd = "ALTER TABLE $tabname DROP $field" ;
1179 0           $db -> do ($cmd) ;
1180              
1181 0 0         die "Fehler beim Entfernen des Feldes $tabname.$field:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1182            
1183 0           print "ok\n" ;
1184             }
1185             }
1186             }
1187             }
1188             else
1189             {
1190 0           printl ("$tabname erstellen", LL) ;
1191              
1192 0           my $cmd = "CREATE TABLE $tabname (" ;
1193 0           $newtab = 1 ;
1194            
1195 0           my $fields = $tabdef{'!Fields'} ;
1196 0           for ($i = 0; $i <= $#$fields; $i+= 2)
1197             {
1198 0           $field = lc($fields -> [$i]) ;
1199 0           $typespec = $fields -> [$i+1] ;
1200 0 0 0       $hasseq = $newseq = 1 if ($createseq && $typespec eq 'counter') ;
1201            
1202 0 0         if ($typespec =~ /^(.*?)\s*\((.*?)\)(.*?)$/)
1203             {
1204 0 0         $type = $trans -> {$1}?$trans -> {$1}:$1 . "($2) $3" ;
1205             }
1206             else
1207             {
1208 0           $type = $typespec ;
1209 0 0         $type = $trans -> {$typespec} if ($trans -> {$typespec}) ;
1210             }
1211              
1212 0           $ccmd = '' ;
1213 0           $ncnt = 0 ;
1214 0 0 0       if ($constraints && ($constraint = $constraints -> {$field}))
1215             {
1216 0           $cname = "${tabname}_$field" ;
1217 0           for ($c = 0 ; $c < $#$constraint; $c+=2)
1218             {
1219 0 0         if ($constraint -> [$c] eq '!Name')
1220             {
1221 0           $cname = $tabprefix . $constraint -> [$c+1] ;
1222 0           $ncnt = 0 ;
1223 0           next ;
1224             }
1225 0           $ncnt++ ;
1226 0   0       $cval = $constraint -> [$c+1] || $constraint -> [$c] ;
1227 0           $cval =~ s#REFERENCES\s+(.*?)\s*\(#REFERENCES $tabprefix$1 (#i ;
1228 0 0         $ccmd .= " CONSTRAINT $cname" . ( $ncnt >1?$ncnt:'') . " $cval" ;
1229             }
1230             }
1231              
1232              
1233 0           $cmd .= "$field $type $ccmd" ;
1234 0 0         $cmd .= ($i == $#$fields - 1?' ':', ') ;
1235             }
1236              
1237 0 0         $cmd .= ", PRIMARY KEY ($tabdef{'!PrimKey'})" if ($tabdef{'!PrimKey'}) ;
1238 0           $cmd .= ')' ;
1239              
1240 0           $db -> do ($cmd) ;
1241              
1242 0 0         die "Fehler beim Erstellen der Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1243              
1244 0           print "ok\n" ;
1245              
1246 0 0         if ($init)
1247             {
1248 0           printl ("$tabname initialisieren", LL) ;
1249            
1250 0           my $rs = DBIx::Recordset -> Setup ({'!DataSource' => $db, '!Table' => $tabname, '!PrimKey' => $tabdef{'!PrimKey'}}) ;
1251 0 0         die "Fehler beim Setup von Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1252              
1253 0           my $rec ;
1254 0           foreach $rec (@$init)
1255             {
1256 0           my %dat ;
1257 0 0         if ($default)
1258             {
1259 0           %dat = (%$default, %$rec) ;
1260             }
1261             else
1262             {
1263 0           %dat = %$rec ;
1264             }
1265            
1266 0           $$rs -> Insert (\%dat) ;
1267 0 0         die "Fehler beim Insert in Tabelle $tabname:\n" . $$rs -> LastSQLStatement . "\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1268             }
1269 0           print "ok\n" ;
1270             }
1271             }
1272              
1273            
1274 0 0         if ($index)
1275             {
1276 0           printl ("$tabname index erstellen", LL) ;
1277              
1278 0           my $i ;
1279 0           for ($i = 0; $i <= $#$index; $i+= 2)
1280             {
1281 0           my $field = lc($index -> [$i]) ;
1282 0           my $name = "${tabname}_${field}_ndx" ;
1283 0           my $attr = $index -> [$i+1] ;
1284 0 0         if (ref($attr) eq 'HASH')
1285             {
1286 0           $name = "$tabprefix$attr->{Name}" ;
1287 0           $attr = $attr -> {Attr} ;
1288             }
1289            
1290 0           my $cmd = "CREATE $attr INDEX $name ON $tabname ($field)" ;
1291 0           $db -> do ($cmd) ;
1292 0 0 0       die "Fehler beim Erstellen des Indexes für $field:\n$cmd\n" . DBIx::Database->LastError if ($newtab && DBIx::Database->LastError) ;
1293             }
1294 0           print "ok\n" ;
1295             }
1296              
1297              
1298 0 0 0       if ($grant && ($newtab || $setpriv))
      0        
1299             {
1300 0 0         if ($createpublic)
1301              
1302             {
1303 0           printl ("public synonym für $tabname erstellen", LL) ;
1304              
1305 0 0 0       if ($setpriv && !$newtab)
1306             {
1307 0           my $cmd = "DROP PUBLIC SYNONYM $tabname " ;
1308 0           $db -> do ($cmd) ;
1309             }
1310              
1311 0           my $cmd = "CREATE PUBLIC SYNONYM $tabname FOR $shema.$tabname" ;
1312 0           $db -> do ($cmd) ;
1313 0 0 0       die "Fehler beim Erstellen von public Synonym $tabname:\n$cmd\n" . DBIx::Database->LastError if ($newtab && DBIx::Database->LastError) ;
1314              
1315 0           print "ok\n" ;
1316             }
1317 0           printl ("$tabname Berechtigungen setzen", LL) ;
1318            
1319 0 0 0       if ($setpriv && !$newtab)
1320             {
1321 0           my $cmd = "REVOKE all ON $tabname FROM $user" ;
1322 0           $db -> do ($cmd) ;
1323 0 0         warn "Fehler beim Entziehen der Berechtigungen für Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1324             }
1325              
1326 0           $cmd = 'GRANT ' . join (',', @$grant) . " ON $tabname TO $user" ;
1327 0           $db -> do ($cmd) ;
1328 0 0         die "Fehler beim Setzen der Berechtigungen für Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1329              
1330 0           print "ok\n" ;
1331             }
1332              
1333 0 0         if ($hasseq)
1334             {
1335 0           $tabname = "${tabname}_seq" ;
1336              
1337 0 0         if ($newseq)
1338             {
1339 0           printl ("$tabname erstellen", LL) ;
1340              
1341 0           my $cmd = "CREATE SEQUENCE $tabname " ;
1342 0           $db -> do ($cmd) ;
1343              
1344 0 0         die "Fehler beim Erstellen von Sequenz $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1345 0           print "ok\n" ;
1346             }
1347              
1348 0 0 0       if ($grant && ($newseq || $setpriv))
      0        
1349             {
1350 0 0         if ($createpublic)
1351              
1352             {
1353 0           printl ("public synonym für $tabname erstellen", LL) ;
1354              
1355 0 0 0       if ($setpriv && !$newseq)
1356             {
1357 0           my $cmd = "DROP PUBLIC SYNONYM $tabname " ;
1358 0           $db -> do ($cmd) ;
1359             }
1360              
1361 0           my $cmd = "CREATE PUBLIC SYNONYM $tabname FOR $shema.$tabname" ;
1362 0           $db -> do ($cmd) ;
1363              
1364 0 0 0       die "Fehler beim Erstellen von public Synonym $tabname:\n$cmd\n" . DBIx::Database->LastError if ($newseq && DBIx::Database->LastError) ;
1365 0           print "ok\n" ;
1366             }
1367              
1368 0           printl ("$tabname Berechtigungen setzen", LL) ;
1369            
1370 0 0 0       if ($setpriv && !$newseq)
1371             {
1372 0           my $cmd = "REVOKE all ON $tabname FROM $user" ;
1373              
1374 0           $db -> do ($cmd) ;
1375 0 0         warn "Fehler beim Entziehen der Berechtigungen für Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1376             }
1377              
1378 0           $cmd = "GRANT select ON $tabname TO $user" ;
1379 0           $db -> do ($cmd) ;
1380 0 0         die "Fehler beim Setzen der Berechtigungen für Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1381 0           print "ok\n" ;
1382              
1383             }
1384             }
1385             }
1386             }
1387              
1388             ## ---------------------------------------------------------------------------------
1389             ##
1390             ## Datenbank Tabellen entfernen
1391             ##
1392             ## in $shema schema name (Oracle)
1393             ## in $user user to revoke rights from
1394             ##
1395              
1396            
1397             sub DropTables
1398              
1399             {
1400             #my $DataSource = shift ;
1401             #my $setupuser = shift ;
1402             #my $setuppass = shift ;
1403             #my $tabprefix = shift ;
1404 0     0 0   my $db = shift ;
1405 0           my $shema = shift ;
1406 0           my $user = shift ;
1407              
1408 0           print "\nDatenbank Tabellen entfernen:\n" ;
1409              
1410             #my $db = DBIx::Database -> new ({'!DataSource' => "$DataSource",
1411             # '!Username' => $setupuser,
1412             # '!Password' => $setuppass,
1413             # '!KeepOpen' => 1,
1414             # '!TableFilter' => $tabprefix}) ;
1415             #
1416             #die DBIx::Database->LastError . "; Datenbank muß bereits bestehen" if (DBIx::Database->LastError) ;
1417              
1418 0           my $tables = $db -> AllTables ;
1419              
1420            
1421 0           my $tab ;
1422             my $tabname ;
1423 0           my @seq ;
1424 0           my $cmd ;
1425              
1426 0   0       my $public = defined ($user) && $db -> {'*Username'} ne $user ;
1427              
1428 0           my $drv = $db->{'*Driver'} ;
1429 0           my $tabprefix = $db -> {'*TableFilter'} ;
1430 0           my $createseq = DBIx::Compat::GetItem ($drv, 'CreateSeq') ;
1431 0   0       my $createpublic = $public && DBIx::Compat::GetItem ($drv, 'CreatePublic') ;
1432              
1433 0           foreach $tabname (keys %$tables)
1434             {
1435 0           printl ("$tabname entfernen", LL) ;
1436              
1437 0 0         if ($createpublic)
1438             {
1439 0           my $cmd = "DROP PUBLIC SYNONYM $tabname " ;
1440              
1441 0           $db -> do ($cmd) ;
1442             }
1443              
1444             #push @seq, $tabname if ($createseq && $typespec eq 'counter') ;
1445            
1446 0           $cmd = "DROP TABLE $tabname" ;
1447              
1448 0           $db -> do ($cmd) ;
1449              
1450 0           $db -> MetaData ($tabname, undef, 1) ;
1451 0           $tables -> {$tabname} = 0 ;
1452              
1453 0 0         die "Fehler beim Entfernen der Tabelle $tabname:\n$cmd\n" . DBIx::Database->LastError if (DBIx::Database->LastError) ;
1454            
1455 0           print "ok\n" ;
1456              
1457 0 0         if ($createseq)
1458             {
1459 0           $tabname = "${tabname}_seq" ;
1460              
1461             #printl ("$tabname erstellen", LL) ;
1462              
1463 0           my $cmd = "DROP SEQUENCE $tabname " ;
1464              
1465 0           $db -> do ($cmd) ;
1466              
1467 0 0         if ($createpublic)
1468             {
1469 0           my $cmd = "DROP PUBLIC SYNONYM $tabname " ;
1470              
1471 0           $db -> do ($cmd) ;
1472             }
1473             }
1474             }
1475             }
1476              
1477             ## ---------------------------------------------------------------------------------
1478             ##
1479             ## Output with fixed length
1480             ##
1481             ## in $txt Text
1482             ## in $length Length
1483             ## in $txt2 Weiterer Text
1484             ##
1485              
1486              
1487             sub printl
1488              
1489             {
1490 0     0 0   my ($txt, $length, $txt2) = @_ ;
1491              
1492 0           print $txt, ' ' x ($length - length($txt)), ' ', $txt2 ;
1493             } ;
1494              
1495              
1496             ###################################################################################
1497              
1498             1;
1499             __END__