DB2-Admin

 view release on metacpan or  search on metacpan

Admin.xs  view on Meta::CPAN

                ptr = "Restore";
                break;
            case DB2HISTORY_OP_ALT_TABLESPACE:
                ptr = "Alter Tablespace";
                break;
            case DB2HISTORY_OP_UNLOAD:
                ptr = "Unload";
                break;
            case DB2HISTORY_OP_ARCHIVE_LOG:
                ptr = "Archive Log";
                break;
            default:
                ptr = "(unknown)";
            }
            hv_store(entry, "Operation", 9,  newSVpv(ptr, strlen(ptr)), FALSE);

            /* Object enum */
            /* FIXME: call this granularity? */
            switch(entry_data.oObject) {
            case DB2HISTORY_GRAN_DB:
                ptr = "Database";
                break;
            case DB2HISTORY_GRAN_TBS:
                ptr = "Tablespace";
                break;
            case DB2HISTORY_GRAN_TABLE:
                ptr = "Table";
                break;
            case DB2HISTORY_GRAN_INDEX:
                ptr = "Index";
                break;
            default:
                ptr = "(unknown)";
            }
            hv_store(entry, "Object", 6,  newSVpv(ptr, strlen(ptr)), FALSE);

            /* Operation type enum */
            ptr = NULL;
            switch(entry_data.oOperation) {
            case DB2HISTORY_OP_BACKUP:
                switch(entry_data.oOptype) {
                case DB2HISTORY_OPTYPE_OFFLINE:
                    ptr = "Offline";
                    break;
                case DB2HISTORY_OPTYPE_ONLINE:
                    ptr = "Online";
                    break;
                case DB2HISTORY_OPTYPE_INCR_OFFLINE:
                    ptr = "Incremental Offline";
                    break;
                case DB2HISTORY_OPTYPE_INCR_ONLINE:
                    ptr = "Incremental Online";
                    break;
                case DB2HISTORY_OPTYPE_DELT_OFFLINE:
                    ptr = "Delta Offline";
                    break;
                case DB2HISTORY_OPTYPE_DELT_ONLINE:
                    ptr = "Delta Online";
                    break;
                default:
                    ptr = "(unknown backup operation type)";
                }
                break;
            case DB2HISTORY_OP_QUIESCE:
                switch(entry_data.oOptype) {
                case DB2HISTORY_OPTYPE_SHARE:
                    ptr = "Share";
                    break;
                case DB2HISTORY_OPTYPE_UPDATE:
                    ptr = "Update";
                    break;
                case DB2HISTORY_OPTYPE_EXCL:
                    ptr = "Exclusive";
                    break;
                case DB2HISTORY_OPTYPE_RESET:
                    ptr = "Reset";
                    break;
                default:
                    ptr = "(unknown quiesce operation type)";
                }
                break;
            case DB2HISTORY_OP_ROLLFWD:
                switch(entry_data.oOptype) {
                case DB2HISTORY_OPTYPE_EOL:
                    ptr = "End Of Logs";
                    break;
                case DB2HISTORY_OPTYPE_PIT:
                    ptr = "Point In Time";
                    break;
                default:
                    ptr = "(unknown rollforward operation type)";
                }
                break;
            case DB2HISTORY_OP_LOAD: /* FALLTHRU */
            case DB2HISTORY_OP_LOAD_COPY:
                switch(entry_data.oOptype) {
                case DB2HISTORY_OPTYPE_INSERT:
                    ptr = "Insert";
                    break;
                case DB2HISTORY_OPTYPE_REPLACE:
                    ptr = "Replace";
                    break;
                default:
                    ptr = "(unknown load operation type)";
                }
                break;
            case DB2HISTORY_OP_ALT_TABLESPACE:
                switch(entry_data.oOptype) {
                case DB2HISTORY_OPTYPE_ADD_CONT:
                    ptr = "Add Container";
                    break;
                case DB2HISTORY_OPTYPE_REB:
                    ptr = "Rebalance";
                    break;
                default:
                    ptr = "(unknown alter tablespace operation type)";
                }
                break;
                /* The Archive Log operation types are for BD2 >= V8.2 */
#ifdef DB2HISTORY_OPTYPE_PRIMARY
            case DB2HISTORY_OP_ARCHIVE_LOG:

Admin.xs  view on Meta::CPAN

                croak("Failed to set client information - sqleseti() failed with sqlcode %d\n", global_sqlca.sqlcode);
            }
            while (--no_items >= 0)
                Safefree(client_app_info[no_items].pValue);
        }

        /* Always retrieve client information */
        client_app_info[0].type = SQLE_CLIENT_INFO_USERID;
        Newz(0, client_app_info[0].pValue, SQLE_CLIENT_USERID_MAX_LEN + 1,
             char);
        client_app_info[1].type = SQLE_CLIENT_INFO_WRKSTNNAME;
        Newz(0, client_app_info[1].pValue, SQLE_CLIENT_WRKSTNNAME_MAX_LEN + 1,
             char);
        client_app_info[2].type = SQLE_CLIENT_INFO_APPLNAME;
        Newz(0, client_app_info[2].pValue, SQLE_CLIENT_APPLNAME_MAX_LEN + 1,
             char);
        client_app_info[3].type = SQLE_CLIENT_INFO_ACCTSTR;
        Newz(0, client_app_info[3].pValue, SQLE_CLIENT_ACCTSTR_MAX_LEN + 1,
             char);
        no_items = 4;
        sqleqryi(strlen(dbname), dbname, no_items, client_app_info,
                 &global_sqlca);
        if (global_sqlca.sqlcode != 0) {
            croak("Failed to get client information - sqleqryi() failed with sqlcode %d\n", global_sqlca.sqlcode);
        }

        /* Create return value */
        retval = (HV*)sv_2mortal((SV*)newHV());
        len = client_app_info[0].length;
        if (len) {
            hv_store(retval, "ClientUserid", 12,
                     newSVpvn(client_app_info[0].pValue, len), FALSE);
        }

        len = client_app_info[1].length;
        if (len) {
            hv_store(retval, "Workstation", 11,
                     newSVpvn(client_app_info[1].pValue, len), FALSE);
        }

        len = client_app_info[2].length;
        if (len) {
            hv_store(retval, "Application", 11,
                     newSVpvn(client_app_info[2].pValue, len), FALSE);
        }

        len = client_app_info[3].length;
        if (len) {
            hv_store(retval, "AccountingString", 16,
                     newSVpvn(client_app_info[3].pValue, len), FALSE);
        }
        no_items = 4;
        while (--no_items >= 0)
            Safefree(client_app_info[no_items].pValue);
        Return = newRV_noinc((SV*)retval);
        XPUSHs(Return);
    }


