MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/lib/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/lib/asmcmdqg.pm

#
# $Header: rdbms/src/client/tools/asmcmd/modules/asmcmdqg.pm /main/4 2016/10/07 07:39:35 diguzman Exp $
#
# asmcmdqg.pm
#
# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
#
#    NAME
#      asmcmdqg.pm - ASM CoMmanD line interface Quota Group operations
#
#    DESCRIPTION
#      This module implements the asmcmd for quota group operations.
#      1. mkqg - add quota group to the disk group
#         asmcmd> mkqg -G <diskgroup> <quotagroup> [ <property> <value> ]
#      2. rmqg - drop the quota group from the disk group
#         asmcmd> rmqg -G <diskgroup> <quotagroup>
#      3. chqg - modify quota group property
#         asmcmd> chqg -G <diskgroup> <quotagroup> <property> <value>
#      4. lsqg - list quota groups
#         asmcmd> lsqg [-G <diskgroup>] [--quotagroup <quotagroup>]
#                      [--suppressheader]
#      5. mvfg - move file group to quota group
#         asmcmd> mvfg -G <diskgroup> --filegroup <filegroup> <quotagroup>
#
#    NOTES
#      Project 47340: ASM Flex Disk Group - Quota Group
#
#    MODIFIED   (MM/DD/YY)
#    diguzman    09/29/16 - 22847981: improve mkqg validations
#    diguzman    05/30/16 - 19654070: Little change at _no_instance_cmd routine
#    jesugonz    08/13/15 - 21507269: Change GB to MB in queries
#    hpikkili    12/03/14 - proj47340: asmcmd for quota group
#    hpikkili    12/03/14 - Creation
#
#############################################################################
#
############################ Functions List #################################
# asmcmdqg_init
# asmcmdqg_process_cmd
# asmcmdqg_is_cmd
# asmcmdqg_process_lsqg
# asmcmdqg_process_mkqg
# asmcmdqg_process_rmqg
# asmcmdqg_process_chqg
# asmcmdqg_process_mvfg
# asmcmdqg_parse_int_args
# asmcmdqg_get_asmcmd_cmds
# asmcmdqg_is_no_instance_cmd
# asmcmdqg_syntax_error
# asmcmdqg_is_wildcard_cmd
# asmcmdqg_process_help
#############################################################################

package asmcmdqg;
require Exporter;
our @ISA    = qw(Exporter);
our @EXPORT = qw(asmcmdqg_init
                );

use strict;
use DBI qw(:sql_types);
use Getopt::Long qw(:config no_ignore_case bundling);
use asmcmdglobal;
use asmcmdshare;
use asmcmdparser;

use List::Util qw[min max];



####################### ASMCMDQG Global Constants ######################
# ASMCMD Column Header Names:
# Below are the names of the column headers for lsqg. These headers are the
# ASMCMD equivalent of the columns of v$asm_quotagroup.
our (%asmcmdqg_lsqg_header) = ('group_number'       , 'Group_Num',
                               'quotagroup_number'  , 'Quotagroup_Num',
                               'name'               , 'Quotagroup_Name',
                               'incarnation'        , 'Incarnation',
                               'used_quota_mb'      , 'Used_Quota_MB',
                               'quota_limit_mb'     , 'Quota_Limit_MB'
                              );



####################### ASMCMDQG Global Variables ######################
#
# The following list is primarily used for is_cmd callback.
# All other data comes from XML.
#
our (%asmcmdqg_cmds) = (mkqg => {},
                        rmqg => {},
                        chqg => {},
                        lsqg => {},
                        mvfg => {}
                       );

sub is_asmcmd
{
  return 1;
}

