Diff for /loncom/metadata_database/LONCAPA/lonmetadata.pm between versions 1.11 and 1.15

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

Removed from v.1.11  
changed lines
  Added in v.1.15


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>