Win32-SqlServer

 view release on metacpan or  search on metacpan

SqlServer.xs  view on Meta::CPAN

  CODE:
{
// This routine is called from DESTROY in the Perl code. We cannot have
// DESTROY here directly, because the Perl code has to take some extra
// precautions.
    internaldata * mydata = get_internaldata(olle_ptr);
    if (mydata != NULL) {
       disconnect(olle_ptr);

       // Free up area allocated to all properties.
       for (int i = 0; gbl_init_props[i].propset_enum != not_in_use; i++) {
          VariantClear(&mydata->init_properties[i].vValue);
       }

       // Make sure strings for SQL version and current database are
       // cleared.
       free_sqlver_currentdb(mydata);

       // And dispense of mydata itself. The Perl DESTROY will set mydata
       // to 0, to avoid a second cleanup when Perl calls DESTROY a second
       // time. (Which it does for some reason.)

connect.cpp  view on Meta::CPAN

 * Updated in $/Perl/OlleDB
 * Also except the settings for Trust Server Certificate and Host Name in
 * Certificate when setting the provider string.
 * 
 * *****************  Version 16  *****************
 * User: Sommar       Date: 22-05-27   Time: 21:59
 * Updated in $/Perl/OlleDB
 * The correction of the one-off error was in the wrong place. When
 * setting provider string, don't clear the Encrypt setting, because for
 * some reason it does not have any effect when you list it in the
 * provider string. When comparing property IDs, also include the propset
 * as some properties have the same ids.
 * 
 * *****************  Version 15  *****************
 * User: Sommar       Date: 22-05-18   Time: 22:23
 * Updated in $/Perl/OlleDB
 * Added validation of the values of the Authentication propery. If
 * AccessToken is given, clear IntegratedSecurity.
 * 
 * *****************  Version 14  *****************
 * User: Sommar       Date: 22-05-08   Time: 23:16

connect.cpp  view on Meta::CPAN

    OLE_malloc_ptr->Free(property_sets[1].rgProperties);
    OLE_malloc_ptr->Free(property_sets);
    property_ptr->Release();
}

// Sets the property for one property set. We have it all set up in mydata - 
// almost. Some property may have status -1, meaning that we should not set
// set them, so we copy to local variables.
void set_one_property_set (SV            * olle_ptr,
                           IDBProperties * property_ptr,
                           init_propsets   init_propset ) 
{
   internaldata * mydata = get_internaldata(olle_ptr);
   DBPROPSET      propset;
   DBPROP         properties[MAX_INIT_PROPERTIES];
   ULONG          prop_ix = 0;


   // Initialise the property set.
   propset.rgProperties    = properties;
   propset.cProperties     = 0;
   propset.guidPropertySet = mydata->init_propsets[init_propset].guidPropertySet;

   // Then copy the *defined* properties to the DBPROP array.
   for (UINT i = init_propset_info[init_propset].start;
        i < mydata->init_propsets[init_propset].cProperties +
             init_propset_info[init_propset].start; i++) {
      if (mydata->init_properties[i].dwStatus == DBPROPSTATUS_OK) {
         DBPROP  &prop = properties[prop_ix++];
         prop.dwPropertyID = mydata->init_properties[i].dwPropertyID;
         prop.dwOptions    = DBPROPOPTIONS_REQUIRED;
         prop.colid        = DB_NULLID;
         prop.dwStatus     = DBPROPSTATUS_OK;
         VariantInit(&prop.vValue);
         if (prop.dwPropertyID == SSPROP_INIT_ENCRYPT &&
             mydata->provider < provider_msoledbsql19) {
             // The special case. This property changed type in MSOLEDBSQL19, so 

connect.cpp  view on Meta::CPAN

             }
         }
         else {
            VariantCopy(&prop.vValue, &mydata->init_properties[i].vValue);
         }
      }
   }

   // If any properties were copied, we can set them now.
   if (prop_ix > 0) {
      propset.cProperties = prop_ix;
      HRESULT ret = property_ptr->SetProperties(1, &propset);
      if (FAILED(ret)) {
         dump_properties(properties, init_propset, propset.cProperties);
         croak("Internal error: property_ptr->SetProperties for initialization propset %d failed with hresult %x", init_propset, ret);
      }
   }
}

                     


// Connect, called from $X->Connect() and $X->executebatch for autoconnect.
BOOL do_connect (SV    * olle_ptr,
                 BOOL    isautoconnect)

