Win32-SqlServer
view release on metacpan or search on metacpan
tableparam.cpp view on Meta::CPAN
// Check that table parameter are supported at all.
if (mydata->provider < provider_sqlncli10 ||
mydata->majorsqlversion < 10) {
olledb_message(olle_ptr, -1, 1, 16,
L"To use table parameters, you need SQL 2008 and SQL Server Native Client 10 or later.");
return FALSE;
}
// Check that maxlen is legal.
if (no_of_cols < 1 || no_of_cols > 1024) {
olle_croak(olle_ptr, "Illegal number of columns (%d) specified for table-valued parameter",
no_of_cols);
}
// Check that we have name for the type.
if (! my_sv_is_defined(tabletypename)) {
olle_croak(olle_ptr, "Name of type missing for table-valued parameter");
}
// Allocate the table parameter itself and initiate the area.
New(902, tabledef, 1, tableparam);
memset(tabledef, 0, sizeof(tableparam));
tabledef->tabletypename = SV_to_BSTR(tabletypename);
tabledef->no_of_cols = tabledef->cols_undefined = no_of_cols;
tabledef->no_of_usedefault = 0;
tabledef->colnamemap = newHV();
New(902, tabledef->columns, no_of_cols, DBCOLUMNDESC);
memset(tabledef->columns, 0, no_of_cols * sizeof(DBCOLUMNDESC));
New(902, tabledef->colbindings, no_of_cols, DBBINDING);
memset(tabledef->colbindings, 0, no_of_cols * sizeof(DBBINDING));
New(902, tabledef->colbindstatus, no_of_cols, DBBINDSTATUS);
memset(tabledef->colbindstatus, 0, no_of_cols * sizeof(DBBINDSTATUS));
New(902, tabledef->usedefault, no_of_cols, BOOL);
memset(tabledef->usedefault, FALSE, no_of_cols * sizeof(BOOL));
New(902, tabledef->bindix, no_of_cols, UINT);
memset(tabledef->bindix, ~0, no_of_cols * sizeof(UINT));
// Set the table definition as the value for the current parameter.
this_param->value.table = tabledef;
// If the table parameter has a name, save it into a hash so that the
// caller can refer to the parameter by name later.
if (this_param->param_info.pwszName != NULL) {
if (mydata->tableparams == NULL) {
mydata->tableparams = newHV();
}
SV * sv_tabledef = newSViv((IV) tabledef);
hv_store_ent(mydata->tableparams, paramname, sv_tabledef, 0);
}
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));
SV * object = newSV(sv_len(typeinfo));
int ix = 0;
DBPROPID dbpropid;
DBPROPID schemapropid;
DBPROPID objectpropid;
// First extract components from typeinfo.
if (! parsename(olle_ptr, typeinfo, 0, server, database, schema, object)) {
return;
}
// If there was a server, cry foul.
if (sv_len(server) > 0) {
BSTR typeinfo_str = SV_to_BSTR(typeinfo);
olledb_message(olle_ptr, -1, -1, 16,
L"Type name/XML schema '%s' includes a server compenent.\n",
typeinfo_str);
SysFreeString(typeinfo_str);
SvREFCNT_dec(server);
SvREFCNT_dec(database);
SvREFCNT_dec(schema);
SvREFCNT_dec(object);
return;
}
// Find out how many components we have.
if (sv_len(database) > 0) propscnt++;
if (sv_len(schema) > 0) propscnt++;
if (sv_len(object) > 0) propscnt++;
// If there was nothing, just drop out.
if (propscnt == 0)
return;
// Set up property ids
switch (coldesc->wType) {
case DBTYPE_UDT :
dbpropid = SSPROP_COL_UDT_CATALOGNAME;
schemapropid = SSPROP_COL_UDT_SCHEMANAME;
objectpropid = SSPROP_COL_UDT_NAME;
break;
case DBTYPE_XML :
dbpropid = SSPROP_COL_XML_SCHEMACOLLECTION_CATALOGNAME;
schemapropid = SSPROP_COL_XML_SCHEMACOLLECTION_SCHEMANAME;
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);
}
//------------------------------------------------------------------------
// definetablecolumn, exposed in the mid-level interface.
int definetablecolumn(SV * olle_ptr,
SV * tblname,
SV * colname,
SV * sv_nameoftype,
SV * sv_maxlen,
SV * sv_precision,
SV * sv_scale,
SV * usedefault,
SV * typeinfo)
{
internaldata * mydata = get_internaldata(olle_ptr);
tableparam * tbldef;
char * nameoftype;
DBLENGTH maxlen;
int colno;
int colix;
int bindix;
DBTYPE typeind;
DBCOLUMNDESC * coldesc;
DBPARAMBINDINFO param_info;
DBBINDING * binding;
// Check that we're in the state where we're accepting parameters at all.
if (mydata->pending_cmd == NULL) {
olle_croak(olle_ptr, "Cannot call definetablecolumn now. There is no pending command. Call initbatch first");
}
if (mydata->cmdtext_ptr != NULL) {
olle_croak(olle_ptr, "Cannot call definetablecolumn now. There are unprocessed result sets. Call cancelbatch first");
}
// See if we have a table parameter to work with. The caller can specify
// a name, or undef to work the the most recently added parameter.
if (my_sv_is_defined(tblname)) {
HE * he = hv_fetch_ent(mydata->tableparams, tblname, 0, 0);
if (he == NULL) {
olle_croak(olle_ptr, "Attempt to define column for parameter %s, but this is not a table-valued parameter",
SvPV_nolen(tblname));
}
tbldef = (tableparam *) SvIV(HeVAL(he));
}
else if (mydata->paramlast && mydata->paramlast->value.table != NULL) {
tbldef = mydata->paramlast->value.table;
}
else {
olle_croak(olle_ptr, "Cannot define table column without a parameter name now. Most recently entered parameter is not a table");
}
( run in 0.511 second using v1.01-cache-2.11-cpan-71847e10f99 )