File Coverage

blib/lib/DBO/Visitor/Insert.pm
Criterion Covered Total %
statement 15 15 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 20 20 100.0


line stmt bran cond sub pod time code
1             #------------------------------------------------------------------------------
2             # DBO::Visitor::Insert
3             #
4             # DESCRIPTION
5             #
6             # AUTHOR
7             # Gareth Rees
8             #
9             # COPYRIGHT
10             # Copyright (c) 1999 Canon Research Centre Europe Ltd.
11             #
12             # $Id: Insert.pm,v 1.2 1999/06/29 17:09:31 garethr Exp $
13             #------------------------------------------------------------------------------
14              
15 1     1   840 use strict;
  1         3  
  1         61  
16              
17             # We maintain a cache of prepared SQL statements accessible on a
18             # combination of Table and Handle. The prepared statement can be
19             # retrieved and executed quickly.
20              
21             my %INSERT_STH;
22              
23             package DBO::Visitor::PrepareInsert;
24 1     1   5 use base qw(DBO::Visitor);
  1         2  
  1         600  
25 1     1   7 use Class::Multimethods;
  1         2  
  1         7  
26              
27             multimethod visit_table =>
28             qw(DBO::Visitor::PrepareInsert DBO::Table DBO::Handle::DBI) =>
29             sub {
30             my ($vis, $table, $dbh) = @_;
31             my @sql = ("INSERT INTO", $table->{name}, "(");
32             my $cols = 0;
33             foreach my $col (@{$table->{columns}}){
34             $vis->{sql} = [];
35             visit_column($vis, $col, $dbh);
36             if (@{$vis->{sql}}) {
37             ++ $cols;
38             push @sql, @{$vis->{sql}}, ",";
39             }
40             }
41             $cols or die DBO::Exception
42             (NO_COLUMNS => "No columns found while preparing insert statement");
43             splice @sql, -1, 1, ") VALUES (", ("?",",") x $cols;
44             splice @sql, -1, 1, ")";
45             my $sql = join ' ', @sql;
46             $INSERT_STH{$table,$dbh} = $dbh->prepare($sql) or die DBO::Exception
47             (PREPARE => "Failed to prepare SQL statement %s: %s.", $sql, $dbh->errstr);
48             };
49              
50             multimethod visit_column =>
51             qw(DBO::Visitor::PrepareInsert DBO::Column::Base DBO::Handle::DBI) =>
52             sub {
53             my ($vis, $col, $dbh) = @_;
54             push @{$vis->{sql}}, $col->{name};
55             };
56              
57             package DBO::Visitor::Insert;
58 1     1   496 use base qw(DBO::Visitor);
  1         2  
  1         635  
59 1     1   8 use Class::Multimethods;
  1         3  
  1         7  
60              
61             multimethod visit_table =>
62             qw(DBO::Visitor::Insert DBO::Table DBO::Handle::DBI) =>
63             sub {
64             my ($vis, $table, $dbh) = @_;
65             my $sth = $INSERT_STH{$table,$dbh}
66             || visit_table(DBO::Visitor::PrepareInsert->new, $table, $dbh);
67             $sth->execute(map { visit_column($vis, $_, $dbh) } @{$table->{columns}})
68             or die DBO::Exception
69             (EXECUTE => "Failed to execute insert: %s.", $dbh->errstr);
70             $sth->finish;
71             };
72              
73             multimethod visit_column =>
74             qw(DBO::Visitor::Insert DBO::Column::Base DBO::Handle::DBI) =>
75             sub {
76             my ($vis, $col, $dbh) = @_;
77             $vis->{record}{$col->{name}};
78             };
79              
80              
81             #------------------------------------------------------------------------------
82             # Method instances for mSQL databases
83             #------------------------------------------------------------------------------
84              
85             multimethod visit_table =>
86             qw(DBO::Visitor::Insert DBO::Table DBO::Handle::DBI::mSQL) =>
87             sub {
88             my ($vis, $table, $dbh) = @_;
89             # Discover the new value of the sequence, if any.
90             if ($table->{autoincrement}) {
91             my $sql = "SELECT _seq FROM $table->{name}";
92             my @seq = $dbh->selectrow_array($sql) or die DBO::Exception
93             (SELECTALL => "Failed to execute SQL statement %s: %s.", $sql, $dbh->errstr);
94             $vis->{record}{$table->{autoincrement}} = $seq[0];
95             }
96             # visit_table($vis, $table, superclass($dbh));
97             call_next_method();
98             };
99              
100              
101             #------------------------------------------------------------------------------
102             # Method instances for MySQL databases.
103             #------------------------------------------------------------------------------
104              
105             my %MYSQL_STH;
106              
107             multimethod visit_table =>
108             qw(DBO::Visitor::Insert DBO::Table DBO::Handle::DBI::mysql) =>
109             sub {
110             my ($vis, $table, $dbh) = @_;
111             # visit_table($vis, $table, superclass($dbh));
112             call_next_method();
113             # Find out the new value of the autoincrement field, if any.
114             if ($table->{autoincrement}) {
115             my $sth = $MYSQL_STH{$table,$dbh} || do {
116             my $sql = "SELECT $table->{autoincrement} FROM $table->{name} WHERE $table->{autoincrement} IS NULL";
117             $MYSQL_STH{$table,$dbh} = $dbh->prepare($sql) or die DBO::Exception
118             (PREPARE => "Failed to prepare SQL statement %s: %s.", $sql,
119             $dbh->errstr);
120             };
121             $sth->execute or die DBO::Exception
122             (EXECUTE => "Failed to select autoincrement column: %s.", $dbh->errstr);
123             $vis->{record}{$table->{autoincrement}} = $sth->fetchrow_array;
124             $sth->finish;
125             }
126             };
127              
128             multimethod visit_column =>
129             qw(DBO::Visitor::Insert DBO::Column::AutoIncrement DBO::Handle::DBI::mysql) =>
130             sub {
131             my ($vis, $col, $dbh) = @_;
132             undef; # MySQL turns the NULL value into the next unused integer
133             };
134              
135             1;