#! /usr/bin/perl
########################################################################
# (c) Copyright IBM Corp. 2009 All rights reserved.
#
# The following sample of source code ("Sample") is owned by International
# Business Machines Corporation or one of its subsidiaries ("IBM") and is
# copyrighted and licensed, not sold. You may use, copy, modify, and
# distribute the Sample in any form without payment to IBM, for the purpose of
# assisting you in the development of your applications.
#
# The Sample code is provided to you on an "AS IS" basis, without warranty of
# any kind. IBM HEREBY EXPRESSLY DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR
# IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Some jurisdictions do
# not allow for the exclusion or limitation of implied warranties, so the above
# limitations or exclusions may not apply to you. IBM shall not be liable for
# any damages you suffer as a result of using, copying, modifying or
# distributing the Sample, even if IBM has been advised of the possibility of
# such damages.
#########################################################################
#
# SOURCE FILE NAME: qpwlmmig.pl
#
# TITLE: Generate a QP to WLM Migration script
#
# PURPOSE: Generates a script that will help migrate a QP environment to
#          a WLM environment.            
#
# DETAILS: This tool reads the DB2 Query Patroller tables and, based   
#          on information from those tables, will generate a script that 
#          will contain the DDL required to create a comparable WLM setup.
#          It will also generate a second script file containing the DDL
#          to undo the changes in the first script.
#
# EXECUTION: qpwlmmig.pl dbAlias userId passwd outputFile
#
# INPUTS: dbAlias    - Database Alias
#         userId     - User Id (optional)
#         passwd     - Password (optional)
#         outputFile - The name of the file that will be generated by this 
#                      script.
#
# OUTPUT FILES: The file <outputFile> containing WLM DDL that will help the 
#               existing QP user set up their WLM environment.  This
#               generated file can be run using the following command:
#
#               db2 -tf <outputFile>
#
#               A second file <outFile>.DROP containing WLM DDL that will
#               undo the changes from the <outputFile> script.  This generated
#               file can be run using the following command:
#
#               db2 -tf <outputFile>.DROP
#
# PREREQUISITES: 
#               - The privileges held by the authorization ID of the user
#                 who runs this script must include DBADM
#               - The privileges held by the authorization ID of the user 
#                 who runs the generated script <outputFile> must include
#                 DBADM or WLMADM
#               - The user who runs this cript must have write permission
#                 on the directory where the generated script <outputFile>
#                 is to be written.
#               - This script has a dependency on the DB2WlmHist.pm file.
#                 If the user who runs this script first choses to copy
#                 this file to a different location before running it,
#                 he/she must also copy the DB2WlmHist.pm file to that
#                 same location
#
##########################################################################

select STDERR; $|=1;
select STDOUT; $|=1;

use strict;
use warnings; 
use DBI;
use Data::Dumper;

# access the module for historical common functions 
#----------------------------------------------------
use DB2WlmHist;

# For Format
use FileHandle;
use English;

# declare return code, statement handler, database handler and local variable
#----------------------------------------------------------------------------
my ($rc, $sth, $dbh, $valueYes, $valueNo, $typeUser, $typeGroup, $publicSubmitter, $defaultUserWorkload, $db2v95, $db2v97, $superclassName, $unmanagedSubclass, $dblevel, $originalMaxTotalQueries);

# defines for different values
#-----------------------------  
$valueYes = "Y";
$valueNo = "N";
$typeUser = "U";
$typeGroup = "G"; 
$publicSubmitter = "PUBLIC";
$defaultUserWorkload = "DEFAULTUSERWORKLOAD";
$db2v95 = "DB2V95";
$db2v97 = "DB2V97";
$superclassName = "MAIN_SC";
$unmanagedSubclass = "UNMANAGED_SSC";
$originalMaxTotalQueries = -1;

# In QP, the max_queries_allowed can be set to -1 which
# means unlimited.  The WLM thresholds don't have "unlimited" 
# values so if QP has a max_queries_allowed value set to -1
# the resultant WLM threshold will be set to a really large value 
# as is defined below and then that WLM threshold will be commented out.  
# Also, in QP, the max_cost_allowed can also
# be set to -1.  In that case, the associated work class will be
# set to a really high cost value and then that threshold will be 
# commented out.
# ---------------------------------------------------------------------
my $unlimitedMaxQueries = -1;
my $unlimitedThresholdQueries = 100000;
my $unlimitedMaxCost = -1;
my $unlimitedWLMCost = 10000000000;

# Variables required for the drop script
#-----------------------------------------

# array of thresholds
#---------------------
my @thresholds;    
my $thresholdIndex = 0;
my @commentedThresholds;
my $commentedThresholdIndex = 0;

# array of workloads
#-------------------
my @workloads;
my $workloadIndex = 0;


# array of service classes
#-------------------------
my @serviceClasses;
my $serviceClassIndex = 0;

# check and parse the command line arguments
# call the subroutine WLMArgChk to verify the arguments passed in.
#------------------------------------------------------------------
my ($database, $user, $password, $outFile) = QPWLMArgChk(@ARGV);

# extract the database name.  It current shows up as dbi:DB2:databasename
#------------------------------------------------------------------------
my ($databaseText, $db2Version, @arr);
@arr = split(':', $database);
$databaseText= $arr[2];


print "\n  Generate qptowlm.ddl script for database $databaseText .\n";

# connect to the database
#------------------------
print "\n  Connecting to database...\n";

if ($password eq "-" or $user eq "-")
{
  $dbh = DBI->connect($database, "", "", {AutoCommit => 0})
              or die "Can't connect to $database: $DBI::errstr";
}
else 
{
  $dbh = DBI->connect($database, $user, $password, {AutoCommit => 0})
              or die "Can't connect to $database: $DBI::errstr";
}

print "\n  Connected to database $database.\n";

# Get the level of DB2 we are currently on
#-----------------------------------------
open(FILEHANDLE, "db2level |");
$dblevel=<FILEHANDLE>;
close(FILEHANDLE);
if ($dblevel =~ m/SQL0907/i)
{
  $db2Version = $db2v97;
}
elsif ($dblevel =~ m/SQL0905/i)
{
  $db2Version = $db2v95;
} 
else
{
  die "DB version is neither DB2V95 or DB2V97";
}

# Call the subroutine MainScriptGen to generate the DDL script. 
#---------------------------------------------------------------
$rc = 0;
$rc = MainScriptGen();
if (!defined $rc)
{
  die "\nSomething went wrong with generating the WLM DDL script\n";
}
else
{
   # Print message indicating that the script was generated
   #-------------------------------------------------------
   print "\n  $outFile", " and ",$outFile, ".DROP have been successfully generated. \n";
}

# Disconnect from the database
#-------------------------------
print "\n  Disconnecting from database...\n";
$dbh->disconnect
  or die $DBI::errstr;
print "\n  Disconnected from database.\n";


