line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DBD::Crate;
|
2
|
5
|
|
|
5
|
|
42271
|
use strict;
|
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
109
|
|
3
|
5
|
|
|
5
|
|
2617
|
use DBI;
|
|
5
|
|
|
|
|
82760
|
|
|
5
|
|
|
|
|
180
|
|
4
|
5
|
|
|
5
|
|
3050
|
use HTTP::Tiny;
|
|
5
|
|
|
|
|
169989
|
|
|
5
|
|
|
|
|
163
|
|
5
|
5
|
|
|
5
|
|
1958
|
use JSON::MaybeXS;
|
|
5
|
|
|
|
|
25200
|
|
|
5
|
|
|
|
|
265
|
|
6
|
5
|
|
|
5
|
|
24
|
use vars qw($VERSION $REVISION);
|
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
243
|
|
7
|
5
|
|
|
5
|
|
20
|
use vars qw($err $errstr $state $drh);
|
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
814
|
|
8
|
|
|
|
|
|
|
$VERSION = "0.0.3";
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
$err = 0;
|
11
|
|
|
|
|
|
|
$errstr = "";
|
12
|
|
|
|
|
|
|
$state = "";
|
13
|
|
|
|
|
|
|
$drh = undef;
|
14
|
|
|
|
|
|
|
my $methods_are_installed = 0;
|
15
|
|
|
|
|
|
|
my ($HTTP, $JSON);
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub driver {
|
18
|
0
|
0
|
|
0
|
0
|
|
return $drh if $drh;
|
19
|
0
|
|
|
|
|
|
my ($class, $attr) = @_;
|
20
|
0
|
|
|
|
|
|
$class .= "::dr";
|
21
|
0
|
0
|
|
|
|
|
$drh = DBI::_new_drh($class, {
|
22
|
|
|
|
|
|
|
'Name' => 'Crate',
|
23
|
|
|
|
|
|
|
'Version' => $VERSION,
|
24
|
|
|
|
|
|
|
'Err' => \$err,
|
25
|
|
|
|
|
|
|
'Errstr' => \$errstr,
|
26
|
|
|
|
|
|
|
'State' => \$state,
|
27
|
|
|
|
|
|
|
'Attribution' => 'DBD::Crate by Mamod Mehyar',
|
28
|
|
|
|
|
|
|
'AutoCommit' => 1
|
29
|
|
|
|
|
|
|
}) or return undef;
|
30
|
0
|
|
|
|
|
|
return $drh;
|
31
|
|
|
|
|
|
|
}
|
32
|
|
|
|
|
|
|
|
33
|
0
|
|
|
0
|
0
|
|
sub http { $HTTP }
|
34
|
0
|
|
|
0
|
0
|
|
sub json { $JSON }
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
#====================================================================
|
37
|
|
|
|
|
|
|
# DBD::Crate::dr
|
38
|
|
|
|
|
|
|
#====================================================================
|
39
|
|
|
|
|
|
|
package DBD::Crate::dr; {
|
40
|
5
|
|
|
5
|
|
26
|
use strict;
|
|
5
|
|
|
|
|
4
|
|
|
5
|
|
|
|
|
120
|
|
41
|
5
|
|
|
5
|
|
17
|
use DBI qw(:sql_types);
|
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
2056
|
|
42
|
5
|
|
|
5
|
|
25
|
use vars qw($imp_data_size);
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
147
|
|
43
|
5
|
|
|
5
|
|
40
|
use Carp qw(carp croak);
|
|
5
|
|
|
|
|
4
|
|
|
5
|
|
|
|
|
199
|
|
44
|
5
|
|
|
5
|
|
2541
|
use Data::Dumper;
|
|
5
|
|
|
|
|
20783
|
|
|
5
|
|
|
|
|
226
|
|
45
|
5
|
|
|
5
|
|
22
|
use DBI;
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
1232
|
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
$imp_data_size = 0;
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub connect {
|
50
|
0
|
|
|
0
|
|
|
my ($drh, $dburl, $user, $pass, $attr) = @_;
|
51
|
|
|
|
|
|
|
my $UTF8 = defined $attr->{utf8} ?
|
52
|
0
|
0
|
|
|
|
|
$attr->{utf8} : 1;
|
53
|
|
|
|
|
|
|
|
54
|
0
|
|
|
|
|
|
$JSON = JSON::MaybeXS->new({ utf8 => $UTF8 });
|
55
|
0
|
|
|
|
|
|
$HTTP = HTTP::Tiny->new( keep_alive => 1 );
|
56
|
|
|
|
|
|
|
|
57
|
0
|
|
|
|
|
|
my @addresses = ($dburl);
|
58
|
0
|
|
|
|
|
|
my @addr;
|
59
|
0
|
0
|
|
|
|
|
if ($dburl =~ s/^\[(.*?)\]$/$1/){
|
60
|
0
|
|
|
|
|
|
@addresses = split ',', $dburl;
|
61
|
|
|
|
|
|
|
}
|
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
foreach my $addr (@addresses){
|
64
|
0
|
|
|
|
|
|
$addr =~ s/\s+//;
|
65
|
0
|
0
|
|
|
|
|
if (!$addr){
|
66
|
0
|
|
|
|
|
|
$addr = 'http://localhost:4200';
|
67
|
|
|
|
|
|
|
}
|
68
|
|
|
|
|
|
|
|
69
|
0
|
0
|
|
|
|
|
if ($addr !~ /^http/){
|
70
|
0
|
|
|
|
|
|
$addr = 'http://' . $addr;
|
71
|
|
|
|
|
|
|
}
|
72
|
|
|
|
|
|
|
|
73
|
0
|
0
|
0
|
|
|
|
if ($user || $pass){
|
74
|
0
|
|
0
|
|
|
|
my $auth = ($user || '') . ':' . ($pass || '');
|
|
|
|
0
|
|
|
|
|
75
|
0
|
|
|
|
|
|
$addr =~ s/^(http(?:.)?:\/\/)(.*?)/$1$auth\@$2/;
|
76
|
|
|
|
|
|
|
}
|
77
|
0
|
|
|
|
|
|
push @addr, $addr;
|
78
|
|
|
|
|
|
|
}
|
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
|
my ($t, $dbh) = DBI::_new_dbh($drh, {
|
81
|
|
|
|
|
|
|
'Name' => \@addr
|
82
|
|
|
|
|
|
|
});
|
83
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
return $dbh;
|
85
|
|
|
|
|
|
|
}
|
86
|
|
|
|
|
|
|
|
87
|
0
|
|
|
0
|
|
|
sub data_sources { return "Cratedb" }
|
88
|
0
|
|
|
0
|
|
|
sub disconnect_all { 1 }
|
89
|
|
|
|
|
|
|
};
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
#====================================================================
|
92
|
|
|
|
|
|
|
# DBD::Crate::db
|
93
|
|
|
|
|
|
|
#====================================================================
|
94
|
|
|
|
|
|
|
package DBD::Crate::db; {
|
95
|
5
|
|
|
5
|
|
21
|
use strict;
|
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
99
|
|
96
|
5
|
|
|
5
|
|
21
|
use base qw(DBD::_::db);
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
1273
|
|
97
|
5
|
|
|
5
|
|
21
|
use vars qw($imp_data_size);
|
|
5
|
|
|
|
|
7
|
|
|
5
|
|
|
|
|
146
|
|
98
|
5
|
|
|
5
|
|
15
|
use Data::Dumper;
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
190
|
|
99
|
5
|
|
|
5
|
|
15
|
use DBI;
|
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
132
|
|
100
|
5
|
|
|
5
|
|
1882
|
use Digest::SHA1 qw(sha1_hex);
|
|
5
|
|
|
|
|
2288
|
|
|
5
|
|
|
|
|
2687
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
$imp_data_size = 0;
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub prepare {
|
105
|
0
|
|
|
0
|
|
|
my ($dbh, $statement, @attr) = @_;
|
106
|
|
|
|
|
|
|
my $sth = DBI::_new_sth($dbh, {
|
107
|
|
|
|
|
|
|
'Statement' => $statement,
|
108
|
|
|
|
|
|
|
'ConnectionHOST' => $dbh->{Name}
|
109
|
0
|
|
|
|
|
|
});
|
110
|
0
|
|
|
|
|
|
return $sth;
|
111
|
|
|
|
|
|
|
}
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
#=============================================================
|
114
|
|
|
|
|
|
|
# blob methods
|
115
|
|
|
|
|
|
|
#=============================================================
|
116
|
|
|
|
|
|
|
sub crate_blob_insert {
|
117
|
0
|
|
|
0
|
|
|
my ($dbh, $table, $digest, $content) = @_;
|
118
|
|
|
|
|
|
|
|
119
|
0
|
0
|
|
|
|
|
if (!$content){
|
120
|
0
|
|
|
|
|
|
$content = $digest;
|
121
|
0
|
|
|
|
|
|
$digest = sha1_hex($content);
|
122
|
|
|
|
|
|
|
}
|
123
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
|
my $path = "/_blobs/$table/" . $digest;
|
125
|
|
|
|
|
|
|
my $sth = DBI::_new_sth($dbh, {
|
126
|
|
|
|
|
|
|
'REQUEST_PATH' => $path,
|
127
|
|
|
|
|
|
|
'REQUEST_METHOD' => 'PUT',
|
128
|
|
|
|
|
|
|
'Statement' => $content,
|
129
|
|
|
|
|
|
|
'ConnectionHOST' => $dbh->{Name},
|
130
|
0
|
|
|
|
|
|
'BLOB' => 1,
|
131
|
|
|
|
|
|
|
'DIGEST' => $digest
|
132
|
|
|
|
|
|
|
});
|
133
|
|
|
|
|
|
|
|
134
|
0
|
|
|
|
|
|
return $sth->execute();
|
135
|
|
|
|
|
|
|
};
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub crate_blob_get {
|
138
|
0
|
|
|
0
|
|
|
my ($dbh, $table, $digest) = @_;
|
139
|
|
|
|
|
|
|
|
140
|
0
|
0
|
|
|
|
|
if (!$digest){
|
141
|
0
|
|
|
|
|
|
$dbh->set_err(-1, "BLOB sha1 digest required");
|
142
|
0
|
|
|
|
|
|
return;
|
143
|
|
|
|
|
|
|
}
|
144
|
|
|
|
|
|
|
|
145
|
0
|
|
0
|
|
|
|
$digest ||= '';
|
146
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
|
my $path = "/_blobs/$table/" . $digest;
|
148
|
|
|
|
|
|
|
my $sth = DBI::_new_sth($dbh, {
|
149
|
|
|
|
|
|
|
'REQUEST_PATH' => $path,
|
150
|
|
|
|
|
|
|
'REQUEST_METHOD' => 'GET',
|
151
|
|
|
|
|
|
|
'Statement' => '',
|
152
|
|
|
|
|
|
|
'ConnectionHOST' => $dbh->{Name},
|
153
|
0
|
|
|
|
|
|
'BLOB' => 1,
|
154
|
|
|
|
|
|
|
'DIGEST' => $digest
|
155
|
|
|
|
|
|
|
});
|
156
|
0
|
|
|
|
|
|
return $sth->execute();
|
157
|
|
|
|
|
|
|
}
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
sub crate_blob_delete {
|
160
|
0
|
|
|
0
|
|
|
my ($dbh, $table, $digest) = @_;
|
161
|
|
|
|
|
|
|
|
162
|
0
|
0
|
|
|
|
|
if (!$digest){
|
163
|
0
|
|
|
|
|
|
$dbh->set_err(-1, "BLOB sha1 digest required");
|
164
|
0
|
|
|
|
|
|
return;
|
165
|
|
|
|
|
|
|
}
|
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
|
my $path = "/_blobs/$table/" . $digest;
|
168
|
|
|
|
|
|
|
my $sth = DBI::_new_sth($dbh, {
|
169
|
|
|
|
|
|
|
'REQUEST_PATH' => $path,
|
170
|
|
|
|
|
|
|
'REQUEST_METHOD' => 'DELETE',
|
171
|
|
|
|
|
|
|
'Statement' => '',
|
172
|
|
|
|
|
|
|
'ConnectionHOST' => $dbh->{Name},
|
173
|
0
|
|
|
|
|
|
'BLOB' => 1,
|
174
|
|
|
|
|
|
|
'DIGEST' => $digest
|
175
|
|
|
|
|
|
|
});
|
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
return $sth->execute();
|
178
|
|
|
|
|
|
|
}
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
#=============================================================
|
181
|
|
|
|
|
|
|
# table info methods
|
182
|
|
|
|
|
|
|
#=============================================================
|
183
|
|
|
|
|
|
|
#return columns information of provided table
|
184
|
|
|
|
|
|
|
sub crate_table_columns {
|
185
|
0
|
|
|
0
|
|
|
my ($dbh, $table) = @_;
|
186
|
0
|
|
|
|
|
|
my $sth = $dbh->prepare(qq~
|
187
|
|
|
|
|
|
|
select column_name, data_type, ordinal_position
|
188
|
|
|
|
|
|
|
from information_schema.columns
|
189
|
|
|
|
|
|
|
where schema_name = 'doc'
|
190
|
|
|
|
|
|
|
AND table_name = ?
|
191
|
|
|
|
|
|
|
~);
|
192
|
|
|
|
|
|
|
|
193
|
0
|
|
|
|
|
|
return $dbh->selectall_arrayref( $sth,
|
194
|
|
|
|
|
|
|
{ Slice => {} },
|
195
|
|
|
|
|
|
|
$table);
|
196
|
|
|
|
|
|
|
}
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
#list all tables with information
|
199
|
|
|
|
|
|
|
sub crate_tables_list {
|
200
|
0
|
|
|
0
|
|
|
my $dbh = shift;
|
201
|
0
|
|
0
|
|
|
|
my $schema = shift || 'doc';
|
202
|
0
|
|
|
|
|
|
my $sth = $dbh->prepare(qq~
|
203
|
|
|
|
|
|
|
select number_of_replicas, partitioned_by, blobs_path, schema_name,
|
204
|
|
|
|
|
|
|
table_name, number_of_shards, clustered_by
|
205
|
|
|
|
|
|
|
from information_schema.tables
|
206
|
|
|
|
|
|
|
where schema_name = ?
|
207
|
|
|
|
|
|
|
~);
|
208
|
|
|
|
|
|
|
|
209
|
0
|
|
|
|
|
|
return $dbh->selectall_arrayref( $sth,
|
210
|
|
|
|
|
|
|
{ Slice => {} },
|
211
|
|
|
|
|
|
|
$schema);
|
212
|
|
|
|
|
|
|
}
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
#get table info
|
215
|
|
|
|
|
|
|
sub crate_table_info {
|
216
|
0
|
|
|
0
|
|
|
my $dbh = shift;
|
217
|
0
|
|
|
|
|
|
my $table = shift;
|
218
|
0
|
|
|
|
|
|
my $sth = $dbh->prepare(qq~
|
219
|
|
|
|
|
|
|
select number_of_replicas, partitioned_by, blobs_path, schema_name,
|
220
|
|
|
|
|
|
|
table_name, number_of_shards, clustered_by
|
221
|
|
|
|
|
|
|
from information_schema.tables
|
222
|
|
|
|
|
|
|
where schema_name = 'doc'
|
223
|
|
|
|
|
|
|
AND table_name = ?
|
224
|
|
|
|
|
|
|
~);
|
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
|
return $dbh->selectrow_hashref( $sth,
|
227
|
|
|
|
|
|
|
undef,
|
228
|
|
|
|
|
|
|
$table);
|
229
|
|
|
|
|
|
|
}
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
#==================================================
|
232
|
|
|
|
|
|
|
# These should be removed once we get crate name
|
233
|
|
|
|
|
|
|
# space registered with DBI
|
234
|
|
|
|
|
|
|
#==================================================
|
235
|
|
|
|
|
|
|
*DBI::db::crate_blob_insert = \&crate_blob_insert;
|
236
|
|
|
|
|
|
|
*DBI::db::crate_blob_get = \&crate_blob_get;
|
237
|
|
|
|
|
|
|
*DBI::db::crate_blob_delete = \&crate_blob_delete;
|
238
|
|
|
|
|
|
|
*DBI::db::crate_table_columns = \&crate_table_columns;
|
239
|
|
|
|
|
|
|
*DBI::db::crate_tables_list = \&crate_tables_list;
|
240
|
|
|
|
|
|
|
*DBI::db::crate_table_info = \&crate_table_info;
|
241
|
|
|
|
|
|
|
};
|
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
#====================================================================
|
244
|
|
|
|
|
|
|
# DBD::Crate::st
|
245
|
|
|
|
|
|
|
#====================================================================
|
246
|
|
|
|
|
|
|
package DBD::Crate::st; {
|
247
|
5
|
|
|
5
|
|
24
|
use strict;
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
98
|
|
248
|
5
|
|
|
5
|
|
14
|
use base qw(DBD::_::st);
|
|
5
|
|
|
|
|
16
|
|
|
5
|
|
|
|
|
1114
|
|
249
|
5
|
|
|
5
|
|
17
|
use vars qw($imp_data_size);
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
135
|
|
250
|
5
|
|
|
5
|
|
16
|
use Data::Dumper;
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
165
|
|
251
|
5
|
|
|
5
|
|
17
|
use DBI;
|
|
5
|
|
|
|
|
5
|
|
|
5
|
|
|
|
|
2786
|
|
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
$imp_data_size = 0;
|
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub _fetch_data {
|
256
|
0
|
|
|
0
|
|
|
my $sth = shift;
|
257
|
0
|
|
|
|
|
|
my $statement = shift;
|
258
|
0
|
|
0
|
|
|
|
my $method = shift || 'POST';
|
259
|
0
|
|
0
|
|
|
|
my $path = shift || '/_sql';
|
260
|
|
|
|
|
|
|
|
261
|
0
|
|
|
|
|
|
my @hosts = @{ $sth->{ConnectionHOST} };
|
|
0
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
|
263
|
0
|
|
|
|
|
|
TRYAGAIN :
|
264
|
|
|
|
|
|
|
my $host = shift @hosts;
|
265
|
0
|
|
|
|
|
|
my $ret = DBD::Crate::http->request($method, $host . $path, {
|
266
|
|
|
|
|
|
|
content => $statement,
|
267
|
|
|
|
|
|
|
# headers => {'Content-Type' => 'application/json'}
|
268
|
|
|
|
|
|
|
});
|
269
|
|
|
|
|
|
|
|
270
|
0
|
0
|
0
|
|
|
|
if ( $ret->{status} == 599 && scalar @hosts){
|
271
|
0
|
|
|
|
|
|
my $i = 0;
|
272
|
0
|
|
|
|
|
|
for (@{ $sth->{ConnectionHOST} }){
|
|
0
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
#put failing address to the end of hosts
|
274
|
|
|
|
|
|
|
#this will work only on persistant environments
|
275
|
0
|
0
|
|
|
|
|
if ( $host eq $_ ){
|
276
|
0
|
|
|
|
|
|
splice @{ $sth->{ConnectionHOST} }, $i, 1;
|
|
0
|
|
|
|
|
|
|
277
|
0
|
|
|
|
|
|
push @{ $sth->{ConnectionHOST} }, $_;
|
|
0
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
}
|
279
|
0
|
|
|
|
|
|
$i++;
|
280
|
|
|
|
|
|
|
}
|
281
|
0
|
|
|
|
|
|
goto TRYAGAIN;
|
282
|
|
|
|
|
|
|
}
|
283
|
|
|
|
|
|
|
|
284
|
0
|
0
|
|
|
|
|
if (!$ret->{success}){
|
285
|
0
|
|
|
|
|
|
my $olderr = $@;
|
286
|
0
|
|
|
|
|
|
my $data = eval { DBD::Crate::json->decode($ret->{content}) };
|
|
0
|
|
|
|
|
|
|
287
|
0
|
|
|
|
|
|
$@ = $olderr;
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
my $error = ref $data eq 'HASH' && ref $data->{error} ? $data->{error} : {
|
290
|
|
|
|
|
|
|
code => ref $data ? $data->{status} : $ret->{status},
|
291
|
|
|
|
|
|
|
message => ref $data ? $data->{error} : ($ret->{content} || $ret->{reason})
|
292
|
0
|
0
|
0
|
|
|
|
};
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
293
|
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
|
$sth->set_err($error->{code}, $error->{message});
|
295
|
0
|
|
|
|
|
|
return;
|
296
|
|
|
|
|
|
|
}
|
297
|
|
|
|
|
|
|
|
298
|
0
|
|
|
|
|
|
return $ret;
|
299
|
|
|
|
|
|
|
}
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
sub execute {
|
302
|
0
|
|
|
0
|
|
|
my $sth = shift;
|
303
|
0
|
|
|
|
|
|
my $statement = $sth->{Statement};
|
304
|
0
|
|
|
|
|
|
my $ret;
|
305
|
0
|
0
|
|
|
|
|
if ($sth->{BLOB}){
|
306
|
0
|
0
|
|
|
|
|
if (!$sth->{DIGEST}){
|
307
|
0
|
|
|
|
|
|
$sth->set_err(-1, "BLOB sha1 digest required");
|
308
|
0
|
|
|
|
|
|
return;
|
309
|
|
|
|
|
|
|
}
|
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
$ret = _fetch_data($sth, $statement,
|
312
|
|
|
|
|
|
|
$sth->{REQUEST_METHOD},
|
313
|
0
|
0
|
|
|
|
|
$sth->{REQUEST_PATH}) or return;
|
314
|
|
|
|
|
|
|
} else {
|
315
|
0
|
|
|
|
|
|
my $hash = {stmt => $statement };
|
316
|
0
|
0
|
|
|
|
|
if (@_){ $hash->{args} = \@_; }
|
|
0
|
|
|
|
|
|
|
317
|
0
|
|
|
|
|
|
my $json = DBD::Crate::json->encode($hash);
|
318
|
0
|
0
|
|
|
|
|
$ret = _fetch_data($sth, $json, 'POST', '/_sql') or return;
|
319
|
|
|
|
|
|
|
}
|
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
$sth->{'driver_raw_data'} = $ret->{content};
|
322
|
0
|
0
|
|
|
|
|
if ($sth->{BLOB}){
|
323
|
0
|
0
|
|
|
|
|
if ($ret->{status} == 201){ # put success
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
324
|
0
|
|
|
|
|
|
return $sth->{DIGEST};
|
325
|
|
|
|
|
|
|
} elsif ($ret->{status} == 200){ #get success
|
326
|
0
|
|
|
|
|
|
return $ret->{content};
|
327
|
|
|
|
|
|
|
} elsif ($ret->{status} == 204){ #delete success
|
328
|
0
|
|
|
|
|
|
return 1;
|
329
|
|
|
|
|
|
|
}
|
330
|
|
|
|
|
|
|
}
|
331
|
|
|
|
|
|
|
|
332
|
0
|
|
|
|
|
|
my $olderr = $@;
|
333
|
0
|
|
|
|
|
|
my $data = eval { DBD::Crate::json->decode($ret->{content}) };
|
|
0
|
|
|
|
|
|
|
334
|
0
|
0
|
|
|
|
|
if (!$data){
|
335
|
0
|
|
|
|
|
|
my $error = $@;
|
336
|
0
|
|
|
|
|
|
$@ = $olderr;
|
337
|
0
|
|
|
|
|
|
$sth->set_err(-1, $error);
|
338
|
0
|
|
|
|
|
|
return;
|
339
|
|
|
|
|
|
|
}
|
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
$sth->{'driver_data'} = $data->{rows};
|
343
|
0
|
|
|
|
|
|
$sth->{'driver_rows'} = $data->{rowcount};
|
344
|
|
|
|
|
|
|
|
345
|
0
|
|
|
|
|
|
$sth->{'NAME'} = $data->{cols};
|
346
|
0
|
|
|
|
|
|
$sth->STORE('NUM_OF_FIELDS', scalar @{ $data->{cols} });
|
|
0
|
|
|
|
|
|
|
347
|
0
|
|
0
|
|
|
|
return $data->{rowcount} || '0E0';
|
348
|
|
|
|
|
|
|
}
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
*fetch = \&fetchrow_arrayref;
|
351
|
|
|
|
|
|
|
sub fetchrow_arrayref {
|
352
|
0
|
|
|
0
|
|
|
my $sth = shift;
|
353
|
0
|
|
|
|
|
|
my $data = $sth->FETCH('driver_data');
|
354
|
0
|
0
|
|
|
|
|
my $row = shift @$data or return;
|
355
|
0
|
|
|
|
|
|
return $sth->_set_fbav($row);
|
356
|
|
|
|
|
|
|
}
|
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
sub raw {
|
359
|
0
|
|
|
0
|
|
|
my $sth = shift;
|
360
|
0
|
|
|
|
|
|
my $data = $sth->FETCH('driver_raw_data');
|
361
|
0
|
|
|
|
|
|
return $data;
|
362
|
|
|
|
|
|
|
}
|
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
*DBI::st::raw = \&raw;
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
#Nothing to close, crate is stateless
|
367
|
|
|
|
0
|
|
|
sub close {}
|
368
|
|
|
|
|
|
|
};
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
1;
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
__END__
|