| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package JDBC; |
|
2
|
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
153758
|
use warnings; |
|
|
5
|
|
|
|
|
32
|
|
|
|
5
|
|
|
|
|
263
|
|
|
4
|
5
|
|
|
5
|
|
32
|
use strict; |
|
|
5
|
|
|
|
|
19
|
|
|
|
5
|
|
|
|
|
593
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
=head1 NAME |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
JDBC - Perl 5 interface to Java JDBC (via Inline::Java) |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 VERSION |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Version 0.02 |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=cut |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use JDBC; |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
JDBC->load_driver("org.apache.derby.jdbc.EmbeddedDriver"); |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $con = JDBC->getConnection($url, "test", "test"); |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my $s = $con->createStatement(); |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
$s->executeUpdate("create table foo (foo int, bar varchar(200), primary key (foo))"); |
|
29
|
|
|
|
|
|
|
$s->executeUpdate("insert into foo (foo, bar) values (42,'notthis')"); |
|
30
|
|
|
|
|
|
|
$s->executeUpdate("insert into foo (foo, bar) values (43,'notthat')"); |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
my $rs = $s->executeQuery("select foo, bar from foo"); |
|
33
|
|
|
|
|
|
|
while ($rs->next) { |
|
34
|
|
|
|
|
|
|
my $foo = $rs->getInt(1); |
|
35
|
|
|
|
|
|
|
my $bar = $rs->getString(2); |
|
36
|
|
|
|
|
|
|
print "row: foo=$foo, bar=$bar\n"; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
This JDBC module provides an interface to the Java C and |
|
42
|
|
|
|
|
|
|
C JDBC APIs. |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=cut |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
our @ISA = qw(Exporter java::sql::DriverManager); |
|
47
|
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
{ # the Inline package needs to be use'd in main in order to |
|
49
|
|
|
|
|
|
|
# get the studied classes to be rooted in main |
|
50
|
|
|
|
|
|
|
package main; |
|
51
|
5
|
|
|
5
|
|
12509
|
use Inline ( Java => q{ }, AUTOSTUDY => 1 ); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
use Inline::Java qw(cast caught study_classes); |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
our @EXPORT_OK = qw(cast caught study_classes); |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
our $debug = $ENV{PERL_JDBC_DEBUG} || 0; |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
#java.sql.ParameterMetaData |
|
61
|
|
|
|
|
|
|
my @classes = (qw( |
|
62
|
|
|
|
|
|
|
java.sql.Array |
|
63
|
|
|
|
|
|
|
java.sql.BatchUpdateException |
|
64
|
|
|
|
|
|
|
java.sql.Blob |
|
65
|
|
|
|
|
|
|
java.sql.CallableStatement |
|
66
|
|
|
|
|
|
|
java.sql.Clob |
|
67
|
|
|
|
|
|
|
java.sql.Connection |
|
68
|
|
|
|
|
|
|
java.sql.DataTruncation |
|
69
|
|
|
|
|
|
|
java.sql.DatabaseMetaData |
|
70
|
|
|
|
|
|
|
java.sql.Date |
|
71
|
|
|
|
|
|
|
java.sql.Driver |
|
72
|
|
|
|
|
|
|
java.sql.DriverManager |
|
73
|
|
|
|
|
|
|
java.sql.DriverPropertyInfo |
|
74
|
|
|
|
|
|
|
java.sql.PreparedStatement |
|
75
|
|
|
|
|
|
|
java.sql.Ref |
|
76
|
|
|
|
|
|
|
java.sql.ResultSet |
|
77
|
|
|
|
|
|
|
java.sql.ResultSetMetaData |
|
78
|
|
|
|
|
|
|
java.sql.SQLData |
|
79
|
|
|
|
|
|
|
java.sql.SQLException |
|
80
|
|
|
|
|
|
|
java.sql.SQLInput |
|
81
|
|
|
|
|
|
|
java.sql.SQLOutput |
|
82
|
|
|
|
|
|
|
java.sql.SQLPermission |
|
83
|
|
|
|
|
|
|
java.sql.SQLWarning |
|
84
|
|
|
|
|
|
|
java.sql.Savepoint |
|
85
|
|
|
|
|
|
|
java.sql.Statement |
|
86
|
|
|
|
|
|
|
java.sql.Struct |
|
87
|
|
|
|
|
|
|
java.sql.Time |
|
88
|
|
|
|
|
|
|
java.sql.Timestamp |
|
89
|
|
|
|
|
|
|
java.sql.Types |
|
90
|
|
|
|
|
|
|
javax.sql.ConnectionEvent |
|
91
|
|
|
|
|
|
|
javax.sql.ConnectionEventListener |
|
92
|
|
|
|
|
|
|
javax.sql.ConnectionPoolDataSource |
|
93
|
|
|
|
|
|
|
javax.sql.DataSource |
|
94
|
|
|
|
|
|
|
javax.sql.PooledConnection |
|
95
|
|
|
|
|
|
|
javax.sql.RowSet |
|
96
|
|
|
|
|
|
|
javax.sql.RowSetEvent |
|
97
|
|
|
|
|
|
|
javax.sql.RowSetInternal |
|
98
|
|
|
|
|
|
|
javax.sql.RowSetListener |
|
99
|
|
|
|
|
|
|
javax.sql.RowSetMetaData |
|
100
|
|
|
|
|
|
|
javax.sql.RowSetReader |
|
101
|
|
|
|
|
|
|
javax.sql.RowSetWriter |
|
102
|
|
|
|
|
|
|
javax.sql.XAConnection |
|
103
|
|
|
|
|
|
|
javax.sql.XADataSource |
|
104
|
|
|
|
|
|
|
)); |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
warn "studying classes\n" if $debug; |
|
107
|
|
|
|
|
|
|
study_classes(\@classes, 'main'); |
|
108
|
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
#Fix a long-standing bug due to changes in @ISA caching introduced in perl 5.10.0. |
|
110
|
|
|
|
|
|
|
#See http://perldoc.perl.org/perl5100delta.html (search for "mro"). |
|
111
|
|
|
|
|
|
|
#RT 1/5/14. |
|
112
|
|
|
|
|
|
|
# |
|
113
|
|
|
|
|
|
|
#force a reset of the @ISA cache after injecting java.sql.DriverManager, which we inherit from: |
|
114
|
|
|
|
|
|
|
@ISA = @ISA; |
|
115
|
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
# Driver => java.sql.Driver, RowSet => javax.sql.RowSet etc |
|
117
|
|
|
|
|
|
|
my %class_base = map { m/^(.*\.(\w+))$/ or die; ( $2 => $1) } @classes; |
|
118
|
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# :Driver => java::sql::Driver, :RowSet => javax::sql::RowSet etc |
|
120
|
|
|
|
|
|
|
my %import_class = map { |
|
121
|
|
|
|
|
|
|
(my $pkg = $class_base{$_}) =~ s/\./::/g; |
|
122
|
|
|
|
|
|
|
(":$_" => $pkg) |
|
123
|
|
|
|
|
|
|
} keys %class_base; |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub import { |
|
127
|
|
|
|
|
|
|
my $pkg = shift; |
|
128
|
|
|
|
|
|
|
my $callpkg = caller($Exporter::ExportLevel); |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# deal with :ClassName imports as a special case |
|
131
|
|
|
|
|
|
|
my %done; |
|
132
|
|
|
|
|
|
|
for my $symbol (@_) { |
|
133
|
|
|
|
|
|
|
# is it a valid JDBC class? |
|
134
|
|
|
|
|
|
|
next unless my $java_pkg = $import_class{$symbol}; |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
no strict 'refs'; |
|
137
|
|
|
|
|
|
|
# get list of "constants" which I've defined as symbols with |
|
138
|
|
|
|
|
|
|
# all-uppercase names that also have defined scalar values |
|
139
|
|
|
|
|
|
|
# (which also avoids perl baggage like ISA, TIEHASH, DESTROY) |
|
140
|
|
|
|
|
|
|
my @const = grep { |
|
141
|
|
|
|
|
|
|
/^[A-Z][_A-Z0-9]*$/ and defined ${$java_pkg.'::'.$_} |
|
142
|
|
|
|
|
|
|
} keys %{ $java_pkg.'::' }; |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# now export those as real perl constants |
|
145
|
|
|
|
|
|
|
warn "import $symbol ($java_pkg): @const" if $debug; |
|
146
|
|
|
|
|
|
|
for my $const (@const) { |
|
147
|
|
|
|
|
|
|
no strict 'refs'; |
|
148
|
|
|
|
|
|
|
my $scalar = ${"$java_pkg\::$const"}; |
|
149
|
|
|
|
|
|
|
*{"$callpkg\::$const"} = sub () { $scalar }; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
++$done{$symbol}; |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
@_ = grep { !$done{$_} } @_; # remove symbols we've now dealt with |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
return if !@_ and %done; # we've dealt with all there was |
|
156
|
|
|
|
|
|
|
# else call standard import to handle anything else |
|
157
|
|
|
|
|
|
|
local $Exporter::ExportLevel = $Exporter::ExportLevel + 1; |
|
158
|
|
|
|
|
|
|
return $pkg->SUPER::import(@_); |
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=head1 METHODS |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=head2 load_driver |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
The load_driver() method is used to load a driver class. |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
JDBC->load_driver($driver_class) |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
is equivalent to the Java: |
|
170
|
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
java.lang.Class.forName(driver_class).newInstance(); |
|
172
|
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=cut |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
sub load_driver { |
|
176
|
|
|
|
|
|
|
my ($self, $class) = @_; |
|
177
|
|
|
|
|
|
|
study_classes([$class], 'main'); |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# override getDrivers to return an Enumeration (not private class) |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub getDrivers { |
|
183
|
|
|
|
|
|
|
return cast('java.util.Enumeration', shift->SUPER::getDrivers) |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
187
|
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head2 cast |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head2 caught |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 study_classes |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
The cast(), caught(), and study_classes() functions of Inline::Java are also |
|
195
|
|
|
|
|
|
|
optionally exported by the JDBC module. |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=cut |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head1 IMPORTING CONSTANTS |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Java JDBC makes use of constants defined in |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
import java.sql.*; |
|
204
|
|
|
|
|
|
|
... |
|
205
|
|
|
|
|
|
|
stmt = con.prepareStatement(PreparedStatement.SELECT); |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
the package can also be specified with the C which then avoids the need |
|
208
|
|
|
|
|
|
|
to prefix the constant with the class: |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
import java.sql.PreparedStatement; |
|
211
|
|
|
|
|
|
|
... |
|
212
|
|
|
|
|
|
|
stmt = con.prepareStatement(SELECT); |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
In Perl the corresponding code can be either: |
|
215
|
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
use JDBC; |
|
217
|
|
|
|
|
|
|
... |
|
218
|
|
|
|
|
|
|
$stmt = $con->prepareStatement($java::sql::PrepareStatement::SELECT); |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
or, the rather more friendly: |
|
221
|
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
use JDBC qw(:PreparedStatement); |
|
223
|
|
|
|
|
|
|
... |
|
224
|
|
|
|
|
|
|
$stmt = $con->prepareStatement(SELECT); |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
When importing a JDBC class in this way the JDBC module only imports defined |
|
227
|
|
|
|
|
|
|
scalars with all-uppercase names, and it turns them into perl constants so the |
|
228
|
|
|
|
|
|
|
C<$> is no longer needed. |
|
229
|
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
All constants in all the java.sql and javax.sql classes can be imported in this way. |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=cut |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
warn "running\n" if $debug; |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
1; # End of JDBC |
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
__END__ |