##########################################################################
# Description : Checks and parses the command line arguments
# Input       : An array containing the command line arguments that was 
#               passed to the calling function
# Output      : Database name, user name, password, outputfile
###########################################################################
sub QPWLMArgChk
{
  my $arg_c = @_; # number of arguments passed to the function
  my @arg_l; # arg_l holds the values to be returned to calling function

  if($arg_c > 4 or $arg_c < 4 or ($arg_c == 1 and (($_[0] eq "?") or
                                  ($_[0] eq "-?") or
                                  ($_[0] eq "/?") or
                                  ($_[0] eq "-h") or
                                  ($_[0] eq "/h") or
                                  ($_[0] eq "-help") or
                                  ($_[0] eq "/help"))) or
      ($arg_c == 4 and ($_[0] eq "-" or  $_[3] eq "-" )))

  {
    die << "EOT";
Usage: 
 qpwlmmig.pl dbAlias userId passwd outputFile 


EOT
  }   

  # Set the database, user, password arguments
  #-------------------------------------------
  $arg_l[0] = "dbi:DB2:".$_[0];
  $arg_l[1] = $_[1];
  $arg_l[2] = $_[2];
  $arg_l[3] = $_[3];

  return @arg_l;
} # WLM ArgChk

#######################################################################
# Description : Main subroutine for generating the output DDL script.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub MainScriptGen
{


  # Print out the initial header for the script.                             
  #-------------------------------------------------------------------------
  open FILE, ">$outFile" or die "\n Unable to open file $outFile\n";
  print FILE "\n-----------------------------------------------------------";
  print FILE "\n-- Generated script for Query Patroller (QP) to            ";
  print FILE "\n-- DB2 workload manager (WLM) migration                    ";
  print FILE "\n--                                                         ";
  print FILE "\n-- Description:                                            ";
  print FILE "\n--                                                         ";
  print FILE "\n--   This generated script contains the DDL to create the  ";
  print FILE "\n--   WLM objects that best match your current DB2 Query    ";
  print FILE "\n--   Patroller setup.  As much as possible, it follows     ";
  print FILE "\n--   the Best Practices white paper for DB2 Workload       ";
  print FILE "\n--   Management that can be found at the following location";
  print FILE "\n--                                                         ";
  print FILE "\n--  http:\/\/download.boulder.ibm.com\/ibmdl\/pub\/software\/  ";
  print FILE "\n--     dw\/dm\/db2\/bestpractices\/                            ";
  print FILE "\n--     DB2BP_Workload_Management_1008I.pdf                 ";
  print FILE "\n--                                                         ";
  print FILE "\n--   Before running this script, you should become familiar";
  print FILE "\n--   with the best practices outlined in this white paper. ";
  print FILE "\n--                                                         ";
  print FILE "\n--   You should look through this script to confirm        ";
  print FILE "\n--   that the objects being created are the ones you       ";
  print FILE "\n--   really want and that they are named appropriately.    ";
  print FILE "\n--   If you decide to change the names of any of the       ";
  print FILE "\n--   objects in this script, you should also change the    ";
  print FILE "\n--   appropriate DDL in the DROP<filename> script          ";
  print FILE "\n--                                                         ";
  print FILE "\n--                                                         ";
  print FILE "\n-- Notes:                                                  ";
  print FILE "\n--                                                         ";
  print FILE "\n--  This script does not take into consideration any       ";
  print FILE "\n--  DB2 governor configuration settings.  If you are       ";
  print FILE "\n--  currently running the DB2 Governor, you need to        ";
  print FILE "\n--  configure similar controls using DB2 workload          ";
  print FILE "\n--  manager functionality separately.  For more            ";
  print FILE "\n--  information, refer to the Best Practices white         ";
  print FILE "\n--  paper.                                                 ";
  print FILE "\n--                                                         ";
  print FILE "\n--  This script contains DDL that will create WLM objects  ";
  print FILE "\n--  that are set up to collect either activity or aggregate";
  print FILE "\n--  information.  In order to capture this information,    ";
  print FILE "\n--  create WLM event monitors using the wlmevmon.ddl script";
  print FILE "\n--  in the sqllib/misc directory.                          ";
  print FILE "\n--                                                         ";
  print FILE "\n--                                                         ";
  print FILE "\n-- Before running this script:                             ";
  print FILE "\n--                                                         ";
  print FILE "\n--   - connect to the database:                            ";
  print FILE "\n--       db2 connect to <database>                         ";
  print FILE "\n--                                                         ";
  print FILE "\n--   - the privileges held by the authorization ID of      ";
  print FILE "\n--     user who runs this script must include DBADM or     ";
  print FILE "\n--     WLMADM.                                             ";
  print FILE "\n--                                                         ";
  print FILE "\n-- To run this script, issue the following command:        ";
  print FILE "\n--                                                         ";
  print FILE "\n--          db2 -tf ", $outFile;
  print FILE "\n--                                                         ";
  print FILE "\n-----------------------------------------------------------";
  print FILE "\n";
 
  # Add DDL to set the workload to the SYSDEFAULTADMWORKLOAD 
  # so that the script can run unaffected by any WLM DDL that
  # may be run in the script itself
  #-----------------------------------------------------------
  print FILE "\n-- Set workload to SYSDEFAULTADMWORKLOAD     ";
  print FILE "\n------------------------------------------   ";
  print FILE "\nSET WORKLOAD TO SYSDEFAULTADMWORKLOAD;       ";
  print FILE "\n                                             ";
 

  # Add DDL to create the two main service classes:
  #   - MAIN_SC      -  will eventually contain subclasses for
  #                     each QP query class.  Activities from
  #                     submitter profiles whose queries were managed will
  #                     run in those subclasses.
  #                     It will also contain an "unmanaged" subclass where
  #                     most of the activities bypassed or unmanaged by QP will
  #                     initially run.
  #   - UNMANAGED_SSC - will be created inside the MAIN_SC and will
  #                     have the activities that are bypassed by QP running
  #                     in it.  It will also have all of the non-DML activities 
  #                     running in it.
  #----------------------------------------------------------------------
  print FILE "\n-- Service superclass for managed activities    ";
  print FILE "\n---------------------------------------------   ";
  print FILE "\nCREATE SERVICE CLASS ", $superclassName, ";";
  print FILE "\n                                                ";

  print FILE "\n-- Service subclass for bypassed activities     ";
  print FILE "\n---------------------------------------------   ";
  print FILE "\nCREATE SERVICE CLASS ", $unmanagedSubclass, " UNDER ", $superclassName, " COLLECT AGGREGATE ACTIVITY DATA; ";
  print FILE "\n                                                 ";

  # Workloads and thresholds for profiles    
  #----------------------------------------
  AddWorkloadsAndThresholdsForSubmitters();

  # Commented statements for QP system settings for max_total_queries
  #-------------------------------------------------------------------
  AddDBWASForQPSystemMaxTotalQueries();

  # Workloads for QP system settings for bypassed applications
  #-----------------------------------------------------------
  AddWorkloadsForQPSystemBypassedApplications();

  # Workloads for bypassed users
  #-----------------------------
  AddWorkloadsForBypassedUsers();

  # Workloads for bypassed applications
  #------------------------------------
  AddWorkloadsForBypassedApplications();

  # WLM objects for query classes
  #---------------------------------
  AddWlmObjectsForQueryClasses();

  # Work class and work action for bypassed activities based on cost
  #-----------------------------------------------------------------
  AddWorkclassForBypassedDMLOnCost();

  # Work class and work action for all other non-dml activities
  #------------------------------------------------------------
  AddWorkclassForNonDML();

  # Set the workload back to automatic
  #-----------------------------------
  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";
  print FILE "\n\n-- Set workload to automatic    ";
  print FILE "\n-----------------------------   ";
  print FILE "\nSET WORKLOAD TO AUTOMATIC;      ";
  print FILE "\n                                ";
  close(FILE);
 

  # Generate the script file to drop the objects
  #----------------------------------------------
  GenerateDropScript();

  $dbh->commit();
  return 0;
} # MainScriptGen

