Commit 4d663bb8 authored by Leigh Stoller's avatar Leigh Stoller

Address a number of issues raised by Mike. The most notable:

* Rework metadata to be somewhat more general so that they can be used for
  things like parameter descriptions.

* My own little part of javascript hell ... add a highlight around the
  "current" template in the template graph. Sheesh!

* Add more tooltips (using the tooltip library). When you mouseover the
  metadata or descriptions, the formatted text is shown in a tooltip,
  which is handy when the valus is truncated cause its too long for the
  tables.
parent 99672233
......@@ -601,6 +601,8 @@ CREATE TABLE experiment_template_metadata (
metadata_guid varchar(16) NOT NULL default '',
metadata_vers smallint(5) unsigned NOT NULL default '0',
internal tinyint(1) NOT NULL default '0',
hidden tinyint(1) NOT NULL default '0',
metadata_type enum('tid','template_description','parameter_description') default NULL,
PRIMARY KEY (parent_guid, parent_vers, metadata_guid, metadata_vers)
) TYPE=MyISAM;
......@@ -616,7 +618,7 @@ CREATE TABLE experiment_template_metadata_items (
template_guid varchar(16) NOT NULL default '',
uid varchar(8) NOT NULL default '',
name varchar(64) NOT NULL default '',
value tinytext,
value mediumtext,
created datetime default NULL,
PRIMARY KEY (guid, vers),
KEY parent (parent_guid,parent_vers),
......@@ -634,6 +636,8 @@ CREATE TABLE experiment_template_parameters (
tid varchar(32) NOT NULL default '',
name varchar(64) NOT NULL default '',
value tinytext,
metadata_guid varchar(16) default NULL,
metadata_vers smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (parent_guid,parent_vers,name),
KEY pidtid (pid,tid)
) TYPE=MyISAM;
......
......@@ -782,6 +782,7 @@ REPLACE INTO table_regex VALUES ('experiment_templates','description','text','re
REPLACE INTO table_regex VALUES ('experiment_templates','guid','text','regex','^[\\w]+$',1,32,NULL);
REPLACE INTO table_regex VALUES ('experiment_template_metadata','name','text','regex','^[\\040-\\176]*$',1,64,NULL);
REPLACE INTO table_regex VALUES ('experiment_template_metadata','value','text','regex','^[\\040-\\176\\012\\015\\011]*$',1,2048,NULL);
REPLACE INTO table_regex VALUES ('experiment_template_metadata','metadata_type','text','regex','^[\\w]*$',1,64,NULL);
REPLACE INTO table_regex VALUES ('virt_parameters','pid','text','redirect','projects:pid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_parameters','eid','text','redirect','experiments:eid',0,0,NULL);
REPLACE INTO table_regex VALUES ('virt_parameters','name','text','regex','^\\w[-\\w]+$',1,64,NULL);
......
......@@ -3354,3 +3354,21 @@ last_net_act,last_cpu_act,last_ext_act);
alter table virt_nodes add plab_role enum('plc','node','none') \
NOT NULL default 'none' after inner_elab_role;
4.60: Various changes to templates.
alter table experiment_template_metadata_items \
change value value mediumtext;
alter table experiment_template_metadata \
add hidden tinyint(1) NOT NULL default '0';
alter table experiment_template_metadata \
add metadata_type enum('tid','template_description',\
'parameter_description') default NULL;
alter table experiment_template_parameters add \
metadata_guid varchar(16) default NULL;
alter table experiment_template_parameters add \
metadata_vers smallint(5) unsigned NOT NULL default '0';
......@@ -170,6 +170,10 @@ CREATE TABLE experiment_template_metadata (
metadata_vers smallint(5) unsigned NOT NULL default '0',
-- Internal metadata items, handled specially.
internal tinyint(1) NOT NULL default '0',
-- Hidden metadata items
hidden tinyint(1) NOT NULL default '0',
-- A type descriptor for the metadata, when not user generated.
metadata_type enum('tid','template_description','parameter_description') default NULL,
PRIMARY KEY (parent_guid, parent_vers, metadata_guid, metadata_vers)
) TYPE=MyISAM;
......@@ -191,7 +195,7 @@ CREATE TABLE experiment_template_metadata_items (
uid varchar(8) NOT NULL default '',
-- Key/Value pairs.
name varchar(64) NOT NULL default '',
value tinytext,
value mediumtext,
created datetime default NULL,
PRIMARY KEY (guid, vers),
KEY parent (parent_guid,parent_vers),
......@@ -231,6 +235,9 @@ CREATE TABLE experiment_template_parameters (
tid varchar(32) NOT NULL default '',
name varchar(64) NOT NULL default '',
value tinytext,
-- These point to the optional metadata description.
metadata_guid varchar(16) default NULL,
metadata_vers smallint(5) unsigned NOT NULL default '0',
PRIMARY KEY (parent_guid, parent_vers, name),
KEY pidtid (pid,tid)
) TYPE=MyISAM;
......
......@@ -26,6 +26,7 @@ use overload ('""' => 'Stringify');
# Configure variables
my $TB = "@prefix@";
my $MD5 = "/sbin/md5";
my $makegraph = "$TB/bin/template_graph";
# Cache of template instances to avoid regenerating them.
my %templates = ();
......@@ -279,7 +280,7 @@ sub Delete($)
my $guid = $self->guid();
my $vers = $self->vers();
DeleteMetadata($self) == 0
DeleteAllMetadata($self) == 0
or return -1;
DeleteInputFiles($self) == 0
......@@ -582,12 +583,13 @@ sub DeleteInputFiles($)
#
# Add a metadata record.
#
sub NewMetadata($$$$)
sub NewMetadata($$$$;$)
{
my ($self, $name, $value, $creator) = @_;
my ($self, $name, $value, $creator, $type) = @_;
my $guid;
my $version = 1;
my $internal = 0;
my $metadata_type;
# Must be a real reference.
return -1
......@@ -601,16 +603,30 @@ sub NewMetadata($$$$)
# Special ...
$internal = 1
if ($name eq "TID" || $name eq "description");
if (defined($type));
$name = DBQuoteSpecial($name);
$value = DBQuoteSpecial($value);
# Current set of allowed types;
my @okay_types = ("tid", "template_description", "parameter_description");
if (defined($type)) {
if (! grep {$_ eq $type} @okay_types) {
tberror("Illegal metadata type: $type");
return -1;
}
$metadata_type = "'$type'";
}
else {
$metadata_type = "NULL";
}
my $safename = DBQuoteSpecial($name);
my $safevalue = DBQuoteSpecial($value);
my $query_result =
DBQueryWarn("insert into experiment_template_metadata_items set ".
" guid='$guid', vers='$version', uid='$creator', ".
" template_guid='$template_guid', ".
" name=$name, value=$value, created=now()");
" name=$safename, value=$safevalue, created=now()");
return -1
if (!$query_result);
......@@ -619,8 +635,22 @@ sub NewMetadata($$$$)
" parent_vers='$template_vers', ".
" metadata_guid='$guid', ".
" metadata_vers='$version', ".
" metadata_type=$metadata_type, ".
" internal=$internal")
or return -1;
# Some metadata is special ...
if (defined($type)) {
if ($type eq "parameter_description") {
$query_result =
DBQueryWarn("update experiment_template_parameters set ".
" metadata_guid='$guid', ".
" metadata_vers='$version' ".
"where name=$safename");
return -1
if (!$query_result);
}
}
return 0;
}
......@@ -628,9 +658,9 @@ sub NewMetadata($$$$)
#
# Lookup a metadata value by name, optionally returning guid/vers.
#
sub LookupMetadata($$;$$)
sub LookupMetadata($$;$$$)
{
my ($self, $name, $pguid, $pvers) = @_;
my ($self, $name, $pguid, $pvers, $ptype) = @_;
# Must be a real reference.
return -1
......@@ -642,7 +672,7 @@ sub LookupMetadata($$;$$)
$name = DBQuoteSpecial($name);
my $query_result =
DBQueryWarn("select metadata_guid,metadata_vers ".
DBQueryWarn("select metadata_guid,metadata_vers,metadata_type ".
" from experiment_template_metadata as m ".
"left join experiment_template_metadata_items as i on ".
" m.metadata_guid=i.guid and m.metadata_vers=i.vers ".
......@@ -655,11 +685,14 @@ sub LookupMetadata($$;$$)
return 0
if (!$query_result->numrows);
my ($metadata_guid, $metadata_vers) = $query_result->fetchrow_array();
my ($metadata_guid, $metadata_vers, $metadata_type) =
$query_result->fetchrow_array();
$$pguid = $metadata_guid
if (defined($pguid));
$$pvers = $metadata_vers
if (defined($pvers));
$$ptype = $metadata_type
if (defined($ptype));
return 1;
}
......@@ -681,8 +714,10 @@ sub ModifyMetadata($$$$)
my $template_vers = $self->vers();
my $parent_guid;
my $parent_vers;
my $metadata_type;
my $already_exists =
$self->LookupMetadata($name, \$parent_guid, \$parent_vers);
$self->LookupMetadata($name,
\$parent_guid, \$parent_vers, \$metadata_type);
return -1
if ($already_exists <= 0);
......@@ -729,17 +764,32 @@ sub ModifyMetadata($$$$)
#
# XXX Some metadata is special ...
#
if ($name eq "'TID'") {
DBQueryWarn("update experiment_templates set tid=$value ".
"where guid='$template_guid' and ".
" vers='$template_vers'");
Refresh($self);
}
elsif ($name eq "'description'") {
DBQueryWarn("update experiment_templates set description=$value ".
"where guid='$template_guid' and ".
" vers='$template_vers'");
Refresh($self);
if (defined($metadata_type)) {
if ($metadata_type eq "tid") {
DBQueryWarn("update experiment_templates set tid=$value ".
"where guid='$template_guid' and ".
" vers='$template_vers'")
or return -1;
Refresh($self);
# This can fail; it is not critical.
system("$makegraph $template_guid");
}
elsif ($metadata_type eq "template_description") {
DBQueryWarn("update experiment_templates set description=$value ".
"where guid='$template_guid' and ".
" vers='$template_vers'")
or return -1;
Refresh($self);
}
elsif ($metadata_type eq "parameter_description") {
DBQueryWarn("update experiment_template_parameters set ".
" metadata_guid='$parent_guid', ".
" metadata_vers='$metadata_vers' ".
"where name=$name")
or return -1
}
}
return 0;
}
......@@ -778,9 +828,9 @@ sub NewFormalParameter($$$)
}
#
# Delete all template metadata; thats all we need here at the moment
# Delete (all) template metadata
#
sub DeleteMetadata($)
sub DeleteAllMetadata($)
{
my ($self) = @_;
......@@ -835,42 +885,111 @@ sub DeleteMetadata($)
return 0;
}
#
# Delete a specific template metadata item from the template, but we leave
# actual items behind.
#
sub DeleteMetadata($$)
{
my ($self, $name) = @_;
# Must be a real reference.
return -1
if (! ref($self));
my $template_guid = $self->guid();
my $template_vers = $self->vers();
$name = DBQuoteSpecial($name);
my $query_result =
DBQueryWarn("select metadata_guid,metadata_vers ".
" from experiment_template_metadata as m ".
"left join experiment_template_metadata_items as i on ".
" m.metadata_guid=i.guid and m.metadata_vers=i.vers ".
"where m.parent_guid='$template_guid' and ".
" m.parent_vers='$template_vers' and ".
" i.name=$name");
return -1
if (!$query_result);
return -1
if (!$query_result->numrows);
my ($metadata_guid, $metadata_vers) = $query_result->fetchrow_array();
DBQueryWarn("update experiment_template_metadata set hidden=1 ".
"where parent_guid='$template_guid' and ".
" parent_vers='$template_vers' and ".
" metadata_guid='$metadata_guid' and ".
" metadata_vers='$metadata_vers'")
or return -1;
return 0;
}
#
# Copy exiting template metadata to a child. This is likely to change
# since we probably want to share at some point.
#
sub CopyMetadata($$$)
{
my ($self, $target, $copier) = @_;
my ($self, $parent, $copier) = @_;
# Must be a real reference.
return -1
if (! (ref($self) && ref($target)));
if (! (ref($self) && ref($parent)));
my $from_guid = $self->guid();
my $from_vers = $self->vers();
my $to_vers = $target->vers();
my $from_guid = $parent->guid();
my $from_vers = $parent->vers();
my $to_vers = $self->vers();
#
# Copy the toplevel items.
#
my $query_result =
DBQueryWarn("select name,value ".
DBQueryWarn("select name,value,metadata_type,internal ".
" from experiment_template_metadata as m ".
"left join experiment_template_metadata_items as i on ".
" i.guid=m.metadata_guid and ".
" i.vers=m.metadata_vers ".
"where m.parent_guid='$from_guid' and ".
" m.parent_vers='$from_vers' and m.internal=0")
" m.parent_vers='$from_vers'")
or return -1;
while (my ($name, $value) = $query_result->fetchrow_array()) {
while (my ($name,$value,$type,$internal) =
$query_result->fetchrow_array()) {
my $guid;
my $version = 1;
my $metadata_type = "NULL";
$name = DBQuoteSpecial($name);
$value = DBQuoteSpecial($value);
#
# XXX Some metadata is special ...
#
if (defined($type)) {
# XXX Skip the tid and template descriptions.
next
if ($type eq "tid" or $type eq "template_description");
# XXX Skip parameters that were deleted.
if ($type eq "parameter_description") {
my $param_result =
DBQueryWarn("select * ".
" from experiment_template_parameters ".
"where name=$name");
return -1
if (!$param_result);
next
if (!$param_result->numrows);
}
$metadata_type = "'$type'";
}
return -1
if (NewGUID(\$guid) < 0);
......@@ -879,7 +998,8 @@ sub CopyMetadata($$$)
" parent_vers='$to_vers', ".
" metadata_guid='$guid', ".
" metadata_vers='$version', ".
" internal=0")
" metadata_type=$metadata_type, ".
" internal=$internal")
or return -1;
DBQueryWarn("insert into experiment_template_metadata_items set ".
......@@ -887,8 +1007,20 @@ sub CopyMetadata($$$)
" template_guid='$from_guid', ".
" name=$name, value=$value, created=now()")
or return -1;
}
#
# XXX Some metadata is special ...
#
if (defined($type)) {
if ($type eq "parameter_description") {
DBQueryWarn("update experiment_template_parameters set ".
" metadata_guid='$guid', ".
" metadata_vers='$version' ".
"where name=$name")
or return -1
}
}
}
return 0;
}
......
......@@ -207,23 +207,16 @@ $justexit = 0;
#
# The description is versioned metadata the user can modify.
#
$template->NewMetadata("description", $description, $dbuid) == 0
$template->NewMetadata("description", $description,
$dbuid, "template_description") == 0
or fatal(-1, "Failed to insert metadata record for description");
#
# The TID is versioned metadata the user can modify.
#
$template->NewMetadata("TID", $tid, $dbuid) == 0
$template->NewMetadata("TID", $tid, $dbuid, "tid") == 0
or fatal(-1, "Failed to insert metadata record for description");
#
# Copy the rest of the metadata from parent to child
#
if ($modify) {
$template->CopyMetadata($parent_template, $dbuid) == 0
or fatal(-1, "Failed to copy metadata records");
}
# Grab stuff we need out of the template.
$guid = $template->guid();
$vers = $template->vers();
......@@ -297,7 +290,16 @@ while (my ($name, $value) = $query_result->fetchrow_array()) {
$template->NewFormalParameter($name, $value) == 0
or fatal(-1, "Could not set formal parameter for $pid/$eid")
}
#
# Copy the rest of the metadata from parent to child.
# XXX This has to be done after the previous step (virt_parameters)
#
if ($modify) {
$template->CopyMetadata($parent_template, $dbuid) == 0
or fatal(-1, "Failed to copy metadata records");
}
#
# Generate the graph for the template.
#
......
......@@ -153,7 +153,7 @@ $template->Children(\@children) == 0
or tbdie("Could not construct list of child templates for $guid/$version");
if ($recursive) {
@templates = @children;
@templates = (@children, $template);
}
else {
tbdie("Cannot delete template $template cause it has children @children")
......
......@@ -287,6 +287,7 @@ my $imapdata = `cat $imapfile`;
# Massage the mapfile; tooltips --> onmouseovers
#
$imapdata =~ s/title=/onmouseover=/g;
$imapdata =~ s/version=(\d*)\"/version=$1\" id=Tarea${1}/g;
#print "$imapdata\n";
......
......@@ -23,22 +23,24 @@ use Getopt::Std;
sub usage()
{
print(STDERR
"Usage: template_metadata -a <action> -f <file> ".
"Usage: template_metadata -a <action> -f <file> [-t type] ".
"<name> <guid/vers>\n".
"switches and arguments:\n".
"-a <action> - add or modify\n".
"-a <action> - add, delete or modify\n".
"-t <type> - type if not generic user metadata (add only)\n".
"-f <file> - file of metadata value\n".
"<name> - Metadata name\n".
"<guid/vers> - GUID and version of template\n");
exit(-1);
}
my $optlist = "a:f:";
my $optlist = "a:f:t:";
my %options = ();
my $action;
my $template_guid;
my $template_vers;
my $metadata_name;
my $metadata_value;
my $metadata_type;
my $inputfile;
#
......@@ -108,23 +110,33 @@ if (! TBProjAccessCheck($dbuid,
exit(1);
}
$metadata_value = `cat $inputfile`;
if ($action ne "delete") {
$metadata_value = `cat $inputfile`;
if (! TBcheck_dbslot($metadata_value,
"experiment_template_metadata", "value",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper characters in metadata value!");
if (! TBcheck_dbslot($metadata_value,
"experiment_template_metadata", "value",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper characters in metadata value!");
}
}
my $already_exists = $template->LookupMetadata($metadata_name);
tbdie("Could not lookup metadata name '$metadata_name'")
if ($already_exists < 0);
if ($action eq "add") {
if ($action eq "delete") {
tbdie("Metadata name '$metadata_name' does not exist!")
if (!$already_exists);
$template->DeleteMetadata($metadata_name, $dbuid) == 0
or tbdie("Could not delete metadata item '$metadata_name'");
}
elsif ($action eq "add") {
tbdie("Metadata name '$metadata_name' already in use!")
if ($already_exists);
$template->NewMetadata($metadata_name, $metadata_value, $dbuid) == 0
$template->NewMetadata($metadata_name, $metadata_value,
$dbuid, $metadata_type) == 0
or tbdie("Could not add new metadata item '$metadata_name'");
}
else {
......@@ -181,7 +193,17 @@ sub ParseArgs()
}
$action = $options{"a"};
usage()
if ($action ne "add" && $action ne "modify");
if ($action ne "add" && $action ne "modify" && $action ne "delete");
if (defined($options{"t"})) {
$metadata_type = $options{"t"};
if (! TBcheck_dbslot($metadata_type,
"experiment_template_metadata", "metadata_type",
TBDB_CHECKDBSLOT_WARN|TBDB_CHECKDBSLOT_ERROR)) {
tbdie("Improper metadata type!");
}
}
if (defined($options{"f"})) {
$inputfile = $options{"f"};
......@@ -227,7 +249,7 @@ sub ParseArgs()
exit(1);
}
}
else {
elsif ($action ne "delete") {
usage();
}
}
......
......@@ -174,10 +174,6 @@ class Template
$created = $this->created();
$description = $this->description();
if (strlen($description) > 40) {
$description = substr($description, 0, 40) . " <b>... </b>";
}
#
# We need the metadata guid/version for the TID and description since
# they are mungable metadata.
......@@ -220,10 +216,15 @@ class Template
ShowItem("Creator", MakeLink("user", "target_uid=$uid", $uid));
ShowItem("Created", $created);
$onmouseover = MakeMouseOver($description);
if (strlen($description) > 40) {
$description = substr($description, 0, 40) . " <b>... </b>";
}
ShowItem("Description",
MakeLink("metadata",
"action=modify&guid=$guid&version=$vers".
"&metadata_guid=$desc_guid&metadata_vers=$desc_vers",
"&metadata_guid=$desc_guid&metadata_vers=$desc_vers".
" $onmouseover",
$description));
if (! $this->IsRoot()) {
......@@ -246,11 +247,16 @@ class Template
$vers = $this->vers();
$query_result =
DBQueryFatal("select name,value ".
" from experiment_template_parameters ".
"where parent_guid='$guid' and ".
" parent_vers='$vers'");
DBQueryFatal("select p.name,p.value, ".
" p.metadata_guid,p.metadata_vers, ".
" m.value as description ".
" from experiment_template_parameters as p ".
"left join experiment_template_metadata_items as m ".
" on m.guid=p.metadata_guid and ".
" m.vers=p.metadata_vers ".
"where p.parent_guid='$guid' and ".
" p.parent_vers='$vers'");
if (!$query_result ||
!mysql_num_rows($query_result))
return 0;
......@@ -263,24 +269,48 @@ class Template
echo "<tr>
<th>Name</th>
<th>Default Value</th>
<th>Description</th>
</tr>\n";
while ($row = mysql_fetch_array($query_result)) {
$name = $row['name'];
$value = $row['value'];
$name = $row['name'];
$value = $row['value'];
$metadata_guid = $row['metadata_guid'];
$metadata_vers = $row['metadata_vers'];
$description = $row['description'];
if (!isset($value)) {
$value = "&nbsp";
}
echo "<tr>
<td>$name</td>
<td>$value</td>
</tr>\n";
}
<td>$value</td>";
if (is_null($description)) {
echo "<td>".
"<a href=template_metadata.php?action=add&".
"guid=$guid&version=$vers&type=parameter_description&".
"formfields[name]=${name}>Click to add</a></td>\n";
}
else {
$onmouseover = MakeMouseOver($description);
if (strlen($description) > 30) {
$description =
substr($description, 0, 30) . " <b>... </b>";
}
echo "<td><a href='template_metadata.php?action=modify".
"&guid=$guid&version=$vers".
"&metadata_guid=$metadata_guid".
"&metadata_vers=$metadata_vers' $onmouseover>".
"$description</a></td>\n";
}
echo "</tr>\n";
}
echo "</table>\n";
return 1;
}
#
# Display template metadata and values in a table
#
......@@ -293,7 +323,8 @@ class Template
"left join experiment_template_metadata_items as i on ".
" m.metadata_guid=i.guid and m.metadata_vers=i.vers ".
"where m.parent_guid='$guid' and ".
" m.parent_vers='$vers' and m.internal=0");
" m.parent_vers='$vers' and ".
" m.internal=0 and m.hidden=0");
if (! mysql_num_rows($query_result))
return 0;
......@@ -305,6 +336,7 @@ class Template
echo "<tr>
<th>Edit</th>
<th>Delete</th>
<th>Name</th>
<th>Value</th>
</tr>\n";
......@@ -314,11 +346,17 @@ class Template
$value = $row['value'];
$metadata_guid = $row['guid'];
$metadata_vers = $row['vers'];
if (!isset($value)) {
$onmouseover = "";
if (!isset($value) || $value == "") {
$value = "&nbsp";
}
elseif (strlen($value) > 40) {
$value = substr($value, 0, 40) . " <b>... </b>";
else {
$onmouseover = MakeMouseOver($value);
if (strlen($value) > 40) {
$value = substr($value, 0, 40) . "<b> ... </b></a>";
}
}
echo "<tr>
......@@ -328,13 +366,14 @@ class Template
"&metadata_guid=$metadata_guid".
"&metadata_vers=$metadata_vers'>
<img border=0 alt='modify' src='greenball.gif'></A></td>
<td align=center>
<a href='template_metadata.php?action=delete".
"&guid=$guid&version=$vers".
"&metadata_guid=$metadata_guid".
"&metadata_vers=$metadata_vers'>
<img border=0 alt='delete' src='redball.gif'></A></td>
<td>$name</td>
<td>
<a href='template_metadata.php?action=modify".
"&guid=$guid&version=$vers".
"&metadata_guid=$metadata_guid".
"&metadata_vers=$metadata_vers'>
$value</a></td>
<td $onmouseover>$value</td>
</tr>\n";
}
echo "</table>\n";
......@@ -515,6 +554,7 @@ class Template
#
function ShowGraph() {