########################################### package CameraStore; ########################################### # Mike Schilli, 2003 (m@perlmeister.com) ########################################### use warnings; use strict; use Class::DBI; use Log::Log4perl qw(:easy); ########################################### sub new { # Constructor ########################################### my($class) = @_; bless {}, $class; } ########################################### sub _img { # INTERNAL: Get image by ID ########################################### my($stamp) = @_; my($img) = CameraStore::IDB::Image-> search( stamp => $stamp ); ERROR "No such ID: $stamp" unless defined $img; return $img; } ########################################### sub _cat { # INTERNAL: Get category by ID ########################################### my($cname) = @_; my($cat) = CameraStore::IDB::Category-> search( name => $cname ); ERROR "No such tag: $cname" unless defined $cat; return $cat; } ########################################### sub list_tags { # Get all tags of one img ########################################### my($self, $stamp) = @_; my @found = (); (my $img = _img($stamp)) or return(); for my $tag ($img->tags) { push @found, $tag->category->name; } return @found; } ########################################### sub add_image { # Add new image (plus tag) ########################################### my($self, $stamp, $path, $cname) = @_; if(CameraStore::IDB::Image->search( stamp => $stamp )) { ERROR "ID $stamp already exists"; return undef; } CameraStore::IDB::Image->create({ stamp => $stamp, path => $path}); return 1 unless $cname; # No tag but ok return $self->add_tag($cname, $stamp); } ########################################### sub delete_image {# Remove image (and tags) ########################################### my($self, $stamp) = @_; (my $img = _img($stamp)) or return undef; $img->delete(); } ########################################### sub add_tag { # Add a new tag name ########################################### my($self, $cname, $stamp) = @_; INFO "Adding tag $cname/$stamp"; (my $img = _img($stamp)) or return undef; # Add category by name my $cat = CameraStore::IDB::Category-> find_or_create({name => $cname}); if(CameraStore::IDB::Tag->search( image => $img->id, category => $cat->id)) { ERROR "$stamp already has $cname"; return undef; } # Add image/cat link to tags table $cat->add_to_tags({image => $img->id}); } ########################################### sub delete_tag { # Take tag off image ########################################### my($self, $cname, $stamp) = @_; INFO "Strip $cname from $stamp"; (my $img = _img($stamp)) or return undef; (my $cat = _cat($cname)) or return undef; my($tag)=CameraStore::IDB::Tag->search( image => $img->id, category => $cat->id, ); unless($tag) { ERROR "No $cname on $stamp"; return undef; } $tag->delete(); } ########################################### sub search_tag { ########################################### my($self, $tag, $paths, $stamp) = @_; my @matches = CameraStore::IDB::Image-> match($tag, $stamp); my $field = $paths ? "path" : "stamp"; return map { $_->$field } @matches; } ########################################### package CameraStore::IDB; ########################################### use base q(Class::DBI); __PACKAGE__->set_db('Main', 'dbi:mysql:idb', 'root', ''); ########################################### package CameraStore::IDB::Image; ########################################### use base q(CameraStore::IDB); __PACKAGE__->table('images'); __PACKAGE__->columns( All => qw(id stamp path)); __PACKAGE__->has_many('tags', 'CameraStore::IDB::Tag' => 'image'); __PACKAGE__->set_sql(rawmatch => q{ SELECT DISTINCT images.stamp, images.path FROM categories, tags, images WHERE categories.name LIKE ? AND categories.id = tags.category AND images.id = tags.image AND images.stamp LIKE ? }); sub match { my ($class, $rex, $stamp) = @_; $stamp = "%" unless defined $stamp; my $sth = $class->sql_rawmatch; $sth->execute($rex, $stamp); return $class->sth_to_objects($sth); } ########################################### package CameraStore::IDB::Category; ########################################### use base q(CameraStore::IDB); __PACKAGE__->table('categories'); __PACKAGE__->has_many('tags', 'CameraStore::IDB::Tag' => 'category'); __PACKAGE__->columns( All => qw(id name)); ########################################### package CameraStore::IDB::Tag; ########################################### use base q(CameraStore::IDB); __PACKAGE__->table('tags'); __PACKAGE__->columns( All => qw(id image category)); __PACKAGE__->has_a('category', 'CameraStore::IDB::Category'); __PACKAGE__->has_a('image', 'CameraStore::IDB::Image'); 1;