Win32-SqlServer

 view release on metacpan or  search on metacpan

internaldata.cpp  view on Meta::CPAN

/*---------------------------------------------------------------------
 $Header: /Perl/OlleDB/internaldata.cpp 17    22-05-27 19:04 Sommar $

  This file holds routines setting up the internaldata struct, and
  also release memory allocated in it.

  Copyright (c) 2004-2022   Erland Sommarskog

  $History: internaldata.cpp $
 * 
 * *****************  Version 17  *****************
 * User: Sommar       Date: 22-05-27   Time: 19:04
 * Updated in $/Perl/OlleDB
 * Added propset as a parameter to dump_properties to avoid surprises when
 * properties in different set have the same value.
 * 
 * *****************  Version 16  *****************
 * User: Sommar       Date: 22-05-08   Time: 23:14
 * Updated in $/Perl/OlleDB
 * Rewrote dump_prooperties to show numeric index, and it was broken
 * anyway.
 * 
 * *****************  Version 15  *****************
 * User: Sommar       Date: 21-07-12   Time: 21:41
 * Updated in $/Perl/OlleDB
 * No longer tracking that a property is supported by SQLOLEDB and done
 * away with the check for SQLOLEDB 2.5. Instead we have optional
 * properties for the benefit of the different versions of MSOLEDBSQL, and
 * this is want dwStatus -1 means this days, and therefore it should be
 * part of the dump.
 * 
 * *****************  Version 14  *****************
 * User: Sommar       Date: 19-07-19   Time: 22:00
 * Updated in $/Perl/OlleDB
 * Removed the olddbtranslate option from internaldata, and entirely
 * deprecated setting the AutoTranslate option to make sure that it always
 * is false. When clearing options when ProviderString is set, we don't
 * clear AutoTranslate.
 * 
 * *****************  Version 13  *****************
 * User: Sommar       Date: 19-07-08   Time: 22:31
 * Updated in $/Perl/OlleDB
 * New elements in internaldata for SQL version,  currentDB and more for
 * UTF-8 support.
 * 
 * *****************  Version 12  *****************
 * User: Sommar       Date: 16-07-11   Time: 22:24
 * Updated in $/Perl/OlleDB
 * Changed data types of ULONG for no_of_cols and no_of_defaults to avoid
 * compilation warnings.
 * 
 * *****************  Version 11  *****************
 * User: Sommar       Date: 12-09-23   Time: 22:52
 * Updated in $/Perl/OlleDB
 * Updated Copyright note.
 * 
 * *****************  Version 10  *****************
 * User: Sommar       Date: 12-08-15   Time: 21:26
 * Updated in $/Perl/OlleDB
 * Change the check for not set by SQLOLEDB to only check options set by
 * SQLOLEDB 2.6.
 * 
 * *****************  Version 9  *****************
 * User: Sommar       Date: 11-08-07   Time: 23:26
 * Updated in $/Perl/OlleDB
 * Fix warnings about unsafe comparisons revealed by /W3.
 * 
 * *****************  Version 8  *****************
 * User: Sommar       Date: 09-07-26   Time: 12:44
 * Updated in $/Perl/OlleDB
 * Determining whether an SV is defined through my_sv_is_defined to as
 * SvOK may return false, unless we first do SvGETMAGIC. This proved to be
 * an issue when using table-valued parameters with threads::shared.
 *
 * *****************  Version 7  *****************
 * User: Sommar       Date: 09-04-25   Time: 22:29
 * Updated in $/Perl/OlleDB
 * setupinternaldata was incorrectly defined to return int, which botched
 * the pointer once address was > 7FFFFFFF.
 *
 * *****************  Version 6  *****************
 * User: Sommar       Date: 08-03-23   Time: 23:29
 * Updated in $/Perl/OlleDB
 * New field for table parameters: bindix, as we don't bind columns that
 * vae default.
 *
 * *****************  Version 5  *****************
 * User: Sommar       Date: 08-02-10   Time: 23:17
 * Updated in $/Perl/OlleDB
 * Clean up column properties in table parameters.
 *
 * *****************  Version 4  *****************
 * User: Sommar       Date: 08-01-06   Time: 23:33
 * Updated in $/Perl/OlleDB
 * Replaced all unsafe CRT functions with their safe replacements in VC8.
 * olledb_message now takes a va_list as argument, so we pass it
 * parameterised strings and don't have to litter the rest of the code
 * with that.
 *
 * *****************  Version 3  *****************
 * User: Sommar       Date: 08-01-05   Time: 20:43
 * Updated in $/Perl/OlleDB
 * Added more fields to the tableparam struct: buffers for saving
 * pointers, and support for defining columns to be sent as default.
 *
 * *****************  Version 2  *****************
 * User: Sommar       Date: 08-01-05   Time: 0:25
 * Updated in $/Perl/OlleDB
 * Support for table-valued parameters added.
 *
 * *****************  Version 1  *****************
 * User: Sommar       Date: 07-12-24   Time: 21:40
 * Created in $/Perl/OlleDB
  ---------------------------------------------------------------------*/

