File Coverage

blib/lib/EV/ClickHouse.pm
Criterion Covered Total %
statement 14 88 15.9
branch 0 70 0.0
condition 0 74 0.0
subroutine 5 8 62.5
pod 1 1 100.0
total 20 241 8.3


line stmt bran cond sub pod time code
1             package EV::ClickHouse;
2 15     15   2103682 use strict;
  15         32  
  15         609  
3 15     15   190 use warnings;
  15         55  
  15         1029  
4              
5 15     15   946 use EV;
  15         3547  
  15         866  
6              
7             BEGIN {
8 15     15   47 our $VERSION = '0.01';
9 15     15   93 use XSLoader;
  15         104  
  15         654  
10 15         92900 XSLoader::load __PACKAGE__, $VERSION;
11             }
12              
13             *q = \&query;
14             *reconnect = \&reset;
15             *disconnect = \&finish;
16              
17 0     0     sub _uri_unescape { my $s = $_[0]; $s =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/ge; $s }
  0            
  0            
  0            
18              
19             sub new {
20 0     0 1   my ($class, %args) = @_;
21              
22             # Connection URI: clickhouse://user:pass@host:port/database
23 0 0         if (my $uri = delete $args{uri}) {
24 0 0         if ($uri =~ m{^clickhouse(?:\+(\w+))?://(?:([^:@]*?)(?::([^@]*))?\@)?([^/:]+)(?::(\d+))?(?:/([^?]*))?(?:\?(.*))?$}) {
25 0           my ($proto, $u, $pw, $h, $p, $db, $qs) = ($1, $2, $3, $4, $5, $6, $7);
26 0 0 0       $args{protocol} //= $proto if $proto;
27 0 0 0       $args{user} //= _uri_unescape($u) if defined $u && $u ne '';
      0        
28 0 0 0       $args{password} //= _uri_unescape($pw) if defined $pw;
29 0   0       $args{host} //= $h;
30 0 0 0       $args{port} //= $p if defined $p;
31 0 0 0       $args{database} //= _uri_unescape($db) if defined $db && $db ne '';
      0        
32 0 0         if (defined $qs) {
33 0           for my $pair (split /&/, $qs) {
34 0           my ($k, $v) = split /=/, $pair, 2;
35 0 0 0       $args{$k} //= _uri_unescape($v) if defined $k && defined $v;
      0        
36             }
37             }
38             } else {
39 0           die "EV::ClickHouse: invalid URI '$uri'\n";
40             }
41             }
42              
43 0   0       my $loop = delete $args{loop} || EV::default_loop;
44 0           my $self = $class->_new($loop);
45              
46 0 0   0     $self->on_error(exists $args{on_error} ? delete $args{on_error} : sub { die @_ });
  0            
47 0 0         $self->on_connect(delete $args{on_connect}) if exists $args{on_connect};
48 0 0         $self->on_progress(delete $args{on_progress}) if exists $args{on_progress};
49 0 0         $self->on_disconnect(delete $args{on_disconnect}) if exists $args{on_disconnect};
50 0 0         $self->on_trace(delete $args{on_trace}) if exists $args{on_trace};
51              
52 0   0       my $host = delete $args{host} // '127.0.0.1';
53 0           my $port = delete $args{port};
54 0   0       my $protocol = delete $args{protocol} // 'http';
55 0   0       my $user = delete $args{user} // 'default';
56 0   0       my $password = delete $args{password} // '';
57 0           my $db_alias = delete $args{db};
58 0   0       my $database = delete $args{database} // $db_alias // 'default';
      0        
59 0   0       my $tls = delete $args{tls} // 0;
60 0           my $tls_ca_file = delete $args{tls_ca_file};
61 0   0       my $tls_skip_verify = delete $args{tls_skip_verify} // 0;
62              
63             # options
64 0   0       my $compress = delete $args{compress} // 0;
65 0           my $session_id = delete $args{session_id};
66 0           my $connect_timeout = delete $args{connect_timeout};
67 0           my $query_timeout = delete $args{query_timeout};
68 0   0       my $auto_reconnect = delete $args{auto_reconnect} // 0;
69 0   0       my $keepalive = delete $args{keepalive} // 0;
70 0   0       my $reconnect_delay = delete $args{reconnect_delay} // 0;
71 0   0       my $reconnect_max_delay = delete $args{reconnect_max_delay} // 0;
72              
73             # decode options (native protocol)
74 0   0       my $decode_datetime = delete $args{decode_datetime} // 0;
75 0   0       my $decode_decimal = delete $args{decode_decimal} // 0;
76 0   0       my $decode_enum = delete $args{decode_enum} // 0;
77 0   0       my $named_rows = delete $args{named_rows} // 0;
78              
79 0 0 0       die "EV::ClickHouse: unknown protocol '$protocol' (expected 'http' or 'native')\n"
80             unless $protocol eq 'http' || $protocol eq 'native';
81              
82 0 0 0       $port //= ($protocol eq 'native') ? 9000 : 8123;
83              
84 0 0         $self->_set_protocol($protocol eq 'native' ? 1 : 0);
85 0 0         $self->_set_compress($compress) if $compress;
86 0 0         $self->_set_session_id($session_id) if defined $session_id;
87 0 0         $self->_set_connect_timeout($connect_timeout) if $connect_timeout;
88 0 0         $self->_set_query_timeout($query_timeout) if $query_timeout;
89 0 0         $self->_set_tls($tls) if $tls;
90 0 0         $self->_set_tls_ca_file($tls_ca_file) if defined $tls_ca_file;
91 0 0         $self->_set_tls_skip_verify($tls_skip_verify) if $tls_skip_verify;
92 0 0         $self->_set_auto_reconnect($auto_reconnect) if $auto_reconnect;
93 0 0         $self->_set_keepalive($keepalive) if $keepalive;
94 0 0         $self->_set_reconnect_delay($reconnect_delay) if $reconnect_delay;
95 0 0         $self->_set_reconnect_max_delay($reconnect_max_delay) if $reconnect_max_delay;
96              
97             # compute decode_flags bitmask
98 0           my $decode_flags = 0;
99 0 0         $decode_flags |= 1 if $decode_datetime; # DECODE_DT_STR
100 0 0         $decode_flags |= 2 if $decode_decimal; # DECODE_DEC_SCALE
101 0 0         $decode_flags |= 4 if $decode_enum; # DECODE_ENUM_STR
102 0 0         $decode_flags |= 8 if $named_rows; # DECODE_NAMED_ROWS
103 0 0         $self->_set_decode_flags($decode_flags) if $decode_flags;
104              
105 0           my $settings = delete $args{settings};
106 0 0         $self->_set_settings($settings) if $settings;
107              
108 0 0         warn "EV::ClickHouse->new: unknown parameter(s): " . join(', ', sort keys %args) . "\n"
109             if %args;
110              
111 0           $self->connect($host, $port, $user, $password, $database);
112              
113 0           $self;
114             }
115              
116             1;
117              
118             __END__