/*************************************************************************
*
*	close.c 	     6/10/93
*
*	This file is about SQLClose for WinWord ODBC
*
*************************************************************************/

#include "wbodbc.h"

/*************************************************************************
*
*	sql_close -- the entrance of SQLClose function
*
*************************************************************************/
SWORD WINAPI _loadds SQLClose(SWORD connection_num)
{
	ODBCHNDL	*htemp, *hlast;
	DLLLIST		*dlllist_temp;
	
	dlllist_temp = wdGetVBlock(TRUE);
	if (dlllist_temp == NULL)
		{
		if(henv)
			return(SQL_OutOfMemory);
		else
			return(0);
		}
	
	hlast = htemp = dlllist_temp->hODBC;
	
	while(htemp) 
		{
		if (htemp->connect_id == connection_num) 
			break;
		hlast = htemp;
		htemp = htemp->next;
		}
	
	if (htemp == NULL) 
		{
		return(SQL_NoMoreData);
		}
	
	if (hlast == htemp) 
		dlllist_temp->hODBC = htemp->next;
	else 
		hlast->next = htemp->next;
	
	if (htemp->hstmt) 
		{
		if (SQLFreeStmt(htemp->hstmt, SQL_DROP) != SQL_SUCCESS) 
			{
			wdSQLError(henv, htemp->hdbc, htemp->hstmt);
			SQLDisconnect(htemp->hdbc);
			SQLFreeConnect(htemp->hdbc);
			free((PTR) htemp);
			return(0);
			}
		}
		
	wdFreeSyn(htemp);
	
	if (SQLDisconnect(htemp->hdbc) != SQL_SUCCESS) 
		{
		wdSQLError(henv, htemp->hdbc, NULL);
		SQLFreeConnect(htemp->hdbc);
		free((PTR) htemp);
		return(0);
		}
	
	if (SQLFreeConnect(htemp->hdbc) != SQL_SUCCESS) 
		{
		wdSQLError(henv, NULL, NULL);
		free((PTR) htemp);
		return(0);
		}
		
	if(htemp->lpDBList)
		wdFreeDBList(htemp->lpDBList);
		
	if(htemp->lpSchemaTable)
		wdFreeSchemaTable(htemp->lpSchemaTable);
		
	free((PTR) htemp);
	return(1);
}

/*************************************************************************
*
*	sql_close_all -- the entrance of SQLCloseAll function
*
*************************************************************************/
SWORD WINAPI _loadds SQLCloseAll()
{
	SWORD   	ret;
	ODBCHNDL	*htemp, *hlast;
	DLLLIST		*dlllist_temp;
	
	dlllist_temp = wdGetVBlock(TRUE);
	if (dlllist_temp == NULL)
		{
		if(henv)
			return(SQL_OutOfMemory);
		else
			return(0);
		}
	
	ret = 1;
	hlast = htemp = dlllist_temp->hODBC;
	
	while(htemp) 
		{
		hlast = htemp->next;
	
		if (htemp->hstmt) 
			{
			if (SQLFreeStmt(htemp->hstmt, SQL_DROP) != SQL_SUCCESS) 
				{
				wdSQLError(henv, htemp->hdbc, htemp->hstmt);
				SQLDisconnect(htemp->hdbc);
				SQLFreeConnect(htemp->hdbc);
				ret = 0;
				}
			}
	
		wdFreeSyn(htemp);
		if (SQLDisconnect(htemp->hdbc) != SQL_SUCCESS) 
			{
			wdSQLError(henv, htemp->hdbc, NULL);
			SQLFreeConnect(htemp->hdbc);
			ret = 0;
			}
	
		if (SQLFreeConnect(htemp->hdbc) != SQL_SUCCESS) 
			{
			wdSQLError(henv, NULL, NULL);
			ret = 0;
			}
			
		if(htemp->lpDBList)
			wdFreeDBList(htemp->lpDBList);
			
		if(htemp->lpSchemaTable)
			wdFreeSchemaTable(htemp->lpSchemaTable);
	
		free((PTR) htemp);
		htemp = hlast;
		}
	dlllist_temp->hODBC = NULL;
	return(ret);
}

void wdFreeDBList(DBLIST * lpDBList)
{
	DBROW   *lpRowNext, *lpRowCurr;
	
	if(lpDBList)
		{
		if(lpDBList->hCurrLock)
			GlobalUnlock(lpDBList->hCurrLock);
		lpDBList->hCurrLock = NULL;
		lpRowCurr = lpDBList -> lpRow;
		while(lpRowCurr)
			{
			lpRowNext = lpRowCurr->next;
			if(lpRowCurr->hGlobal&&lpDBList->hCurrLock!=lpRowCurr->hGlobal)
				{
				lpDBList->hCurrLock = lpRowCurr->hGlobal;
				GlobalFree(lpRowCurr->hGlobal);
				}
			free((PTR)lpRowCurr);
			lpRowCurr = lpRowNext;
			}
		free((PTR)lpDBList);
		}
}

void wdFreeSchemaTable(DBCOL * lpSchemaTable)
{
	DBCOL   *lpColNext;
	
	while(lpSchemaTable)
		{
		lpColNext = lpSchemaTable -> next;
		if(lpSchemaTable->item)
			free(lpSchemaTable->item);
		free(lpSchemaTable);
		lpSchemaTable = lpColNext;
		}
}

void wdFreeSyn(ODBCHNDL *hODBC)
{
	if(hODBC->synchronize_flag)
		{
		if(hODBC->lpSynBuf)
			free(hODBC->lpSynBuf);
		if(hODBC->synchronize_flag>20)
			SQLFreeStmt(hODBC->hSynStmt, SQL_DROP);
		}
}
