bless($self,$class);
$self->{me}=shift;
- $self->{dbpath}=shift;
+ $self->{verbose}=shift;
+ my $init=shift;
+ my $dbpath=shift;
$self->{base}=shift;
- $self->{fallbackdir}=shift;
+ my $fallbackdir=shift;
- if(!defined($self->{base}) &&
- defined($self->{fallbackdir}) &&
- -d $self->{fallbackdir})
- {
- $self->{base}=$self->{fallbackdir};
- }
- $self->{dbpath}="$self->{base}/$dbfile" unless(defined($self->{dbpath}));
+ $dbpath=$self->find_db($init, $dbpath, $fallbackdir);
+ return undef unless($dbpath);
$self->{absbase}=Cwd::abs_path($self->{base});
- my $connectstr="dbi:SQLite:dbname=$self->{dbpath}";
+ my $connectstr="dbi:SQLite:dbname=$dbpath";
my ($user, $pass)=("", "");
if($self->{postgres})
{
$user="ianb";
$pass="foo";
}
- my $exists=-f $self->{dbpath};
+ my $exists=-f $dbpath;
$self->{dbh}=DBI->connect($connectstr, $user, $pass,
{ AutoCommit=>1 } );
unless(defined($self->{dbh}))
return $self;
}
+sub find_db
+{
+ my($self, $init, $dbpath, $fallbackdir)=@_;
+ my $file=undef;
+ my $base=undef;
+ if(defined($dbpath))
+ {
+ $file=$dbpath;
+ }
+ if(defined ($self->{base}))
+ {
+ $file="$self->{base}/$dbfile" unless defined($file);
+ $base=$self->{base};
+ }
+ elsif(defined($fallbackdir) && -d $fallbackdir)
+ {
+ my $path=Cwd::abs_path($fallbackdir);
+ do
+ {
+ $file="$path/$dbfile";
+ $base=$path;
+ $path=~s/(.*)\/.*/$1/;
+ }
+ while(! -f $file && length($path) && -d $path);
+ if(! -f $file)
+ {
+ $file="$fallbackdir/$dbfile";
+ $base=$fallbackdir;
+ }
+ }
+ if(!-f $file && !$init)
+ {
+ print "$self->{me}: db not found at $file\n";
+ return undef;
+ }
+ $self->{base}=$base;
+ return $file;
+}
+
sub create
{
my($self,$name)=@_;
my $cid=$constraint->{id};
push(@ids, $cid);
}
- @ids = map( { "\"$_\""; } @ids) unless($self->{postgres});
+ @ids = map( { "\"$_\""; } grep { defined; } @ids) unless($self->{postgres});
my $tagstr=join(", ", @ids);
my $sql = ($main_sql_start . $tagstr .
$main_sql_mid . $tagstr .
my $cid=$constraint->{id};
push(@ids, $cid);
}
- @ids = map( { "\"$_\""; } @ids) unless($self->{postgres});
+ @ids = map( { "\"$_\""; } grep { defined; } @ids) unless($self->{postgres});
my $tagstr=join(", ", @ids);
my $sql = ($main_sql_start . $tagstr .
$main_sql_end);
my $cid=$constraint->{id};
push(@ids, $cid);
}
- @ids = map( { "\"$_\""; } @ids) unless($self->{postgres});
+ @ids = map( { "\"$_\""; } grep { defined; } @ids) unless($self->{postgres});
my $str=join(", ", @ids);
my $sql = ($main_sql_start . $str .
$main_sql_end);
print "ARTIST_TRACKS SQL: $sql\n";
my $result=$self->cmd_rows($sql, $artist_id);
my @names=map { $_->[0]; } @$result;
- @names = map { s/.*\///; $_; } @names;
print "ARTISTTRACKS: ", join(', ', @names), "\n";
return(@names);
}
print "ALBUM_TRACKS SQL($artist_id, $album_id): $sql\n";
my $result=$self->cmd_rows($sql, $artist_id, $album_id);
my @names=map { $_->[0]; } @$result;
- @names = map { s/.*\///; $_;} @names;
print "TRACKS: ", join(', ', @names), "\n";
return(@names);
}
my $cid=$constraint->{id};
push(@ids, $cid);
}
- @ids = map( { "\"$_\""; } @ids) unless($self->{postgres});
+ @ids = map( { "\"$_\""; } grep { defined; } @ids) unless($self->{postgres});
my $str=join(", ", @ids);
my $sql = ($main_sql_start . $str .
$main_sql_end);
print "SQL: $sql\n";
my $result=$self->cmd_rows($sql);
my @names=map { $_->[0]; } @$result;
- @names = map { s/.*\///; $_; } @names;
print "TRACKS: ", join(', ', @names), "\n";
return(@names);
}
die("DB::filename: unhandled case\n"); #FIXME
}
+sub bare_tags
+{
+ my($self)=@_;
+ my $sql=("SELECT tags.name FROM tags\n" .
+ "LEFT JOIN tags_x_tagvals ON tags.id=tags_x_tagvals.tags_id\n" .
+ "WHERE tags_x_tagvals.tags_id IS NULL\n" .
+ "GROUP BY tags.name\n");
+ my $result=$self->cmd_rows($sql);
+ my @names=map { $_->[0]; } @$result;
+ return (@names);
+}
+
+sub tags_with_values
+{
+ my($self)=@_;
+ my $sql=("SELECT tags.name, tagvals.name FROM tags\n" .
+ "INNER JOIN tags_x_tagvals ON tags.id=tags_x_tagvals.tags_id\n" .
+ "INNER JOIN tagvals ON tagvals.id=tags_x_tagvals.tagvals_id\n" .
+ "GROUP BY tags.name, tagvals.name\n");
+ my $result=$self->cmd_rows($sql);
+ my $tags={};
+ for my $pair (@$result)
+ {
+ push(@{$tags->{$pair->[0]}}, $pair->[1]);
+ }
+ return $tags;
+}
+
sub id
{
my($self, $type, $val)=@_;
return $rows;
}
+sub files_in
+{
+ my ($self, $dir)=@_;
+ $dir=~s/^$self->{base}\/?//;
+ print "Munged dir: $dir\n";
+ my $sql=("SELECT files.name FROM files\n" .
+ "INNER JOIN paths ON files.paths_id=paths.id\n" .
+ "WHERE paths.name=?\n");
+ my $files=$self->cmd_rows($sql, $dir);
+ return(map { $_->[0]; } @$files);
+}
+
+sub prune_directories
+{
+ my($self)=@_;
+ my $sql=("SELECT name, id FROM paths ORDER BY name\n");
+ my $pathsref=$self->cmd_rows($sql);
+ my @ids=();
+ for my $pathpair (@$pathsref)
+ {
+ my($path, $id)=@$pathpair;
+ my $fullpath="$self->{absbase}/$path";
+ print "PRUNING PATH $fullpath: ";
+ unless(-d $fullpath)
+ {
+ push(@ids, $id)
+ }
+ }
+ $self->prune_paths(@ids);
+ return scalar(@ids);
+}
+
+sub prune_paths
+{
+ my($self, @ids)=@_;
+ my $sql=("DELETE FROM files WHERE paths_id IN (\n\t" .
+ join(', ', map { "\"$_\""; } @ids). "\n\t)");
+ print "SQL: \n", $sql, "\n";
+ $self->cmd($sql);
+}
+
+sub remove_unused
+{
+ my($self)=@_;
+ my $sql=<<'EOT';
+ DELETE FROM artists WHERE id IN (
+ SELECT artists.id FROM artists
+ LEFT JOIN files ON files.artists_id=artists.id
+ WHERE files.id IS NULL);
+
+ DELETE FROM albums WHERE id IN (
+ SELECT albums.id FROM albums
+ LEFT JOIN files ON files.albums_id=albums.id
+ WHERE files.id IS NULL);
+
+ DELETE FROM paths WHERE id IN (
+ SELECT paths.id FROM paths
+ LEFT JOIN files ON files.paths_id=paths.id
+ WHERE files.id IS NULL);
+
+ DELETE FROM files_x_tags WHERE files_id IN (
+ SELECT files_x_tags.files_id FROM files_x_tags
+ LEFT JOIN files ON files.id=files_x_tags.files_id
+ WHERE files.id IS NULL);
+
+ DELETE FROM tags WHERE id IN (
+ SELECT tags.id FROM tags
+ LEFT JOIN files_x_tags ON files_x_tags.tags_id=tags.id
+ WHERE files_x_tags.files_id IS NULL);
+
+ DELETE FROM tags_x_tagvals WHERE tags_id IN (
+ SELECT tags_x_tagvals.tags_id FROM tags_x_tagvals
+ LEFT JOIN tags ON tags.id=tags_x_tagvals.tags_id
+ WHERE tags.id IS NULL);
+
+ DELETE FROM tagvals WHERE id IN (
+ SELECT tagvals.id FROM tagvals
+ LEFT JOIN tags_x_tagvals ON tags_x_tagvals.tagvals_id=tagvals.id
+ WHERE tags_x_tagvals.tagvals_id IS NULL);
+EOT
+ print "SQL: $sql\n";
+ my @sql=split(/\n\n/, $sql);
+ $self->cmd($_) for (@sql);
+}
+
sub relation_exists
{
my ($self, $relname, $fields)=@_;
FOREIGN KEY(tags_id) REFERENCES tags(id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY(tagvals_id) REFERENCES tagvals(id) ON DELETE CASCADE ON UPDATE CASCADE
);
+