#
# Perform a backup
#
# Parameters:
# - Database name
# - Target (ref to array of strings)
# - Tablespaces (ref to array of tablespaces)
# - Options (hash reference)
# Returns:
# - Ref to hash with ApplicationId/Timestamp/BackupSize/SQLCode/NodeInfo/...
#
void
db2Backup(db_alias, target, tbspaces, options)
     char *db_alias;
     SV   *target;
     SV   *tbspaces;
     SV   *options;

     PPCODE:
     {
         db2BackupStruct            backup_info;
         db2MediaListStruct         location_info = { NULL, 0, 0 };
         char                     **locations = NULL;
         db2TablespaceStruct        tablespace_info = { NULL, 0 };
         char                     **tablespaces = NULL;
#ifdef DB2BACKUP_MPP
         db2NodeType               *node_list = NULL;
         db2BackupMPPOutputStruct  *mpp_output = NULL;
#endif /* DB2BACKUP_MPP */
         SV                        *value;
         char                      *key;
         I32                        keylen;

         /* Check target is valid */
         if ((!SvROK(target)) ||
             (SvTYPE(SvRV(target)) != SVt_PVAV)) {
             croak("Array reference expected for parameter 'target'");
         }
         /* Check tablespaces is valid */
         if ((!SvROK(tbspaces)) ||
             (SvTYPE(SvRV(tbspaces)) != SVt_PVAV)) {
             croak("Array reference expected for parameter 'tbspaces'");
         }
         /* Check options is valid */
         if ((!SvROK(options)) ||
             (SvTYPE(SvRV(options)) != SVt_PVHV)) {
             croak("Hash reference expected for parameter 'options'");
         }

         /*
          * The backup structure differs between DB2 releases,
          * so it's hard to write an initializer.  We will
          * just zero it.
          */
         memset(&backup_info, 0, sizeof(backup_info));
         backup_info.piDBAlias = db_alias;

         /* Set up target */
         backup_info.piMediaList = &location_info;
         backup_info.iCallerAction = DB2BACKUP_NOINTERRUPT; /* See Action below */
         location_info.locationType = SQLU_LOCAL_MEDIA;  /* See TargetType below */
         if (av_len((AV*)SvRV(target)) >= 0) {
             AV     *media;
             I32     no_entries, counter;

             media = (AV*)SvRV(target);
             no_entries = av_len(media) + 1;
             location_info.numLocations = no_entries;
             Newz(0, locations, no_entries, char *);
             location_info.locations = locations;

             for (counter = 0; counter < no_entries; counter++) {
                 SV **array_elem;

                 array_elem = av_fetch(media, counter, FALSE);
                 if (SvPOK(*array_elem)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(*array_elem, len);
                     locations[counter] = val;
                 } else {
                     croak("Element '%d' (offset-zero based) in target array is invalid: not a string\n", counter);
                 }
             }
         } /* End if: have target entries */

         /* Set up tablespaces */
         if (av_len((AV*)SvRV(tbspaces)) >= 0) {
             AV     *tblist;
             I32     no_entries, counter;

             backup_info.iOptions |= DB2BACKUP_TABLESPACE;
             backup_info.piTablespaceList = &tablespace_info;
             tblist = (AV*)SvRV(tbspaces);
             no_entries = av_len(tblist) + 1;
             tablespace_info.numTablespaces = no_entries;
             Newz(0, tablespaces, no_entries, char *);
             tablespace_info.tablespaces = tablespaces;

             for (counter = 0; counter < no_entries; counter++) {
                 SV **array_elem;

                 array_elem = av_fetch(tblist, counter, FALSE);
                 if (SvPOK(*array_elem)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(*array_elem, len);
                     tablespaces[counter] = val;
                 } else {
                     croak("Element '%d' (offset-zero based) in tablespaces array is invalid: not a string\n", counter);
                 }
             }
         } else {
             backup_info.iOptions |= DB2BACKUP_DB;
         } /* End if: have tablespace entries */

         /*
          * Handle the backup options (hash reference):
          * - Type
          * - Action
          * - Nodes
          * - ExceptNodes
          * - Online
          * - Compress
          * - IncludeLogs
          * - ExcludeLogs
          * - ImpactPriority
          * - Parallelism
          * - NumBuffers
          * - BufferSize
          * - TargetType
          * - Userid
          * - Password
          */
         (void)hv_iterinit((HV*)SvRV(options));
         while ((value = hv_iternextsv((HV*)SvRV(options),
                                       (char **)&key, &keylen))) {
             if (strEQ(key, "Type")) { /* Full / Incremental / Delta */
                 if (SvPOK(value)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(value, len);
                     if (strEQ(val, "Full")) {
                         /* Default: nothing to do */
                     } else if (strEQ(val, "Incremental")) {
                         backup_info.iOptions |= DB2BACKUP_INCREMENTAL;
                     } else if (strEQ(val, "Delta")) {
                         backup_info.iOptions |= DB2BACKUP_DELTA;
                     } else {
                         croak("Unsupported value '%s' for Options key '%s'\n",
                               val, key);
                     }
                 } else {
                     croak("Illegal value for Options key '%s': not a string\n", key);
                 }
             } else if (strEQ(key, "Action")) {
                 if (SvPOK(value)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(value, len);
                     if (strEQ(val, "Start")) {
                         backup_info.iCallerAction = DB2BACKUP_BACKUP;
                     } else if (strEQ(val, "NoInterrupt")) {
                         backup_info.iCallerAction = DB2BACKUP_NOINTERRUPT;
                     } else if (strEQ(val, "Continue")) {
                         backup_info.iCallerAction = DB2BACKUP_CONTINUE;
                     } else if (strEQ(val, "Terminate")) {
                         backup_info.iCallerAction = DB2BACKUP_TERMINATE;
                     } else if (strEQ(val, "DeviceTerminate")) {
                         backup_info.iCallerAction = DB2BACKUP_DEVICE_TERMINATE;
                     } else if (strEQ(val, "ParamCheck")) {
                         backup_info.iCallerAction = DB2BACKUP_PARM_CHK;
                     } else if (strEQ(val, "ParamCheckOnly")) {
                         backup_info.iCallerAction = DB2BACKUP_PARM_CHK_ONLY;
                     } else {
                         croak("Unsupported value '%s' for Options key '%s'\n",
                               val, key);
                     }
                 } else {
                     croak("Illegal value for Options key '%s': not a string\n", key);
                 }
#ifdef DB2BACKUP_MPP
             } else if (strEQ(key, "Nodes") || strEQ(key, "ExceptNodes")) {
                 if (backup_info.iOptions & DB2BACKUP_MPP)
                     croak("The options 'Nodes' and 'ExceptNodes' may not be combinbed\n");
                 backup_info.iOptions |= DB2BACKUP_MPP;
                 if (strEQ(key, "Nodes") && SvPOK(value)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(value, len);
                     if (strEQ(val, "All"))
                         backup_info.iAllNodeFlag = DB2_ALL_NODES;
                     else
                         croak("Invalid Options key %s value %s: must be 'All' or array-reference\n", key, val);
                 } else if (SvROK(value) && SvTYPE(SvRV(value)) == SVt_PVAV) {
                     AV     *nodes;
                     I32     no_nodes, counter;

                     if (strEQ(key, "Nodes"))
                         backup_info.iAllNodeFlag = DB2_NODE_LIST;
                     else
                         backup_info.iAllNodeFlag = DB2_ALL_EXCEPT;

                     nodes = (AV*)SvRV(value);
                     no_nodes = backup_info.iNumNodes = av_len(nodes) + 1;
                     Newz(0, node_list, no_nodes, db2NodeType);
                     backup_info.piNodeList = node_list;
                     for (counter = 0; counter < no_nodes; counter++) {
                         SV **array_elem;

                         array_elem = av_fetch(nodes, counter, FALSE);
                         if ((!SvROK(*array_elem)) && looks_like_number(*array_elem)) {
                             node_list[counter] = SvUV(*array_elem);
                         } else {
                             croak("Element '%d' (offset-zero based) in %s array is invalid: not a number\n", counter, key);
                         }
                     } /* End: for each node */
                 } else {
                     croak("Illegal value for Options key '%s': must be an array reference, or 'All' for key 'Nodes'\n", key);
                 }

                 /*
                  * Set up output list.  Size it at maximum of 1024 nodes.
                  *
                  * We configure the first node to look like the last-node
                  * marker that db2Backup writes when successful.
                  */
                 Newz(0, mpp_output, 1024, db2BackupMPPOutputStruct);
                 backup_info.iNumMPPOutputStructs = 1024;
                 backup_info.poMPPOutputStruct = mpp_output;
                 mpp_output[0].nodeNumber = (db2NodeType)-1;
#endif /* DB2BACKUP_MPP */
             } else if (strEQ(key, "Online")) { /* Boolean */
                 if (SvTRUE(value)) {
                     backup_info.iOptions |= DB2BACKUP_ONLINE;
                 } else {
                     backup_info.iOptions |= DB2BACKUP_OFFLINE;
                 }
             } else if (strEQ(key, "Compress")) { /* Boolean */
                 if (SvTRUE(value)) {
                     backup_info.iOptions |= DB2BACKUP_COMPRESS;
                 }
             } else if (strEQ(key, "IncludeLogs")) { /* Boolean */
                 if (SvTRUE(value)) {
                     backup_info.iOptions |= DB2BACKUP_INCLUDE_LOGS;
                 }
             } else if (strEQ(key, "ExcludeLogs")) { /* Boolean */
                 if (SvTRUE(value)) {
                     backup_info.iOptions |= DB2BACKUP_EXCLUDE_LOGS;
                 }
             } else if (strEQ(key, "ImpactPriority")) { /* 32-bit unsgn number */
                 if ((!SvROK(value)) && looks_like_number(value)) {
                     backup_info.iUtilImpactPriority = SvUV(value);
                 } else {
                     croak("Illegal value for Options key '%s': not a number\n", key);
                 }
             } else if (strEQ(key, "Parallelism")) { /* 32-bit unsg number */
                 if ((!SvROK(value)) && looks_like_number(value)) {
                     backup_info.iParallelism = SvUV(value);
                 } else {
                     croak("Illegal value for Options key '%s': not a number\n", key);
                 }
             } else if (strEQ(key, "NumBuffers")) { /* 32-bit unsg number */
                 if ((!SvROK(value)) && looks_like_number(value)) {
                     backup_info.iNumBuffers = SvUV(value);
                 } else {
                     croak("Illegal value for Options key '%s': not a number\n", key);
                 }
             } else if (strEQ(key, "BufferSize")) { /* 32-bit unsg number */
                 if ((!SvROK(value)) && looks_like_number(value)) {
                     backup_info.iBufferSize = SvUV(value);
                 } else {
                     croak("Illegal value for Options key '%s': not a number\n", key);
                 }
             } else if (strEQ(key, "TargetType")) { /* String */
                 if (SvPOK(value)) {
                     char   *val;
                     STRLEN  len;

                     val = SvPV(value, len);
                     if (strEQ(val, "Local")) {
                         location_info.locationType = SQLU_LOCAL_MEDIA;
#ifdef SQLU_XBSA_MEDIA
                     } else if (strEQ(val, "XBSA")) {
                         location_info.locationType = SQLU_XBSA_MEDIA;
#endif /* SQLU_XBSA_MEDIA */
                     } else if (strEQ(val, "TSM")) {
                         location_info.locationType = SQLU_TSM_MEDIA;
#ifdef SQLU_SNAPSHOT_MEDIA
                     } else if (strEQ(val, "Snapshot")) {
                         location_info.locationType = SQLU_SNAPSHOT_MEDIA;
#endif /* SQLU_SNAPSHOT_MEDIA */
                     } else if (strEQ(val, "Other")) {
                         location_info.locationType = SQLU_OTHER_MEDIA;
                     } else {
                         croak("Unsupported value '%s' for Options key '%s'\n",
                               val, key);
                     }
                 } else {
                     croak("Illegal value for Options key '%s': not a string\n", key);
                 }
             } else if (strEQ(key, "Userid")) { /* String */
                 if (SvPOK(value)) {
                     STRLEN  len;

                     backup_info.piUsername = SvPV(value, len);
                 } else {
                     croak("Illegal value for Options key '%s': not a string\n", key);
                 }
             } else if (strEQ(key, "Password")) { /* String */
                 if (SvPOK(value)) {
                     STRLEN  len;

                     backup_info.piPassword = SvPV(value, len);
                 } else {
                     croak("Illegal value for Options key '%s': not a string\n", key);
                 }
             } else {
                 croak("Unexpected Options key '%s'", key);
             }
         } /* End: each hash entry */

         /* Actually call db2Backup */
         db2Backup(DB2_VERSION_ENUM, &backup_info, &global_sqlca);
         Safefree(locations);
         Safefree(tablespaces);

         /* Return a hash with backup details if okay, undef on error */
         {
             HV   *retval;
             SV   *Return;
             char  buffer[MESSAGE_BUFFER_SIZE];
             int   status;

             /* Main return code */
             retval = (HV*)sv_2mortal((SV*)newHV());
             if (backup_info.oApplicationId[0]) { /* SKip empty string */
                 hv_store(retval, "ApplicationId", 13,
                          newSVpv(backup_info.oApplicationId, strlen(backup_info.oApplicationId)), FALSE);
             }
             if (backup_info.oTimestamp[0]) { /* Skip empty string */
                 hv_store(retval, "Timestamp", 9,
                          newSVpv(backup_info.oTimestamp, strlen(backup_info.oTimestamp)), FALSE);
             }
             hv_store(retval, "BackupSize", 10,
                      newSVuv(backup_info.oBackupSize), FALSE);
             hv_store(retval, "SQLCode", 7,
                      newSViv(global_sqlca.sqlcode), FALSE);
             status = sqlaintp(buffer, MESSAGE_BUFFER_SIZE, 0,
                               &global_sqlca);
             if (status > 0) {
                 hv_store(retval, "Message", 7,
                          newSVpv(buffer, status), FALSE);
             }
             status = sqlogstt(buffer, MESSAGE_BUFFER_SIZE, 0,
                               global_sqlca.sqlstate);
             if (status > 0) {
                 hv_store(retval, "State", 5,
                          newSVpv(buffer, status), FALSE);
             }
#ifdef DB2BACKUP_MPP
             if (mpp_output) {
                 int  counter;
                 AV  *part_retval;

                 part_retval = newAV();
                 hv_store(retval, "NodeInfo", 8,
                          newRV_noinc((SV*)part_retval), FALSE);
                 for (counter = 0;
                      counter < backup_info.iNumMPPOutputStructs;
                      counter++) {
                     HV                       *node_elem;
                     db2BackupMPPOutputStruct *ni;

                     /*
                      * We may have more elements than results;
                      * leave if we find an empty element.  Note
                      * we configure the first node like this
                      * before calling db2Backup, so we can handle
                      * the case where the call fails entirely.
                      */
                     ni = mpp_output + counter;
                     if (ni->nodeNumber == (db2NodeType)-1 &&
                         ni->backupSize == 0 &&
                         ni->sqlca.sqlcode == 0)
                         break;

                     node_elem = newHV();
                     hv_store(node_elem, "NodeNum", 7,
                              newSVuv(ni->nodeNumber), FALSE);
                     hv_store(node_elem, "BackupSize", 10,
                              newSVuv(ni->backupSize), FALSE);
                     hv_store(node_elem, "SQLCode", 7,
                              newSViv(ni->sqlca.sqlcode), FALSE);
                     status = sqlaintp(buffer, MESSAGE_BUFFER_SIZE, 0,
                                       &ni->sqlca);
                     if (status > 0) {
                         hv_store(node_elem, "Message", 7,
                                  newSVpv(buffer, status), FALSE);
                     }
                     status = sqlogstt(buffer, MESSAGE_BUFFER_SIZE, 0,
                                       ni->sqlca.sqlstate);
                     if (status > 0) {
                         hv_store(node_elem, "State", 5,
                                  newSVpv(buffer, status), FALSE);
                     }
                     av_push(part_retval, newRV_noinc((SV*)node_elem));
                 } /* End: for each node */

                 Safefree(mpp_output);
                 Safefree(node_list);
             } /* End: if have node output */
#endif /* DB2BACKUP_MPP */

             /* Push both return values. */
             Return = newRV_noinc((SV*)retval);
             XPUSHs(Return);
         }
     }


#
# Return the SQL code for the global sqlca data structure
#
#   0: okay
# > 0: warning
# < 0: error
#
int
sqlcode()
CODE:
     RETVAL = global_sqlca.sqlcode;
OUTPUT:
     RETVAL


#
# Display the error message for the global sqlca data structure
#
# Returns:
# - String with error message / undef
#
void
sqlaintp()

     PPCODE:
     {
         char buffer[MESSAGE_BUFFER_SIZE];
         int  status;
         SV  *Return;

         status = sqlaintp(buffer, MESSAGE_BUFFER_SIZE, 0, &global_sqlca);



( run in 1.571 second using v1.01-cache-2.11-cpan-5837b0d9d2c )