Author: arkurth
Date: Mon Oct  5 15:25:33 2009
New Revision: 821841

URL: http://svn.apache.org/viewvc?rev=821841&view=rev
Log:
VCL-184
Reworked the get_variable() and set_variable() subroutines in DataStructure.pm 
to handle the serialization column.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=821841&r1=821840&r2=821841&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Mon Oct  5 
15:25:33 2009
@@ -694,7 +694,7 @@
                # Make sure the value was set in the hash
                my $check_value = eval $hash_path;
                if ($check_value eq $set_data) {
-                       notify($ERRORS{'DEBUG'}, 0, "data structure updated: 
$data_identifier = $set_data");
+                       notify($ERRORS{'DEBUG'}, 0, "data structure updated: 
$hash_path\n$data_identifier = $set_data");
                        return sub {1;};
                }
                else {
@@ -1501,18 +1501,22 @@
 
 =head2 get_variable
 
- Parameters  : $variable_name
- Returns     : If successful: reference to the data stored in the variable 
table for
-                              the variable name specified
+ Parameters  : variable name
+ Returns     : If successful: data stored in the variable table for the 
variable name specified
                If failed: false
- Description : Queries the variable table for the variable with the name 
specified by the subroutine argument.
-               Returns a reference to the data.
+ Description : Queries the variable table for the variable with the name
+                                       specified by the argument. Returns the 
data stored for the
+                                       variable. Values are deserialized 
before being returned if the
+                                       value stored was a reference.
+                                       
+                                       Undefined is returned if the variable 
name does not exist in the
+                                       variable table.
 
 =cut
 
 sub get_variable {
        my $self = shift;
-       my $name = shift;
+       my $variable_name = shift;
        
        # Check if subroutine was called as an object method
        unless (ref($self) && $self->isa('VCL::DataStructure')) {
@@ -1521,7 +1525,7 @@
        }
        
        # Check the arguments
-       if (!defined($name)) {
+       if (!defined($variable_name)) {
                notify($ERRORS{'WARNING'}, 0, "variable name argument was not 
supplied");
                return;
        }
@@ -1529,50 +1533,66 @@
        # Construct the select statement
 my $select_statement .= <<"EOF";
 SELECT
-variable.value
+variable.value,
+variable.serialization
 FROM
 variable
 WHERE
-variable.name = '$name'
+variable.name = '$variable_name'
 EOF
        
        # Call the database select subroutine
        my @selected_rows = database_select($select_statement);
 
        # Check to make 1 sure row was returned
-       if (!...@selected_rows) {
-               notify($ERRORS{'WARNING'}, 0, "unable to execute select 
statement to retrieve variable '$name' from the database");
-               return;
-       }
-       elsif (@selected_rows == 0){
-               notify($ERRORS{'WARNING'}, 0, "variable '$name' does not exist 
in the database");
+       if (!...@selected_rows){
+               notify($ERRORS{'WARNING'}, 0, "unable to get value of variable 
'$variable_name', it does not exist in the database");
                return;
        }
        elsif (@selected_rows > 1){
-               notify($ERRORS{'WARNING'}, 0, "multiple rows exist in the 
database for variable '$name':\n" . format_data(\...@selected_rows));
+               notify($ERRORS{'WARNING'}, 0, "unable to get value of variable 
'$variable_name', multiple rows exist in the database for variable:\n" . 
format_data(\...@selected_rows));
                return;
        }
        
        # Get the serialized value from the variable row
-       my $serialized_value = $selected_rows[0]{value};
-       
-       # Attempt to deserialize the value
-       # Use eval because Load() will call die() if it encounters an error
+       my $serialization_type = $selected_rows[0]{serialization};
+       my $database_value = $selected_rows[0]{value};
        my $deserialized_value;
-       eval '$deserialized_value = YAML::Load($serialized_value)';
-       if ($EVAL_ERROR) {
-               notify($ERRORS{'WARNING'}, 0, "unable to deserialize the value 
using YAML::Load(): $serialized_value");
-               return;
-       }
        
-       # Display the data type of the value retrieved from the variable table
-       if (my $deserialized_data_type = ref($deserialized_value)) {
-               notify($ERRORS{'DEBUG'}, 0, "returning $deserialized_data_type 
reference");
+       # Deserialize the variable value if necessary
+       if ($serialization_type eq 'none') {
+               $deserialized_value = $database_value;
+       }
+       elsif ($serialization_type eq 'yaml') {
+               # Attempt to deserialize the value
+               # Use eval because Load() will call die() if it encounters an 
error
+               eval '$deserialized_value = YAML::Load($database_value)';
+               if ($EVAL_ERROR) {
+                       notify($ERRORS{'WARNING'}, 0, "unable to get value of 
variable '$variable_name', unable to deserialize value using YAML::Load(): 
$database_value");
+                       return;
+               }
+               
+               # Display the data type of the value retrieved from the 
variable table
+               if (my $deserialized_data_type = ref($deserialized_value)) {
+                       notify($ERRORS{'DEBUG'}, 0, "data type of variable 
'$variable_name': $deserialized_data_type reference");
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "data type of variable 
'$variable_name': scalar");
+               }
+       }
+       elsif ($serialization_type eq 'phpserialize') {
+               # TODO: find Perl module to handle PHP serialized data
+               # Add module to list of dependencies
+               # Add code here to call PHP deserialize function
+               notify($ERRORS{'CRITICAL'}, 0, "unable to get value of variable 
'$variable_name', PHP serialized data is NOT supported yet by the VCL backend, 
returning null");
+               return;
        }
        else {
-               notify($ERRORS{'DEBUG'}, 0, "returning scalar 
($deserialized_value)");
+               notify($ERRORS{'CRITICAL'}, 0, "unable to get value of variable 
'$variable_name', serialization type '$serialization_type' is NOT supported by 
the VCL backend, returning null");
+               return;
        }
        
+       notify($ERRORS{'DEBUG'}, 0, "retrieved variable '$variable_name', 
serialization: $serialization_type");
        return $deserialized_value;
 }
 
@@ -1580,20 +1600,33 @@
 
 =head2 set_variable
 
- Parameters  : $variable_name, $variable_value
+ Parameters  : variable name, variable value
  Returns     : If successful: true
                If failed: false
- Description : Inserts or updates a row in the variable table. This subroutine
-               will also update the variable.timestamp column. The
-               variable.setby column is automatically set to the filename and
-               line number which called this subroutine.
+ Description : Inserts or updates a row in the variable table. The variable 
name
+               and value arguments must be specified.
+               
+               The value can be a simple scalar such as a string or a reference
+               to a complex data structure such as an array of hashes.
+               
+               Simple scalar values are stored in the variable.value column
+               as-is and the variable.serialization column will be set to
+               'none'.
+               
+               References are serialized using YAML before being stored. The
+               variable.value column will contain the YAML representation of 
the
+               data and the variable.serialization column will be set to 
'yaml'.
+               
+               This subroutine will also update the variable.timestamp column.
+               The variable.setby column is automatically set to the filename
+               and line number which called this subroutine.
 
 =cut
 
 sub set_variable {
        my $self = shift;
-       my $name_argument = shift;
-       my $value_argument = shift;
+       my $variable_name = shift;
+       my $variable_value = shift;
        
        # Check if subroutine was called as an object method
        unless (ref($self) && $self->isa('VCL::DataStructure')) {
@@ -1602,52 +1635,72 @@
        }
        
        # Check the arguments
-       if (!defined($name_argument)) {
+       if (!defined($variable_name)) {
                notify($ERRORS{'WARNING'}, 0, "variable name argument was not 
supplied");
                return;
        }
-       elsif (!defined($value_argument)) {
+       elsif (!defined($variable_value)) {
                notify($ERRORS{'WARNING'}, 0, "variable value argument was not 
supplied");
                return;
        }
        
+       # Set serialization type to yaml if the value being stored is a 
reference
+       # Otherwise, a simple scalar is being stored and serialization is not 
necessary
+       my $serialization_type;
+       if (ref($variable_value)) {
+               $serialization_type = 'yaml';
+       }
+       else {
+               $serialization_type = 'none';
+       }
+       
        # Construct a string indicating where the variable was set from
        my @caller = caller(0);
        (my $calling_file) = $caller[1] =~ /([^\/]*)$/;
        my $calling_line = $caller[2];
        my $caller_string = "$calling_file:$calling_line";
        
-       # Attempt to serialize the value using YAML::Dump()
-       # Use eval because Dump() will call die() if it encounters an error
-       my $serialized_value;
-       eval '$serialized_value = YAML::Dump($value_argument)';
-       if ($EVAL_ERROR) {
-               notify($ERRORS{'WARNING'}, 0, "unable to serialize the value 
using YAML::Dump(): $value_argument");
-               return;
+       # Attempt to serialize the value if necessary
+       my $database_value;
+       if ($serialization_type eq 'none') {
+               $database_value = $variable_value;
        }
-
+       else {
+               # Attempt to serialize the value using YAML::Dump()
+               # Use eval because Dump() will call die() if it encounters an 
error
+               
+               eval '$database_value = YAML::Dump($variable_value)';
+               if ($EVAL_ERROR) {
+                       notify($ERRORS{'WARNING'}, 0, "unable to serialize 
variable '$variable_name' using YAML::Dump(), value: $variable_value");
+                       return;
+               }
+       }
+       
        # Escape all single quote characters with a backslash
        #   or else the SQL statement will fail becuase it is wrapped in single 
quotes
-       $serialized_value =~ s/'/\\'/g;;
+       $database_value =~ s/'/\\'/g;;
        
        # Assemble an insert statement, if the variable already exists, update 
the existing row
        my $insert_statement .= <<"EOF";
 INSERT INTO variable
 (
 name,
+serialization,
 value,
 setby,
 timestamp
 )
 VALUES
 (
-'$name_argument',
-'$serialized_value',
+'$variable_name',
+'$serialization_type',
+'$database_value',
 '$caller_string',
 NOW()
 )
 ON DUPLICATE KEY UPDATE
 name=VALUES(name),
+serialization=VALUES(serialization),
 value=VALUES(value),
 setby=VALUES(setby),
 timestamp=VALUES(timestamp)
@@ -1656,10 +1709,10 @@
        # Execute the insert statement, the return value should be the id of 
the row
        my $inserted_id = database_execute($insert_statement);
        if ($inserted_id) {
-               notify($ERRORS{'OK'}, 0, "set variable '$name_argument', id: 
$inserted_id");
+               notify($ERRORS{'OK'}, 0, "set variable '$variable_name', 
variable id: $inserted_id, serialization: $serialization_type");
        }
        else {
-               notify($ERRORS{'WARNING'}, 0, "failed to set variable 
'$name_argument'");
+               notify($ERRORS{'WARNING'}, 0, "failed to set variable 
'$variable_name', serialization: $serialization_type");
                return;
        }
        


Reply via email to