/* * Reconnect to server (after error) */ sword db_oracle_reconnect(ora_con_t* con) { sword status; if (con->connected) db_oracle_disconnect(con); /* timelimited operation, but OCI tcp-network does not support it :( */ status = OCIServerAttach(con->srvhp, con->errhp, (OraText*)con->uri, con->uri_len, 0); if (status == OCI_SUCCESS) { ++con->connected; /* * timelimited operation, but OCI has BUG in asynch * implementation of OCISessionBegin :(. * * Next code is 'empiric hack' that work (tested) in v10/v11. */ status = begin_timelimit(con, 1); if (status != OCI_SUCCESS) goto done; status = OCISessionBegin(con->svchp, con->errhp, con->authp, OCI_CRED_RDBMS, OCI_DEFAULT); while (wait_timelimit(con, status)) { sword code; status = OCIServerVersion(con->svchp, con->errhp, NULL, 0, OCI_HTYPE_SVCCTX); if ( status != OCI_ERROR || OCIErrorGet(con->errhp, 1, NULL, &code, NULL, 0, OCI_HTYPE_ERROR) != OCI_SUCCESS) break; switch (code) { case 24909: /* other call in progress */ status = OCI_STILL_EXECUTING; continue; case 3127: /* no new operation until active ends */ status = OCISessionBegin(con->svchp, con->errhp, con->authp, OCI_CRED_RDBMS, OCI_DEFAULT); default: break; } break; } if (done_timelimit(con, status)) goto done; if (status == OCI_SUCCESS) ++con->connected; } done: return status; }
/* * Close the connection and release memory */ void db_oracle_free_connection(ora_con_t* con) { if (!con) return; if (con->connected) db_oracle_disconnect(con); if (con->svchp) OCIHandleFree(con->svchp, OCI_HTYPE_SVCCTX); if (con->authp) OCIHandleFree(con->authp, OCI_HTYPE_SESSION); if (con->srvhp) OCIHandleFree(con->srvhp, OCI_HTYPE_SERVER); if (con->errhp) OCIHandleFree(con->errhp, OCI_HTYPE_ERROR); if (con->envhp) OCIHandleFree(con->envhp, OCI_HTYPE_ENV); pkg_free(con); }
/* * close current timelimited operation and disconnect if timeout occured * return true only if work in asynch mode and timeout detect */ int done_timelimit(ora_con_t* con, sword status) { int ret = 0; if (!cur_asynch_mode) return 0; if (remap_status(con, status) == OCI_STILL_EXECUTING) { sword code; status = OCIBreak(con->svchp, con->errhp); if (status != OCI_SUCCESS) LM_ERR("driver: %s\n", db_oracle_error(con, status)); status = OCIReset(con->svchp, con->errhp); if ( status == OCI_ERROR && OCIErrorGet(con->errhp, 1, NULL, &code, NULL, 0, OCI_HTYPE_ERROR) == OCI_SUCCESS && code == 1013) { status = OCI_SUCCESS; } if (status != OCI_SUCCESS) LM_ERR("driver: %s\n", db_oracle_error(con, status)); db_oracle_disconnect(con); ++ret; } else { status = change_mode(con); if (status != OCI_SUCCESS) { LM_ERR("driver: %s\n", db_oracle_error(con, status)); ++ret; } else { cur_asynch_mode = 0; } } return ret; }
static const char* db_oracle_errorinfo(ora_con_t* con) { sword errcd; if (OCIErrorGet(con->errhp, 1, NULL, &errcd, (OraText*)errbuf, sizeof(errbuf), OCI_HTYPE_ERROR) != OCI_SUCCESS) errbuf[0] = '\0'; else switch (errcd) { case 28: /* your session has been killed */ case 30: /* session ID does not exists */ case 31: /* session marked for kill */ case 41: /* active time limit exceeded session terminated */ case 107: /* failed to connect to oracle listener */ case 115: /* connection refused; dispatcher table is full */ case 1033: /* init/shutdown in progress */ case 1034: /* not available (startup) */ case 1089: /* server shutdown */ case 1090: /* shutdown wait after command */ case 1092: /* oracle instance terminated. Disconnection forced */ case 1573: /* shutdown instance, no futher change allowed */ case 2049: /* timeout: distributed transaction waiting lock */ case 3113: /* EOF on communication channel */ case 3114: /* not connected */ case 3135: /* lost connection */ case 6033: /* connect failed, partner rejected connection */ case 6034: /* connect failed, partner exited unexpectedly */ case 6037: /* connect failed, node unrecheable */ case 6039: /* connect failed */ case 6042: /* msgrcv failure (DNT) */ case 6043: /* msgsend failure (DNT) */ case 6107: /* network server not found */ case 6108: /* connect to host failed */ case 6109: /* msgrcv failure (TCP) */ case 6110: /* msgsend failure (TCP) */ case 6114: /* SID lookup failure */ case 6124: /* TCP timeout */ case 6135: /* connect rejected; server is stopping (TCP) */ case 6144: /* SID unavaliable (TCP) */ case 6413: /* connection not open */ case 12150: /* tns can't send data, probably disconnect */ case 12152: /* tns unable to send break message */ case 12153: /* tns not connected */ case 12161: /* tns internal error */ case 12170: /* tns connect timeout */ case 12224: /* tns no listener */ case 12225: /* tns destination host unrecheable */ case 12230: /* tns network error */ case 12525: /* tns (internal) timeout */ case 12521: /* tns can't resolve db name */ case 12537: /* tns connection cloed */ case 12541: /* tns not running */ case 12543: /* tns destination host unrecheable */ case 12547: /* tns lost contact */ case 12560: /* tns protocol(transport) error */ case 12561: /* tns unknown error */ case 12608: /* tns send timeount */ case 12609: /* tns receive timeount */ LM_ERR("conneciom dropped\n"); db_oracle_disconnect(con); default: break; } return errbuf; }