version 1.11, 2004/06/17 20:33:21
|
version 1.15, 2006/12/29 19:15:28
|
Line 30 package LONCAPA::lonmetadata;
|
Line 30 package LONCAPA::lonmetadata;
|
|
|
use strict; |
use strict; |
use DBI; |
use DBI; |
|
use vars qw($Metadata_Table_Description $Portfolio_metadata_table_description |
|
$Portfolio_access_table_description $Fulltext_indicies $Portfolio_metadata_indices $Portfolio_access_indices $Portfolio_addedfields_table_description $Portfolio_addedfields_indices); |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
Line 75 creationdate DATETIME,
|
Line 77 creationdate DATETIME,
|
lastrevisiondate DATETIME, |
lastrevisiondate DATETIME, |
owner TEXT, |
owner TEXT, |
copyright TEXT, |
copyright TEXT, |
|
domain TEXT |
|
|
FULLTEXT idx_title (title), |
FULLTEXT idx_title (title), |
FULLTEXT idx_author (author), |
FULLTEXT idx_author (author), |
Line 95 TYPE=MYISAM;
|
Line 98 TYPE=MYISAM;
|
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
my @Metadata_Table_Description = |
$Metadata_Table_Description = |
( |
[ |
{ name => 'title', type=>'TEXT'}, |
{ name => 'title', type=>'TEXT'}, |
{ name => 'author', type=>'TEXT'}, |
{ name => 'author', type=>'TEXT'}, |
{ name => 'subject', type=>'TEXT'}, |
{ name => 'subject', type=>'TEXT'}, |
Line 111 my @Metadata_Table_Description =
|
Line 114 my @Metadata_Table_Description =
|
{ name => 'lastrevisiondate', type=>'DATETIME'}, |
{ name => 'lastrevisiondate', type=>'DATETIME'}, |
{ name => 'owner', type=>'TEXT'}, |
{ name => 'owner', type=>'TEXT'}, |
{ name => 'copyright', type=>'TEXT'}, |
{ name => 'copyright', type=>'TEXT'}, |
|
{ name => 'domain', type=>'TEXT'}, |
#-------------------------------------------------- |
#-------------------------------------------------- |
{ name => 'dependencies', type=>'TEXT'}, |
{ name => 'dependencies', type=>'TEXT'}, |
{ name => 'modifyinguser', type=>'TEXT'}, |
{ name => 'modifyinguser', type=>'TEXT'}, |
Line 142 my @Metadata_Table_Description =
|
Line 146 my @Metadata_Table_Description =
|
{ name => 'depth', type=>'FLOAT'}, |
{ name => 'depth', type=>'FLOAT'}, |
{ name => 'hostname', type=> 'TEXT'}, |
{ name => 'hostname', type=> 'TEXT'}, |
#-------------------------------------------------- |
#-------------------------------------------------- |
); |
]; |
|
|
my @Fulltext_indicies = qw/ |
$Fulltext_indicies = [ qw/ |
title |
title |
author |
author |
subject |
subject |
Line 156 my @Fulltext_indicies = qw/
|
Line 160 my @Fulltext_indicies = qw/
|
mime |
mime |
language |
language |
owner |
owner |
copyright/; |
copyright/ ]; |
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
|
$Portfolio_metadata_table_description = |
|
[ |
|
{ name => 'title', type=>'TEXT'}, |
|
{ name => 'author', type=>'TEXT'}, |
|
{ name => 'subject', type=>'TEXT'}, |
|
{ name => 'url', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'keywords', type=>'TEXT'}, |
|
{ name => 'version', type=>'TEXT'}, |
|
{ name => 'notes', type=>'TEXT'}, |
|
{ name => 'abstract', type=>'TEXT'}, |
|
{ name => 'mime', type=>'TEXT'}, |
|
{ name => 'language', type=>'TEXT'}, |
|
{ name => 'creationdate', type=>'DATETIME'}, |
|
{ name => 'lastrevisiondate', type=>'DATETIME'}, |
|
{ name => 'owner', type=>'TEXT'}, |
|
{ name => 'copyright', type=>'TEXT'}, |
|
{ name => 'domain', type=>'TEXT'}, |
|
{ name => 'groupname', type=>'TEXT'}, |
|
{ name => 'courserestricted', type=>'TEXT'}, |
|
{ name => 'addedfieldnames', type=>'TEXT'}, |
|
{ name => 'addedfieldvalues', type=>'TEXT'}, |
|
#-------------------------------------------------- |
|
{ name => 'dependencies', type=>'TEXT'}, |
|
{ name => 'modifyinguser', type=>'TEXT'}, |
|
{ name => 'authorspace', type=>'TEXT'}, |
|
{ name => 'lowestgradelevel', type=>'INT'}, |
|
{ name => 'highestgradelevel', type=>'INT'}, |
|
{ name => 'standards', type=>'TEXT'}, |
|
{ name => 'hostname', type=> 'TEXT'}, |
|
#-------------------------------------------------- |
|
]; |
|
|
|
$Portfolio_metadata_indices = [qw/ |
|
title |
|
author |
|
subject |
|
url |
|
keywords |
|
version |
|
notes |
|
abstract |
|
mime |
|
language |
|
owner/]; |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
$Portfolio_access_table_description = |
|
[ |
|
{ name => 'url', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'keynum', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'scope', type=>'TEXT'}, |
|
{ name => 'start', type=>'DATETIME'}, |
|
{ name => 'end', type=>'DATETIME'}, |
|
]; |
|
|
|
$Portfolio_access_indices = [qw/ |
|
url |
|
keynum |
|
scope |
|
start |
|
end/]; |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
$Portfolio_addedfields_table_description = |
|
[ |
|
{ name => 'url', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'field', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'courserestricted', type=>'TEXT', restrictions => 'NOT NULL' }, |
|
{ name => 'value', type=>'TEXT'}, |
|
]; |
|
|
|
$Portfolio_addedfields_indices = [qw/ |
|
url |
|
field |
|
value |
|
courserestricted/]; |
|
|
|
###################################################################### |
|
###################################################################### |
|
|
|
|
=pod |
=pod |
|
|
Line 174 of the metadata table(s).
|
Line 262 of the metadata table(s).
|
|
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub describe_metadata_storage { |
sub describe_metadata_storage { |
return (\@Metadata_Table_Description,\@Fulltext_indicies); |
my ($tabletype) = @_; |
|
my %table_description = ( |
|
metadata => $Metadata_Table_Description, |
|
portfolio_metadata => $Portfolio_metadata_table_description, |
|
portfolio_access => $Portfolio_access_table_description, |
|
portfolio_addedfields => $Portfolio_addedfields_table_description, |
|
); |
|
my %index_description = ( |
|
metadata => $Fulltext_indicies, |
|
portfolio_metadata => $Portfolio_metadata_indices, |
|
portfolio_access => $Portfolio_access_indices, |
|
portfolio_addedfields => $Portfolio_addedfields_indices, |
|
); |
|
if ($tabletype eq 'portfolio_search') { |
|
my @portfolio_search_table = @{$table_description{portfolio_metadata}}; |
|
foreach my $item (@{$table_description{portfolio_access}}) { |
|
if (ref($item) eq 'HASH') { |
|
if ($item->{'name'} eq 'url') { |
|
next; |
|
} |
|
} |
|
push(@portfolio_search_table,$item); |
|
} |
|
my @portfolio_search_indices = @{$index_description{portfolio_metadata}}; |
|
push(@portfolio_search_indices,('scope','keynum')); |
|
return (\@portfolio_search_table,\@portfolio_search_indices); |
|
} else { |
|
return ($table_description{$tabletype},$index_description{$tabletype}); |
|
} |
} |
} |
|
|
###################################################################### |
###################################################################### |
Line 195 metadata storage to be initialized.
|
Line 311 metadata storage to be initialized.
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub create_metadata_storage { |
sub create_metadata_storage { |
my ($tablename) = @_; |
my ($tablename,$tabletype) = @_; |
$tablename = 'metadata' if (! defined($tablename)); |
$tablename = 'metadata' if (! defined($tablename)); |
|
$tabletype = 'metadata' if (! defined($tabletype)); |
my $request = "CREATE TABLE IF NOT EXISTS ".$tablename." "; |
my $request = "CREATE TABLE IF NOT EXISTS ".$tablename." "; |
# |
# |
# Process the columns (this code is stolen from lonmysql.pm) |
# Process the columns (this code is stolen from lonmysql.pm) |
my @Columns; |
my @Columns; |
my $col_des; # mysql column description |
my $col_des; # mysql column description |
foreach my $coldata (@Metadata_Table_Description) { |
my ($table_columns,$table_indices) = |
|
&describe_metadata_storage($tabletype); |
|
my %coltype; |
|
foreach my $coldata (@{$table_columns}) { |
my $column = $coldata->{'name'}; |
my $column = $coldata->{'name'}; |
|
$coltype{$column} = $coldata->{'type'}; |
$col_des = ''; |
$col_des = ''; |
if (lc($coldata->{'type'}) =~ /(enum|set)/) { # 'enum' or 'set' |
if (lc($coldata->{'type'}) =~ /(enum|set)/) { # 'enum' or 'set' |
$col_des.=$column." ".$coldata->{'type'}."('". |
$col_des.=$column." ".$coldata->{'type'}."('". |
Line 229 sub create_metadata_storage {
|
Line 350 sub create_metadata_storage {
|
# skip blank items. |
# skip blank items. |
push (@Columns,$col_des) if ($col_des ne ''); |
push (@Columns,$col_des) if ($col_des ne ''); |
} |
} |
foreach my $colname (@Fulltext_indicies) { |
foreach my $colname (@{$table_indices}) { |
my $text = 'FULLTEXT idx_'.$colname.' ('.$colname.')'; |
my $text; |
|
if ($coltype{$colname} eq 'TEXT') { |
|
$text = 'FULLTEXT '; |
|
} else { |
|
$text = 'INDEX '; |
|
} |
|
$text .= 'idx_'.$colname.' ('.$colname.')'; |
push (@Columns,$text); |
push (@Columns,$text); |
} |
} |
$request .= "(".join(", ",@Columns).") TYPE=MyISAM"; |
$request .= "(".join(", ",@Columns).") TYPE=MyISAM"; |
Line 244 sub create_metadata_storage {
|
Line 371 sub create_metadata_storage {
|
|
|
=item store_metadata() |
=item store_metadata() |
|
|
Inputs: database handle ($dbh), a table name, and a hash or hash reference |
Inputs: database handle ($dbh), a table name, table type and a hash or hash |
containing the metadata for a single resource. |
reference containing the metadata for a single resource. |
|
|
Returns: 1 on success, 0 on failure to store. |
Returns: 1 on success, 0 on failure to store. |
|
|
Line 261 Returns: 1 on success, 0 on failure to s
|
Line 388 Returns: 1 on success, 0 on failure to s
|
## |
## |
## In most scripts, this will work fine. If the dbi is going to be |
## In most scripts, this will work fine. If the dbi is going to be |
## dropped and (possibly) later recreated, call &clear_sth. Yes it |
## dropped and (possibly) later recreated, call &clear_sth. Yes it |
## is annoying but $sth appearantly does not have a link back to the |
## is annoying but $sth apparently does not have a link back to the |
## $dbh, so we can't check our validity. |
## $dbh, so we can't check our validity. |
## |
## |
my $sth = undef; |
my $sth = undef; |
my $sth_table = undef; |
my $sth_table = undef; |
|
|
sub create_statement_handler { |
sub create_statement_handler { |
my $dbh = shift(); |
my ($dbh,$tablename,$tabletype) = @_; |
my $tablename = shift(); |
|
$tablename = 'metadata' if (! defined($tablename)); |
$tablename = 'metadata' if (! defined($tablename)); |
|
$tabletype = 'metadata' if (! defined($tabletype)); |
|
my ($table_columns,$table_indices) = |
|
&describe_metadata_storage($tabletype); |
$sth_table = $tablename; |
$sth_table = $tablename; |
my $request = 'INSERT INTO '.$tablename.' VALUES('; |
my $request = 'INSERT INTO '.$tablename.' VALUES('; |
foreach (@Metadata_Table_Description) { |
foreach (@{$table_columns}) { |
$request .= '?,'; |
$request .= '?,'; |
} |
} |
chop $request; |
chop $request; |
Line 285 sub create_statement_handler {
|
Line 414 sub create_statement_handler {
|
sub clear_sth { $sth=undef; $sth_table=undef;} |
sub clear_sth { $sth=undef; $sth_table=undef;} |
|
|
sub store_metadata { |
sub store_metadata { |
my ($dbh,$tablename,@Metadata)=@_; |
my ($dbh,$tablename,$tabletype,@Metadata)=@_; |
my $errors = ''; |
my $errors = ''; |
if (! defined($sth) || |
if (! defined($sth) || |
( defined($tablename) && ($sth_table ne $tablename)) || |
( defined($tablename) && ($sth_table ne $tablename)) || |
(! defined($tablename) && $sth_table ne 'metadata')) { |
(! defined($tablename) && $sth_table ne 'metadata')) { |
&create_statement_handler($dbh,$tablename); |
&create_statement_handler($dbh,$tablename,$tabletype); |
} |
} |
my $successcount = 0; |
my $successcount = 0; |
|
if (! defined($tabletype)) { |
|
$tabletype = 'metadata'; |
|
} |
|
my ($table_columns,$table_indices) = |
|
&describe_metadata_storage($tabletype); |
foreach my $mdata (@Metadata) { |
foreach my $mdata (@Metadata) { |
next if (ref($mdata) ne "HASH"); |
next if (ref($mdata) ne "HASH"); |
my @MData; |
my @MData; |
foreach my $field (@Metadata_Table_Description) { |
foreach my $field (@{$table_columns}) { |
my $fname = $field->{'name'}; |
my $fname = $field->{'name'}; |
if (exists($mdata->{$fname}) && |
if (exists($mdata->{$fname}) && |
defined($mdata->{$fname}) && |
defined($mdata->{$fname}) && |
Line 420 Inputs:
|
Line 554 Inputs:
|
$dbh, database handle |
$dbh, database handle |
$newmetadata, hash reference containing the new metadata |
$newmetadata, hash reference containing the new metadata |
$tablename, metadata table name. Defaults to 'metadata'. |
$tablename, metadata table name. Defaults to 'metadata'. |
|
$tabletype, type of table (metadata, portfolio_metadata, portfolio_access) |
|
|
Returns: |
Returns: |
$error on failure. undef on success. |
$error on failure. undef on success. |
Line 429 $error on failure. undef on success.
|
Line 564 $error on failure. undef on success.
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub update_metadata { |
sub update_metadata { |
my ($dbh,$tablename,$newmetadata)=@_; |
my ($dbh,$tablename,$tabletype,$newmetadata)=@_; |
my $error; |
my $error; |
$tablename = 'metadata' if (! defined($tablename)); |
$tablename = 'metadata' if (! defined($tablename)); |
|
$tabletype = 'metadata' if (! defined($tabletype)); |
if (! exists($newmetadata->{'url'})) { |
if (! exists($newmetadata->{'url'})) { |
$error = 'Unable to update: no url specified'; |
$error = 'Unable to update: no url specified'; |
} |
} |
Line 443 sub update_metadata {
|
Line 579 sub update_metadata {
|
' url='.$dbh->quote($newmetadata->{'url'}), |
' url='.$dbh->quote($newmetadata->{'url'}), |
undef,$tablename); |
undef,$tablename); |
return $error if ($error); |
return $error if ($error); |
my %metadata = &LONCAPA::lonmetadata::metadata_col_to_hash(@{$row->[0]}); |
my %metadata = &LONCAPA::lonmetadata::metadata_col_to_hash($tabletype,@{$row->[0]}); |
# |
# |
# Update metadata values |
# Update metadata values |
while (my ($key,$value) = each(%$newmetadata)) { |
while (my ($key,$value) = each(%$newmetadata)) { |
Line 456 sub update_metadata {
|
Line 592 sub update_metadata {
|
# |
# |
# Store updated metadata |
# Store updated metadata |
my $success; |
my $success; |
($success,$error) = &store_metadata($dbh,$tablename,\%metadata); |
($success,$error) = &store_metadata($dbh,$tablename,$tabletype,\%metadata); |
return $error; |
return $error; |
} |
} |
|
|
Line 477 passed in as values
|
Line 613 passed in as values
|
###################################################################### |
###################################################################### |
###################################################################### |
###################################################################### |
sub metadata_col_to_hash { |
sub metadata_col_to_hash { |
my @cols=@_; |
my ($tabletype,@cols)=@_; |
my %hash=(); |
my %hash=(); |
for (my $i=0; $i<=$#Metadata_Table_Description;$i++) { |
my ($columns,$indices) = &describe_metadata_storage($tabletype); |
$hash{$Metadata_Table_Description[$i]->{'name'}}=$cols[$i]; |
for (my $i=0; $i<@{$columns};$i++) { |
|
$hash{$columns->[$i]->{'name'}}=$cols[$i]; |
|
unless ($hash{$columns->[$i]->{'name'}}) { |
|
if ($columns->[$i]->{'type'} eq 'TEXT') { |
|
$hash{$columns->[$i]->{'name'}}=''; |
|
} elsif ($columns->[$i]->{'type'} eq 'DATETIME') { |
|
$hash{$columns->[$i]->{'name'}}='0000-00-00 00:00:00'; |
|
} else { |
|
$hash{$columns->[$i]->{'name'}}=0; |
|
} |
|
} |
} |
} |
return %hash; |
return %hash; |
} |
} |
Line 754 sub process_dynamic_metadata {
|
Line 900 sub process_dynamic_metadata {
|
if (exists($resdata->{'stats'})) { |
if (exists($resdata->{'stats'})) { |
$data{'stats'} = $resdata->{'stats'}; |
$data{'stats'} = $resdata->{'stats'}; |
} |
} |
|
if (exists($DynamicData->{'domain'})) { |
|
$data{'domain'} = $DynamicData->{'domain'}; |
|
} |
# |
# |
return %data; |
return %data; |
} |
} |
Line 780 sub dynamic_metadata_storage {
|
Line 929 sub dynamic_metadata_storage {
|
} |
} |
|
|
###################################################################### |
###################################################################### |
|
###################################################################### |
|
|
|
## Utility originally in searchcat.pl. Moved to be more widely available. |
|
## |
|
## &sqltime($timestamp) |
|
## |
|
## Convert perl $timestamp to MySQL time. MySQL expects YYYY-MM-DD HH:MM:SS |
|
## |
|
sub sqltime { |
|
my ($time) = @_; |
|
my $mysqltime; |
|
if ($time =~ |
|
/(\d+)-(\d+)-(\d+) # YYYY-MM-DD |
|
\s # a space |
|
(\d+):(\d+):(\d+) # HH:MM::SS |
|
/x ) { |
|
# Some of the .meta files have the time in mysql |
|
# format already, so just make sure they are 0 padded and |
|
# pass them back. |
|
$mysqltime = sprintf('%04d-%02d-%02d %02d:%02d:%02d', |
|
$1,$2,$3,$4,$5,$6); |
|
} elsif ($time =~ /^\d+$/) { |
|
my @TimeData = gmtime($time); |
|
# Alter the month to be 1-12 instead of 0-11 |
|
$TimeData[4]++; |
|
# Alter the year to be from 0 instead of from 1900 |
|
$TimeData[5]+=1900; |
|
$mysqltime = sprintf('%04d-%02d-%02d %02d:%02d:%02d', |
|
@TimeData[5,4,3,2,1,0]); |
|
} elsif (! defined($time) || $time == 0) { |
|
$mysqltime = 0; |
|
} else { |
|
&log(0," sqltime:Unable to decode time ".$time); |
|
$mysqltime = 0; |
|
} |
|
return $mysqltime; |
|
} |
|
|
|
###################################################################### |
###################################################################### |
###################################################################### |
## |
## |
## The usual suspects, repeated here to reduce dependency hell |
## The usual suspects, repeated here to reduce dependency hell |