view release on metacpan or search on metacpan
docs/SCHEMA.pod view on Meta::CPAN
+-----------------+-------------+------------------------------------------------------------------------------+
| COLUMN_NAME | COLUMN_TYPE | COLUMN_COMMENT |
+-----------------+-------------+------------------------------------------------------------------------------+
| archive_id | int(11) | Unique ID of this archive |
| archive_type_id | int(11) | ID of this type of archive |
| name | varchar(45) | Name of this archive |
| max_width | int(11) | Maximum width of media that this archive can store |
| max_height | int(11) | Maximum height of media that this archive can store |
| location | varchar(45) | Location of this archive |
| storage | varchar(45) | The type of storage used for this archive, e.g. box, folder, ringbinder, etc |
| sealed | tinyint(1) | Whether or not this archive is sealed (closed to new additions) |
+-----------------+-------------+------------------------------------------------------------------------------+
=head2 ARCHIVE_TYPE
Table to list the different types of archive available for materials
+-----------------+-------------+------------------------------+
| COLUMN_NAME | COLUMN_TYPE | COLUMN_COMMENT |
+-----------------+-------------+------------------------------+
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
# Dump data for debugging
print "\n\nThis is what I will update into $table where:\n" unless $silent;
print Dump($where) unless $silent;
print Dump($data) unless $silent;
print "\n$rowcount records will be updated\n" unless $silent;
print "\n" unless $silent;
# Build query
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->update($table, $data, $where);
# Final confirmation
unless ($silent) {
if (!&prompt({default=>'yes', prompt=>'Proceed?', type=>'boolean'})) {
print "Aborted!\n";
return;
}
}
# Execute query
my $sth = $db->prepare($stmt);
my $rows = $sth->execute(@bind);
$rows = &unsci($rows);
print "Updated $rows rows\n" unless $silent;
&logger({db=>$db, type=>'EDIT', message=>"$table $rows rows"}) if $log;
return $rows;
}
# Delete an existing record in any table
=head2 deleterecord
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
# Work out affected rows
my $rowcount = &lookupval({db=>$db, col=>'count(*)', table=>$table, where=>$where});
# Dump data for debugging
print "\n\nI will delete from $table where:\n" unless $silent;
print Dump($where) unless $silent;
print "$rowcount records will be deleted\n" unless $silent;
# Build query
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->delete($table, $where);
# Final confirmation
unless ($silent) {
if (!&prompt({default=>'yes', prompt=>'Proceed?', type=>'boolean'})) {
print "Aborted!\n";
return;
}
}
# Execute query
my $sth = $db->prepare($stmt);
my $rows = $sth->execute(@bind);
$rows = &unsci($rows);
print "Deleted $rows rows\n" unless $silent;
&logger({db=>$db, type=>'DELETE', message=>"$table $rows rows"}) if $log;
return $rows;
}
=head2 newrecord
Insert a record into any table
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
# Delete empty strings from data hash
$data = &thin($data);
# Dump data for debugging
print "\n\nThis is what I will insert into $table:\n" unless $silent;
print Dump($data) unless $silent;
print "\n" unless $silent;
# Build query
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->insert($table, $data);
# Final confirmation
unless ($silent) {
if (!&prompt({default=>'yes', prompt=>'Proceed?', type=>'boolean'})) {
print "Aborted!\n";
return;
}
}
# Execute query
my $sth = $db->prepare($stmt);
$sth->execute(@bind);
# Display inserted row
my $insertedrow = $sth->{mysql_insertid};
print "Inserted $table $insertedrow\n" unless $silent;
&logger({db=>$db, type=>'ADD', message=>"$table #$insertedrow"}) if $log;
return $insertedrow;
}
=head2 notimplemented
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
my $char = $href->{char} // '+'; # character to use to signal that you want to enter a new row
my ($sth, $rows);
if ($query) {
# Use the manual query
$sth = $db->prepare($query) or die "Couldn't prepare statement: " . $db->errstr;
$rows = $sth->execute();
} elsif ($table && $cols && $where) {
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($table, $cols, $where);
$sth = $db->prepare($stmt);
$rows = $sth->execute(@bind);
} else {
die "Must pass in either query OR table, cols, where\n";
}
# No point in proceeding if there are no valid options to choose from
if ($rows == 0) {
print "No valid $keyword options to choose from\n";
if ($inserthandler && &prompt({prompt=>"Add a new $keyword?", type=>'boolean', default=>'no'})) {
# add a new entry
my $id = $inserthandler->({db=>$db});
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
my $cols = $href->{cols} // ('id, opt'); # Part of the SQL::Abstract tuple
my $where = $href->{where} // {}; # Part of the SQL::Abstract tuple
my $order = $href->{order}; # Part of the SQL::Abstract tuple
print "Now showing $msg\n";
my ($sth, $rows);
if ($table && $cols && $where) {
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($table, $cols, $where, $order);
$sth = $db->prepare($stmt);
$rows = $sth->execute(@bind);
$rows = &unsci($rows);
} else {
print "Must pass in table, cols, where\n";
return;
}
while (my $ref = $sth->fetchrow_hashref) {
print "\t$ref->{id}\t$ref->{opt}\n";
}
return $rows;
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
my $cols = $href->{cols} // '*'; # Part of the SQL::Abstract tuple
my $where = $href->{where} // {}; # Part of the SQL::Abstract tuple
my ($sth, $rows);
if ($query) {
$sth = $db->prepare($query) or die "Couldn't prepare statement: " . $db->errstr;
$rows = $sth->execute();
} elsif ($table && $cols && $where) {
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($table, $cols, $where);
$sth = $db->prepare($stmt);
$rows = $sth->execute(@bind);
} else {
print "Must pass in either query OR table, cols, where\n";
return;
}
my @array;
while (my $ref = $sth->fetchrow_hashref) {
$ref = &thin($ref);
push(@array, $ref);
}
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
my $where = $href->{where} // {}; # Part of the SQL::Abstract tuple
my ($sth, $rows);
if ($query) {
# Use the manual query
$sth = $db->prepare($query) or die "Couldn't prepare statement: " . $db->errstr;
$rows = $sth->execute();
} elsif ($table && $col && $where) {
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($table, $col, $where);
$sth = $db->prepare($stmt);
$rows = $sth->execute(@bind);
} else {
print "Must pass in either query OR table, col, where\n";
return;
}
my $row = $sth->fetchrow_array();
return $row;
}
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
my $db = $href->{db}; # DB handle
my $table = $href->{table}; # Part of the SQL::Abstract tuple
my $col = $href->{col}; # Part of the SQL::Abstract tuple
my $where = $href->{where} // {}; # Part of the SQL::Abstract tuple
my ($sth, $rows);
if ($table && $col && $where) {
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($table, $col, $where);
$sth = $db->prepare($stmt);
$rows = $sth->execute(@bind);
} else {
print "Must pass in table, col, where\n";
return;
}
my @list;
while (my @row = $sth->fetchrow_array()) {
push(@list, $row[0]);
}
return \@list;
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
sub unsetdisplaylens {
my $href = shift;
my $db = $href->{db};
my %where;
$where{camera_id} = $href->{camera_id};
$where{display_lens} = $href->{lens_id};
my $thinwhere = &thin(\%where);
# Build query
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->update('CAMERA', {display_lens => undef}, $thinwhere);
# Execute query
my $sth = $db->prepare($stmt);
return $sth->execute(@bind);
}
=head2 welcome
Print a friendly welcome message
=head4 Usage
&welcome;
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
'FocalLengthIn35mmFormat',
'LensSerialNumber',
'SerialNumber',
'LensMake',
'Copyright',
'UserComment',
);
# This is the query that fetches (and calculates) values from the DB that we want to write as EXIF tags
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select('exifdata', '*', $where);
# Prepare and execute the SQL
my $sth = $db->prepare($stmt) or die "Couldn't prepare statement: " . $db->errstr;
my $rows = $sth->execute(@bind);
$rows = &unsci($rows);
# Get confirmation
if ($rows == 0) {
print "No scans be will tagged\n";
return;
}
return unless &prompt({prompt=>"This will review and potentially update the tags of $rows scans. Proceed?", type=>'boolean'});
# Set some globals
lib/App/PhotoDB/funcs.pm view on Meta::CPAN
sub tabulate {
my $href = shift;
my $db = $href->{db};
my $view = $href->{view};
my $cols = $href->{cols} // '*';
my $where = $href->{where} // {};
# Use SQL::Abstract
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select($view, $cols, $where);
my $sth = $db->prepare($stmt);
my $rows = $sth->execute(@bind);
my $returnedcols = $sth->{'NAME'};
my @array;
my $table = Text::TabularDisplay->new(@$returnedcols);
while (my @row = $sth->fetchrow) {
$table->add(@row);
}
# print "$choices[$action]{'desc'}\n";
print $table->render;
print "\n";
lib/App/PhotoDB/handlers.pm view on Meta::CPAN
# Add a new physical archive for prints or films
sub archive_add {
my $href = shift;
my $db = $href->{db};
my %data;
$data{archive_type_id} = $href->{archive_type_id} // &listchoices({db=>$db, cols=>['archive_type_id as id', 'archive_type as opt'], table=>'ARCHIVE_TYPE'});
$data{name} = $href->{name} // &prompt({prompt=>'What is the name of this archive?'});
$data{max_width} = $href->{max_width} // &prompt({prompt=>'What is the maximum width of media that this archive can accept (if applicable)?'});
$data{max_height} = $href->{max_height} // &prompt({prompt=>'What is the maximum height of media that this archive can accept (if applicable)?'});
$data{location} = $href->{location} // &prompt({prompt=>'What is the location of this archive?'});
$data{storage} = $href->{storage} // &prompt({prompt=>'What is the storage type of this archive? (e.g. box, folder, ringbinder, etc)'});
$data{sealed} = $href->{sealed} // &prompt({default=>'no', prompt=>'Is this archive sealed (closed to new additions)?', type=>'boolean'});
return &newrecord({db=>$db, data=>\%data, table=>'ARCHIVE'});
}
# Bulk-add multiple films to an archive
sub archive_films {
my $href = shift;
my $db = $href->{db};
my %data;
my $minfilm = $href->{minfilm} // &prompt({prompt=>'What is the lowest film ID in the range?', type=>'integer'});
lib/App/PhotoDB/handlers.pm view on Meta::CPAN
# Read in cmdline args
my $href = shift;
my $db = $href->{db};
my $film_id = $href->{film_id} // &film_choose({db=>$db});
# Make sure basepath is valid
my $basepath = &basepath;
# Find matching scans
my $sql = SQL::Abstract->new;
my($stmt, @bind) = $sql->select('scans_negs', '*', {film_id=>$film_id});
my $sth = $db->prepare($stmt) or die "Couldn't prepare statement: " . $db->errstr;
my $rows = $sth->execute(@bind);
$rows = &unsci($rows);
return if ($rows == 0);
# Loop through our result set
while (my $ref = $sth->fetchrow_hashref()) {
# First check the path is defined in MySQL
if (defined($ref->{'filename'})) {
# Now make sure the path actually exists on the system
if (-e "$basepath/$ref->{'directory'}/$ref->{'filename'}") {
migrations/000-base-schema.sql view on Meta::CPAN
DROP TABLE IF EXISTS `ARCHIVE`;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `ARCHIVE` (
`archive_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Unique ID of this archive',
`archive_type_id` int(11) DEFAULT NULL COMMENT 'ID of this type of archive',
`name` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Name of this archive',
`max_width` int(11) DEFAULT NULL COMMENT 'Maximum width of media that this archive can store',
`max_height` int(11) DEFAULT NULL COMMENT 'Maximum height of media that this archive can store',
`location` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Location of this archive',
`storage` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'The type of storage used for this archive, e.g. box, folder, ringbinder, etc',
`sealed` tinyint(1) DEFAULT '0' COMMENT 'Whether or not this archive is sealed (closed to new additions)',
PRIMARY KEY (`archive_id`),
KEY `fk_ARCHIVE_3_idx` (`archive_type_id`),
CONSTRAINT `fk_ARCHIVE_3` FOREIGN KEY (`archive_type_id`) REFERENCES `ARCHIVE_TYPE` (`archive_type_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Table to list all archives that exist for storing physical media';
SET character_set_client = @saved_cs_client;
DROP TABLE IF EXISTS `LIGHT_METER`;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `LIGHT_METER` (