File Coverage

blib/lib/AnyEvent/ClickHouse.pm
Criterion Covered Total %
statement 32 118 27.1
branch 0 28 0.0
condition 0 12 0.0
subroutine 11 22 50.0
pod 4 4 100.0
total 47 184 25.5


line stmt bran cond sub pod time code
1             package AnyEvent::ClickHouse;
2              
3 1     1   12766 use 5.010000;
  1         2  
4 1     1   3 use strict;
  1         1  
  1         17  
5 1     1   3 no strict 'refs';
  1         1  
  1         23  
6 1     1   2 use warnings;
  1         1  
  1         31  
7              
8             our $VERSION = '0.02';
9              
10 1     1   5 use vars qw(@ISA @EXPORT);
  1         1  
  1         62  
11             our @ISA = qw(Exporter);
12             our @EXPORT = qw(clickhouse_do clickhouse_select clickhouse_select_array clickhouse_select_hash);
13              
14 1     1   840 use AnyEvent;
  1         3750  
  1         25  
15 1     1   538 use AnyEvent::HTTP;
  1         21400  
  1         69  
16 1     1   559 use URI;
  1         4671  
  1         24  
17 1     1   373 use URI::QueryParam;
  1         508  
  1         26  
18 1     1   10 use Scalar::Util qw/looks_like_number/;
  1         1  
  1         63  
19              
20 1     1   501 use Data::Dumper;
  1         4688  
  1         868  
21              
22             our $headers;
23             $headers->{'User-agent'} = 'Mozilla/5.0 (compatible; U; Perl-AnyEvent-ClickHouse;)';
24             $headers->{'Te'} = undef;
25             $headers->{'Referer'} = undef;
26             $headers->{'Connection'} = 'Keep-Alive';
27              
28             sub _init {
29 0     0     my $param = shift;
30              
31 0           my %_param = (
32             host => '127.0.0.1',
33             port => 8123,
34             database => 'default',
35             user => undef,
36             password => undef
37             );
38 0           foreach my $_key ( keys %_param ) {
39 0 0         unless ($param->{$_key}){
40 0           $param->{$_key} = $_param{$_key};
41             }
42             }
43              
44 0 0         unless ($param->{uri}) {
45 0           my $_uri = URI->new(sprintf ("http://%s:%d/",$param->{host},$param->{port}));
46 0 0         $_uri->query_param('user' => $param->{user}) if $param->{user};
47 0 0         $_uri->query_param('password' => $param->{password}) if $param->{password};
48 0           $_uri->query_param('database' => $param->{database});
49 0           $param->{uri} = $_uri;
50             }
51              
52 0           return $param;
53             }
54              
55             sub _data_prepare {
56 0     0     my $self = shift;
57 0           my @_rows = map { [@$_] } @_;
  0            
58 0           foreach my $row (@_rows) {
59 0           foreach my $val (@$row) {
60 0 0 0       unless (defined ($val)) {
    0          
    0          
61 0           $val = qq{''};
62             }
63             elsif (ref($val) eq 'ARRAY') {
64 0           $val = q{'}.join ("','", @$val).q{'};
65             }
66             elsif (defined ($val) && !looks_like_number($val)) {
67 0           $val =~ s/\\/\\\\/g;
68 0           $val =~ s/'/\\'/g;
69 0           $val = qq{'$val'};
70             }
71             }
72             }
73 0 0         return scalar @_rows ? join ",", map { "(".join (",", @{ $_ }).")" } @_rows : "\n";
  0            
  0            
74             }
75              
76             sub clickhouse_do {
77 0     0 1   my $param = shift;
78 0           my $query = shift;
79 0           my $cb = shift;
80 0           my $err_cb = shift;
81 0           my $data = _data_prepare(@_);
82              
83 0           $param = _init $param;
84 0           $param->{uri}->query_param('query' => $query);
85              
86             http_request
87             POST => $param->{uri}->as_string(),
88             body => $data,
89             headers => $headers,
90             persistent => 1,
91             keepalive => 1,
92             sub {
93 0     0     my $data = shift;
94 0           my $hdr = shift;
95 0           my $status = $hdr->{Status};
96              
97 0 0         if ($status == 200){
98             # do ok
99 0 0 0       if (defined $cb && ref $cb eq 'CODE') {
100 0           $cb->($data);
101             }
102             }
103             else {
104             # 500 error
105 0 0 0       if (defined $err_cb && ref $err_cb eq 'CODE') {
106             # if defined err cb func
107 0           $err_cb->($data);
108             }
109             }
110             }
111 0           ;
112             }
113              
114             sub _select {
115 0     0     my $format = shift;
116 0           my $param = shift;
117 0           my $query = shift;
118 0           my $cb = shift;
119 0           my $err_cb = shift;
120              
121 0           $param = _init $param;
122 0           $param->{uri}->query_param('query' => $query);
123              
124             http_request
125             GET => $param->{uri}->as_string(),
126             headers => $headers,
127             persistent => 1,
128             keepalive => 1,
129             sub {
130 0     0     my $data = shift;
131 0           my $hdr = shift;
132 0           my $status = $hdr->{Status};
133              
134 0 0         if ($status == 200){
135             # select ok
136 0 0         unless ($format eq 'raw') {
137 0           $data = $format->($data);
138             }
139 0           $cb->($data);
140             }
141             else {
142             # 500 error
143 0 0 0       if (defined $err_cb && ref $err_cb eq 'CODE') {
144             # if defined err cb func
145 0           $err_cb->($data);
146             }
147             }
148             }
149 0           ;
150             }
151              
152             sub clickhouse_select {
153 0     0 1   unshift @_, 'raw';
154 0           &_select;
155             }
156              
157             sub clickhouse_select_array {
158             unshift @_, sub {
159 0     0     my @data = split /\n/, shift;
160 0           return [ map { [ split (/\t/) ] } @data ];
  0            
161 0     0 1   };
162 0           &_select;
163             }
164              
165             sub clickhouse_select_hash {
166 0     0 1   my $param = shift;
167 0           my $query = shift;
168 0           $query .= ' FORMAT TabSeparatedWithNames';
169              
170 0           unshift @_, $query;
171 0           unshift @_, $param;
172             unshift @_, sub {
173 0     0     my @data = split /\n/, shift;
174 0           my @_response = @{[ map { [ split (/\t/) ] } @data ]};
  0            
  0            
175 0           my $response;
176 0           my $key = shift @_response;
177 0           for (0..$#_response) {
178 0           my $row = $_;
179 0           for (0..$#{$_response[$row]}) {
  0            
180 0           my $col = $_;
181 0           $response->[$row]->{"".$key->[$col].""} = $_response[$row][$_];
182             }
183             }
184 0           return $response;
185 0           };
186 0           &_select;
187             }
188              
189             1;
190              
191             __END__