Line data Source code
1 : /* 2 : * SPDX-License-Identifier: MPL-2.0 3 : * 4 : * This Source Code Form is subject to the terms of the Mozilla Public 5 : * License, v. 2.0. If a copy of the MPL was not distributed with this 6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. 7 : * 8 : * Copyright 2024 MonetDB Foundation; 9 : * Copyright August 2008 - 2023 MonetDB B.V.; 10 : * Copyright 1997 - July 2008 CWI. 11 : */ 12 : 13 : /* 14 : * This code was created by Peter Harvey (mostly during Christmas 98/99). 15 : * This code is LGPL. Please ensure that this message remains in future 16 : * distributions and uses of this code (thats about all I get out of it). 17 : * - Peter Harvey pharvey@codebydesign.com 18 : * 19 : * This file has been modified for the MonetDB project. See the file 20 : * Copyright in this directory for more information. 21 : */ 22 : 23 : /********************************************** 24 : * ODBCDbc.c 25 : * 26 : * Description: 27 : * This file contains the functions which operate on 28 : * ODBC connection structures/objects (see ODBCDbc.h). 29 : * 30 : * Author: Martin van Dinther, Sjoerd Mullender 31 : * Date : 30 aug 2002 32 : * 33 : **********************************************/ 34 : 35 : #include "ODBCGlobal.h" 36 : #include "ODBCDbc.h" 37 : 38 : #define ODBC_DBC_MAGIC_NR 1365 /* for internal sanity check only */ 39 : 40 : 41 : /* 42 : * Creates a new allocated ODBCDbc object and initializes it. 43 : * 44 : * Precondition: none 45 : * Postcondition: returns a new ODBCDbc object 46 : */ 47 : ODBCDbc * 48 6 : newODBCDbc(ODBCEnv *env) 49 : { 50 6 : ODBCDbc *dbc; 51 : 52 6 : assert(env); 53 : 54 6 : dbc = (ODBCDbc *) malloc(sizeof(ODBCDbc)); 55 6 : if (dbc == NULL) { 56 : /* Memory allocation error */ 57 0 : addEnvError(env, "HY001", NULL, 0); 58 0 : return NULL; 59 : } 60 : 61 6 : *dbc = (ODBCDbc) { 62 : .Env = env, 63 : .sql_attr_autocommit = SQL_AUTOCOMMIT_ON, /* default is autocommit */ 64 : .sql_attr_metadata_id = SQL_FALSE, 65 : /* add this dbc to start of the administrative linked dbc list */ 66 6 : .next = env->FirstDbc, 67 : .Type = ODBC_DBC_MAGIC_NR, /* set it valid */ 68 : }; 69 6 : env->FirstDbc = dbc; 70 6 : return dbc; 71 : } 72 : 73 : 74 : /* 75 : * Check if the connection handle is valid. 76 : * Note: this function is used internally by the driver to assert legal 77 : * and save usage of the handle and prevent crashes as much as possible. 78 : * 79 : * Precondition: none 80 : * Postcondition: returns 1 if it is a valid connection handle, 81 : * returns 0 if is invalid and thus an unusable handle. 82 : */ 83 : int 84 218 : isValidDbc(ODBCDbc *dbc) 85 : { 86 : #ifdef ODBCDEBUG 87 218 : if (!(dbc && dbc->Type == ODBC_DBC_MAGIC_NR)) 88 0 : ODBCLOG("dbc %p: not a valid connection handle\n", dbc); 89 : #endif 90 218 : return dbc && dbc->Type == ODBC_DBC_MAGIC_NR; 91 : } 92 : 93 : 94 : 95 : /* 96 : * Creates and adds an error msg object to the end of the error list of 97 : * this ODBCDbc struct. 98 : * When the errMsg is NULL and the SQLState is an ISO SQLState the 99 : * standard ISO message text for the SQLState is used as message. 100 : * 101 : * Precondition: dbc must be valid. SQLState and errMsg may be NULL. 102 : */ 103 : void 104 4 : addDbcError(ODBCDbc *dbc, const char *SQLState, const char *errMsg, int nativeErrCode) 105 : { 106 4 : ODBCError *error = NULL; 107 : 108 : #ifdef ODBCDEBUG 109 4 : ODBCLOG("addDbcError %p %s %s %d\n", dbc, SQLState, errMsg ? errMsg : getStandardSQLStateMsg(SQLState), nativeErrCode); 110 : #endif 111 4 : assert(isValidDbc(dbc)); 112 : 113 4 : error = newODBCError(SQLState, errMsg, nativeErrCode); 114 4 : appendODBCError(&dbc->Error, error); 115 4 : } 116 : 117 : 118 : /* 119 : * Extracts an error object from the error list of this ODBCDbc struct. 120 : * The error object itself is removed from the error list. 121 : * The caller is now responsible for freeing the error object memory. 122 : * 123 : * Precondition: dbc and error must be valid 124 : * Postcondition: returns a ODBCError object or null when no error is available. 125 : */ 126 : ODBCError * 127 1 : getDbcError(ODBCDbc *dbc) 128 : { 129 1 : assert(isValidDbc(dbc)); 130 1 : return dbc->Error; 131 : } 132 : 133 : 134 : /* 135 : * Destroys the ODBCDbc object including its own managed data. 136 : * 137 : * Precondition: dbc must be valid, inactive (not connected) and 138 : * no ODBCStmt (or ODBCDesc) objects may refer to this dbc. 139 : * Postcondition: dbc is completely destroyed, dbc handle is become invalid. 140 : */ 141 : void 142 6 : destroyODBCDbc(ODBCDbc *dbc) 143 : { 144 6 : assert(isValidDbc(dbc)); 145 6 : assert(!dbc->Connected); 146 6 : assert(dbc->FirstStmt == NULL); 147 : 148 : /* first set this object to invalid */ 149 6 : dbc->Type = 0; 150 : 151 : /* remove this dbc from the env */ 152 6 : assert(dbc->Env); 153 6 : assert(dbc->Env->FirstDbc); 154 : { 155 : /* search for this dbc in the list */ 156 : ODBCDbc *tmp_dbc = (ODBCDbc *) dbc->Env->FirstDbc; 157 : ODBCDbc *prv_dbc = NULL; 158 : 159 6 : while ((tmp_dbc != NULL) && (tmp_dbc != dbc)) { 160 0 : prv_dbc = tmp_dbc; 161 0 : tmp_dbc = tmp_dbc->next; 162 : } 163 : 164 6 : assert(tmp_dbc == dbc); /* we must have found it */ 165 : 166 : /* now remove it from the linked list */ 167 6 : if (prv_dbc != NULL) { 168 0 : prv_dbc->next = dbc->next; 169 : } else { 170 6 : dbc->Env->FirstDbc = dbc->next; 171 : } 172 : } 173 : 174 : /* cleanup own managed data */ 175 6 : deleteODBCErrorList(&dbc->Error); 176 6 : if (dbc->dsn) 177 6 : free(dbc->dsn); 178 6 : if (dbc->uid) 179 6 : free(dbc->uid); 180 6 : if (dbc->pwd) 181 6 : free(dbc->pwd); 182 6 : if (dbc->host) 183 6 : free(dbc->host); 184 6 : if (dbc->dbname) 185 6 : free(dbc->dbname); 186 : 187 6 : free(dbc); 188 6 : }