line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MonetDB::CLI::MapiPP; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
80656
|
use IO::Socket::INET(); |
|
3
|
|
|
|
|
89090
|
|
|
3
|
|
|
|
|
76
|
|
4
|
3
|
|
|
3
|
|
2996
|
use Text::ParseWords(); |
|
3
|
|
|
|
|
4532
|
|
|
3
|
|
|
|
|
66
|
|
5
|
3
|
|
|
3
|
|
21
|
use strict; |
|
3
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
86
|
|
6
|
3
|
|
|
3
|
|
16
|
use warnings; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
5868
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.03'; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
my %unescape = ( n => "\n", t => "\t", r => "\r", f => "\f"); |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub unquote |
14
|
|
|
|
|
|
|
{ |
15
|
0
|
|
|
0
|
0
|
0
|
my ($class, $v) = @_; |
16
|
|
|
|
|
|
|
|
17
|
0
|
0
|
0
|
|
|
0
|
return undef if $v eq 'NULL' || $v eq 'nil'; |
18
|
|
|
|
|
|
|
|
19
|
0
|
0
|
|
|
|
0
|
if ( $v =~ /^["']/) { |
20
|
0
|
|
|
|
|
0
|
$v =~ s/^["']//; |
21
|
0
|
|
|
|
|
0
|
$v =~ s/["']$//; |
22
|
0
|
0
|
|
|
|
0
|
$v =~ s/\\(.)/$unescape{$1}||$1/eg; |
|
0
|
|
|
|
|
0
|
|
23
|
|
|
|
|
|
|
} |
24
|
0
|
|
|
|
|
0
|
return $v; |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub connect |
29
|
|
|
|
|
|
|
{ |
30
|
2
|
|
|
2
|
0
|
1624
|
my ($class, $host, $port, $user, $pass, $lang) = @_; |
31
|
|
|
|
|
|
|
|
32
|
2
|
50
|
|
|
|
26
|
my $h = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port ) |
33
|
|
|
|
|
|
|
or die "Handle is undefined: $@"; |
34
|
0
|
|
|
|
|
|
<$h>; |
35
|
0
|
0
|
|
|
|
|
print $h "$user:$pass:$lang:line\n" or die $!; |
36
|
0
|
|
|
|
|
|
while ( local $_ = <$h> ) { |
37
|
0
|
0
|
|
|
|
|
last if /^\001/; |
38
|
|
|
|
|
|
|
} |
39
|
0
|
|
|
|
|
|
bless { h => $h, lang => $lang },'MonetDB::CLI::MapiPP::Cxn'; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
package MonetDB::CLI::MapiPP::Cxn; |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub query |
46
|
|
|
|
|
|
|
{ |
47
|
0
|
|
|
0
|
|
|
my ($self, $statement) = @_; |
48
|
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
my $h = $self->new_handle; |
50
|
0
|
|
|
|
|
|
$h->query( $statement ); |
51
|
|
|
|
|
|
|
|
52
|
0
|
|
|
|
|
|
return $h; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
sub new_handle |
56
|
|
|
|
|
|
|
{ |
57
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
58
|
|
|
|
|
|
|
|
59
|
0
|
|
|
|
|
|
bless { p => $self },'MonetDB::CLI::MapiPP::Req'; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub DESTROY |
63
|
|
|
|
|
|
|
{ |
64
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
65
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
|
$self->{h}->close; |
67
|
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
return; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
package MonetDB::CLI::MapiPP::Req; |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
sub query |
75
|
|
|
|
|
|
|
{ |
76
|
0
|
|
|
0
|
|
|
my ($self, $statement) = @_; |
77
|
|
|
|
|
|
|
|
78
|
0
|
|
|
|
|
|
my $lang = $self->{p}{lang}; |
79
|
0
|
|
|
|
|
|
my $h = $self->{p}{h}; |
80
|
0
|
0
|
|
|
|
|
my $delim = $lang eq 'sql' ? qr(\s*,\s*) : qr(\s+); |
81
|
0
|
|
|
|
|
|
my @err; |
82
|
|
|
|
|
|
|
|
83
|
0
|
0
|
|
|
|
|
if ( $lang eq 'sql') { |
84
|
0
|
|
|
|
|
|
my @statement = split /\n/, $statement; |
85
|
0
|
|
|
|
|
|
s/--.*// for @statement; # TODO: -- inside '' (or blocked mode?) |
86
|
0
|
|
|
|
|
|
$statement = join ' ', @statement; |
87
|
0
|
0
|
|
|
|
|
$statement .= ';' unless $statement =~ /;$/; |
88
|
0
|
|
|
|
|
|
$statement = 's' . $statement; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
else { |
91
|
0
|
|
|
|
|
|
$statement =~ s/\n/ /g; |
92
|
|
|
|
|
|
|
} |
93
|
0
|
0
|
|
|
|
|
print $h $statement,"\n" or die $!; |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
$self->finish; |
96
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
|
while ( local $_ = <$h> ) { |
98
|
0
|
|
|
|
|
|
chomp; |
99
|
0
|
0
|
|
|
|
|
if (/^\[/) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
100
|
0
|
0
|
|
|
|
|
die "Incomplete tuple: $_" unless /\]$/; |
101
|
0
|
|
|
|
|
|
s/^\[\s*//; |
102
|
0
|
|
|
|
|
|
s/\s*\]$//; |
103
|
0
|
|
|
|
|
|
my @a = Text::ParseWords::parse_line( qr(\s*,\s*), 0, $_ ); |
104
|
0
|
|
|
|
|
|
push @{$self->{rs}}, [ map { MonetDB::CLI::MapiPP->unquote( $_ ) } @a ]; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
elsif (/^&(\d) (\d+) (\d+) (\d+)/) { |
107
|
0
|
0
|
|
|
|
|
$self->{querytype} = $1 if $self->{querytype} < 0; |
108
|
0
|
0
|
|
|
|
|
$self->{id} = $2 if $self->{id} < 0; |
109
|
0
|
0
|
|
|
|
|
$self->{tuplecount} = $3 if $self->{tuplecount} < 0; |
110
|
0
|
0
|
|
|
|
|
$self->{columncount} = $4 if $self->{columncount} < 0; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
elsif (/^&(\d) (\d+)/) { |
113
|
0
|
0
|
|
|
|
|
$self->{querytype} = $1 if $self->{querytype} < 0; |
114
|
0
|
0
|
|
|
|
|
$self->{tuplecount} = $2 if $self->{tuplecount} < 0; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
elsif (/^#\s+\b(.*)\b\s+# (name|type|length)$/) { |
117
|
0
|
|
|
|
|
|
$self->{$2} = [ split $delim, $1 ]; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
elsif (/^!/) { |
120
|
0
|
|
|
|
|
|
push @err, $_; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
elsif (/^\001\001/) { |
123
|
0
|
|
|
|
|
|
last; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
elsif (/^\001\002/) { |
126
|
0
|
|
|
|
|
|
die "Incomplete query: $statement"; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} |
129
|
0
|
0
|
|
|
|
|
$self->{columncount} = @{$self->{name}} if $self->{columncount} < 0;; |
|
0
|
|
|
|
|
|
|
130
|
0
|
0
|
0
|
|
|
|
$self->{columncount} ||= @{$self->{rs}[0]} if $self->{rs}[0]; |
|
0
|
|
|
|
|
|
|
131
|
0
|
0
|
|
|
|
|
$self->{tuplecount} = @{$self->{rs}} if $lang ne 'sql'; |
|
0
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
0
|
0
|
|
|
|
|
die join "\n", @err if @err; |
134
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
return; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub querytype |
139
|
|
|
|
|
|
|
{ |
140
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
141
|
|
|
|
|
|
|
|
142
|
0
|
|
|
|
|
|
return $self->{querytype}; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub id |
146
|
|
|
|
|
|
|
{ |
147
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
return $self->{id}; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub rows_affected |
153
|
|
|
|
|
|
|
{ |
154
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
155
|
|
|
|
|
|
|
|
156
|
0
|
|
|
|
|
|
return $self->{tuplecount}; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub columncount |
160
|
|
|
|
|
|
|
{ |
161
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
162
|
|
|
|
|
|
|
|
163
|
0
|
|
|
|
|
|
return $self->{columncount}; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
sub name |
167
|
|
|
|
|
|
|
{ |
168
|
0
|
|
|
0
|
|
|
my ($self, $fnr) = @_; |
169
|
|
|
|
|
|
|
|
170
|
0
|
|
0
|
|
|
|
return $self->{name}[$fnr] || ''; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub type |
174
|
|
|
|
|
|
|
{ |
175
|
0
|
|
|
0
|
|
|
my ($self, $fnr) = @_; |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
0
|
|
|
|
return $self->{type}[$fnr] || ''; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub length |
181
|
|
|
|
|
|
|
{ |
182
|
0
|
|
|
0
|
|
|
my ($self, $fnr) = @_; |
183
|
|
|
|
|
|
|
|
184
|
0
|
|
0
|
|
|
|
return $self->{length}[$fnr] || 0; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub fetch |
188
|
|
|
|
|
|
|
{ |
189
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
190
|
|
|
|
|
|
|
|
191
|
0
|
0
|
|
|
|
|
return if ++$self->{i} > $#{$self->{rs}}; |
|
0
|
|
|
|
|
|
|
192
|
0
|
|
|
|
|
|
return $self->{columncount}; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub field |
196
|
|
|
|
|
|
|
{ |
197
|
0
|
|
|
0
|
|
|
my ($self, $fnr) = @_; |
198
|
|
|
|
|
|
|
|
199
|
0
|
|
|
|
|
|
return $self->{rs}[$self->{i}][$fnr]; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub finish |
203
|
|
|
|
|
|
|
{ |
204
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
205
|
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
$self->{$_} = -1 for qw(querytype id tuplecount columncount i); |
207
|
0
|
|
|
|
|
|
$self->{$_} = [] for qw(rs name type length); |
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
|
return; |
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
sub DESTROY |
213
|
|
|
|
|
|
|
{ |
214
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
215
|
|
|
|
|
|
|
|
216
|
0
|
|
|
|
|
|
return; |
217
|
|
|
|
|
|
|
} |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
__PACKAGE__; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 NAME |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
MonetDB::CLI::MapiPP - MonetDB::CLI implementation, using the Mapi protocol |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head1 DESCRIPTION |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
MonetDB::CLI::MapiPP is an implementation of the MonetDB call level interface |
228
|
|
|
|
|
|
|
L. |
229
|
|
|
|
|
|
|
It's a Pure Perl module. |
230
|
|
|
|
|
|
|
It uses the Mapi protocol - a text based communication layer on top of TCP. |
231
|
|
|
|
|
|
|
Normally, you don't use this module directly, but let L |
232
|
|
|
|
|
|
|
choose an implementation module. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 AUTHORS |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
Steffen Goeldner Esgoeldner@cpan.orgE. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENCE |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
The contents of this file are subject to the MonetDB Public License |
241
|
|
|
|
|
|
|
Version 1.1 (the "License"); you may not use this file except in |
242
|
|
|
|
|
|
|
compliance with the License. You may obtain a copy of the License at |
243
|
|
|
|
|
|
|
http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
Software distributed under the License is distributed on an "AS IS" |
246
|
|
|
|
|
|
|
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
247
|
|
|
|
|
|
|
License for the specific language governing rights and limitations |
248
|
|
|
|
|
|
|
under the License. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
The Original Code is the MonetDB Database System. |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
The Initial Developer of the Original Code is CWI. |
253
|
|
|
|
|
|
|
Portions created by CWI are Copyright (C) 1997-2006 CWI. |
254
|
|
|
|
|
|
|
All Rights Reserved. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=head1 SEE ALSO |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=head2 MonetDB |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Homepage : http://monetdb.cwi.nl |
261
|
|
|
|
|
|
|
SourceForge : http://sourceforge.net/projects/monetdb |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=head2 Perl modules |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
L |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
=cut |