#############################################################################
# NAME
#   asmcmdqg_init
#
# DESCRIPTION
#   This function initializes the asmcmdqg module.  For now it merely
#   registers its callbacks with the asmcmdglobal module.
#
# PARAMETERS
#   None
#
# RETURNS
#   Null
#
# NOTES
#   Only asmcmdcore_main() calls this routine.
#############################################################################
sub init
{
  # All of the arrays defined in the asmcmdglobal module must be
  # initialized here.  Otherwise, an internal error will result.
  push (@asmcmdglobal_command_callbacks, \&asmcmdqg_process_cmd);
  push (@asmcmdglobal_help_callbacks, \&asmcmdqg_process_help);
  push (@asmcmdglobal_command_list_callbacks, \&asmcmdqg_get_asmcmd_cmds);
  push (@asmcmdglobal_is_command_callbacks, \&asmcmdqg_is_cmd);
  push (@asmcmdglobal_is_wildcard_callbacks, \&asmcmdqg_is_wildcard_cmd);
  push (@asmcmdglobal_syntax_error_callbacks, \&asmcmdqg_syntax_error);
  push (@asmcmdglobal_no_instance_callbacks, \&asmcmdqg_is_no_instance_cmd);
  %asmcmdglobal_cmds = (%asmcmdglobal_cmds, %asmcmdqg_cmds);

  #Perform ASMCMD consistency check if enabled
  if ($asmcmdglobal_hash{'consistchk'} eq 'y')
  {
     if (!asmcmdshare_check_option_consistency(%asmcmdqg_cmds))
     {
       exit 1;
     }
  }
}


#############################################################################
# NAME
#   asmcmdqg_process_cmd
#
# DESCRIPTION
#   This routine calls the appropriate routine to process the command
#   specified by $asmcmdglobal_hash{'cmd'}.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   1 if command is found in the asmcmdqg module; 0 otherwise.
#
# NOTES
#   Only asmcmdcore_shell() calls this routine.
#############################################################################
sub asmcmdqg_process_cmd
{
  my ($dbh) = @_;
  my ($succ) = 0;

  # Get current command from global value, which is set by
  # asmcmdtemplate_parse_asmcmd_args() and by asmcmdcore_shell().
  my ($cmd) = $asmcmdglobal_hash{'cmd'};

  # Declare and initialize hash of function pointers, each designating a
  # routine that processes an ASMCMDTEMPLATE command.
  my (%cmdhash) = ( mkqg => \&asmcmdqg_process_mkqg ,
                    rmqg => \&asmcmdqg_process_rmqg ,
                    chqg => \&asmcmdqg_process_chqg ,
                    lsqg => \&asmcmdqg_process_lsqg ,
                    mvfg => \&asmcmdqg_process_mvfg );

  if (defined ( $cmdhash{ $cmd } ))
  {    # If user specifies a known command, then call routine to process it. #
    $cmdhash{ $cmd }->($dbh);
    $succ = 1;
  }

  return $succ;
}


#############################################################################
# NAME
#   asmcmdqg_is_cmd
#
# DESCRIPTION
#   This routine checks if a user-entered command is one of the known ASMCMD
#   internal commands that belong to the ASMCMDQG module.
#
# PARAMETERS
#   arg (IN) - user-entered command name string.
#
# RETURNS
#   True if $arg is one of the known commands, false otherwise.
#############################################################################
sub asmcmdqg_is_cmd 
{
  my ($arg) = shift;

  return defined ( $asmcmdqg_cmds{ $arg } );
}