#include "CommonInclude.h"
#include "handleattributes.h"
#include "convenience.h"
#include "init.h"
#include "internaldata.h"

// Dumps the contents of a property array in case of an error
void dump_properties(DBPROP *props, init_propsets propset, int cProps)
{
  for (int i = 0; i < cProps; i++) {
     char *propname = NULL;
     char *ststxt;
     int  j = 0;

     while (gbl_init_props[j].propset_enum != propset ||
            gbl_init_props[j].property_id != props[i].dwPropertyID) { 
        j++;
     }

     if (gbl_init_props[j].propset_enum != not_in_use) {
        propname = gbl_init_props[j].name;
     }

     switch (props[i].dwStatus) {
        case DBPROPSTATUS_OK :
             ststxt = "DBPROPSTATUS_OK"; break;
        case DBPROPSTATUS_BADCOLUMN :
             ststxt = "DBPROPSTATUS_BADCOLUMN"; break;
        case DBPROPSTATUS_BADOPTION :
             ststxt = "DBPROPSTATUS_BADOPTION"; break;
        case DBPROPSTATUS_BADVALUE :
             ststxt = "DBPROPSTATUS_BADVALUE"; break;
        case DBPROPSTATUS_CONFLICTING :
             ststxt = "DBPROPSTATUS_CONFLICTING"; break;
        case DBPROPSTATUS_NOTALLSETTABLE :
             ststxt = "DBPROPSTATUS_NOTALLSETTABLE"; break;
        case DBPROPSTATUS_NOTAVAILABLE :
             ststxt = "DBPROPSTATUS_NOTAVAILABLE"; break;
        case DBPROPSTATUS_NOTSET :
             ststxt = "DBPROPSTATUS_NOTSET"; break;
        case DBPROPSTATUS_NOTSETTABLE :
             ststxt = "DBPROPSTATUS_NOTSETTABLE"; break;
        case DBPROPSTATUS_NOTSUPPORTED :
             ststxt = "DBPROPSTATUS_NOTSUPPORTED"; break;
        default :
             New(902, ststxt, 50, char);
             sprintf_s(ststxt, 50, "%d", props[i].dwStatus);
             Safefree(ststxt);
     }
     PerlIO_printf(PerlIO_stderr(), "Ix: %d, Property '%s', Status: %s, Value: ",
                    i, (propname != NULL ? propname : "Unknown"), ststxt);
     if (props[i].vValue.vt == VT_EMPTY) {
         PerlIO_printf(PerlIO_stderr(), "VT_EMPTY");
     }
     else {
        switch (props[i].vValue.vt) {
           case VT_BOOL :
              PerlIO_printf(PerlIO_stderr(), "%d",
                            props[i].vValue.boolVal);
              break;

           case VT_I2 :
              PerlIO_printf(PerlIO_stderr(), "%d",
                            props[i].vValue.iVal);
              break;

           case VT_I4 :
              PerlIO_printf(PerlIO_stderr(), "%d",
                            props[i].vValue.lVal);
              break;

           case VT_BSTR : {
              char * str = BSTR_to_char(props[i].vValue.bstrVal);
              PerlIO_printf(PerlIO_stderr(), "'%s'", str);
              Safefree(str);
              break;
          }

          default :
              PerlIO_printf(PerlIO_stderr(), "UNKNOWN DATATYPE");

internaldata.cpp  view on Meta::CPAN

   warn("data_buffer = %x.\n", mydata->data_buffer);
   warn("size_data_buffer = %d.\n", mydata->size_data_buffer);
}


// This routine allocates an internaldata structure and returns the pointer
// as an integer value.
void * setupinternaldata()
{
    internaldata  * mydata;  // Pointer to area for internal data.

    // Create struct for pointers we need to keep between calls, and initiate
    // all pointers to NULL.
    New(902, mydata, 1, internaldata);
    mydata->isautoconnected   = FALSE;
    mydata->isnestedquery     = FALSE;
    mydata->SQL_version       = &PL_sv_undef;
    mydata->majorsqlversion   = 0;
    mydata->CurrentDB         = &PL_sv_undef;
    mydata->provider          = default_provider();
    mydata->init_ptr          = NULL;
    mydata->pending_cmd       = NULL;
    mydata->paramfirst        = NULL;
    mydata->paramlast         = NULL;
    mydata->no_of_params      = 0;
    mydata->no_of_out_params  = 0;
    mydata->params_available  = FALSE;
    mydata->datasrc_ptr       = NULL;
    mydata->session_ptr       = NULL;
    mydata->cmdtext_ptr       = NULL;
    mydata->paramcmd_ptr      = NULL;
    mydata->ss_paramcmd_ptr   = NULL;
    mydata->paramaccess_ptr   = NULL;
    mydata->all_params_OK     = TRUE;
    mydata->param_info        = NULL;
    mydata->param_bindings    = NULL;
    mydata->param_buffer      = NULL;
    mydata->size_param_buffer = 0;
    mydata->param_accessor    = NULL;
    mydata->param_bind_status = NULL;
    mydata->tableparams       = NULL;
    mydata->results_ptr       = NULL;
    mydata->have_resultset    = FALSE;
    mydata->rowset_ptr        = NULL;
    mydata->rowaccess_ptr     = NULL;
    mydata->row_accessor      = NULL;
    mydata->column_keys       = NULL;
    mydata->rowbuffer         = NULL;
    mydata->rows_in_buffer    = 0;
    mydata->current_rowno     = 0;
    mydata->no_of_cols        = NULL;
    mydata->column_info       = NULL;
    mydata->colname_buffer    = NULL;
    mydata->col_bindings      = NULL;
    mydata->col_bind_status   = NULL;
    mydata->data_buffer       = NULL;
    mydata->size_data_buffer  = 0;


    // Set up the init property sets. First the GUIDs.
    mydata->init_propsets[oleinit_props].guidPropertySet =
            DBPROPSET_DBINIT;
    mydata->init_propsets[ssinit_props].guidPropertySet  =
            DBPROPSET_SQLSERVERDBINIT;
    mydata->init_propsets[datasrc_props].guidPropertySet =
            DBPROPSET_DATASOURCE;

    // Then number and pointer to the arrays.
    for (int i = 0; i <= NO_OF_INIT_PROPSETS; i++) {
       mydata->init_propsets[i].cProperties  = init_propset_info[i].no_of_props;
       mydata->init_propsets[i].rgProperties =
           &(mydata->init_properties[init_propset_info[i].start]);
    }

    // Then copy the properties from the global default properties.
    for (int j = 0; gbl_init_props[j].propset_enum != not_in_use; j++) {
       DBPROP  &prop = mydata->init_properties[j];
       prop.dwPropertyID = gbl_init_props[j].property_id;
       prop.dwOptions    = DBPROPOPTIONS_REQUIRED;
       prop.colid        = DB_NULLID;
       prop.dwStatus     = (gbl_init_props[j].isoptional ? -1 : DBPROPSTATUS_OK);
       VariantInit(&prop.vValue);
       VariantCopy(&prop.vValue, &gbl_init_props[j].default_value);
    }

    return (void *) mydata;
}

// Retrieves the internal data pointer in opaque form and reinterprets
// the pointer.
internaldata * get_internaldata(SV * olle_ptr) {
   internaldata * ptr = (internaldata *) OptInternalData(olle_ptr);
   return ptr;
}


// We release pointers a lot, so we have a macro that does it all.
#define free_ole_ptr(oleptr) \
   if (oleptr != NULL) { \
      oleptr->Release(); \
      oleptr = NULL; \
   } \


// This routine frees about allocation for receiving a result. It is
// called by nextrow, when there aer no more rows, or by cancelresultset.
void free_resultset_data(internaldata *mydata) {
   HRESULT ret;

   if (mydata->column_info != NULL) {
      OLE_malloc_ptr->Free(mydata->column_info);
      mydata->column_info = NULL;
   }
   if (mydata->colname_buffer != NULL) {
      OLE_malloc_ptr->Free(mydata->colname_buffer);
      mydata->colname_buffer = NULL;
   }
   if (mydata->col_bindings != NULL) {
      Safefree(mydata->col_bindings);
      mydata->col_bindings = NULL;
   }
   if (mydata->col_bind_status != NULL) {
      Safefree(mydata->col_bind_status);
      mydata->col_bind_status = NULL;
   }
   if (mydata->data_buffer != NULL) {
      Safefree(mydata->data_buffer);
      mydata->data_buffer = NULL;
   }

   if (mydata->rowbuffer != NULL) {
      ret = mydata->rowset_ptr->ReleaseRows(mydata->rows_in_buffer,
                                            mydata->rowbuffer,
                                            NULL, NULL, NULL);
      if (FAILED(ret)) {
         croak("rowset_ptr->ReleaseRows failed with %08X.\n", ret);



( run in 0.621 second using v1.01-cache-2.11-cpan-71847e10f99 )