package # Hide
  DBICTest::Schema::JobQueue;

use strict;
use warnings;

use base 'DBIx::Class';
use Storable;
use DateTime;

__PACKAGE__->load_components(qw/InflateColumn::DateTime Core/);

__PACKAGE__->table('job_queue');

__PACKAGE__->add_columns(
	job_id => {
		data_type         => 'int',
		is_auto_increment => 1,
		is_nullable       => 0,
		extra => { unsigned => 1 },
	},

	status => {
		data_type => 'enum',
		is_nullable => 0,
		default_value => 'available',
		extra => { list => [qw/available in_progress done failed/] },
	},

	job_type => { 
		data_type   => 'varchar',
		is_nullable => 0,
	},
	args => { # Storable args to pass to the job
		data_type   => 'blob',
		is_nullable => 1,
	},
	not_before => { # Only run the job after the given time. 
									# Default value set in insert method
		data_type => 'datetime'
	},
	coalesce => { # field use to gorup related jobs. For example Email would
	              # put the domain in this column so that emails to the same
	              # domain would get handled by the same worker (up to a limit)
		data_type   => 'varchar',
		is_nullable => 1,
		size        => 255,
	},
	locked_by => { # Used to allow the job manager process to run on multiple 
	               # machines talking to the same DB. Stores "${host}-{$pid} here
		data_type   => 'varchar',
		is_nullable => 1,
		size        => 255,
	}
);
__PACKAGE__->set_primary_key('job_id');
__PACKAGE__->inflate_column('args', {
	inflate => sub { Storable::thaw(shift) },
	deflate => sub { Storable::nfreeze(shift) },
});

sub insert {
	my ($self) = @_;

	# Default value of now.
	$self->not_before(DateTime->now)
		unless $self->not_before;

	$self->next::method;
}

sub sqlt_deploy_hook {
	my ($class, $table) = @_;

	$table->add_index(
		name => 'job_queue_idx1',
		fields => [ 'locked_by', 'coalesce', 'job_type', 'not_before', 'status' ],
		type => 'NORMAL'
	) || warn "Error: ".$table->error."\n";
}