#######################################################################
# Description : Routine to add CREATE WORKLOAD statements for each
#               QP submitter profile.  Also, add
#               CREATE THRESHOLD statements when appropriate
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkloadsAndThresholdsForSubmitters
{

  # Prepare and execute SQL statement that extracts the submitter profile
  # information
  # 
  # Note: The max_cost_allowed is a DOUBLE in QP and the max value for
  #       a threshold is a BIGINT.  A DOUBE can be quite a bit larger
  #       than a BIGINT.  If the max_cost_allowed is larger than the
  #       max value of a BIGINT, then simple set the max value that
  #       threshold value can have.
  #-----------------------------------------------------------------------
  my ($subId, $subName, $subType, $subIntercept, $subMaxQueries, $subSuspended, $subMaxCost);
  my $selectStmt = "select id, name, type, intercept, max_queries_allowed, case when max_cost_allowed > 9223372036854775807 then 9223372036854775807 else cast(max_cost_allowed as BIGINT) end, suspended from db2qp.submitter_profile order by id";
  my ($itemName, $itemWlName, $itemCostThName, $itemWlaThName) = " ";
  my $hasBlanks = 0;

  $sth = PrepareExecuteSql($dbh, $selectStmt);

 
  # Fetch the submitter profiles and for each profile add a CREATE WORKLOAD
  # statement into the script with the following rules:
  #  - Workload name = <submitter profile name>_<id>_<type>_WL
  #
  #  - QP user profile type mapping
  #    - if the type is a user (U), the SESSION_USER connection
  #      attribute will be used
  #    - if the type is a group (G), the SESSION_USER GROUP connection
  #      attribute will be used
  #
  #  - QP user profile intercept flag mapping
  #    - if the intercept flag is set to Y, the workload will map its
  #      activities to the MAIN_SC.  From there, the work action set will
  #      eventually map its activities to the appropriate subclass based on the
  #      query class values.
  #    - if the intercept flag is set to N, the workload will map its
  #      activities to the UNMANAGED_SSC that resides within the MAIN_SC
  #    - if the submitter profile is PUBLIC and the intercept flag is set to Y,
  #      the default user workload will be updated to map its activities
  #      to the MAIN_SC.  If the PUBLIC intercept flag is set to N, the
  #      default user workload will be altered to map its activities
  #      directly to the UNMANAGED_SSC.
  #
  #  - QP user profile access suspended mapping
  #    - if the user profile has the access suspended flag turned on,
  #      the "DISALLOW DB ACCESS" attribute will be generated for the associated
  #      workload.        
  #    - if the user profile has the access suspended flag turned off, the 
  #      default value of "ALLOW DB ACCESS" attribute will be generated for the 
  #      associated workload.
  #
  #  - For each workload DDL that is generated, and associated GRANT USAGE
  #    statement will also be generated.
  #
  #
  # Threshold Statements:
  #  - For each workload (including the SYSDEFAULTUSERWORKLOAD), if the    
  #    associated QP Profile's intercept flag was set to Y, DDL statement
  #    creating an ESTIMATEDSQLCOST threshold will be included with its  
  #    max value being the value of the max_cost_allowed from the QP profile.
  #
  # - For each submitter profile, also create a commented out line for the 
  #   CONCURRENTWORKLOADACTIVITIES threshold.
  # 
  # - threshold name will be generated using the following rules:
  #    - threshold name = <submitter profile name>_<id>_<type>_TH
  #    - value for threshold will be based on the max_queries_allowed value
  #      on the submitter profile
  #
  #-----------------------------------------------------------------------
  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";
  print FILE "\n\n-- Workloads and thresholds for QP Submitter Profiles     ";
  print FILE "\n--                                                          ";
  print FILE "\n-- Note:                                                    ";
  print FILE "\n-- The CONCURRENTWORKLOADACTIVITIES threshold is not        ";
  print FILE "\n-- a queuing threshold.  If this threshold is exceeded, the ";
  print FILE "\n-- activity will be stopped.  For this reason, it is        ";
  print FILE "\n-- commented out for each workload.                         ";
  print FILE "\n------------------------------------------------------------";
  
  while (($subId, $subName, $subType, $subIntercept, $subMaxQueries, $subMaxCost, $subSuspended) = $sth->fetchrow())
  {
    
    my $blank = " ";
    if ($subName =~ m/$blank/)
    {
      $hasBlanks = 1;
    } 
    else
    {
      $hasBlanks = 0;
    }

    # Public submitter profile
    #-------------------------
    if ($subName eq $publicSubmitter)
    {
      # Generate ALTER WORKLOAD statement for default user workload
      # and map to appropriate service class based on Intercept value
      #---------------------------------------------------------------
      if ($subIntercept eq $valueYes)
      {
        print FILE "\n\n-- The QP PUBLIC Profile was set to have QP        ";
        print FILE "\n--   intercept:                                      ";
        print FILE "\n-- Map activities from default user workload to the  ";
        print FILE "\n-- main service superclass so that the activities can";
        print FILE "\n-- be mapped to the appropriate service subclass     ";
        print FILE "\n-- based on their cost.                              ";
        print FILE "\n-----------------------------------------------------";
        print FILE "\nALTER WORKLOAD SYSDEFAULTUSERWORKLOAD SERVICE CLASS ", $superclassName;
      } 
      else
      {
        print FILE "\n\n-- PUBLIC Profile was set to have QP not intercept:";
        print FILE "\n-- Map activities from default user workload         ";
        print FILE "\n-- directly to the unmanaged service subclass.       ";
        print FILE "\n-----------------------------------------------------";
        print FILE "\n\nALTER WORKLOAD SYSDEFAULTUSERWORKLOAD SERVICE CLASS ", $unmanagedSubclass, " UNDER ", $superclassName;
      }

      # Generate DISALLOW attribute for profiles that have access suspended
      #---------------------------------------------------------------------
      if ($subSuspended eq $valueYes)
      {
        print FILE " DISALLOW DB ACCESS;";
      }
      else 
      {
        print FILE ";";
      }

      $itemName = $defaultUserWorkload;

    }

    # All other user defined submitter profiles
    #------------------------------------------
    else
    {
      # Add the CREATE WORKLOAD statement
      #----------------------------------
      print FILE "\n\n-- Workload and threshold for QP ";
      if ($subType eq $typeUser)
      {
        print FILE "user ";
      }
      else
      {
        print FILE "group ";
      }
      print FILE "profile ", $subName;
      print FILE "\n-----------------------------------------------------";

      # If the name has any blanks in it, then they are likely surrounded
      # by quotes so we need to remove those quotes from the name
      #--------------------------------------------------------------
      $itemName = $subName."_".$subId."_".$subType;
      if ($hasBlanks)
      {
        $subName =~ s/\'//g;
        $itemName =~ s/\'//g;
        $itemWlName = "\"".$itemName."\"";
        $itemCostThName = "\"".$itemName."_COST_TH"."\"";
        $itemWlaThName = "\"".$itemName."_WLA_TH"."\"";
      }
      else
      {
        $itemWlName = $itemName."_WL";
        $itemCostThName = $itemName."_COST_TH";
        $itemWlaThName = $itemName."_WLA_TH";
      }

      print FILE "\nCREATE WORKLOAD ";
      print FILE "$itemWlName"," SESSION_USER ";
      
      if ($subType eq $typeGroup)
      {
        print FILE "GROUP ";
      }
      # Map activities for workload to appropriate service class based on 
      # Intercept value
      #-------------------------------------------------------------------
      
      print FILE "( '$subName' ) SERVICE CLASS ";
      if ($subIntercept eq $valueYes)
      {
        print FILE $superclassName, " ";
      }
      else
      {
        print FILE $unmanagedSubclass, " UNDER ", $superclassName, " ";
      }

      # Add the workload to the workload array
      #---------------------------------------
      $workloads[$workloadIndex] = $itemWlName;
      $workloadIndex++;

      # Generate DISALLOW attribute for profiles that have access suspended
      #---------------------------------------------------------------------
      if ($subSuspended eq $valueYes)
      {
        print FILE " DISALLOW DB ACCESS ";
      }
      
      # Create the workloads so that those representing the USER profiles
      # are ahead in the evaluation order than those representing GROUP
      # profiles
      #-------------------------------------------------------------------
      if ($subType ne $typeGroup)
      {
        print FILE "POSITION AT 1;"
      }
      else
      {
        print FILE "POSITION LAST;"
      }
     
      # Add the GRANT USAGE on the workload to the appropriate group or user
      #---------------------------------------------------------------------
      if ($subName ne $publicSubmitter)
      {

        print FILE "\n\nGRANT USAGE ON WORKLOAD ", $itemWlName, " TO ";
        if ($subType eq $typeGroup)
        {
          print FILE "GROUP ";
        }
        else
        {
          print FILE "USER ";
        }
        if ($hasBlanks)
        { 
          $subName =~ tr/a-z/A-Z/;
          print FILE "\"",$subName,"\";";
        }
        else
        {
          print FILE $subName, ";";
        }
      }

    }

    if ($itemName eq $defaultUserWorkload)
    {
      $itemWlaThName = $itemName."_WLA_TH";
      $itemWlName =  "SYS".$defaultUserWorkload;
    }

    # If the version is V97, then also create an estimated cost threshold
    # on the workload. 
    # Note: this threshold cannot be created on a workload in V95
    #--------------------------------------------------------------------
    if ($db2Version eq $db2v97)
    {
      if ($itemName eq $defaultUserWorkload)
      {
        $itemCostThName = $itemName."_COST_TH";
      }

      # This was set to unlimited in QP so it will be set to a really
      # high value in WLM and then commented out because it is not
      # a useful threshold.
      #-----------------------------------------------------------------
      if ($subMaxCost eq $unlimitedMaxCost)
      {
        # Add the threshold name to the commented threshold array
        #----------------------------------------------------------
        $commentedThresholds[$commentedThresholdIndex] = $itemCostThName;
        $commentedThresholdIndex++;

        $subMaxCost = $unlimitedWLMCost;
        print FILE "\n\n-- QP value was -1 so set threshold to a high value";
        print FILE "\n-- and then comment out the threshold                ";
        print FILE "\n-----------------------------------------------------";
        print FILE "\n--";

      }
      else
      {
        # Add the threshold name to the threshold array
        #----------------------------------------------
        $thresholds[$thresholdIndex] = $itemCostThName;
        $thresholdIndex++;
        print FILE "\n\n";
      }
      print FILE "CREATE THRESHOLD ";
      print FILE "$itemCostThName"," FOR WORKLOAD ", "$itemWlName";
      print FILE " ACTIVITIES ENFORCEMENT DATABASE WHEN ESTIMATEDSQLCOST > $subMaxCost COLLECT ACTIVITY DATA STOP EXECUTION;";
      
    }

    # Now add the commented out CREATE THRESHOLD statement for
    # CONCURRENTWORKLOADACTIVITIES THRESHOLD
    # 
    # Note: In QP, the max_queries_allowed can be set to -1 which
    #       means unlimited.  The CONCURRENTWORKLOADACTIVITIES threshold
    #       doesn't have an "unlimited" value so set it to a really
    #       large value.
    #--------------------------------------------------------------------
    if ($subMaxQueries eq $unlimitedMaxQueries)
    {
      $subMaxQueries = $unlimitedThresholdQueries;
    }
    print FILE "\n\n--CREATE THRESHOLD ";
    print FILE "$itemWlaThName"," FOR WORKLOAD $itemWlName"," ACTIVITIES ENFORCEMENT WORKLOAD OCCURRENCE WHEN CONCURRENTWORKLOADACTIVITIES > $subMaxQueries COLLECT ACTIVITY DATA STOP EXECUTION;\n";

    # Add the threshold name to the commented threshold array
    #----------------------------------------------------------
    $commentedThresholds[$commentedThresholdIndex] = $itemWlaThName;
    $commentedThresholdIndex++;


  }
  $sth->finish;  
  
  close(FILE);

  return 0;
} # AddWorkloadsAndThresholdsForSubmitters

