DB2-Admin
view release on metacpan or search on metacpan
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:
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 )