/*
**    Name: freeb.c
**
**    Date: Thu Jan 17 12:02:13 2002
**
*/

#include "ODBC.h"
#include "rmamem.h"
#include <string.h>

/* Statement to connection map, so a disconnect can release its bindings */

typedef struct _ODBCStatement {
    int stmt;
    int dbc;
} ODBCStatement;

static ODBCStatement odbcstatements[ODBCLIBMAXBOUNDPARAMETERS];

void free_bound_slot(int slot)
    {
    int index;

    if (slot < 0 || slot >= ODBCLIBMAXBOUNDPARAMETERS)
        {
        return;
        }

    if (odbcquerytype.boundparameters[slot].rmadata != 0)
        {
        rmafree((void *)odbcquerytype.boundparameters[slot].rmadata);
        }

    for (index = 0;index < ODBCLIBMAXBOUNDPARAMETERS;index++)
        {
        if (odbcboundinfo[index].indslot == slot)
            {
            odbcboundinfo[index].indslot = -1;
            }
        }

    odbcquerytype.boundparameters[slot].stmt    = 0;
    odbcquerytype.boundparameters[slot].data    = 0;
    odbcquerytype.boundparameters[slot].rmadata = 0;
    odbcquerytype.boundparameters[slot].size    = 0;

    memset(&odbcboundinfo[slot],0,sizeof(ODBCBoundInfo));
    odbcboundinfo[slot].indslot = -1;
    }

void free_bound_parameters(int stmt,int which)
    {
    int index;

    int column;

    if (stmt == 0)
        {
        return;
        }

    for (index = 0;index < ODBCLIBMAXBOUNDPARAMETERS;index++)
        {
        if (odbcquerytype.boundparameters[index].stmt == stmt)
            {
            column = odbcboundinfo[index].kind == ODBC_BOUND_COLUMN;

            if (which == ODBC_FREE_ALL ||
                (which == ODBC_FREE_COLUMNS && column) ||
                (which == ODBC_FREE_PARAMS && !column))
                {
                free_bound_slot(index);
                }
            }
        }

    if (which == ODBC_FREE_ALL)
        {
        for (index = 0;index < ODBCLIBMAXBOUNDPARAMETERS;index++)
            {
            if (odbcstatements[index].stmt == stmt)
                {
                odbcstatements[index].stmt = 0;
                odbcstatements[index].dbc  = 0;
                }
            }
        }
    }

/* A newly allocated statement handle; anything still bound to that value is stale */

void track_statement(int stmt,int dbc)
    {
    int index;

    if (stmt == 0)
        {
        return;
        }

    free_bound_parameters(stmt,ODBC_FREE_ALL);

    for (index = 0;index < ODBCLIBMAXBOUNDPARAMETERS;index++)
        {
        if (odbcstatements[index].stmt == 0)
            {
            odbcstatements[index].stmt = stmt;
            odbcstatements[index].dbc  = dbc;
            break;
            }
        }
    }

void free_connection_statements(int dbc)
    {
    int index;

    if (dbc == 0)
        {
        return;
        }

    for (index = 0;index < ODBCLIBMAXBOUNDPARAMETERS;index++)
        {
        if (odbcstatements[index].stmt != 0 && odbcstatements[index].dbc == dbc)
            {
            free_bound_parameters(odbcstatements[index].stmt,ODBC_FREE_ALL);
            }
        }
    }