#######################################################################
# Description : Routine to add CREATE WORKLOAD statements for each
#               application listed to be bypassed in the QP system
#               settings
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkloadsForQPSystemBypassedApplications
{

  # prepare and execute SQL statement that extracts the QP System
  # information
  #----------------------------------------------------------------------
  my ($sysInterceptApps, $sysExcludeApps);
  my $selectStmt = "select intercept_application, exclude_applications from db2qp.qp_system";
  my $interceptAllBut = "E";
  my $itemName = " ";
  my (@arr, $numApps, $i, $element, @arr2, $appName);
  

  $sth = PrepareExecuteSql($dbh, $selectStmt);

 
  # Fetch the QP system values.  If the intercept application value is
  # E (intercept all but the applications in the EXCLUDE_APPLICATIONS 
  # column), then generate a CREATE WORKLOAD command for each of the 
  # applications listed and use the APPLNAME connection attribute.  
  # Map those activities to the UNMANAGED_SSC service subclass.
  #
  # For each workload DDL that is generated, an associated GRANT USAGE
  # statement to PUBLIC will also be generated.
  #
  #-----------------------------------------------------------------------
  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";

  print FILE "\n-- Workloads for each bypassed application from the   ";
  print FILE "\n-- QP system settings                                 ";
  print FILE "\n------------------------------------------------------";
  while (($sysInterceptApps, $sysExcludeApps) = $sth->fetchrow())
  {
    if ($sysExcludeApps and $sysInterceptApps eq $interceptAllBut)
    {
      @arr = split(',', $sysExcludeApps);
      $numApps = scalar @arr;

      for ($i = 0; $i < $numApps; $i++)
      {
        $element = $arr[$i];
        # remove leading and trailing blanks
        #------------------------------------
        $element =~ s/\s+$//;
        $element =~ s/^\s+//;
    
        # Remove the . in the appname.  For example, test.exe will become
        # testexe
        #-----------------------------------------------------------------
        @arr2 = split('\.', $element);
        if ($arr2[1])
        {
          $appName = $arr2[0].$arr2[1];
        }
        else
        {
          $appName = $arr2[0];
        }

        # Generate the CREATE WORKLOAD statement
        #----------------------------------------
        print FILE "\nCREATE WORKLOAD BYPASSAPPS_", $appName, "_WL APPLNAME ('", $element, "') SERVICE CLASS ", $unmanagedSubclass, " UNDER " , $superclassName, " POSITION AT 1;";

        # Generate the GRANT USAGE statement
        #-----------------------------------
        print FILE "\n\nGRANT USAGE ON WORKLOAD BYPASSAPPS_", $appName, "_WL TO PUBLIC;\n\n";

        # Add the workload to the workload array
        #---------------------------------------
        $workloads[$workloadIndex] = "BYPASSAPPS_".$appName."_WL";
        $workloadIndex++;

      }
    }
  }
  $sth->finish;  
  close(FILE);

  return 0;
} # AddWorkloadsForQPSystemBypassedApplications