#############################################################################
# NAME
#   asmcmdqg_process_lsqg
#
# DESCRIPTION
#   This function processes the asmcmd command lsqg.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   Null.
#
# NOTES
#   Only asmcmdqg_process_cmd() calls this function.
#############################################################################
sub asmcmdqg_process_lsqg
{
  my ($dbh) = shift;

  my (%args);
  my ($ret);
  my (@what , @from, $sth, $qry, @where, @order, @tmp_cols);
  my ($k, $v, $row, $h);
  my (@qglist) = ();
  my ($qgname);
  my ($gnum);

  my (%min_col_wid, $print_format, $print_string, @what_print);

  # Get option parameters, if any.
  $ret = asmcmdqg_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
  return unless defined ($ret);

  if (defined($args{'G'}))
  {
    $gnum = asmcmdshare_get_gnum_from_gname($dbh, $args{'G'});
    if (!defined ($gnum))
    {
      my (@eargs) = ($args{'G'});
      asmcmdshare_error_msg(8001, \@eargs);
      return;
    }
  }

  if (defined($args{'quotagroup'}))
  {
    $qgname = $args{'quotagroup'};
    $qgname =~ tr/a-z/A-Z/;
  }

  @what_print = ();
  if ($gnum && $qgname)
  {
    push (@what, 'v$asm_quotagroup.quotagroup_number');
    push (@what, 'v$asm_quotagroup.incarnation');
    push (@what, 'v$asm_quotagroup.used_quota_mb');
    push (@what, 'v$asm_quotagroup.quota_limit_mb');

    push (@where, "v\$asm_quotagroup.group_number = $gnum");
    push (@where, "v\$asm_quotagroup.name = \'$qgname\'");

    push (@what_print, $asmcmdqg_lsqg_header{'quotagroup_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'incarnation'});
    push (@what_print, $asmcmdqg_lsqg_header{'used_quota_mb'});
    push (@what_print, $asmcmdqg_lsqg_header{'quota_limit_mb'});
  }
  elsif ($gnum)
  {
    push (@what, 'v$asm_quotagroup.quotagroup_number');
    push (@what, 'v$asm_quotagroup.name');
    push (@what, 'v$asm_quotagroup.incarnation');
    push (@what, 'v$asm_quotagroup.used_quota_mb');
    push (@what, 'v$asm_quotagroup.quota_limit_mb');

    push (@where, "v\$asm_quotagroup.group_number = $gnum");

    push (@what_print, $asmcmdqg_lsqg_header{'quotagroup_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'name'});
    push (@what_print, $asmcmdqg_lsqg_header{'incarnation'});
    push (@what_print, $asmcmdqg_lsqg_header{'used_quota_mb'});
    push (@what_print, $asmcmdqg_lsqg_header{'quota_limit_mb'});
  }
  elsif ($qgname)
  {
    push (@what, 'v$asm_quotagroup.group_number');
    push (@what, 'v$asm_quotagroup.quotagroup_number');
    push (@what, 'v$asm_quotagroup.incarnation');
    push (@what, 'v$asm_quotagroup.used_quota_mb');
    push (@what, 'v$asm_quotagroup.quota_limit_mb');

    push (@where, "v\$asm_quotagroup.name = \'$qgname\'");

    push (@order, 'v$asm_quotagroup.group_number');

    push (@what_print, $asmcmdqg_lsqg_header{'group_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'quotagroup_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'incarnation'});
    push (@what_print, $asmcmdqg_lsqg_header{'used_quota_mb'});
    push (@what_print, $asmcmdqg_lsqg_header{'quota_limit_mb'});
  }
  else
  {
    push (@what, 'v$asm_quotagroup.group_number');
    push (@what, 'v$asm_quotagroup.quotagroup_number');
    push (@what, 'v$asm_quotagroup.name');
    push (@what, 'v$asm_quotagroup.incarnation');
    push (@what, 'v$asm_quotagroup.used_quota_mb');
    push (@what, 'v$asm_quotagroup.quota_limit_mb');

    push (@order, 'v$asm_quotagroup.group_number');

    push (@what_print, $asmcmdqg_lsqg_header{'group_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'quotagroup_number'});
    push (@what_print, $asmcmdqg_lsqg_header{'name'});
    push (@what_print, $asmcmdqg_lsqg_header{'incarnation'});
    push (@what_print, $asmcmdqg_lsqg_header{'used_quota_mb'});
    push (@what_print, $asmcmdqg_lsqg_header{'quota_limit_mb'});
  }

  push (@from, 'v$asm_quotagroup');

  push (@order, 'v$asm_quotagroup.quotagroup_number');

  $sth = asmcmdshare_do_construct_select($dbh, \@what, \@from, \@where, 
                                         \@order);

  @tmp_cols = @{$sth->{NAME}};

  @what = ();
  foreach (@tmp_cols)
  {
    push (@what, "\L$_");
  }

  %min_col_wid = ();
  #initialize the min_col_wid array
  foreach (@what)
  {
    $min_col_wid{$_} = length($asmcmdqg_lsqg_header{$_});
  }

  #get the rows
  while (defined($row = asmcmdshare_fetch($sth)))
  {
    my (%info) = ();

    while (($k,$v) = each(%{$row}))
    {
      $k =~ tr/[A-Z]/[a-z]/;
      $info{$k} = $v;

      $min_col_wid{$k} = max($min_col_wid{$k}, length($v));
    }

    push (@qglist, \%info);
  }
  asmcmdshare_finish($sth);

  #create print format
  $print_format = '';

  foreach (@what)
  {
    $print_format .= "%-" . $min_col_wid{$_} . "s  ";
  }
  $print_format .= "\n";

  #print header if not suppressed and if #rows >= 1
  if (defined ($args{'suppressheader'}) || ($#qglist lt 0))
  {
    @what_print = ();
  }
  else
  {
    $print_string = sprintf($print_format, @what_print);
    asmcmdshare_print($print_string);
  }

  #print rows
  foreach $h (@qglist)
  {
    @what_print = ();
    foreach (@what)
    {
      push (@what_print, $h->{$_});
    }
    $print_string = sprintf($print_format, @what_print);
    asmcmdshare_print($print_string);
  }

  return;
}


#############################################################################
# NAME
#   asmcmdqg_process_mkqg
#
# DESCRIPTION
#   This function processes the asmcmd command mkqg.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   Null.
#
# NOTES
#   Only asmcmdqg_process_cmd() calls this function.
#############################################################################
sub asmcmdqg_process_mkqg
{
  my $dbh  = shift;
  my $trim = 1;
  my %args;
  my $ret;
  my $qry;
  my $dgname;
  my $qgname;
  my $property;
  my $value;
  my $set;

  # Get option parameters, if any.
  $ret = asmcmdqg_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
  return unless defined ($ret);

  # If there is an error with the generated SQL statement, avoid printing
  # details regarding it unless trace level is set to 'debug'
  undef $trim if ($asmcmdglobal_hash{'verbose'} =~ /^debug$/);

  # get the disk group name
  $dgname = uc($args{'G'});

  # get the quota group name and any specified property
  ($qgname, $property, $value) = @{$args{'mkqg'}};
  $qgname = uc($qgname);

  $qry = "ALTER DISKGROUP $dgname ADD QUOTAGROUP $qgname";

  if (defined($property))
  {
    $qry .= " SET $property = ";
    $qry .= "$value" if (defined ($value));
  }

  $ret = asmcmdshare_do_stmt($dbh, $qry, $trim);

  asmcmdshare_print "Diskgroup altered.\n" ;
}


#############################################################################
# NAME
#   asmcmdqg_process_rmqg
#
# DESCRIPTION
#   This function processes the asmcmd command rmqg.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   Null.
#
# NOTES
#   Only asmcmdqg_process_cmd() calls this function.
#############################################################################
sub asmcmdqg_process_rmqg
{
  my ($dbh) = @_;
  my (%args);
  my ($ret);
  my ($qry);
  my ($dgname, $qgname);

  # Get option parameters, if any.
  $ret = asmcmdqg_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
  return unless defined ($ret);

  # get the disk group name
  $dgname = $args{'G'};
  $dgname =~ tr/[a-z]/[A-Z]/;

  # get the quota group name
  ($qgname) = @{$args{'rmqg'}};
  $qgname =~ tr/[a-z]/[A-Z]/;

  $qry = "ALTER DISKGROUP " . $dgname . " DROP QUOTAGROUP " . $qgname;

  $ret = asmcmdshare_do_stmt($dbh, $qry);

  asmcmdshare_print "Diskgroup altered.\n" ;
}


#############################################################################
# NAME
#   asmcmdqg_process_chqg
#
# DESCRIPTION
#   This function processes the asmcmd command chqg.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   Null.
#
# NOTES
#   Only asmcmdqg_process_cmd() calls this function.
#############################################################################
sub asmcmdqg_process_chqg
{
  my ($dbh) = @_;
  my (%args);
  my ($ret);
  my ($qry);
  my ($dgname, $qgname, $property, $value);

  # Get option parameters, if any.
  $ret = asmcmdqg_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
  return unless defined ($ret);

  # get the disk group name
  $dgname = $args{'G'};
  $dgname =~ tr/[a-z]/[A-Z]/;

  # get the quota group name and any specified property
  ($qgname, $property, $value) = @{$args{'chqg'}};
  $qgname =~ tr/[a-z]/[A-Z]/;

  $qry = "ALTER DISKGROUP " . $dgname . " MODIFY QUOTAGROUP " . $qgname;

  if (defined($property))
  {
    $qry .= " SET $property = ";
    if (defined ($value))
    {
      $qry .= $value;
    }
  }

  $ret = asmcmdshare_do_stmt($dbh, $qry);

  asmcmdshare_print "Diskgroup altered.\n" ;
}


#############################################################################
# NAME
#   asmcmdqg_process_mvfg
#
# DESCRIPTION
#   This function processes the asmcmd command mvfg.
#
# PARAMETERS
#   dbh (IN) - initialized database handle, must be non-null.
#
# RETURNS
#   Null.
#
# NOTES
#   Only asmcmdqg_process_cmd() calls this function.
#############################################################################
sub asmcmdqg_process_mvfg
{
  my ($dbh) = @_;
  my (%args);
  my ($ret);
  my ($qry);
  my ($dgname, $qgname, $filegroup);

  # Get option parameters, if any.
  $ret = asmcmdqg_parse_int_args($asmcmdglobal_hash{'cmd'}, \%args);
  return unless defined ($ret);

  # get the disk group name
  $dgname = $args{'G'};
  $dgname =~ tr/[a-z]/[A-Z]/;

  # get the file group name
  $filegroup = $args{'filegroup'};
  $filegroup =~ tr/[a-z]/[A-Z]/;

  # get the quota group name and any specified property
  ($qgname) = @{$args{'mvfg'}};
  $qgname =~ tr/[a-z]/[A-Z]/;

  $qry  = "ALTER DISKGROUP " . $dgname . " MOVE FILEGROUP " . $filegroup;
  $qry .= " TO " . $qgname;

  $ret = asmcmdshare_do_stmt($dbh, $qry);

  asmcmdshare_print "Diskgroup altered.\n" ;
}


#############################################################################
# NAME
#   asmcmdqg_parse_int_args
#
# DESCRIPTION
#   This routine parses the arguments for flag options for ASMCMD internal
#   commands.
#
# PARAMETERS
#   cmd      (IN)  - user-entered command name string.
#   args_ref (OUT) - hash of user-specified flag options for a command,
#                    populated by getopts().
#
# RETURNS
#   Zero on success; undefined on error.
#
# NOTES
#   $cmd must already be verified as a valid ASMCMD internal command.
#############################################################################
sub asmcmdqg_parse_int_args
{
  my ($cmd, $args_ref) = @_;
  my ($key);
  my (@string);

  #include deprecated options if any
  if ($asmcmdglobal_deprecated_options{ $cmd })
  {
    foreach my $key (keys %{$asmcmdglobal_deprecated_options{ $cmd }})
    {
      push(@string, $asmcmdglobal_deprecated_options{$cmd}{$key}[0]);
    }
  }

  # Use asmcmdparser_parse_issued_command() from the asmcmdparser package to
  # parse arguments for internal commands. These arguments are stored in @ARGV.
  if (!asmcmdparser_parse_issued_command($cmd, $args_ref, \@string))
  {
    # Print correct command format if syntax error. #
    asmcmdqg_syntax_error($cmd);
    return undef;
  }
  return 0;
}


#############################################################################
# NAME
#   asmcmdqg_get_asmcmd_cmds
#
# DESCRIPTION
#   This routine constructs a string that contains a list of the names of all
#   ASMCMD internal commands and returns this string.
#
# PARAMETERS
#   None.
#
# RETURNS
#   A string contain a list of the names of all ASMCMD internal commands.
#
# NOTES
#   Used by the help command and by the error command when the user enters
#   an invalid internal command.
#############################################################################
sub asmcmdqg_get_asmcmd_cmds
{
  return asmcmdshare_filter_invisible_cmds(%asmcmdqg_cmds);
}


#############################################################################
# NAME
#   asmcmdqg_is_no_instance_cmd
#
# DESCRIPTION
#   This routine determines if a command can run without an ASM instance.
#
# PARAMETERS
#   arg (IN) - user-entered command name string.
#
# RETURNS
#   1 if $arg is a command that can run without an ASM instance or it does not
#   belong to this module
#   0 if $arg is a command that needs to connect to an ASM instance
#   -1 if $arg is a command that may use an ASM instance.
#
# NOTES
#
#############################################################################
sub asmcmdqg_is_no_instance_cmd
{
  my ($arg) = shift;
  my ($rc);

  return 1 unless defined($asmcmdqg_cmds{$arg});

  $rc = asmcmdshare_get_cmd_noinst($arg);
  if ($rc eq "true")
  {
    return 1;
  }
  elsif ($rc eq "undef")
  {
    return -1;
  }

  return 0;
}


#############################################################################
# NAME
#   asmcmdqg_syntax_error
#
# DESCRIPTION
#   This routine prints the correct syntax for a command to STDERR, used
#   when there is a syntax error.  If the command with bad syntax is asmcmd
#   itself, then asmcmdbase_syntax_error also calls exit() to quit out.
#
# PARAMETERS
#   cmd (IN) - user-entered command name string.
#
# RETURNS
#   Exits if cmd is "asmcmd" or "asmcmd_no_conn_str"; 1 if another command
#   that belongs to this module; 0 if command not found.
#
# NOTES
#   These errors are user-errors and not internal errors.  They are of type
#   record, not signal.  Thus, even if exit() is called, the exit value is
#   zero.
#############################################################################
sub asmcmdqg_syntax_error
{
  my ($cmd) = shift;
  my ($cmd_syntax);                               # Correct syntax for $cmd. #
  my ($succ) = 0;

  # display syntax only for commands from this module.
  if (asmcmdqg_is_cmd($cmd))
  {
    $cmd_syntax = asmcmdshare_get_help_syntax($cmd);  # Get syntax for $cmd. #
    $cmd_syntax = asmcmdshare_trim_str ($cmd_syntax);

    if (defined ($cmd_syntax))
    {
      asmcmdshare_printstderr 'usage: ' . $cmd_syntax . "\n";
      asmcmdshare_printstderr 'help:  help ' . $cmd . "\n";
      $succ = 1;
    }
  }

  return $succ;
}


#############################################################################
# NAME
#   asmcmdqg_is_wildcard_cmd
#
# DESCRIPTION
#   This routine determines if an ASMCMDQG command allows the use of wild
#   cards.
#
# PARAMETERS
#   arg (IN) - user-entered command name string.
#
# RETURNS
#   True if $arg is a command that can take wildcards as part of its argument,
#   false otherwise.
#############################################################################
sub asmcmdqg_is_wildcard_cmd
{
  my ($arg) = shift;

  return (defined ($asmcmdqg_cmds{ $arg }) &&
          (asmcmdshare_get_cmd_wildcard($arg) eq "true"));
}


#############################################################################
# NAME
#   asmcmdqg_process_help
#
# DESCRIPTION
#   This function is the help function for the asmcmdqg module.
#
# PARAMETERS
#   command (IN) - display the help message for this command.
#
# RETURNS
#   1 if command found; 0 otherwise.
#############################################################################
sub asmcmdqg_process_help
{
  my ($command) = shift;       # User-specified argument; show help on $cmd. #
  my ($desc);                                # Command description for $cmd. #
  my ($succ) = 0;                         # 1 if command found, 0 otherwise. #

  if (asmcmdqg_is_cmd ($command))
  {                              # User specified a command name to look up. #
    $desc = asmcmdshare_get_help_desc($command);
    asmcmdshare_print "$desc\n";
    $succ = 1;
  }

  return $succ;
}
1;

OHA YOOOO