package APKPM::Store;

use base qw(Gearman::Driver::Worker);
use Moose;
use Time::HiRes;
use Data::Dump qw(dump);
use DBD::Pg;
use Redis;

with 'APKPM::Gearman';

sub prefix { 'Store_' }

sub process_name {
	my ( $self, $orig, $job_name ) = @_;
	warn "# process_name $orig $job_name\n";
	return "$orig ($job_name)";
}

sub dbh {
	DBI->connect_cached('DBI:Pg:dbname=apkpm','','', {
		RaiseError => 1,
		AutoCommit => 1,
	});
}

sub pg_insert {
	my ( $self, $table, $h ) = @_;

	my $redis = Redis->new;

	my @c;

	if ( my $cols = $redis->get("pg.$table") ) {
		@c = split(/\s+/,$cols);
	} else {
		my $sth = $self->dbh->prepare( "select * from $table limit 1" );
		$sth->execute;
		@c = @{ $sth->{NAME_lc} };
		$redis->set( "pg.$table" => join(' ',@c) );
		$redis->expire( "pg.$table" => 5 * 60 ); # refresh every 5 min
	}

	my $sql = "INSERT INTO $table (" . join(',',@c) . ') values (' . join(',', map { '?' } 0 .. $#c) . ')';
	warn $sql;
	my $sth = $self->dbh->prepare($sql);

	my $h_lc;
	$h_lc->{ lc $_ } = $h->{$_} foreach keys %$h;

	$sth->execute( map { $h_lc->{$_} } @c );
}

sub insert : Job : Decode(d_json) : MinProcesses(0) {
	my ( $self, $job, $workload ) = @_;
	my $table = delete $workload->{_table} || die "no _table";
	$self->pg_insert($table => $workload);
}

sub sql : Job : Encode(e_json) : MinProcesses(0) {
	my ( $self, $job, $workload ) = @_;

	my $sth = $self->dbh->prepare($workload);
	my $rows = eval { $sth->execute };
	return { error => $@ } if $@;

	warn "# $rows rows get_username_table $workload\n";

	return {
		columns => $sth->{NAME},
		rows => $sth->fetchall_arrayref,
	};
}

1;
