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) {
// 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
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 :
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,
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,
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.
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) {
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);
}