print "\tsize\t\t", -s $file, "\n";
}
+# db_select returns an anonymous function that returns a filename on
+# every call, then undef when there are no more filenames
+sub db_select {
+ my (@where, $order, $ltype, $limit);
+
+ $order = 'ORDER BY artist,album,year,track';
+ foreach (@_) {
+ if (/^(artist|title|album|genre|comment|filename)(==|=)(.*?)$/) {
+ my ($k, $op, $v) = ($1, $2, $3);
+ $v =~ s/"/""/g;
+ if ($op eq '==') {
+ push @where, qq{$k LIKE "$v"};
+ } else {
+ push @where, qq{$k LIKE "\%$v\%"};
+ }
+ } elsif (/^(track|year|length|bitrate|samplerate|channels)(>|<|==|=)(.*)$/) {
+ my ($k, $op, $v) = ($1, $2, int($3));
+ if ($op eq '=' or $op eq '==') {
+ push @where, qq{$k=$v};
+ } elsif ($op eq '>' or $op eq '<') {
+ push @where, qq{$k$op$v};
+ }
+ } elsif ($_ eq 'random') {
+ $order = 'ORDER BY random()';
+ } elsif (/^limit==?(.*)$/) {
+ my $v = $1;
+ if ($v =~ /^\d+$/) {
+ $order .= " LIMIT $v";
+ } elsif ($v =~ /:/) {
+ $ltype = 'time';
+ $limit = time_expand($v);
+ } elsif ($v =~ /[bkmgt]$/) {
+ $ltype = 'size';
+ $limit = size_expand($v);
+ } else {
+ print "Unknown type of limit: $v\n";
+ exit 1;
+ }
+ } else {
+ s/"/""/g;
+ push @where, qq{(artist LIKE "\%$_\%" OR title LIKE "\%$_\%" OR album LIKE "\%$_\%" OR comment LIKE "\%$_\%" OR filename LIKE "\%$_\%")};
+ }
+ }
+ my $query = "SELECT filename,length FROM tunes ";
+ if (@where) {
+ $query .= "WHERE " . join(' AND ', @where) . ' ';
+ }
+ $query .= $order;
+ #print $query,"\n";
+ my $sth = $dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute;
+
+ # /me kicks lisp in the teeth
+ if (not defined $ltype) {
+ return sub {
+ return ($sth->fetchrow_array)[0];
+ }
+ } elsif ($ltype eq 'time') {
+ my $length = 0;
+ return sub {
+ if ($length < $limit) {
+ my $fi = $sth->fetchrow_hashref;
+ $length += $fi->{length};
+ return $fi->{filename};
+ }
+ }
+ } elsif ($ltype eq 'size') {
+ my $size = 0;
+ return sub {
+ if ($size < $limit) {
+ my $file = ($sth->fetchrow_array)[0];
+ $size += -s $file;
+ return $file;
+ }
+ }
+ }
+}
+
if ($ARGV[0] eq 'add') {
shift;
$dbh->begin_work;
while ($r = $sth->fetchrow_hashref()) {
if (blacklisted($r->{filename}) ||
! (-e $r->{filename} || -e decode('utf8', $r->{filename}))) {
- print "Purging |$r->{filename}|\n";
+ print "Purging $r->{filename}\n";
my $hash = $r->{hash};
$dbh->do(qq{DELETE FROM tunes WHERE hash="$hash"});
}
db_info($_);
}
}
-} elsif ($ARGV[0] eq 'random') {
- shift;
- my $method = shift;
- my $quantity = shift;
- if ($method eq 'size') {
- $quantity = size_expand($quantity);
- } elsif ($method eq 'length') {
- $quantity = time_expand($quantity);
- } elsif ($method eq 'all') {
- ($quantity) = $dbh->selectrow_array(qq{SELECT count(*) FROM tunes});
- $method = 'count';
- } elsif ($method eq 'count') {
- # Do nothing
- } elsif ($method =~ /^\d+$/) {
- $quantity = int($method);
- $method = 'count';
- } else {
- print "Unknown kind of random: $method $quantity\n";
- exit 1;
- }
- my $n_files;
-
- if ($method eq 'count') {
- # This could take a very large amount of memory...
- my @files = @{$dbh->selectcol_arrayref(qq{SELECT filename FROM tunes})};
-
- for my $i (1..$quantity) {
- my $n = int(rand(@files));
- print scalar splice(@files, $n, 1), "\n";
- last unless @files;
- }
- } elsif ($method eq 'size') {
- my @files = @{$dbh->selectcol_arrayref(qq{SELECT filename FROM tunes})};
-
- my $size = 0;
- while ($size < $quantity) {
- my $n = int(rand(@files));
- my $file = splice(@files, $n, 1);
- $size += -s $file;
- print "$file\n";
- last unless @files;
- }
- } elsif ($method eq 'length') {
- my @files;
- my $sth = $dbh->prepare(qq{SELECT filename,length FROM tunes});
- $sth->execute;
- while (my $row = $sth->fetchrow_arrayref) {
- push @files, [@$row];
- }
-
- my $length = 0;
- while ($length < $quantity) {
- my $n = int(rand(@files));
- my $file = splice(@files, $n, 1);
- $length += $file->[1];
- print "$file->[0]\n";
- last unless @files;
- }
- }
} elsif ($ARGV[0] eq 'scan') {
shift;
unless (@ARGV) {
$import_dbh->disconnect;
$dbh->commit;
} else {
- my @where;
- foreach (@ARGV) {
- if (/^(artist|title|album|genre|comment|filename)(==|=)(.*?)$/) {
- my ($k, $op, $v) = ($1, $2, $3);
- $v =~ s/"/""/g;
- if ($op eq '==') {
- push @where, qq{$k LIKE "$v"};
- } else {
- push @where, qq{$k LIKE "\%$v\%"};
- }
- } elsif (/^(track|year|length|bitrate|samplerate|channels)(>|<|==|=)(.*)$/) {
- my ($k, $op, $v) = ($1, $2, int($3));
- if ($op eq '=' or $op eq '==') {
- push @where, qq{$k=$v};
- } elsif ($op eq '>' or $op eq '<') {
- push @where, qq{$k$op$v};
- }
- } else {
- s/"/""/g;
- push @where, qq{(artist LIKE "\%$_\%" OR title LIKE "\%$_\%" OR album LIKE "\%$_\%" OR comment LIKE "\%$_\%" OR filename LIKE "\%$_\%")};
- }
- }
- my $query = "SELECT filename FROM tunes WHERE " . join(' AND ', @where);
- #print $query,"\n";
- my $sth = $dbh->prepare($query);
- $sth->execute;
- while (my $file = ($sth->fetchrow_array)[0]) {
- print "$file\n";
- }
+ my $results = db_select(@ARGV);
+ my $file;
+ print "$file\n" while $file = $results->();
}
$dbh->disconnect();