| File: | lib/OpenAPI.pm |
| Coverage: | 83.2% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package OpenAPI; | ||||||
| 2 | |||||||
| 3 | our $VERSION = '1.0.1'; | ||||||
| 4 | |||||||
| 5 | 22 22 22 | 194 68 202 | use strict; | ||||
| 6 | 22 22 22 | 239 67 178 | use warnings; | ||||
| 7 | |||||||
| 8 | #use Smart::Comments; | ||||||
| 9 | 22 22 22 | 414 118 99 | use YAML::Syck (); | ||||
| 10 | 22 22 22 | 318 90 90 | use JSON::Syck (); | ||||
| 11 | |||||||
| 12 | 22 22 22 | 256 74 442 | use List::Util qw(first); | ||||
| 13 | 22 22 22 | 274 221 349 | use Params::Util qw(_HASH _STRING _ARRAY0 _ARRAY _SCALAR); | ||||
| 14 | 22 22 22 | 331 86 287 | use Encode qw(from_to encode decode); | ||||
| 15 | 22 22 22 | 310 103 2589 | use DBI; | ||||
| 16 | |||||||
| 17 | 22 22 22 | 352 116 390 | use SQL::Select; | ||||
| 18 | 22 22 22 | 512 108 357 | use SQL::Update; | ||||
| 19 | 22 22 22 | 291 107 343 | use SQL::Insert; | ||||
| 20 | |||||||
| 21 | 22 22 22 | 293 100 317 | use OpenAPI::Backend; | ||||
| 22 | 22 22 22 | 230 81 286 | use OpenAPI::Limits; | ||||
| 23 | |||||||
| 24 | 22 22 22 | 300 101 396 | use MiniSQL::Select; | ||||
| 25 | #use encoding "utf8"; | ||||||
| 26 | |||||||
| 27 | 22 22 22 | 498 132 296 | use OpenAPI::Util; | ||||
| 28 | 22 22 22 | 306 119 303 | use OpenAPI::Handler::Model; | ||||
| 29 | 22 22 22 | 333 131 287 | use OpenAPI::Handler::View; | ||||
| 30 | 22 22 22 | 317 127 256 | use OpenAPI::Handler::Action; | ||||
| 31 | 22 22 22 | 340 118 312 | use OpenAPI::Handler::Role; | ||||
| 32 | 22 22 22 | 336 128 264 | use OpenAPI::Handler::Admin; | ||||
| 33 | 22 22 22 | 301 128 270 | use OpenAPI::Handler::Login; | ||||
| 34 | 22 22 22 | 342 108 297 | use OpenAPI::Handler::Captcha; | ||||
| 35 | 22 22 22 | 322 103 249 | use OpenAPI::Handler::Version; | ||||
| 36 | 22 22 22 | 300 95 174 | use Encode::Guess; | ||||
| 37 | |||||||
| 38 | $YAML::Syck::ImplicitUnicode = 1; | ||||||
| 39 | #$YAML::Syck::ImplicitBinary = 1; | ||||||
| 40 | |||||||
| 41 | our ($Backend, $BackendName); | ||||||
| 42 | our $Cache; | ||||||
| 43 | our $UUID = Data::UUID->new; | ||||||
| 44 | |||||||
| 45 | our %OpMap = ( | ||||||
| 46 | contains => 'like', | ||||||
| 47 | gt => '>', | ||||||
| 48 | ge => '>=', | ||||||
| 49 | lt => '<', | ||||||
| 50 | le => '<=', | ||||||
| 51 | eq => '=', | ||||||
| 52 | ne => '<>', | ||||||
| 53 | ); | ||||||
| 54 | |||||||
| 55 | our %ext2dumper = ( | ||||||
| 56 | '.yml' => \&YAML::Syck::Dump, | ||||||
| 57 | '.yaml' => \&YAML::Syck::Dump, | ||||||
| 58 | '.js' => \&JSON::Syck::Dump, | ||||||
| 59 | '.json' => \&JSON::Syck::Dump, | ||||||
| 60 | ); | ||||||
| 61 | |||||||
| 62 | our %EncodingMap = ( | ||||||
| 63 | 'cp936' => 'GBK', | ||||||
| 64 | 'utf8' => 'UTF-8', | ||||||
| 65 | 'euc-cn' => 'GB2312', | ||||||
| 66 | 'big5-eten' => 'Big5', | ||||||
| 67 | ); | ||||||
| 68 | |||||||
| 69 | our %ext2importer = ( | ||||||
| 70 | '.yml' => \&YAML::Syck::Load, | ||||||
| 71 | '.yaml' => \&YAML::Syck::Load, | ||||||
| 72 | '.js' => \&JSON::Syck::Load, | ||||||
| 73 | '.json' => \&JSON::Syck::Load, | ||||||
| 74 | ); | ||||||
| 75 | |||||||
| 76 | our $Ext = qr/\.(?:js|json|xml|yaml|yml)/; | ||||||
| 77 | our ($Dumper, $Importer); | ||||||
| 78 | $Dumper = \&JSON::Syck::Dump; | ||||||
| 79 | $Importer = \&JSON::Syck::Load; | ||||||
| 80 | |||||||
| 81 | # XXX more data types... | ||||||
| 82 | sub parse_data { | ||||||
| 83 | 222 | 0 | 941 | shift; | |||
| 84 | 222 | 1379 | if (!$Importer) { | ||||
| 85 | 0 | 0 | $Importer = \&JSON::Syck::Load; | ||||
| 86 | } | ||||||
| 87 | 222 | 20070 | return $Importer->($_[0]); | ||||
| 88 | } | ||||||
| 89 | |||||||
| 90 | sub new { | ||||||
| 91 | 602 | 0 | 3851 | my ($class, $cgi) = @_; | |||
| 92 | 602 | 12017 | return bless { _cgi => $cgi, _charset => 'UTF-8' }, $class; | ||||
| 93 | } | ||||||
| 94 | |||||||
| 95 | sub init { | ||||||
| 96 | 602 | 0 | 3633 | my ($self, $rurl) = @_; | |||
| 97 | 602 | 2786 | my $class = ref $self; | ||||
| 98 | 602 | 3143 | my $cgi = $self->{_cgi}; | ||||
| 99 | |||||||
| 100 | 602 | 8677 | my $db_state = $Backend->state; | ||||
| 101 | 602 | 5270 | if ($db_state && $db_state =~ /^(?:08|57)/) { | ||||
| 102 | 0 | 0 | $Backend->disconnect; | ||||
| 103 | 0 | 0 | my $backend = $OpenAPI::Config{'backend.type'}; | ||||
| 104 | 0 | 0 | OpenAPI->connect($backend); | ||||
| 105 | #die "Backend connection lost: ", $db_state, "\n"; | ||||||
| 106 | } | ||||||
| 107 | |||||||
| 108 | 602 | 4213 | my $as_html = $cgi->url_param('as_html') || 0; | ||||
| 109 | 602 | 4385 | $self->{_as_html} = $as_html; | ||||
| 110 | |||||||
| 111 | 602 | 3913 | $self->{_use_cookie} = $cgi->url_param('use_cookie') || 0; | ||||
| 112 | 602 | 4046 | $self->{_session} = $cgi->url_param('session'); | ||||
| 113 | |||||||
| 114 | 602 | 3954 | my $charset = $cgi->url_param('charset') || 'UTF-8'; | ||||
| 115 | |||||||
| 116 | 602 | 4972 | if ($charset =~ /^guess(?:ing)?$/i) { | ||||
| 117 | 4 | 13 | undef $charset; | ||||
| 118 | 4 | 25 | my $url = $ENV{REQUEST_URI}; | ||||
| 119 | 4 0 | 16 0 | $url =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; | ||||
| 120 | ### Raw URL: $url | ||||||
| 121 | 4 | 25 | my $data = $url . | ||||
| 122 | ($cgi->param('PUTDATA') || '') . | ||||||
| 123 | ($cgi->param('POSTDATA') || ''); | ||||||
| 124 | ### $data | ||||||
| 125 | 4 | 189 | my @enc = qw( UTF-8 GB2312 Big5 GBK Latin1 ); | ||||
| 126 | 4 | 20 | for my $enc (@enc) { | ||||
| 127 | 11 | 67 | my $decoder = guess_encoding($data, $enc); | ||||
| 128 | 11 | 687 | if (ref $decoder) { | ||||
| 129 | # if ($enc ne 'ascii') { | ||||||
| 130 | # print "line $.: $enc message found: ", $decoder->decode($s), "\n"; | ||||||
| 131 | # } | ||||||
| 132 | 4 | 34 | $charset = $decoder->name; | ||||
| 133 | 4 | 44 | $charset = $EncodingMap{$charset} || $charset; | ||||
| 134 | 4 | 16 | last; | ||||
| 135 | } | ||||||
| 136 | } | ||||||
| 137 | 4 | 26 | if (!$charset) { | ||||
| 138 | 0 | 0 | die "Can't determine the charset of the input.\n"; | ||||
| 139 | } | ||||||
| 140 | ### $charset | ||||||
| 141 | } | ||||||
| 142 | 602 | 3559 | $self->{'_charset'} = $charset; | ||||
| 143 | |||||||
| 144 | 602 | 3903 | $self->{'_var'} = $cgi->url_param('var'); | ||||
| 145 | 602 | 3855 | $self->{'_callback'} = $cgi->url_param('callback'); | ||||
| 146 | |||||||
| 147 | 602 | 3963 | my $offset = $cgi->url_param('offset'); | ||||
| 148 | 602 | 3808 | $offset ||= 0; | ||||
| 149 | 602 | 6101 | if ($offset !~ /^\d+$/) { | ||||
| 150 | 2 | 7 | die "Invalid value for the \"offset\" param: $offset\n"; | ||||
| 151 | } | ||||||
| 152 | 600 | 5241 | $self->{_offset} = $offset; | ||||
| 153 | |||||||
| 154 | 600 | 4012 | my $limit = $cgi->url_param('count'); | ||||
| 155 | # limit is an alias for count | ||||||
| 156 | 600 | 4204 | if (!defined $limit) { | ||||
| 157 | 588 | 3747 | $limit = $cgi->url_param('limit'); | ||||
| 158 | } | ||||||
| 159 | 600 | 3345 | if (!defined $limit) { | ||||
| 160 | 587 | 2699 | $limit = $MAX_SELECT_LIMIT; | ||||
| 161 | } else { | ||||||
| 162 | 13 | 80 | $limit ||= 0; | ||||
| 163 | 13 | 125 | if ($limit !~ /^\d+$/) { | ||||
| 164 | 2 | 8 | die "Invalid value for the \"count\" param: $limit\n"; | ||||
| 165 | } | ||||||
| 166 | 11 | 94 | if ($limit > $MAX_SELECT_LIMIT) { | ||||
| 167 | 0 | 0 | die "Value too large for the limit param: $limit\n"; | ||||
| 168 | } | ||||||
| 169 | } | ||||||
| 170 | 598 | 3762 | $self->{_limit} = $limit; | ||||
| 171 | |||||||
| 172 | 598 | 3449 | my $http_meth = $ENV{REQUEST_METHOD}; | ||||
| 173 | #$self->{'_method'} = $http_meth; | ||||||
| 174 | |||||||
| 175 | #die "#XXXX !!!! $http_meth", Dumper($self); | ||||||
| 176 | |||||||
| 177 | 598 | 2615 | my $url = $$rurl; | ||||
| 178 | 598 | 1848 | eval { | ||||
| 179 | 598 | 4761 | from_to($url, $charset, 'UTF-8'); | ||||
| 180 | }; | ||||||
| 181 | |||||||
| 182 | 598 | 35702 | $url =~ s{/+$}{}g; | ||||
| 183 | 598 | 2954 | $url =~ s/\%2A/*/g; | ||||
| 184 | 598 | 7621 | if ($url =~ s/$Ext$//) { | ||||
| 185 | 94 | 634 | my $ext = $&; | ||||
| 186 | # XXX obsolete | ||||||
| 187 | 94 | 729 | $self->set_formatter($ext); | ||||
| 188 | } else { | ||||||
| 189 | 504 | 3705 | $self->set_formatter; | ||||
| 190 | } | ||||||
| 191 | 598 | 1814 | my $req_data; | ||||
| 192 | 598 | 5199 | if ($http_meth eq 'POST') { | ||||
| 193 | 162 | 1107 | $req_data = $cgi->param('POSTDATA'); | ||||
| 194 | #die "Howdy! >>$req_data<<", $cgi->param('data'), "\n"; | ||||||
| 195 | #die $Dumper->(\%ENV); | ||||||
| 196 | |||||||
| 197 | 162 | 8171 | if (!defined $req_data) { | ||||
| 198 | 0 | 0 | $req_data = $cgi->param('data') or | ||||
| 199 | die "No POST content specified or no \"data\" field found.\n"; | ||||||
| 200 | } else { | ||||||
| 201 | 162 | 1677 | if (length($req_data) > $POST_LEN_LIMIT) { | ||||
| 202 | 0 | 0 | die "Exceeded POST content length limit: $POST_LEN_LIMIT\n"; | ||||
| 203 | } | ||||||
| 204 | } | ||||||
| 205 | } | ||||||
| 206 | elsif ($http_meth eq 'PUT') { | ||||||
| 207 | 57 | 450 | $req_data = $cgi->param('PUTDATA'); | ||||
| 208 | |||||||
| 209 | 57 | 3063 | if (!defined $req_data) { | ||||
| 210 | 0 | 0 | $req_data = $cgi->param('data') or | ||||
| 211 | die "No PUT content specified.\n"; | ||||||
| 212 | } else { | ||||||
| 213 | 57 | 531 | if (length($req_data) > $POST_LEN_LIMIT) { | ||||
| 214 | 0 | 0 | die "Exceeded PUT content length limit: $POST_LEN_LIMIT\n"; | ||||
| 215 | } | ||||||
| 216 | } | ||||||
| 217 | } | ||||||
| 218 | |||||||
| 219 | 598 | 20088 | if ($http_meth eq 'POST' and $url =~ s{^=/put/}{=/}) { | ||||
| 220 | 3 | 14 | $http_meth = 'PUT'; | ||||
| 221 | } elsif ($http_meth =~ /^(?:GET|POST)$/ and $url =~ s{^=/delete/}{=/}) { | ||||||
| 222 | 6 | 30 | $http_meth = 'DELETE'; | ||||
| 223 | } elsif ($http_meth eq 'GET' and $url =~ s{^=/(post|put)/}{=/} ) { | ||||||
| 224 | 6 | 48 | $http_meth = uc($1); | ||||
| 225 | 6 | 48 | $req_data = $cgi->url_param('data'); | ||||
| 226 | #$req_data = $Importer->($content); | ||||||
| 227 | |||||||
| 228 | #warn "Content: ", $Dumper->($content); | ||||||
| 229 | #warn "Data: ", $Dumper->($req_data); | ||||||
| 230 | } | ||||||
| 231 | |||||||
| 232 | 598 | 3375 | $$rurl = $url; | ||||
| 233 | 598 | 5216 | $self->{'_url'} = $url; | ||||
| 234 | 598 | 3832 | $self->{'_http_method'} = $http_meth; | ||||
| 235 | |||||||
| 236 | 598 | 3241 | if ($req_data) { | ||||
| 237 | 222 | 1485 | from_to($req_data, $charset, 'UTF-8'); | ||||
| 238 | 222 | 14085 | $req_data = $self->parse_data($req_data); | ||||
| 239 | } | ||||||
| 240 | |||||||
| 241 | 597 | 6001 | $self->{_req_data} = $req_data; | ||||
| 242 | } | ||||||
| 243 | |||||||
| 244 | sub fatal { | ||||||
| 245 | 159 | 0 | 1136 | my ($self, $s) = @_; | |||
| 246 | 159 | 1139 | $self->error($s); | ||||
| 247 | 159 | 1113 | $self->response(); | ||||
| 248 | } | ||||||
| 249 | |||||||
| 250 | sub error { | ||||||
| 251 | 159 | 0 | 964 | my ($self, $s) = @_; | |||
| 252 | 159 | 723 | $s =~ s/^Syck parser \(line (\d+), column (\d+)\): syntax error at .+/Syntax error found in the JSON input: line $1, column $2./; | ||||
| 253 | 159 | 728 | $s =~ s/^DBD::Pg::st execute failed:\s+ERROR:\s+//; | ||||
| 254 | #$s =~ s/^DBD::Pg::db do failed:\s.*?ERROR:\s+//; | ||||||
| 255 | 159 | 2273 | $self->{_error} .= $s . "\n"; | ||||
| 256 | |||||||
| 257 | } | ||||||
| 258 | |||||||
| 259 | sub data { | ||||||
| 260 | 438 | 0 | 6317 | $_[0]->{_data} = $_[1]; | |||
| 261 | } | ||||||
| 262 | |||||||
| 263 | sub warning { | ||||||
| 264 | 10 | 0 | 126 | $_[0]->{_warning} = $_[1]; | |||
| 265 | } | ||||||
| 266 | |||||||
| 267 | sub response { | ||||||
| 268 | 602 | 0 | 3215 | my $self = shift; | |||
| 269 | 602 0 | 4595 0 | if ($self->{_no_response}) { return; } | ||||
| 270 | 602 | 3504 | my $charset = $self->{_charset}; | ||||
| 271 | 602 | 3232 | my $cgi = $self->{_cgi}; | ||||
| 272 | 602 | 2909 | my $cookie_data = $self->{_cookie}; | ||||
| 273 | 602 | 1790 | my @cookies; | ||||
| 274 | 602 | 3137 | if ($cookie_data) { | ||||
| 275 | 38 | 500 | while (my ($key, $val) = each %$cookie_data) { | ||||
| 276 | 38 | 633 | push @cookies, CGI::Cookie->new( | ||||
| 277 | -name => $key, -value => $val | ||||||
| 278 | ); | ||||||
| 279 | } | ||||||
| 280 | } | ||||||
| 281 | |||||||
| 282 | 602 | 4789 | print "HTTP/1.1 200 OK\n"; | ||||
| 283 | 602 | 23199 | my $as_html = $self->{_as_html}; | ||||
| 284 | 602 | 10370 | my $type = $self->{_type} || ($as_html ? 'text/html' : 'text/plain'); | ||||
| 285 | #warn $s; | ||||||
| 286 | 602 | 2679 | my $str = ''; | ||||
| 287 | 602 | 4610 | if (my $bin_data = $self->{_bin_data}) { | ||||
| 288 | 16 | 106 | binmode \*STDOUT; | ||||
| 289 | 16 | 373 | print $cgi->header( | ||||
| 290 | -type => "$type" . ($type =~ /text/ ? "; charset=$charset" : ""), | ||||||
| 291 | @cookies ? (-cookie => \@cookies) : () | ||||||
| 292 | ); | ||||||
| 293 | 16 | 586 | if (my $callback = $self->{_callback}) { | ||||
| 294 | 1 | 5 | chomp($bin_data); | ||||
| 295 | 1 | 4 | print "$callback($bin_data);\n"; | ||||
| 296 | } else { | ||||||
| 297 | 15 | 70 | print $bin_data; | ||||
| 298 | } | ||||||
| 299 | 16 | 905 | return; | ||||
| 300 | } | ||||||
| 301 | 586 | 5909 | if ($self->{_error}) { | ||||
| 302 | 159 | 1397 | $str = $self->emit_error($self->{_error}); | ||||
| 303 | } elsif ($self->{_data}) { | ||||||
| 304 | 427 | 2274 | my $data = $self->{_data}; | ||||
| 305 | 427 | 2620 | if ($self->{_warning}) { | ||||
| 306 | 8 | 73 | $data->{warning} = $self->{_warning}; | ||||
| 307 | } | ||||||
| 308 | 427 | 3093 | $str = $self->emit_data($data); | ||||
| 309 | } | ||||||
| 310 | #die $charset; | ||||||
| 311 | # XXX if $charset is 'UTF-8' then don't bother decoding and encoding... | ||||||
| 312 | 586 | 3806 | eval { | ||||
| 313 | #$str = decode_utf8($str); | ||||||
| 314 | #if (is_utf8($str)) { | ||||||
| 315 | #} else { | ||||||
| 316 | 586 | 5404 | $str = $Backend->encode_string($str, $charset); | ||||
| 317 | #$str = decode('UTF-8', $str); | ||||||
| 318 | #$str = encode($charset, $str); | ||||||
| 319 | #} | ||||||
| 320 | }; #warn $@ if $@; | ||||||
| 321 | 586 | 11222 | if (my $var = $self->{_var} and $Dumper eq \&JSON::Syck::Dump) { | ||||
| 322 | 8 | 87 | $str = "$var=$str;"; | ||||
| 323 | } elsif (my $callback = $self->{_callback} and $Dumper eq \&JSON::Syck::Dump) { | ||||||
| 324 | 28 | 264 | $str = "$callback($str);"; | ||||
| 325 | } | ||||||
| 326 | 586 | 3716 | $str =~ s/\n+$//s; | ||||
| 327 | |||||||
| 328 | 586 | 3365 | if ($as_html) { | ||||
| 329 | 0 | 0 | $str = "<html><body><script type=\"text/javascript\">parent.location.hash = ".$Dumper->($str)."</script></body></html>"; | ||||
| 330 | } | ||||||
| 331 | |||||||
| 332 | 586 | 7222 | if ($self->{_http_method} =~ /^(?:PUT|POST)$/) { | ||||
| 333 | 224 | 4538 | push @cookies, CGI::Cookie->new( | ||||
| 334 | -name => 'last_response', | ||||||
| 335 | -value => length($str) > 1024 ? substr($str, 0, 1024) : $str, | ||||||
| 336 | ); | ||||||
| 337 | } | ||||||
| 338 | #warn ">>>>>>>>>>>>Cookies<<<<<<<<<<<<<<: @cookies\n"; | ||||||
| 339 | 586 | 142849 | print $cgi->header( | ||||
| 340 | -type => "$type" . ($type =~ /text/ ? "; charset=$charset" : ""), | ||||||
| 341 | @cookies ? (-cookie => \@cookies) : () | ||||||
| 342 | ); | ||||||
| 343 | |||||||
| 344 | 586 | 2723 | print $str, "\n"; | ||||
| 345 | } | ||||||
| 346 | |||||||
| 347 | sub set_formatter { | ||||||
| 348 | 598 | 0 | 3869 | my ($self, $ext) = @_; | |||
| 349 | 598 | 4027 | $ext ||= '.json'; | ||||
| 350 | 598 | 3863 | $Dumper = $ext2dumper{$ext}; | ||||
| 351 | 598 | 4657 | $Importer = $ext2importer{$ext}; | ||||
| 352 | } | ||||||
| 353 | |||||||
| 354 | sub connect { | ||||||
| 355 | 22 | 0 | 138 | my $self = shift; | |||
| 356 | 22 | 216 | my $name = shift || $BackendName; | ||||
| 357 | 22 | 102 | $BackendName = $name; | ||||
| 358 | 22 | 327 | $Backend = OpenAPI::Backend->new($name); | ||||
| 359 | #$Backend->select(""); | ||||||
| 360 | } | ||||||
| 361 | |||||||
| 362 | sub emit_data { | ||||||
| 363 | 586 | 0 | 3741 | my ($self, $data) = @_; | |||
| 364 | 586 | 53970 | return $Dumper->($data); | ||||
| 365 | } | ||||||
| 366 | |||||||
| 367 | sub has_user { | ||||||
| 368 | 589 | 0 | 3891 | my ($self, $user) = @_; | |||
| 369 | 589 | 5125 | return $Backend->has_user($user); | ||||
| 370 | } | ||||||
| 371 | |||||||
| 372 | sub add_user { | ||||||
| 373 | 0 | 0 | 0 | my ($self, $user) = @_; | |||
| 374 | 0 | 0 | $Backend->add_user($user); | ||||
| 375 | } | ||||||
| 376 | |||||||
| 377 | sub drop_user { | ||||||
| 378 | 0 | 0 | 0 | my ($self, $user) = @_; | |||
| 379 | 0 | 0 | $Backend->drop_user($user); | ||||
| 380 | } | ||||||
| 381 | |||||||
| 382 | sub _IDENT { | ||||||
| 383 | 2192 | 55836 | (defined $_[0] && $_[0] =~ /^[A-Za-z]\w*$/) ? $_[0] : undef; | ||||
| 384 | } | ||||||
| 385 | |||||||
| 386 | sub set_user { | ||||||
| 387 | 589 | 0 | 4413 | my ($self, $user) = @_; | |||
| 388 | 589 | 4730 | $Backend->set_user($user); | ||||
| 389 | 589 | 5310 | $self->{_user} = $user; | ||||
| 390 | } | ||||||
| 391 | |||||||
| 392 | sub current_user { | ||||||
| 393 | 33 | 0 | 171 | my ($self) = @_; | |||
| 394 | 33 | 273 | $self->{_user}; | ||||
| 395 | } | ||||||
| 396 | |||||||
| 397 | sub do { | ||||||
| 398 | 151 | 0 | 1106 | my $self = shift; | |||
| 399 | 151 | 1199 | $Backend->do(@_); | ||||
| 400 | } | ||||||
| 401 | |||||||
| 402 | sub select { | ||||||
| 403 | 2317 | 0 | 21739 | my $self = shift; | |||
| 404 | 2317 | 17091 | $Backend->select(@_); | ||||
| 405 | } | ||||||
| 406 | |||||||
| 407 | sub last_insert_id { | ||||||
| 408 | 39 | 0 | 223 | my $self = shift; | |||
| 409 | 39 | 314 | $Backend->last_insert_id(@_); | ||||
| 410 | } | ||||||
| 411 | |||||||
| 412 | sub emit_success { | ||||||
| 413 | 0 | 0 | 0 | my $self = shift; | |||
| 414 | 0 | 0 | return $self->emit_data( { success => 1 } ); | ||||
| 415 | } | ||||||
| 416 | |||||||
| 417 | sub emit_error { | ||||||
| 418 | 159 | 0 | 791 | my $self = shift; | |||
| 419 | 159 | 785 | my $msg = shift; | ||||
| 420 | 159 | 1576 | $msg =~ s/\n+$//s; | ||||
| 421 | 159 | 2305 | return $self->emit_data( { success => 0, error => $msg } ); | ||||
| 422 | } | ||||||
| 423 | |||||||
| 424 | sub set_role { | ||||||
| 425 | 573 | 0 | 4552 | my ($self, $role) = @_; | |||
| 426 | 573 | 6043 | $self->{_role} = $role; | ||||
| 427 | } | ||||||
| 428 | |||||||
| 429 | 1; | ||||||
| 430 | |||||||