#######################################################################
# Description : Routine to add CREATE WORK CLASS SET, CREATE WORK 
#               ACTION SET at the database level that will contain 
#               a concurrency threshold to be applied against DML that
#               reflects the value in the max_total_queries value in 
#               the system settings.
#               Note: this code will be commented out since the value
#               will likely need to be changed due to the nature of QP
#               bypassing activities from other applications or users
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddDBWASForQPSystemMaxTotalQueries     
{

  # prepare and execute SQL statement that extracts the QP System
  # information
  #----------------------------------------------------------------------
  my ($sysMaxTotalQueries);
  my $selectStmt = "select max_total_queries from db2qp.qp_system";

  $sth = PrepareExecuteSql($dbh, $selectStmt);

  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";
  ($sysMaxTotalQueries) = $sth->fetchrow();

  # Hang on to the originalTotalMaxQueries so that we know whether
  # we will need to generate drop code for this
  #---------------------------------------------------------------
  $originalMaxTotalQueries = $sysMaxTotalQueries;
  
  # If the max_total_queries is set to a value and not unlimited
  #--------------------------------------------------------------
  if ($sysMaxTotalQueries > -1)
  {
    print FILE "\n-- Work class set and work action set to control the  ";
    print FILE "\n-- number of activities that can run at the database  ";
    print FILE "\n-- level.  This represents the max_total_queries in   ";
    print FILE "\n-- qp_system.                                         ";
    print FILE "\n--                                                    ";
    print FILE "\n-- Note:                                              ";
    print FILE "\n-- Because there could be other activies bypassed     ";
    print FILE "\n-- asside from those with a larger estimated cost     ";
    print FILE "\n-- than what is specified in the DB2_QP_BYPASS_COST   ";
    print FILE "\n-- registry variable, the value for the threshold     ";
    print FILE "\n-- in the work action set will likely have to be      ";
    print FILE "\n-- changed.  For this reason, the database work class ";
    print FILE "\n-- set and database work action set is commented out  ";
    print FILE "\n------------------------------------------------------";

    # Add in commented out CREATE WORK CLASS SET statement.      
    # This work class set will contain a work class representing DML
    # and if there are queries being bypassed using the DB2_QP_BYPASS_COST
    # registry variable, it will be further qualified by an timerone
    # value
    #---------------------------------------------------------------------
    print FILE "\n\n-- Database work class set ";
    print FILE "\n----------------------------- ";
    print FILE "\n--CREATE WORK CLASS SET DATABASE_WCS ";

    # Get the bypass cost value if it is specified 
    #------------------------------------------------
    my $bypassCost;

    open(FILEHANDLE, "db2set DB2_QP_BYPASS_COST |");
    $bypassCost=<FILEHANDLE>;
    close(FILEHANDLE);

    # remove leading and trailing blanks
    #------------------------------------
    $bypassCost =~ s/\s+$//;
    $bypassCost =~ s/^\s+//;
 
    # Add in the work class representing DML 
    #---------------------------------------
    print FILE "(WORK CLASS DML_WC WORK TYPE DML ";
  
    # If there is a bypasscost value, then specify a timeron value in the
    # work class
    #----------------------------------------------------------------------
    if ($bypassCost)
    {
      $bypassCost++;
      # Add statement to add work class
      #-----------------------------------------------------------------
      print FILE "FOR TIMERONCOST FROM $bypassCost ";
    }
    print FILE "POSITION LAST);";

    # Add in CREATE WORK ACTION SET statement that will be 
    # applied to the database.                    
    # This work action set will contain a concurrency work action  
    # threshold representing the qp_system max_total_queries
    #--------------------------------------------------------------
    print FILE "\n\n-- Work action set for the database";
    print FILE "\n-------------------------------------";
    print FILE "\n--CREATE WORK ACTION SET DATABASE_WAS FOR DATABASE USING WORK CLASS SET DATABASE_WCS (WORK ACTION MAXQUERIES_WA ON WORK CLASS DML_WC WHEN CONCURRENTDBCOORDACTIVITIES > ", $sysMaxTotalQueries, " AND QUEUEDACTIVITIES UNBOUNDED COLLECT ACTIVITY DATA CONTINUE);\n";
  }

  $sth->finish;  
  close(FILE);

  return 0;
} # AddWorkloadsForQPSystemBypassedApplications



#######################################################################
# Description : Routine to add CREATE WORKLOAD statement for the
#               DB2_QP_BYPASS_USERS registry variable listing every
#               user specified in the registry variable in the 
#               SESSION_USER workload attribute.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkloadsForBypassedUsers
{
  my $bypassUsers;
  my (@arr, $numUsers, $i, $element);

  open(FILEHANDLE, "db2set DB2_QP_BYPASS_USERS |");
  $bypassUsers=<FILEHANDLE>;
  close(FILEHANDLE);

  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";

  # remove leading and trailing blanks
  #------------------------------------
  $bypassUsers =~ s/\s+$//;
  $bypassUsers =~ s/^\s+//;
  if ($bypassUsers)
  {
    @arr = split(',', $bypassUsers);
    $numUsers = scalar @arr;

    # If the registry variable was specified, then generate the CREATE 
    # WORKLOAD and GRANT USAGE statements
    #-----------------------------------------------------------------
    if ($numUsers > 0)
    {
      # Generate the CREATE WORKLOAD statement
      #----------------------------------------
      print FILE "\n\n-- WLM Object for the DB2_QP_BYPASS_USERS registry   "; 
      print FILE "\n-- variable                                            ";
      print FILE "\n--                                                     ";
      print FILE "\n-- Add a workload for all the users specified in the   "; 
      print FILE "\n-- registry variable and have those activities mapped  ";
      print FILE "\n-- to the unmanaged service subclass.                  ";
      print FILE "\n------------------------------------------------------ ";

      print FILE "\nCREATE WORKLOAD BYPASSUSERS_WL SESSION_USER (";
 
      for ($i = 0; $i < $numUsers; $i++)
      {
        $element = $arr[$i];

        # remove leading and trailing blanks
        #------------------------------------
        $element =~ s/\s+$//;
        $element =~ s/^\s+//;

        print FILE "'$element'";
        if ($i < ($numUsers - 1))
        {
          print FILE ", ";
        } else {
          print FILE " ) ";
        }
      }
      print FILE "SERVICE CLASS ", $unmanagedSubclass, " UNDER ", $superclassName, " POSITION AT 1;";

      # Generate the GRANT USAGE statement
      #-----------------------------------
      print FILE "\n\nGRANT USAGE ON WORKLOAD BYPASSUSERS_WL TO PUBLIC;\n\n";
    }

    # Add the workload to the workload array
    #---------------------------------------
    $workloads[$workloadIndex] = "BYPASSUSERS_WL";
    $workloadIndex++;

  }
  close(FILE);
  return 0;

} # AddWorkloadsForBypassedUsers

