connection.c
来自「postgresql-odbc,跨平台应用」· C语言 代码 · 共 2,634 行 · 第 1/5 页
C
2,634 行
mylog("CC_commit: sending COMMIT!\n"); ret = QR_command_maybe_successful(res); QR_Destructor(res); } return ret;}/* * Used to cancel a transaction. * We are almost always in the middle of a transaction. */charCC_abort(ConnectionClass *self){ char ret = TRUE; if (CC_is_in_trans(self)) { QResultClass *res = CC_send_query(self, rbkcmd, NULL, 0, NULL); mylog("CC_abort: sending ABORT!\n"); ret = QR_command_maybe_successful(res); QR_Destructor(res); } return ret;}/* This is called by SQLSetConnectOption etc also */charCC_set_autocommit(ConnectionClass *self, BOOL on){ CSTR func = "CC_set_autocommit"; BOOL currsts = CC_is_in_autocommit(self); if ((on && currsts) || (!on && !currsts)) return on; mylog("%s: %d->%d\n", func, currsts, on); if (CC_is_in_trans(self)) CC_commit(self); if (on) self->transact_status |= CONN_IN_AUTOCOMMIT; else self->transact_status &= ~CONN_IN_AUTOCOMMIT; return on;}/* This is called by SQLDisconnect also */charCC_cleanup(ConnectionClass *self){ int i; StatementClass *stmt; DescriptorClass *desc; if (self->status == CONN_EXECUTING) return FALSE; mylog("in CC_Cleanup, self=%p\n", self); /* Cancel an ongoing transaction */ /* We are always in the middle of a transaction, */ /* even if we are in auto commit. */ if (self->sock) { CC_abort(self); mylog("after CC_abort\n"); /* This actually closes the connection to the dbase */ SOCK_Destructor(self->sock); self->sock = NULL; } mylog("after SOCK destructor\n"); /* Free all the stmts on this connection */ for (i = 0; i < self->num_stmts; i++) { stmt = self->stmts[i]; if (stmt) { stmt->hdbc = NULL; /* prevent any more dbase interactions */ SC_Destructor(stmt); self->stmts[i] = NULL; } }#if (ODBCVER >= 0x0300) /* Free all the descs on this connection */ for (i = 0; i < self->num_descs; i++) { desc = self->descs[i]; if (desc) { DC_get_conn(desc) = NULL; /* prevent any more dbase interactions */ DC_Destructor(desc); free(desc); self->descs[i] = NULL; } }#endif /* ODBCVER */ /* Check for translation dll */#ifdef WIN32 if (self->translation_handle) { FreeLibrary(self->translation_handle); self->translation_handle = NULL; }#endif self->status = CONN_NOT_CONNECTED; self->transact_status = CONN_IN_AUTOCOMMIT; CC_conninfo_init(&(self->connInfo)); if (self->original_client_encoding) { free(self->original_client_encoding); self->original_client_encoding = NULL; } if (self->current_client_encoding) { free(self->current_client_encoding); self->current_client_encoding = NULL; } if (self->server_encoding) { free(self->server_encoding); self->server_encoding = NULL; } reset_current_schema(self); /* Free cached table info */ if (self->col_info) { for (i = 0; i < self->ntables; i++) { if (self->col_info[i]->result) /* Free the SQLColumns result structure */ QR_Destructor(self->col_info[i]->result); NULL_THE_NAME(self->col_info[i]->schema_name); NULL_THE_NAME(self->col_info[i]->table_name); free(self->col_info[i]); } free(self->col_info); self->col_info = NULL; } self->ntables = 0; self->coli_allocated = 0; if (self->num_discardp > 0 && self->discardp) { for (i = 0; i < self->num_discardp; i++) free(self->discardp[i]); self->num_discardp = 0; } if (self->discardp) { free(self->discardp); self->discardp = NULL; } mylog("exit CC_Cleanup\n"); return TRUE;}intCC_set_translation(ConnectionClass *self){#ifdef WIN32 CSTR func = "CC_set_translation"; if (self->translation_handle != NULL) { FreeLibrary(self->translation_handle); self->translation_handle = NULL; } if (self->connInfo.translation_dll[0] == 0) return TRUE; self->translation_option = atoi(self->connInfo.translation_option); self->translation_handle = LoadLibrary(self->connInfo.translation_dll); if (self->translation_handle == NULL) { CC_set_error(self, CONN_UNABLE_TO_LOAD_DLL, "Could not load the translation DLL.", func); return FALSE; } self->DataSourceToDriver = (DataSourceToDriverProc) GetProcAddress(self->translation_handle, "SQLDataSourceToDriver"); self->DriverToDataSource = (DriverToDataSourceProc) GetProcAddress(self->translation_handle, "SQLDriverToDataSource"); if (self->DataSourceToDriver == NULL || self->DriverToDataSource == NULL) { CC_set_error(self, CONN_UNABLE_TO_LOAD_DLL, "Could not find translation DLL functions.", func); return FALSE; }#endif return TRUE;}static intmd5_auth_send(ConnectionClass *self, const char *salt){ char *pwd1 = NULL, *pwd2 = NULL; ConnInfo *ci = &(self->connInfo); SocketClass *sock = self->sock; size_t md5len;inolog("md5 pwd=%s user=%s salt=%02x%02x%02x%02x%02x\n", ci->password, ci->username, (UCHAR)salt[0], (UCHAR)salt[1], (UCHAR)salt[2], (UCHAR)salt[3], (UCHAR)salt[4]); if (!(pwd1 = malloc(MD5_PASSWD_LEN + 1))) return 1; if (!EncryptMD5(ci->password, ci->username, strlen(ci->username), pwd1)) { free(pwd1); return 1; } if (!(pwd2 = malloc(MD5_PASSWD_LEN + 1))) { free(pwd1); return 1; } if (!EncryptMD5(pwd1 + strlen("md5"), salt, 4, pwd2)) { free(pwd2); free(pwd1); return 1; } free(pwd1); if (PROTOCOL_74(&(self->connInfo))){inolog("putting p and %s\n", pwd2); SOCK_put_char(sock, 'p');} md5len = strlen(pwd2); SOCK_put_int(sock, (Int4) (4 + md5len + 1), 4); SOCK_put_n_char(sock, pwd2, (Int4) (md5len + 1)); SOCK_flush_output(sock);inolog("sockerr=%d\n", SOCK_get_errcode(sock)); free(pwd2); return 0; }intEatReadyForQuery(ConnectionClass *conn){ int id = 0; if (PROTOCOL_74(&(conn->connInfo))) { BOOL is_in_error_trans = CC_is_in_error_trans(conn); switch (id = SOCK_get_char(conn->sock)) { case 'I': if (CC_is_in_trans(conn)) { if (is_in_error_trans) CC_on_abort(conn, NO_TRANS); else CC_on_commit(conn); } break; case 'T': CC_set_in_trans(conn); CC_set_no_error_trans(conn); if (is_in_error_trans) CC_on_abort_partial(conn); break; case 'E': CC_set_in_error_trans(conn); break; } } return id; }inthandle_error_message(ConnectionClass *self, char *msgbuf, size_t buflen, char *sqlstate, const char *comment, QResultClass *res){ BOOL new_format = FALSE, msg_truncated = FALSE, truncated, hasmsg = FALSE; SocketClass *sock = self->sock; char msgbuffer[ERROR_MSG_LENGTH]; UDWORD abort_opt;inolog("handle_error_message prptocol=%s\n", self->connInfo.protocol); if (PROTOCOL_74(&(self->connInfo))) new_format = TRUE;inolog("new_format=%d\n", new_format); if (new_format) { size_t msgl; msgbuf[0] = '\0'; for (;;) { truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); if (!msgbuffer[0]) break; mylog("%s: 'E' - %s\n", comment, msgbuffer); qlog("ERROR from backend during %s: '%s'\n", comment, msgbuffer); msgl = strlen(msgbuffer + 1); switch (msgbuffer[0]) { case 'S': if (buflen > 0) { strncat(msgbuf, msgbuffer + 1, buflen); buflen -= msgl; } if (buflen > 0) { strncat(msgbuf, ": ", buflen); buflen -= 2; } break; case 'M': case 'D': if (buflen > 0) { if (hasmsg) { strcat(msgbuf, "\n"); buflen--; } if (buflen > 0) { strncat(msgbuf, msgbuffer + 1, buflen); buflen -= msgl; } } if (truncated) msg_truncated = truncated; hasmsg = TRUE; break; case 'C': if (sqlstate) strncpy(sqlstate, msgbuffer + 1, 8); break; } if (buflen < 0) buflen = 0; while (truncated) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); } } else { msg_truncated = SOCK_get_string(sock, msgbuf, (Int4) buflen); /* Remove a newline */ if (msgbuf[0] != '\0' && msgbuf[(int)strlen(msgbuf) - 1] == '\n') msgbuf[(int)strlen(msgbuf) - 1] = '\0'; mylog("%s: 'E' - %s\n", comment, msgbuf); qlog("ERROR from backend during %s: '%s'\n", comment, msgbuf); for (truncated = msg_truncated; truncated;) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); } abort_opt = 0; if (!strncmp(msgbuffer, "FATAL", 5)) { CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_ERROR); abort_opt = CONN_DEAD; } else { CC_set_errornumber(self, CONNECTION_SERVER_REPORTED_WARNING); if (CC_is_in_trans(self)) CC_set_in_error_trans(self); } if (0 != abort_opt#ifdef _LEGACY_MODE_ || TRUE#endif /* _LEGACY_NODE_ */ ) CC_on_abort(self, abort_opt); if (res) { QR_set_rstatus(res, PORES_FATAL_ERROR); QR_set_message(res, msgbuf); QR_set_aborted(res, TRUE); } return msg_truncated;}inthandle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char *sqlstate, const char *comment, QResultClass *res){ BOOL new_format = FALSE, msg_truncated = FALSE, truncated, hasmsg = FALSE; SocketClass *sock = self->sock; char msgbuffer[ERROR_MSG_LENGTH]; if (PROTOCOL_74(&(self->connInfo))) new_format = TRUE; if (new_format) { size_t msgl; msgbuf[0] = '\0'; for (;;) { truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); if (!msgbuffer[0]) break; mylog("%s: 'N' - %s\n", comment, msgbuffer); qlog("NOTICE from backend during %s: '%s'\n", comment, msgbuffer); msgl = strlen(msgbuffer + 1); switch (msgbuffer[0]) { case 'S': if (buflen > 0) { strncat(msgbuf, msgbuffer + 1, buflen); buflen -= msgl; } if (buflen > 0) { strncat(msgbuf, ": ", buflen); buflen -= 2; } break; case 'M': case 'D': if (buflen > 0) { if (hasmsg) { strcat(msgbuf, "\n"); buflen--; } if (buflen > 0) { strncat(msgbuf, msgbuffer + 1, buflen); buflen -= msgl; } } else msg_truncated = TRUE; if (truncated) msg_truncated = truncated; hasmsg = TRUE; break; case 'C': if (sqlstate && !sqlstate[0] && strcmp(msgbuffer + 1, "00000")) strncpy(sqlstate, msgbuffer + 1, 8); break; } if (buflen < 0) msg_truncated = TRUE; while (truncated) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); } } else { msg_truncated = SOCK_get_string(sock, msgbuf, (Int4) buflen); /* Remove a newline */ if (msgbuf[0] != '\0' && msgbuf[strlen(msgbuf) - 1] == '\n') msgbuf[strlen(msgbuf) - 1] = '\0'; mylog("%s: 'N' - %s\n", comment, msgbuf); qlog("NOTICE from backend during %s: '%s'\n", comment, msgbuf); for (truncated = msg_truncated; truncated;) truncated = SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); } if (res) { if (QR_command_successful(res)) QR_set_rstatus(res, PORES_NONFATAL_ERROR); QR_set_notice(res, msgbuf); /* will dup this string */ } return msg_truncated;}CSTR std_cnf_strs = "standard_conforming_strings";void getParameterValues(ConnectionClass *conn){ SocketClass *sock = conn->sock; /* ERROR_MSG_LENGTH is suffcient */ char msgbuffer[ERROR_MSG_LENGTH + 1]; SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer));inolog("parameter name=%s\n", msgbuffer); if (stricmp(msgbuffer, "server_encoding") == 0) { SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); if (conn->server_encoding) free(conn->server_encoding); conn->server_encoding = strdup(msgbuffer); } else if (stricmp(msgbuffer, "client_encoding") == 0) { SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); if (conn->current_client_encoding) free(conn->current_client_encoding); conn->current_client_encoding = strdup(msgbuffer); } else if (stricmp(msgbuffer, std_cnf_strs) == 0) { SOCK_get_string(sock, msgbuffer, sizeof(msgbuffer)); if (stricmp(msgbuffer, "on") == 0) { mylog("%s=%s\n", std_cnf_strs, msgbuffer); conn->escape_in_literal = '\0'; } } else if (stricmp(msgbuffer, "server_version") == 0) { char szVersion[32]; int major, minor;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?