connect.cpp  view on Meta::CPAN

    }

    // We need a property object.
    ret = mydata->init_ptr->QueryInterface(IID_IDBProperties,
                                           (void **) &property_ptr);
    if (FAILED(ret)) {
       croak("Internal error: init_ptr->QueryInterface to create Property object failed with hresult %x", ret);
    }

    // Set the number of SSPROPS depending on the provider.
    mydata->init_propsets[ssinit_props].cProperties =  
                                          no_of_ssprops(mydata->provider);

    // Set the properties for the initialisation sets.
    set_one_property_set(olle_ptr, property_ptr, oleinit_props);
    set_one_property_set(olle_ptr, property_ptr, ssinit_props);

    // This is the place where we actually log in to SQL Server. We might
    // be reusing a connection from a pool.
    ret = mydata->init_ptr->Initialize();

connect.cpp  view on Meta::CPAN

   if (mydata->datasrc_ptr != NULL) {
      olle_croak(olle_ptr, "You cannot set login properties while connected");
   }

   // Check we got a proper prop_name.
   if (prop_name == NULL) {
      croak("Property name must not be NULL.");
   }

   // Look up property name in the global array.
   while (gbl_init_props[ix].propset_enum != not_in_use &&
          _stricmp(prop_name, gbl_init_props[ix].name) != 0) {
      ix++;
   }

   if (gbl_init_props[ix].propset_enum == not_in_use) {
     croak("Unknown property '%s' passed to setloginproperty", prop_name);
   }

   // AutoTranslate is not settable, and we pretend that it does not exist.
   if (gbl_init_props[ix].propset_enum == ssinit_props &&
       gbl_init_props[ix].property_id == SSPROP_INIT_AUTOTRANSLATE) {
     croak("Unknown property 'AutoTranslate' passed to setloginproperty");
   }


   // Some properties affects others.
   if (gbl_init_props[ix].propset_enum == oleinit_props &&
         gbl_init_props[ix].property_id == DBPROP_AUTH_USERID ||
         gbl_init_props[ix].property_id == SSPROP_AUTH_MODE   ||
         gbl_init_props[ix].property_id == SSPROP_AUTH_ACCESS_TOKEN) {
      // If userid is set, we clear Integrated security.
      setloginproperty(olle_ptr, "IntegratedSecurity", &PL_sv_undef);
   }
   else if (gbl_init_props[ix].propset_enum == oleinit_props &&
            gbl_init_props[ix].property_id == DBPROP_INIT_PROVIDERSTRING) {
      // In this case, all other properties should be ignored, except for
      // AUTOTRANSLATE, since we over rule its default.
      // We also except the Encrypt option, since for some reason it does not seem to work
      // in the provider string, so we want the setting through SetDefaultForEncryption to prevail.
      for (int j = 0; gbl_init_props[j].propset_enum != datasrc_props; j++) {
         if (! (gbl_init_props[j].propset_enum == ssinit_props &&
                   (mydata->init_properties[j].dwPropertyID == SSPROP_INIT_AUTOTRANSLATE ||
                    mydata->init_properties[j].dwPropertyID == SSPROP_INIT_ENCRYPT ||
                    mydata->init_properties[j].dwPropertyID == SSPROP_INIT_TRUST_SERVER_CERTIFICATE ||
                    mydata->init_properties[j].dwPropertyID == SSPROP_INIT_HOST_NAME_CERTIFICATE ||
                    mydata->init_properties[j].dwPropertyID == SSPROP_INIT_SERVER_CERTIFICATE))) {
            VariantClear(&mydata->init_properties[j].vValue);
         }
      }
   }

   // If the server changes, there are some attributes that are no
   // longer valid.
   if (gbl_init_props[ix].propset_enum == oleinit_props &&
       (gbl_init_props[ix].property_id == DBPROP_INIT_PROVIDERSTRING ||
        gbl_init_props[ix].property_id == DBPROP_INIT_DATASOURCE ||
        gbl_init_props[ix].property_id == SSPROP_INIT_NETWORKADDRESS)) {
      free_sqlver_currentdb(mydata);
      ClearCodepages(olle_ptr);
   }

   // The property ApplicationIntent requires validation.
   if (gbl_init_props[ix].propset_enum == ssinit_props &&
       gbl_init_props[ix].property_id == SSPROP_INIT_APPLICATIONINTENT) {
       char * appintent = SvPV_nolen(prop_value);
       if (_stricmp(appintent, "readwrite") != 0 &&
           _stricmp(appintent, "readonly") != 0) {
              croak("Illegal value '%s' passed for the '%s' property",
                    appintent, prop_name);
       }
   }
    
   // So does the Authentication property.
   if (gbl_init_props[ix].propset_enum == ssinit_props &&
       gbl_init_props[ix].property_id == SSPROP_AUTH_MODE) {
       char * authmode = SvPV_nolen(prop_value);
       if (_stricmp(authmode, "SqlPassword") != 0                     &&
           _stricmp(authmode, "ActiveDirectoryIntegrated") != 0       &&
           _stricmp(authmode, "ActiveDirectoryPassword") != 0         &&
           _stricmp(authmode, "ActiveDirectoryInteractive") != 0      &&
           _stricmp(authmode, "ActiveDirectoryServicePrincipal") != 0 &&
           _stricmp(authmode, "ActiveDirectoryMSI") != 0) {
              croak("Illegal value '%s' passed for the '%s' property",
                    authmode, prop_name);

connect.cpp  view on Meta::CPAN

   mydata->init_properties[ix].dwStatus = DBPROPSTATUS_OK;
   
   // clear the current value and set property to VT_EMPTY.
   VariantClear(&mydata->init_properties[ix].vValue);

   // Then set the value appropriately
   if (my_sv_is_defined(prop_value)) {
      mydata->init_properties[ix].vValue.vt = gbl_init_props[ix].datatype;

      // First handle any specials. Currently there are three.
      if (gbl_init_props[ix].propset_enum == oleinit_props &&
          gbl_init_props[ix].property_id == DBPROP_INIT_OLEDBSERVICES) {
         // For OLE DB Services, we are only using connection pooling.
         mydata->init_properties[ix].vValue.lVal = (SvTRUE(prop_value)
                 ? DBPROPVAL_OS_RESOURCEPOOLING : DBPROPVAL_OS_DISABLEALL);
      }
      else if (gbl_init_props[ix].propset_enum == oleinit_props &&
               gbl_init_props[ix].property_id == DBPROP_AUTH_INTEGRATED) {
         // For integrated security, handle numeric values gently.
         if (SvIOK(prop_value)) {
            if (SvIV(prop_value) != 0) {
                mydata->init_properties[ix].vValue.bstrVal =
                    SysAllocString(L"SSPI");
            }
            else {
               mydata->init_properties[ix].vValue.vt = VT_EMPTY;
             }
         }
         else {
            mydata->init_properties[ix].vValue.bstrVal = SV_to_BSTR(prop_value);
         }
      }
      else if (gbl_init_props[ix].propset_enum == ssinit_props &&
               gbl_init_props[ix].property_id == SSPROP_INIT_ENCRYPT) {
         if (SvIOK(prop_value)) {
             mydata->init_properties[ix].vValue.bstrVal = 
                 SysAllocString(SvTRUE(prop_value) ? L"Mandatory" : L"Optional");
         }
         else {
            char * encryptopt = SvPV_nolen(prop_value);
            if (_stricmp(encryptopt, "no") == 0 ||
                _stricmp(encryptopt, "false") == 0 ||
                _stricmp(encryptopt, "optional") == 0) {

init.cpp  view on Meta::CPAN


// Number of properties per provider:
int no_of_ssprops_sqloledb     = -1;
int no_of_ssprops_sqlncli      = -1;
int no_of_ssprops_sqlncli10    = -1;
int no_of_ssprops_sqlncli11    = -1;
int no_of_ssprops_msoledbsql   = -1;
int no_of_ssprops_msoledbsql19 = -1;

// This array holds where each property set starts in gbl_init_props;
propset_info_struct init_propset_info[NO_OF_INIT_PROPSETS];


// Global pointer to OLE DB Services. Set once when we intialize, and
// never released.
IDataInitialize * data_init_ptr    = NULL;

// Global pointer the OLE DB conversion library.
IDataConvert    * data_convert_ptr = NULL;

// Global pointer to the IMalloc interface. Most of the time when we allocate

init.cpp  view on Meta::CPAN

   BSTR hostname = SysAllocStringLen(NULL, 31);
   memset(hostname, 0, 60);
   GetEnvironmentVariable(L"COMPUTERNAME", hostname, 30);
   return hostname;
}

// Add a property to the global array.
// isoptoinal: properties that were added in a .X version of a provider, or
// options where we want the provider default to apply.
static void add_init_property (const char *  name,
                               init_propsets propset_enum,
                               DBPROPID      propid,
                               BOOL          isoptional, 
                               VARTYPE       datatype,
                               BOOL          default_empty,
                               const WCHAR * default_str,
                               int           default_int,
                               int          &ix)
{

   // Check that we are not exceeding the global array. Note that the last
   // slot must be left unusued, as this is used as a stop condition!
   if (ix >= MAX_INIT_PROPERTIES - 1) {
      croak("Internal error: size of array for init properties exceeded");
   }

   // Increment property set counter.
   init_propset_info[propset_enum].no_of_props++;

   strcpy_s(gbl_init_props[ix].name, INIT_PROPNAME_LEN, name);
   gbl_init_props[ix].propset_enum  = propset_enum;
   gbl_init_props[ix].property_id   = propid;
   gbl_init_props[ix].isoptional    = isoptional;
   gbl_init_props[ix].datatype      = datatype;
   VariantInit(&gbl_init_props[ix].default_value);

   if (! default_empty) {
      gbl_init_props[ix].default_value.vt = datatype;

      switch (datatype) {
         case VT_BOOL :

init.cpp  view on Meta::CPAN

    ix++;
}

// And this is the routine that sets up the array.
static void setup_init_properties ()
{
   int ix = 0;
   BSTR scriptname = get_scriptname();
   BSTR hostname   = get_hostname();

   // Init array so that all entrys are unused and init propset_info.
   memset(gbl_init_props, not_in_use,
          MAX_INIT_PROPERTIES * sizeof(init_property));


   // DBPROPSET_DBINIT, main OLE DB init and auth properties.
   init_propset_info[oleinit_props].start = ix;
   init_propset_info[oleinit_props].no_of_props = 0;

   add_init_property("IntegratedSecurity", oleinit_props, DBPROP_AUTH_INTEGRATED,
                     FALSE, VT_BSTR, FALSE, L"SSPI", NULL, ix);
   add_init_property("Password", oleinit_props, DBPROP_AUTH_PASSWORD,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("Username", oleinit_props, DBPROP_AUTH_USERID,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("Database", oleinit_props, DBPROP_INIT_CATALOG,
                     FALSE, VT_BSTR, FALSE, L"tempdb", NULL, ix);
   add_init_property("Server", oleinit_props, DBPROP_INIT_DATASOURCE,

init.cpp  view on Meta::CPAN

   add_init_property("Pooling", oleinit_props, DBPROP_INIT_OLEDBSERVICES,
                     FALSE, VT_I4, FALSE, NULL, DBPROPVAL_OS_RESOURCEPOOLING, ix);
   add_init_property("Prompt", oleinit_props, DBPROP_INIT_PROMPT,
                     FALSE, VT_I2, FALSE, NULL, DBPROMPT_NOPROMPT, ix);
   add_init_property("ConnectionString", oleinit_props, DBPROP_INIT_PROVIDERSTRING,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("ConnectTimeout", oleinit_props, DBPROP_INIT_TIMEOUT,
                     FALSE, VT_I4, FALSE, NULL, 15, ix);

   // DBPROPSET_SQLSERVERDBINIT, SQLOLEDB specific proprties.
   init_propset_info[ssinit_props].start = ix;
   init_propset_info[ssinit_props].no_of_props = 0;

   add_init_property("Appname", ssinit_props, SSPROP_INIT_APPNAME,
                     FALSE, VT_BSTR, FALSE, scriptname, NULL, ix);
   add_init_property("Autotranslate", ssinit_props, SSPROP_INIT_AUTOTRANSLATE,
                     FALSE, VT_BOOL, FALSE, NULL, NULL, ix);   // This property is not settable by the user, but we also force it as FALSE.
   add_init_property("Language", ssinit_props, SSPROP_INIT_CURRENTLANGUAGE,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("AttachFilename", ssinit_props, SSPROP_INIT_FILENAME,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("NetworkAddress", ssinit_props, SSPROP_INIT_NETWORKADDRESS,

init.cpp  view on Meta::CPAN

                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("PacketSize", ssinit_props, SSPROP_INIT_PACKETSIZE,
                     FALSE, VT_I4, TRUE, NULL, NULL, ix);
   add_init_property("UseProcForPrep", ssinit_props, SSPROP_INIT_USEPROCFORPREP,
                     FALSE, VT_I4, FALSE, NULL, SSPROPVAL_USEPROCFORPREP_OFF, ix);
   add_init_property("Hostname", ssinit_props, SSPROP_INIT_WSID,
                     FALSE, VT_BSTR, FALSE, hostname, NULL, ix);
   add_init_property("Encrypt", ssinit_props, SSPROP_INIT_ENCRYPT,
                     TRUE, VT_BSTR, TRUE, NULL, NULL, ix);  // Set as is_optional, to permit for different provider defaults.
   // The above properties are those that are in SQLOLEDB.
   no_of_ssprops_sqloledb = init_propset_info[ssinit_props].no_of_props;

   // These properties were added in SQL 2005.
   add_init_property("FailoverPartner", ssinit_props, SSPROP_INIT_FAILOVERPARTNER,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("TrustServerCert", ssinit_props, SSPROP_INIT_TRUST_SERVER_CERTIFICATE,
                     FALSE, VT_BOOL, TRUE, NULL, NULL, ix);
   add_init_property("OldPassword", ssinit_props, SSPROP_AUTH_OLD_PASSWORD,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   no_of_ssprops_sqlncli = init_propset_info[ssinit_props].no_of_props;

   // These two were added with SQL 2008.
   add_init_property("ServerSPN", ssinit_props, SSPROP_INIT_SERVERSPN,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   add_init_property("FailoverPartnerSPN", ssinit_props, SSPROP_INIT_FAILOVERPARTNERSPN,
                     FALSE, VT_BSTR, TRUE, NULL, NULL, ix);
   no_of_ssprops_sqlncli10 = init_propset_info[ssinit_props].no_of_props;

   // And here is a single one that made it into SQL 2012.
   add_init_property("ApplicationIntent", ssinit_props, SSPROP_INIT_APPLICATIONINTENT,
                     FALSE, VT_BSTR, FALSE, L"ReadWrite", NULL, ix);
   no_of_ssprops_sqlncli11 = init_propset_info[ssinit_props].no_of_props;

   // This one appeared first with the undeprecated driver in 2018.
   add_init_property("MultiSubnetFailover", ssinit_props, SSPROP_INIT_MULTISUBNETFAILOVER,
                     TRUE, VT_BOOL, FALSE, NULL, FALSE, ix);
   add_init_property("AccessToken", ssinit_props, SSPROP_AUTH_ACCESS_TOKEN,
                     TRUE, VT_BSTR, TRUE, NULL, FALSE, ix);
   add_init_property("Authentication", ssinit_props, SSPROP_AUTH_MODE,
                     TRUE, VT_BSTR, TRUE, NULL, FALSE, ix);
   add_init_property("ConnectRetryCount", ssinit_props, SSPROP_INIT_CONNECT_RETRY_COUNT,
                     TRUE, VT_I4, FALSE, NULL, 1, ix);
   add_init_property("ConnectRetryInterval", ssinit_props, SSPROP_INIT_CONNECT_RETRY_INTERVAL,
                     TRUE, VT_I4, FALSE, NULL, 10, ix);
   add_init_property("TransparentNetworkIPResolution", ssinit_props, SSPROP_INIT_TNIR,
                     TRUE, VT_BOOL, FALSE, NULL, FALSE, ix);
   no_of_ssprops_msoledbsql = init_propset_info[ssinit_props].no_of_props;

   // Properties new in MSOLEDBSQL19.
   add_init_property("HostNameInCertificate", ssinit_props, SSPROP_INIT_HOST_NAME_CERTIFICATE,
                     FALSE, VT_BSTR, TRUE, NULL, FALSE, ix);
   add_init_property("ServerCertificate", ssinit_props, SSPROP_INIT_SERVER_CERTIFICATE,
                     FALSE, VT_BSTR, TRUE, NULL, FALSE, ix);
   no_of_ssprops_msoledbsql19 = init_propset_info[ssinit_props].no_of_props;   

   
   // DBPROPSET_DATASOURCE, data-source properties.
   init_propset_info[datasrc_props].start = ix;
   init_propset_info[datasrc_props].no_of_props = 0;

   add_init_property("MultiConnections", datasrc_props, DBPROP_MULTIPLECONNECTIONS,
                     FALSE, VT_BOOL, FALSE, NULL, FALSE, ix);

   SysFreeString(scriptname);
   SysFreeString(hostname);
}

// Above we leave the Encrypt option without a default, to let the provider to decide. But this
// routine permits the user to override.

init.cpp  view on Meta::CPAN

   int    encrypt_ix = -1;
   int    trust_cert_ix = -1;
   int    host_name_ix  = -1;
   int    server_cert_ix = -1;

   // Loop over gbl_init_props to find the indexes for the Encrypt and TrustServerCert options
   for (int ix = 0; 
            ix < MAX_INIT_PROPERTIES && 
                 (encrypt_ix < 0 || trust_cert_ix < 0 || 
                  host_name_ix < 0 || server_cert_ix < 0); ix++) {
      if (gbl_init_props[ix].propset_enum == ssinit_props) {
         if (gbl_init_props[ix].property_id == SSPROP_INIT_ENCRYPT) {
            encrypt_ix = ix;
         }
         else if (gbl_init_props[ix].property_id == SSPROP_INIT_TRUST_SERVER_CERTIFICATE) {
            trust_cert_ix = ix;
         }
         else if (gbl_init_props[ix].property_id == SSPROP_INIT_HOST_NAME_CERTIFICATE) {
            host_name_ix = ix;
         }
         else if (gbl_init_props[ix].property_id == SSPROP_INIT_SERVER_CERTIFICATE) {

init.h  view on Meta::CPAN

extern CLSID  clsid_sqloledb;
extern CLSID  clsid_sqlncli;
extern CLSID  clsid_sqlncli10;
extern CLSID  clsid_sqlncli11;
extern CLSID  clsid_msoledbsql;
extern CLSID  clsid_msoledbsql19;


// This is stuff for init properties. When the module starts up, we set up a
// static array, and then is read-only.
typedef enum init_propsets
    {not_in_use = -1, oleinit_props = 0, ssinit_props = 1, datasrc_props = 2}
init_propsets;
#define NO_OF_INIT_PROPSETS 3


#define INIT_PROPNAME_LEN 50
typedef struct {
   char             name[INIT_PROPNAME_LEN];  // Name of prop exposed to user.
   init_propsets    propset_enum;    // In which property set property belongs.
   BOOL             isoptional;      // We only send this property to OLE DB if it has been set explicitly.
   DBPROPID         property_id;     // ID for property in OLE DB.
   VARTYPE          datatype;        // Datatype of the property.
   VARIANT          default_value;   // Default value for the property.
} init_property;
#define MAX_INIT_PROPERTIES 50


extern init_property gbl_init_props[MAX_INIT_PROPERTIES];

// This array holds where each property set starts in gbl_init_props;
typedef struct {
   int start;
   int no_of_props;
} propset_info_struct;
extern propset_info_struct init_propset_info[NO_OF_INIT_PROPSETS];


// Returns the number of properties in the SSPROP structure for the 
// given provider.
extern int no_of_ssprops(provider_enum);

// Global pointer to OLE DB Services. Set once when we intialize, and
// never released.
extern IDataInitialize * data_init_ptr;

internaldata.cpp  view on Meta::CPAN

  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

internaldata.cpp  view on Meta::CPAN

 * 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;

internaldata.cpp  view on Meta::CPAN

    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;

internaldata.h  view on Meta::CPAN


  There are also routines to set it up and tear it down.

  Copyright (c) 2004-2022   Erland Sommarskog

  $History: internaldata.h $
 * 
 * *****************  Version 12  *****************
 * 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 11  *****************
 * User: Sommar       Date: 22-05-08   Time: 23:11
 * Updated in $/Perl/OlleDB
 * Changed interface of dump_properties.
 * 
 * *****************  Version 10  *****************
 * User: Sommar       Date: 19-07-19   Time: 22:00
 * Updated in $/Perl/OlleDB

internaldata.h  view on Meta::CPAN


    // Various properties about the connection.
    BOOL                     isautoconnected;  // If connection was through connect() or not.
    BOOL                     isnestedquery;    // If current query was from inside the module.
    SV                     * SQL_version;      // The handle attribute SQL_version.
    int                      majorsqlversion;   
    SV                     * CurrentDB;
    provider_enum            provider;         // SQLOLEDB or SQLNCLI

    // Property sets and properties with initialization properties.
    DBPROPSET                init_propsets[NO_OF_INIT_PROPSETS];
    DBPROP                   init_properties[MAX_INIT_PROPERTIES];

    // A command text, possibly with parameters that are being assembled
    // with initbatch and enterparameter.
    BSTR                     pending_cmd;  // (Parameterised) cmd for which caller is supplying parmeters.
    paramdata              * paramfirst;   // Head of linked list for parameters.
    paramdata              * paramlast;    // Tail of parameter list.
    DBORDINAL                no_of_params; // Length of parameter list.
    DBORDINAL                no_of_out_params;  // And how many that are outparams.
    BOOL                     params_available;  // Not set until all result sets are exhausted.

internaldata.h  view on Meta::CPAN

    DBCOLUMNINFO           * column_info;
    WCHAR                  * colname_buffer; // Memory area for names in *colunm_info.
    DBBINDING              * col_bindings;
    DBBINDSTATUS           * col_bind_status;
    BYTE                   * data_buffer;    // Data buffer for a single row.
    size_t                   size_data_buffer;  // Size of that data buffer.
    SV                    ** column_keys;    // We convert column names for hash keys once and save them.
} internaldata;


extern void dump_properties(DBPROP *dbprops, init_propsets propset, int cProps);

extern void * setupinternaldata();

extern internaldata * get_internaldata(SV *olle_ptr);

extern void dump_internaldata(internaldata * mydata);

extern void free_resultset_data(internaldata *mydata);

extern void free_pending_cmd(internaldata *mydata);

senddata.cpp  view on Meta::CPAN

//-------------------------------------------------------------------
static void set_rowset_properties (SV           * olle_ptr,
                                   internaldata * mydata)
{
    IV                   optCommandTimeout = OptCommandTimeout(olle_ptr);
    HV                 * optQN = OptQueryNotification(olle_ptr);
    ICommandProperties * property_ptr;
    DBPROP               property[3];
    int                  no_of_props = 0;
    DBPROPSET            property_set[2];
    int                  no_of_propsets = 0;
    HRESULT              ret;

    if (optCommandTimeout > 0) {
       // There are a lot of properties in DBPROPSET_ROWSET, but we only care
       // about this single one.
       property[0].dwPropertyID = DBPROP_COMMANDTIMEOUT;
       property[0].dwOptions    = DBPROPOPTIONS_REQUIRED;
       property[0].colid        = DB_NULLID;
       VariantInit(&property[0].vValue);
       property[0].vValue.vt    = VT_I4;
       property[0].vValue.lVal  = (LONG) optCommandTimeout;

       property_set[0].guidPropertySet = DBPROPSET_ROWSET;
       property_set[0].cProperties     = 1;
       property_set[0].rgProperties    = property;

       no_of_propsets++;
    }

    // Check for query notification - but not if we run the nested
    // query to get the codepage.
    if (optQN && ! mydata->isnestedquery) {
       SV   * sv_service;
       SV   * sv_message;
       SV   * sv_timeout;

       no_of_props = 0;

senddata.cpp  view on Meta::CPAN

          property[no_of_props].vValue.vt    = VT_UI4;
          property[no_of_props].vValue.ulVal  = (ULONG) SvIV(sv_timeout);
          no_of_props++;
       }


       // Wipe out the hash.
       hv_clear(optQN);

       if (no_of_props > 0) {
          property_set[no_of_propsets].guidPropertySet = DBPROPSET_SQLSERVERROWSET;
          property_set[no_of_propsets].cProperties     = no_of_props;
          property_set[no_of_propsets].rgProperties    = property;

          no_of_propsets++;
       }
    }

    if (no_of_propsets > 0) {
       // Get a property pointer.
       ret = mydata->cmdtext_ptr->QueryInterface(IID_ICommandProperties,
                                                (void **) &property_ptr);
       check_for_errors(olle_ptr, "cmdtext_ptr->QueryInterface to create Property object", ret);

       ret = property_ptr->SetProperties(no_of_propsets, property_set);
       check_for_errors(NULL, "property_ptr->SetProperties for rowset props", ret);

       property_ptr->Release();
    }

    // We must free up memory allocated to the BSTRs in the QN propset.
    if (optQN) {
       for (int i = 0; i < no_of_props; i++) {
          VariantClear(&property[no_of_props].vValue);
       }
    }
}


//-------------------------------------------------------------------
// $X->executebatch.

senddata.cpp  view on Meta::CPAN

                  current_param->param_info.pwszName,
                  current_param->binding.obStatus,
                  current_param->binding.obValue);
            */

          }

          // Add parameter properties. These are not available with SQLOLEDB.
          if (current_param->param_props_cnt > 0 &&
              mydata->provider >= provider_sqlncli) {
              DBPROPSET  * propset;
              New(902, propset, 2 * current_param->param_props_cnt, DBPROPSET);
              propset->rgProperties = current_param->param_props;
              propset->cProperties = current_param->param_props_cnt;
              propset->guidPropertySet = DBPROPSET_SQLSERVERPARAMETER;
              ss_param_props[ss_param_props_cnt].rgPropertySets = propset;
              ss_param_props[ss_param_props_cnt].cPropertySets = 1;
              ss_param_props[ss_param_props_cnt].iOrdinal =
                  param_ordinals[param_ix];

              // If it's a table parameter with default values, there's
              // one more property.
              if (current_param->datatype == DBTYPE_TABLE &&
                  ! current_param->isnull &&
                  current_param->value.table->no_of_usedefault > 0) {
                  propset[1].rgProperties =
                       &(current_param->value.table->defcolprop);
                  propset[1].cProperties = 1;
                  propset[1].guidPropertySet = DBPROPSET_SQLSERVERPARAMETER;
                  ss_param_props[ss_param_props_cnt].cPropertySets++;
              }

              ss_param_props_cnt++;
          }

          // Move to next.
          current_param = current_param->next;
          param_ix++;
       }

tableparam.cpp  view on Meta::CPAN


   return TRUE;
}

// add_column_props is called to handle XML and UDT columns to define
// the type name or schema collection.
static void add_column_props (SV           * olle_ptr,
                              DBCOLUMNDESC * coldesc,
                              SV           * typeinfo)
{
    DBPROPSET * propset;
    int         propscnt = 0;

    // Drop out if there is no typeinfo.
    if (! my_sv_is_defined(typeinfo)) {
       return;
    }

    SV * server   = newSV(sv_len(typeinfo));
    SV * database = newSV(sv_len(typeinfo));
    SV * schema   = newSV(sv_len(typeinfo));

tableparam.cpp  view on Meta::CPAN

             objectpropid = SSPROP_COL_XML_SCHEMACOLLECTIONNAME;
             break;

         default :
             olle_croak(olle_ptr,
                        "Internal error: Unexpected value %d for data type in add_column_props",
                        coldesc->wType);
    }

    // Set up the property set.
    New(902, propset, 1, DBPROPSET);
    propset->guidPropertySet = DBPROPSET_SQLSERVERCOLUMN;
    propset->cProperties = propscnt;
    New(902, propset->rgProperties, propscnt, DBPROP);

    // Store database if any.
    if (sv_len(database) > 0) {
       propset->rgProperties[ix].dwPropertyID = dbpropid;
       propset->rgProperties[ix].colid = DB_NULLID;
       propset->rgProperties[ix].dwOptions = DBPROPOPTIONS_REQUIRED;
       VariantInit(&(propset->rgProperties[ix].vValue));
       propset->rgProperties[ix].vValue.vt = VT_BSTR;
       propset->rgProperties[ix].vValue.bstrVal = SV_to_BSTR(database);
       ix++;
    }

    // And schema if any.
    if (sv_len(schema) > 0) {
       propset->rgProperties[ix].dwPropertyID = schemapropid;
       propset->rgProperties[ix].colid = DB_NULLID;
       propset->rgProperties[ix].dwOptions = DBPROPOPTIONS_REQUIRED;
       VariantInit(&(propset->rgProperties[ix].vValue));
       propset->rgProperties[ix].vValue.vt = VT_BSTR;
       propset->rgProperties[ix].vValue.bstrVal = SV_to_BSTR(schema);
       ix++;
    }

    // And the type name.
    if (sv_len(object) > 0) {
       propset->rgProperties[ix].dwPropertyID = objectpropid;
       propset->rgProperties[ix].colid = DB_NULLID;
       propset->rgProperties[ix].dwOptions = DBPROPOPTIONS_REQUIRED;
       VariantInit(&(propset->rgProperties[ix].vValue));
       propset->rgProperties[ix].vValue.vt = VT_BSTR;
       propset->rgProperties[ix].vValue.bstrVal = SV_to_BSTR(object);
    }

    // And save the property set.
    coldesc->rgPropertySets = propset;
    coldesc->cPropertySets = 1;

    // We must clean up our SVs to not leak memory.
    SvREFCNT_dec(server);
    SvREFCNT_dec(database);
    SvREFCNT_dec(schema);
    SvREFCNT_dec(object);
}




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