#######################################################################
# Description : Routine to add CREATE WORKLOAD statement for the 
#               DB2_QP_BYPASS_APPLICATIONS registry variable listing 
#               every sepcified application in the registry variable
#               in the APPLNAME workload attribute.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkloadsForBypassedApplications
{
  my $bypassApps;
  my (@arr, $numApps, $i, $element);

  open(FILEHANDLE, "db2set DB2_QP_BYPASS_APPLICATIONS |");
  $bypassApps=<FILEHANDLE>;
  close(FILEHANDLE);

  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";
 
  # remove leading and trailing blanks
  #------------------------------------
  $bypassApps =~ s/\s+$//;
  $bypassApps =~ s/^\s+//;
 
  if ($bypassApps)
  {
    @arr = split(',', $bypassApps);
    $numApps = scalar @arr;
    if ($numApps > 0)
    {
      # Generate the CREATE WORKLOAD statement
      #----------------------------------------
      print FILE "\n\n-- WLM Object for the DB2_QP_BYPASS_APPLICATIONS     "; 
      print FILE "\n-- registry variable                                   ";
      print FILE "\n--                                                     ";
      print FILE "\n-- Add a workload for all the applications specified   "; 
      print FILE "\n-- in the registry variable and have those activities  ";
      print FILE "\n-- mapped to the unmanaged service subclass.           ";
      print FILE "\n------------------------------------------------------ ";

      print FILE "\nCREATE WORKLOAD BYPASSAPPS_WL APPLNAME (";

      for ($i = 0; $i < $numApps; $i++)
      {
        $element = $arr[$i];
        # remove leading and trailing blanks
        #------------------------------------
        $element =~ s/\s+$//;
        $element =~ s/^\s+//;

        print FILE "'$element'";
        if ($i < ($numApps - 1))
        {
          print FILE ", ";
        } else {
          print FILE " ) ";
        }
      }
      print FILE "SERVICE CLASS ", $unmanagedSubclass, " UNDER ", $superclassName, " POSITION AT 1;";
    
      # Generate the GRANT USAGE statement
      #-----------------------------------
      print FILE "\n\nGRANT USAGE ON WORKLOAD BYPASSAPPS_WL TO PUBLIC;";

      # Add the workload to the workload array
      #---------------------------------------
      $workloads[$workloadIndex] = "BYPASSAPPS_WL";
      $workloadIndex++;

    }
  }

  close(FILE);

  return 0;
} # AddWorkloadsForBypassedApplications

#######################################################################
# Description : Routine to generate ALTER statements to add a work 
#               class and a work action to bypass activities that
#               that have an estimated cost that is less than or equal to
#               that which is specified in the DB2_QP_BYPASS_COST
#               registry variable.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkclassForBypassedDMLOnCost
{
  my $bypassCost;

  open(FILEHANDLE, "db2set DB2_QP_BYPASS_COST |");
  $bypassCost=<FILEHANDLE>;
  close(FILEHANDLE);

  # remove leading and trailing blanks
  #------------------------------------
  $bypassCost =~ s/\s+$//;
  $bypassCost =~ s/^\s+//;
  
  if ($bypassCost)
  {

    open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";

    print FILE "\n\n-- WLM objects for the DB2_QP_BYPASS_COST registry variable ";
    print FILE "\n--                                                            ";
    print FILE "\n-- Add a work class and a work action to map activities with  ";
    print FILE "\n-- an estimated cost equal to or less than that specified     ";
    print FILE "\n-- in the DB2_QP_BYPASS_COST registry variable to the         ";
    print FILE "\n-- unmanaged service subclass.                                ";
    print FILE "\n------------------------------------------------------------- ";

    # Add the work class reflecting the DML estimated cost
    #------------------------------------------------------
    print FILE "\nALTER WORK CLASS SET GLOBAL_WCS ADD WORK CLASS BYPASSCOST_WC WORK TYPE DML FOR TIMERONCOST FROM 0 to ", $bypassCost, " POSITION AT 1;";

    # Add the work action to map the activities to the unmanaged service subclass
    #--------------------------------------------------------------------------
    print FILE "\nALTER WORK ACTION SET SC_WAS ADD WORK ACTION MAPBYPASSCOST_WA ON WORK CLASS BYPASSCOST_WC MAP ACTIVITY TO ", $unmanagedSubclass, ";"; 

 }
  close(FILE);

} # AddWorkclassForBypassedDMLOnCost

#######################################################################
# Description : Routine to generate ALTER statements to add a work 
#               class and a work action to represent all non_DML
#               activities and have them mapped to the UNMANAGED_SSC.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWorkclassForNonDML
{

  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";

  print FILE "\n\n-- Add work class and work action to map non-DML activities ";
  print FILE "\n-- to the unmanaged service subclass.                ";
  print FILE "\n--------------------------------------------------------------- ";

  print FILE "\nALTER WORK CLASS SET GLOBAL_WCS ADD WORK CLASS NONDML_WC WORK TYPE ALL POSITION LAST;";

  print FILE "\n\nALTER WORK ACTION SET SC_WAS ADD WORK ACTION MAPNONDML_WA on WORK CLASS NONDML_WC MAP ACTIVITY TO ", $unmanagedSubclass, ";"; 

  close(FILE);

  return 0;
} # AddWorkclassForNonDML


