Simple database: Difference between revisions

Line 2,104:
 
item5,2014-06-03 19:30:23,cat3</pre>
 
=={{header|Perl}}==
<lang Perl>#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
 
use JSON::PP;
use Time::Piece;
 
use constant {
NAME => 0,
CATEGORY => 1,
DATE => 2,
DB => 'simple-db',
};
 
my $operation = shift // "";
 
my %dispatch = (
n => \&add_new,
l => \&print_latest,
L => \&print_latest_for_categories,
a => \&print_all,
);
 
if ($dispatch{$operation}) {
$dispatch{$operation}->(@ARGV);
} else {
die "Invalid option. Use one of n, l, L, a.\n"
}
 
sub add_new {
my ($name, $category, $date) = @_;
my $db = eval { load() } || {};
if (defined $date) {
eval { 'Time::Piece'->strptime($date, '%Y-%m-%d'); 1 }
or die "Invalid date format: YYYY-MM-DD.\n";
 
} else {
$date //= localtime->ymd;
}
 
my @ids = keys %{ $db->{by_id} };
my $max_id = max(num => @ids) || 0;
$db->{by_id}{ ++$max_id } = [ $name, $category, $date ];
save($db);
}
 
sub print_latest {
build_indexes( my $db = load(), 0, 1 );
_print_latest($db);
}
 
sub _print_latest {
my ($db, $category) = @_;
my @dates = keys %{ $db->{by_date} };
@dates = grep {
grep $db->{by_id}{$_}[CATEGORY] eq $category,
@{ $db->{by_date}{$_} };
} @dates if defined $category;
 
my $last_date = max(str => @dates);
say for map $db->{by_id}{$_}[NAME],
grep ! defined $category
|| $db->{by_id}{$_}[CATEGORY] eq $category,
@{ $db->{by_date}{$last_date} };
}
 
sub max {
my $type = shift;
my $max = $_[0];
{ num => sub { $_ > $max },
str => sub { $_ gt $max},
}->{$type}->() and $max = $_
for @_[ 1 .. $#_ ];
return $max
}
 
sub print_latest_for_categories {
build_indexes( my $db = load(), 1, 1 );
 
for my $category (sort keys %{ $db->{by_category} }){
say "* $category";
_print_latest($db, $category);
}
}
 
sub print_all {
build_indexes( my $db = load(), 0, 1 );
 
for my $date (sort keys %{ $db->{by_date} }) {
for my $id (@{ $db->{by_date}{$date} }) {
say $db->{by_id}{$id}[NAME];
}
}
}
 
sub load {
open my $in, '<', DB or die "Can't open database: $!\n";
local $/;
return { by_id => decode_json(<$in>) };
}
 
sub save {
my ($db) = @_;
open my $out, '>', DB or die "Can't save database: $!\n";
print {$out} encode_json($db->{by_id});
close $out;
}
 
sub build_indexes {
my ($db, $by_category, $by_date) = @_;
for my $id (keys %{ $db->{by_id} }) {
push @{ $db->{by_category}{ $db->{by_id}{$id}[CATEGORY] } }, $id
if $by_category;
push @{ $db->{by_date}{ $db->{by_id}{$id}[DATE] } }, $id
if $by_date;
}
}</lang>
Sample session<pre> ~ $ db.pl n 'Donald Trump' Republican 2017-01-20
~ $ db.pl n 'Barack Obama' Democratic 2009-01-20
~ $ db.pl n 'Bill Clinton' Democratic 1993-01-20
~ $ db.pl n 'George W. Bush' Republican 2001-01-20
~ $ db.pl a
Bill Clinton
George W. Bush
Barack Obama
Donald Trump
~ $ db.pl l
Donald Trump
~ $ db.pl L
* Democratic
Barack Obama
* Republican
Donald Trump</pre>
 
=={{header|Phix}}==
Anonymous user