use Newslash::Model::SlashDB;
use Data::Dumper;
+use DateTime;
#========================================================================
$sth->execute($limit);
my $rs = $sth->fetchall_arrayref(+{});
- $sth->finish;
if (@$rs == 0) {
$dbh->disconnect();
=cut
sub select {
- my ($self, $query_type, $value) = @_;
+ my $self = shift;
+ my $params = {@_};
+ my $query_type;
+ my $value;
+ my $return_single = 0;
+
+ for my $k (qw(sid stoid)) {
+ if ($params->{$k}) {
+ $query_type = $k;
+ $value = $params->{$k};
+ $return_single = 1;
+ }
+ }
- if ($query_type !~ m/\A(sid|stoid)\z/) {
- return undef;
- }
+ my @where_clauses;
+ my @query_param;
- my $dbh = $self->connect_db;
- my $sql = <<"EOSQL";
+ if ($query_type && $value) {
+ push @where_clauses, "stories.$query_type = ?";
+ push @query_param, $value;
+ }
+
+ # show future story?
+ if (!$params->{show_future}) {
+ push @where_clauses, "stories.time <= NOW()";
+ }
+
+ # target period
+ my $date_limit = "";
+ for my $term (qw(years months weeks days hours minutes)) {
+ if (defined $params->{$term}) {
+ my $dt = DateTime->now();
+ $dt->subtract($term => $params->{$term});
+ $date_limit = $dt->ymd("-") . " " . $dt->hms(":");
+ }
+ }
+ if (length $date_limit) {
+ push @where_clauses, "stories.time > ?";
+ push @query_param, $date_limit;
+ }
+
+ my @order_clauses;
+ # set ORDER BY clause
+ my @safe_params = qw(commentcount hits);
+ if (defined $params->{order_by}) {
+ # check order_by's value
+ my $k = $params->{order_by};
+ if (grep {$_ eq $k} @safe_params) {
+ my $order = "DESC";
+ if (defined $params->{order} && $params->{order} eq "ASC") {
+ $order = "ASC";
+ }
+ push @order_clauses, "ORDER BY $k $order";
+ }
+ }
+
+ # set LIMIT clause
+ my $limit_clause = "";
+ if (defined $params->{limit}) {
+ push @order_clauses, "LIMIT ?";
+ push @query_param, $params->{limit};
+ }
+
+ my $where_clause = "WHERE " . join("\n AND ", @where_clauses) . "\n";
+ my $sub_clauses = $where_clause . join("\n", @order_clauses);
+ my $dbh = $self->connect_db;
+ my $sql = <<"EOSQL";
SELECT stories.*, story_text.*, users.nickname as author
FROM stories
LEFT JOIN story_text ON stories.stoid = story_text.stoid
LEFT JOIN users ON stories.uid = users.uid
- WHERE stories.$query_type = ?
+ $sub_clauses
EOSQL
- my $sth = $dbh->prepare($sql);
-
- $sth->execute($value);
- my $story = $sth->fetchrow_hashref;
- $sth->finish;
-
- if (!$story) {
- $dbh->disconnect();
- return undef;
- }
+ warn $sub_clauses;
+ warn Dumper(@query_param);
- my $stoid = $story->{stoid};
- if (!$stoid) {
- $dbh->disconnect();
- return undef;
- }
+ my $sth = $dbh->prepare($sql);
+ $sth->execute(@query_param);
+ my $rs = $sth->fetchall_arrayref({});
+ if (!$rs) {
+ $dbh->disconnect();
+ return;
+ }
+ if (@$rs == 0) {
+ $dbh->disconnect();
+ return;
+ }
- # get tags
- $sql = <<"EOSQL";
+ # get tags
+ $sql = <<"EOSQL";
SELECT story_topics_rendered.*, story_topics_chosen.weight, topics.*
- FROM story_topics_rendered
+ FROM (SELECT stoid FROM stories $sub_clauses) AS latest
+ INNER JOIN story_topics_rendered ON latest.stoid = story_topics_rendered.stoid
LEFT JOIN story_topics_chosen ON story_topics_rendered.stoid = story_topics_chosen.stoid
AND story_topics_rendered.tid = story_topics_chosen.tid
LEFT JOIN topics ON story_topics_rendered.tid = topics.tid
- WHERE story_topics_rendered.stoid = ?
EOSQL
- $sth = $dbh->prepare($sql);
+ $sth = $dbh->prepare($sql);
+ $sth->execute(@query_param);
+ my $topics_table = $sth->fetchall_arrayref(+{});
+ $dbh->disconnect();
- $sth->execute($stoid);
- my $topics = $sth->fetchall_arrayref(+{});
- $sth->finish;
- $dbh->disconnect();
+ my $topics = {};
+ for my $topic (@$topics_table) {
+ if (!$topic->{stoid}) {
+ $topics->{$topic->{stoid}} = [];
+ }
+ push @{$topics->{$topic->{stoid}}}, $topic;
+ }
- $story->{topics} = $topics;
- $self->_generalize($story);
+ for my $story (@$rs) {
+ my $stoid = $story->{stoid};
+ $story->{topics} = $topics->{$stoid};
+ $self->_generalize($story);
+ }
- return $story;
+ return $rs->[0] if $return_single;
+ return $rs;
}
=head2 create(\%params, $uid)