#######################################################################
# Description : Routine to add service classes, thresholds,     
#               work classes and work actions statements for each 
#               QP query class.
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub AddWlmObjectsForQueryClasses
{

  my ($id, $maxQueries, $maxCost, $description, $i, $itemName);
  my $fromValueMaxCost = 0;
  my $concThAdded = 0;
  my $selectStmt = "select id, max_queries, max_cost, description from db2qp.query_class order by max_cost";

  open FILE, ">>$outFile" or die "\n Unable to open file $outFile\n";

  # Add in CREATE WORK CLASS SET statement.      
  # This work class set will eventually contain one work class for
  # every QP query class. 
  #---------------------------------------------------------------
  print FILE "\n\n-- Global work class set ";
  print FILE "\n-------------------------- ";
  print FILE "\nCREATE WORK CLASS SET GLOBAL_WCS;";

  # Add in CREATE WORK ACTION SET statement that will be 
  # applied to the MAIN_SC service superclass.  
  # This work action set will eventually contain one work action 
  # for every QP query class
  #--------------------------------------------------------------
  print FILE "\n\n-- Work action set for the main service superclass";
  print FILE "\n----------------------------------------------------";
  print FILE "\nCREATE WORK ACTION SET SC_WAS FOR SERVICE CLASS ", $superclassName, " USING WORK CLASS SET GLOBAL_WCS;";

  
  # For every QP query class add in the following:
  #  - add a work class to the work class set reflecting the DML
  #    cost that was specified in the query class
  #  - create service subclass in the MAIN_SC super class
  #  - add a mapping work action to the work action set to map 
  #    activities to appropriate service subclass.
  #  - create a concurrency threshold using the max_value from the 
  #    query class and apply it to the service subclass
  #-----------------------------------------------------------------
  $sth = PrepareExecuteSql($dbh, $selectStmt);
  $i = 1;

  print FILE "\n\n-- WLM objects for each QP query class                    ";
  print FILE "\n--   - Add a work class containing the estimated cost from  ";
  print FILE "\n--     the associated QP query class                        ";
  print FILE "\n--   - Add a service subclass where the DML statements that ";
  print FILE "\n--     fall within an estimated cost range will run         ";
  print FILE "\n--   - Add a work action to map the activities that fall    ";
  print FILE "\n--     within the estimated cost range to the service class ";
  print FILE "\n--     above                                                ";
  print FILE "\n--   - Add an activity concurrency threshold with the value ";
  print FILE "\n--     that is specified in the associated QP query class   ";
  print FILE "\n----------------------------------------------------------- ";

  while (($id, $maxQueries, $maxCost, $description) = $sth->fetchrow())
  {
    $itemName = "QUERYCLASS".$i;
    # Add statement to add work class representing DML that falls within
    # the estimated cost from the QP query class
    #--------------------------------------------------------------------
    print FILE "\n\n-- WLM objects for query class ID ", $id;
    if ($description)
    {
      print FILE " (", $description, ")";
    }
    print FILE "\n--------------------------------------------------------------";
    # Add statement to add work class
    #-----------------------------------------------------------------
    print FILE "\nALTER WORK CLASS SET GLOBAL_WCS ADD WORK CLASS ",$itemName,"_WC WORK TYPE DML FOR TIMERONCOST FROM $fromValueMaxCost TO $maxCost POSITION LAST;";
    $fromValueMaxCost = $maxCost;
   
    # Add statement to create service subclass where activities with
    # estimated cost from query class will run
    #----------------------------------------------------------------
    print FILE "\n\nCREATE SERVICE CLASS ",$itemName,"_SSC UNDER ", $superclassName, " COLLECT AGGREGATE ACTIVITY DATA;";

    # Add the threshold name to the threshold array
    #----------------------------------------------
    $serviceClasses[$serviceClassIndex] = $itemName."_SSC";
    $serviceClassIndex++;

    # Add statement to add work action that will map the activities 
    # from the associated work class to the appropriate service subclass
    #----------------------------------------------------------------------
    print FILE "\n\nALTER WORK ACTION SET SC_WAS ADD WORK ACTION ", $itemName,"_WA ON WORK CLASS ", $itemName, "_WC MAP ACTIVITY TO ", $itemName, "_SSC;";

    # Add statement to create a concurrency threshold with a max value
    # from the QP query class
    #
    # Note: In QP, the max_queries can be set to -1 which means unlimited.
    #       If unlimited is specified in QP, because there is no "unlimited"
    #       value for the threshold, set the value to a really high number 
    #       and the concurrency threshold will be commented out.
    #-------------------------------------------------------------------------
    
    $concThAdded = 0;
    if ($maxQueries eq $unlimitedMaxQueries)
    {
      print FILE "\n\n-- QP value was -1 so set threshold to a high value";
      print FILE "\n-- and then comment out the threshold               ";
      print FILE "\n-----------------------------------------------------";
      $maxQueries = $unlimitedThresholdQueries;
      print FILE "\n--";
    }
    else
    {
      print FILE "\n\n";
      $concThAdded = 1;
    }
    print FILE "CREATE THRESHOLD ", $itemName, "_CONC_TH FOR SERVICE CLASS ",$itemName, "_SSC UNDER ", $superclassName, " ACTIVITIES ENFORCEMENT DATABASE WHEN CONCURRENTDBCOORDACTIVITIES > ", $maxQueries, " AND QUEUEDACTIVITIES UNBOUNDED COLLECT ACTIVITY DATA CONTINUE;\n";

    # Add the threshold name to the correct threshold array
    #-------------------------------------------------------
    if ($concThAdded)
    {
      $thresholds[$thresholdIndex] = $itemName."_CONC_TH";
      $thresholdIndex++;
    } 
    else
    {
      $commentedThresholds[$commentedThresholdIndex] = $itemName."_CONC_TH";
      $commentedThresholdIndex++;
    }

    $i++;
  }

  $sth->finish;  

  close(FILE);

  return 0;
} # AddWlmObjectsForQueryClasses

#######################################################################
# Description : Routine to get values for SYSDEFAULTWORKLOAD    
#               so that during the DROP routine, they can be set back
#               to their original values
# Input       : None 
# Output      : Returns the following values for the SYSDEFAULTWORKLOAD:
#               - enabled
#               - allowaccess
#               - serviceclassname
#               - parentserviceclassname
#######################################################################
sub GetDefaultUserWorkloadInfo
{

  my ($i, $enabled, $allowAccess, $serviceClassName, $parentServiceClassName);
  my @arg_l; # arg_l will hold the values to be returned to calling function

  my $selectStmt = "select enabled, allowaccess, serviceclassname, parentserviceclassname from syscat.workloads where workloadname = 'SYSDEFAULTUSERWORKLOAD'";
  
  # execute the statement and get the values
  #-----------------------------------------------------------------
  $sth = PrepareExecuteSql($dbh, $selectStmt);
  $i = 1;

  while (($enabled, $allowAccess, $serviceClassName, $parentServiceClassName) = $sth->fetchrow())
  {
    $arg_l[0] = $enabled;
    $arg_l[1] = $allowAccess;
    $arg_l[2] = $serviceClassName;
    $arg_l[3] = $parentServiceClassName;
  }

  $sth->finish;  


  return @arg_l;
} # GetDefaultUserWorkloadInfo

#######################################################################
# Description : Routine to generate the script to drop all of the
#               WLM objects.                                       
# Input       : None 
# Output      : Returns 0 on success, exits otherwise
#######################################################################
sub GenerateDropScript
{

  my $dropOutFile = $outFile.".DROP";
  my $i = 0;
  
  open FILE, ">$dropOutFile" or die "\n Unable to open file $dropOutFile\n";

  print FILE "\n-----------------------------------------------------------";
  print FILE "\n-- Generated script for dropping the WLM objects from      ";
  print FILE "\n-- the generated QP to WLM migration script.               ";
  print FILE "\n--                                                         ";
  print FILE "\n-- Description:                                            ";
  print FILE "\n--                                                         ";
  print FILE "\n--   This generated script contains the DDL to drop the    ";
  print FILE "\n--   WLM objects that were part of the QP to WLM generated ";
  print FILE "\n--   migration script.                                     ";
  print FILE "\n--                                                         ";
  print FILE "\n-- Before running this script:                             ";
  print FILE "\n--                                                         ";
  print FILE "\n--   - connect to the database:                            ";
  print FILE "\n--       db2 connect to <database>                         ";
  print FILE "\n--                                                         ";
  print FILE "\n--   - the privileges held by the authorization ID of      ";
  print FILE "\n--     user who runs this script must include DBADM or     ";
  print FILE "\n--     WLMADM.                                             ";
  print FILE "\n--                                                         ";
  print FILE "\n-- To run this script, issue the following command:        ";
  print FILE "\n--                                                         ";
  print FILE "\n--          db2 -tf DROP", $outFile;
  print FILE "\n--                                                         ";
  print FILE "\n-----------------------------------------------------------";
  print FILE "\n";

  # Add DDL to set the workload to the SYSDEFAULTADMWORKLOAD 
  # so that the script can run unaffected by any WLM DDL that
  # may be run in the script itself
  #-----------------------------------------------------------
  print FILE "\n-- Set workload to SYSDEFAULTADMWORKLOAD     ";
  print FILE "\n------------------------------------------   ";
  print FILE "\nSET WORKLOAD TO SYSDEFAULTADMWORKLOAD;       ";
  print FILE "\n                                             ";
 
  
  print FILE "\n-- Disable all the objects ";
  print FILE "\n---------------------------------";

  print FILE "\n\n-- Disable all the thresholds ";
  print FILE "\n------------------------------";
  for ($i = 0; $i < $thresholdIndex; $i++)
  {
    print FILE "\n ALTER THRESHOLD ", $thresholds[$i], " DISABLE;";
  }
  for ($i = 0; $i < $commentedThresholdIndex; $i++)
  {
    print FILE "\n-- ALTER THRESHOLD ", $commentedThresholds[$i], " DISABLE;";
  }
  
  print FILE "\n\n-- Disable the work action set ";
  print FILE "\n-------------------------------";
  print FILE "\nALTER WORK ACTION SET SC_WAS DISABLE;";

  if ($originalMaxTotalQueries > -1)
  {

    print FILE "\n\n-- Disable the database work action set ";
    print FILE "\n------------------------------------------";
    print FILE "\n--ALTER WORK ACTION SET DATABASE_WAS ALTER WORK ACTION MAXQUERIES_WA DISABLE;";
    print FILE "\n--ALTER WORK ACTION SET DATABASE_WAS DISABLE;";
  }

  print FILE "\n\n-- Disable all of the workloads  ";
  print FILE "\n---------------------------------";
  for ($i = 0; $i < $workloadIndex; $i++)
  {
    print FILE "\n ALTER WORKLOAD ", $workloads[$i], " DISABLE;";
  }

  # Get the default user workload's original values and alter it so
  # that it goes back to the way it was when this script was first
  # run
  #---------------------------------------------------------------------
  my ($enabled, $allowAccess, $serviceClassName, $parentServiceClassName) = GetDefaultUserWorkloadInfo();
  print FILE "\n\n-- Alter default user workload back to its original   ";
  print FILE "\n-- values                                               ";
  print FILE "\n--------------------------------------------------------";
  print FILE "\n ALTER WORKLOAD SYSDEFAULTUSERWORKLOAD ";
  if ($allowAccess)
  {
    print FILE "ALLOW DB ACCESS;";
  } 
  else
  {
    print FILE "DISALLOW DB ACCESS;";
  } 
  print FILE "\n ALTER WORKLOAD SYSDEFAULTUSERWORKLOAD ";
  if (!$parentServiceClassName)
  {
    print FILE "SERVICE CLASS ", $serviceClassName, ";"
  }
  elsif ($serviceClassName eq "SYSDEFAULTSUBCLASS")
  {
    print FILE "SERVICE CLASS ", $parentServiceClassName, ";"
  }
  else
  {
    print FILE "SERVICE CLASS ", $serviceClassName, " UNDER ", $parentServiceClassName,";"
  }

  print FILE "\n\n-- Disable the service classes ";
  print FILE "\n-------------------------------";
  print FILE "\n ALTER SERVICE CLASS ", $unmanagedSubclass," UNDER ", $superclassName, " DISABLE;";
  for ($i = 0; $i < $serviceClassIndex; $i++)
  {
    print FILE "\n ALTER SERVICE CLASS ", $serviceClasses[$i], " UNDER " , $superclassName, " DISABLE;";
  }
  print FILE "\n ALTER SERVICE CLASS ", $superclassName, " DISABLE;";


  print FILE "\n\n-- Next, drop  all the objects\n ";
  print FILE "\n---------------------------------";

  print FILE "\n\n-- Drop all the thresholds ";
  print FILE "\n---------------------------";
  for ($i = 0; $i < $thresholdIndex; $i++)
  {
    print FILE "\n DROP THRESHOLD ", $thresholds[$i],";";
  }
  for ($i = 0; $i < $commentedThresholdIndex; $i++)
  {
    print FILE "\n-- DROP THRESHOLD ", $commentedThresholds[$i],";";
  }

  print FILE "\n\n-- Drop the work action set ";
  print FILE "\n----------------------------";
  print FILE "\nDROP WORK ACTION SET SC_WAS;\n";

  print FILE "\n\n-- Drop the work class set ";
  print FILE "\n----------------------------";
  print FILE "\nDROP WORK CLASS SET GLOBAL_WCS;\n";

 
  if ($originalMaxTotalQueries > -1)
  {
    print FILE "\n\n-- Drop the database work action set ";
    print FILE "\n---------------------------------------";
    print FILE "\n--DROP WORK ACTION SET DATABASE_WAS;\n";

    print FILE "\n\n-- Drop the work class set ";
    print FILE "\n----------------------------";
    print FILE "\n--DROP WORK CLASS SET DATABASE_WCS;\n";
  }

  print FILE "\n\n-- Drop all of the workloads  ";
  print FILE "\n------------------------------";
  for ($i = 0; $i < $workloadIndex; $i++)
  {
    print FILE "\n DROP WORKLOAD ", $workloads[$i], ";";
  }
 
  print FILE "\n\n-- Drop all of the service classes ";
  print FILE "\n-----------------------------------";
  print FILE "\n DROP SERVICE CLASS ", $unmanagedSubclass," UNDER ", $superclassName, ";";
  for ($i = 0; $i < $serviceClassIndex; $i++)
  {
    print FILE "\n DROP SERVICE CLASS ", $serviceClasses[$i], " UNDER " , $superclassName, ";";
  }
  print FILE "\n DROP SERVICE CLASS ", $superclassName, ";";

  # Set the workload back to automatic
  #-----------------------------------
  print FILE "\n\n-- Set workload to automatic    ";
  print FILE "\n-----------------------------   ";
  print FILE "\nSET WORKLOAD TO AUTOMATIC;      ";
  print FILE "\n                                ";

  close(FILE);

  return 0;
} # GenerateDropScript