|
|
// prop.cpp : Implementation of CMetaPropertySet
#include "stdafx.h"
#include "Property.h"
#include "util.h"
HRESULT SaveObjectToField(VARIANT var, ADODB::Field *pfield) { HRESULT hr; if ((var.vt != VT_UNKNOWN) && (var.vt != VT_DISPATCH)) return E_INVALIDARG;
CComPtr<IStream> pstream; hr = CreateStreamOnHGlobal(NULL, TRUE, &pstream); if (FAILED(hr)) return hr; CComQIPtr<IPersistStream> ppersiststream(var.punkVal);
if (ppersiststream != NULL) { // Write a tag to indicate IPersistStream was used.
char ch = Format_IPersistStream; ULONG cb = sizeof(ch); hr = pstream->Write(&ch, cb, &cb); if (FAILED(hr)) return hr;
hr = OleSaveToStream(ppersiststream, pstream); if (FAILED(hr)) return hr; } else { CComQIPtr<IPersistPropertyBag> ppersistpropbag(var.punkVal); if (ppersistpropbag == NULL) return E_INVALIDARG; // Write a tag to indicate IPersistPropertyBag was used.
char ch = Format_IPersistPropertyBag; ULONG cb = sizeof(ch); hr = pstream->Write(&ch, cb, &cb); if (FAILED(hr)) return hr; hr = SaveToPropBagInStream(ppersistpropbag, pstream); if (FAILED(hr)) return hr; } HANDLE hdata; hr = GetHGlobalFromStream(pstream, &hdata); if (FAILED(hr)) return hr; long cb = GlobalSize(hdata); SAFEARRAY *parray = SafeArrayCreateVector(VT_UI1, 0, cb); if (parray == NULL) return E_OUTOFMEMORY; BYTE *pbDst; hr = SafeArrayAccessData(parray, (void **) &pbDst); if (FAILED(hr)) return hr; BYTE *pbSrc = (BYTE *) GlobalLock(hdata);
memcpy(pbDst, pbSrc, cb);
GlobalUnlock(hdata); SafeArrayUnaccessData(parray);
_variant_t varT; varT.vt = VT_ARRAY | VT_UI1; varT.parray = parray;
hr = pfield->AppendChunk(varT); if (FAILED(hr)) return hr;
return S_OK; }
HRESULT LoadObjectFromField(ADODB::Field *pfield, VARIANT *pvar) { HRESULT hr; long cb; hr = pfield->get_ActualSize(&cb); if (FAILED(hr)) return hr;
_variant_t varData; hr = pfield->GetChunk(cb, &varData); if (FAILED(hr)) return hr; if ((varData.vt & VT_ARRAY) == 0) return E_FAIL; BYTE *pbSrc; hr = SafeArrayAccessData(varData.parray, (void **) &pbSrc); if (FAILED(hr)) return hr; HANDLE hdata; BOOL fFree = FALSE; hdata = GlobalHandle(pbSrc); if (hdata == NULL) { hdata = GlobalAlloc(GHND, cb); if (hdata == NULL) { SafeArrayUnaccessData(varData.parray); return E_OUTOFMEMORY; } BYTE *pbDst = (BYTE *) GlobalLock(hdata);
memcpy(pbDst, pbSrc, cb); fFree = TRUE; } else { BYTE *pbTest = (BYTE *) GlobalLock(hdata); int i = 0; if (pbTest != pbSrc) i++; GlobalUnlock(hdata); }
CComPtr<IUnknown> punk; { CComPtr<IStream> pstream; hr = CreateStreamOnHGlobal(hdata, fFree, &pstream); if (FAILED(hr)) { if (fFree) GlobalFree(hdata); return hr; } char ch; ULONG cbT = sizeof(ch); hr = pstream->Read(&ch, cbT, &cbT); switch (ch) { case Format_IPersistStream: hr = OleLoadFromStream(pstream, __uuidof(IUnknown), (void **) &punk); break; case Format_IPersistPropertyBag: hr = LoadFromPropBagInStream(pstream, &punk); break; default: return STG_E_DOCFILECORRUPT; } } SafeArrayUnaccessData(varData.parray);
if (FAILED(hr)) return hr;
pvar->vt = VT_UNKNOWN; pvar->punkVal = punk.Detach();
return S_OK; }
HRESULT SeekPropsRS(ADODB::_RecordsetPtr prs, boolean fSQLServer, long idObj, long idPropType, boolean fAnyProvider, long idProvider, long idLang) { _ASSERTE(idObj != 0); HRESULT hr;
if (fAnyProvider && idProvider != NULL) { // First try to find the specified provider, only if it is not found
// do we look for any provider.
hr = SeekPropsRS(prs, fSQLServer, idObj, idPropType, FALSE, idProvider, idLang); if (SUCCEEDED(hr)) return hr; idProvider = NULL; }
try { TCHAR szFind[32]; DeclarePerfTimerOff(perf, "SeekPropsRS");
#if 1
{ static bool fDump= FALSE;
if (fDump) { prs->MoveFirst(); while (!prs->EndOfFile) { long idObjCur = prs->Fields->Item["idObj"]->Value; long idPropTypeCur = prs->Fields->Item["idPropType"]->Value;
TRACE("idObj = %d idPropType = %d\n", idObjCur, idPropTypeCur); prs->MoveNext(); } } } #endif
PerfTimerReset(); if (fSQLServer) { prs->MoveFirst(); wsprintf(szFind, _T("idObj = %d"), idObj); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
wsprintf(szFind, _T("idPropType = %d"), idPropType); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward); } else { // Create elements used in the array
_variant_t varCriteria[4]; varCriteria[0] = idObj; varCriteria[1] = idPropType; varCriteria[2] = idProvider; varCriteria[3] = idLang; const int nCrit = sizeof varCriteria / sizeof varCriteria[0];
// Create SafeArray Bounds and initialize the array
SAFEARRAYBOUND rgsabound[1]; rgsabound[0].lLbound = 0; rgsabound[0].cElements = nCrit; SAFEARRAY *psa = SafeArrayCreate( VT_VARIANT, 1, rgsabound );
hr = S_OK; // Set the values for each element of the array
for( long i = 0 ; i < nCrit && SUCCEEDED( hr );i++) { hr = SafeArrayPutElement(psa, &i,&varCriteria[i]); }
// Initialize and fill the SafeArray
VARIANT var; var.vt = VT_VARIANT | VT_ARRAY; V_ARRAY(&var) = psa;
hr = prs->Seek(var, fAnyProvider ? ADODB::adSeekAfterEQ : ADODB::adSeekFirstEQ);
if (FAILED(hr)) return hr; if (prs->EndOfFile) return E_INVALIDARG; if (!fAnyProvider) return S_OK; }
while (TRUE) { if (prs->EndOfFile) break;
long idObjCur = prs->Fields->Item["idObj"]->Value; if (idObjCur != idObj) break;
long idPropTypeCur = prs->Fields->Item["idPropType"]->Value; if (idPropTypeCur != idPropType) break; long idLang2 = prs->Fields->Item["idLanguage"]->Value; long idProvider2 = prs->Fields->Item["idProvider"]->Value; if ((idLang == idLang2) && (fAnyProvider || (idProvider == idProvider2))) { PerfTimerDump("Successful seek"); return S_OK; } prs->MoveNext(); } PerfTimerDump("Failed seek"); return E_INVALIDARG; } catch (_com_error & e) { TCHAR sz[1024]; wsprintf(sz, _T("Error: %s"), e.ErrorMessage());
return e.Error(); } }
/////////////////////////////////////////////////////////////////////////////
// CMetaPropertySet
HRESULT CMetaPropertySet::Load() { HRESULT hr;
ADODB::_RecordsetPtr prs; hr = m_pdb->get_PropTypesRS(&prs); if (FAILED(hr)) return hr; if (!CreatePropTypes()) return E_OUTOFMEMORY; prs->MoveFirst(); TCHAR szFind[20]; wsprintf(szFind, _T("idPropSet = %d"), m_id); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
while (!prs->EndOfFile) { CComPtr<CMetaPropertyType> pproptype; long idPropSet = prs->Fields->Item["idPropSet"]->Value; if (idPropSet != m_id) break; bstr_t bstrName = prs->Fields->Item["Name"]->Value; long idPropType = prs->Fields->Item["idProp"]->Value; long id = prs->Fields->Item["id"]->Value; variant_t varNil;
hr = m_pproptypes->Cache(id, idPropType, bstrName, &pproptype); prs->MoveNext(); }
return S_OK; }
STDMETHODIMP CMetaPropertySet::get_Name(BSTR *pbstrName) { ENTER_API { ValidateOut(pbstrName);
*pbstrName = m_bstrName.copy();
return S_OK; } LEAVE_API }
bool CMetaPropertySet::CreatePropTypes() { if (m_pproptypes == NULL) { CComPtr<CMetaPropertyTypes> pproptypes = NewComObject(CMetaPropertyTypes);
if (pproptypes == NULL) return FALSE; pproptypes->Init(m_pdb, this); m_pproptypes = pproptypes; } return TRUE; }
STDMETHODIMP CMetaPropertySet::get_MetaPropertyTypes(IMetaPropertyTypes **ppproptypes) { ENTER_API { ValidateOutPtr<IMetaPropertyTypes>(ppproptypes, NULL);
if (!CreatePropTypes()) return E_OUTOFMEMORY;
(*ppproptypes = m_pproptypes)->AddRef();
return S_OK; } LEAVE_API }
/////////////////////////////////////////////////////////////////////////////
// CMetaPropertySets
HRESULT CMetaPropertySets::Load() { HRESULT hr; ADODB::_RecordsetPtr prs; hr = m_pdb->get_PropSetsRS(&prs); if (FAILED(hr)) return hr; prs->MoveFirst(); while (!prs->EndOfFile) { // Read in all the records
CComPtr<CMetaPropertySet> ppropset;
long id = prs->Fields->Item["id"]->Value; bstr_t bstrName = prs->Fields->Item["Name"]->Value;
hr = Cache(id, bstrName, &ppropset); if (SUCCEEDED(hr) && ppropset != NULL) { ppropset->Load(); } prs->MoveNext(); }
return S_OK; }
STDMETHODIMP CMetaPropertySets::get_Count(long *plCount) { ENTER_API { ValidateOut<long>(plCount);
*plCount = m_map.size();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertySets::get_Item(VARIANT varIndex, IMetaPropertySet **pppropset) { ENTER_API { ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
if (varIndex.vt == VT_BSTR) return get_ItemWithName(varIndex.bstrVal, pppropset);
_variant_t var(varIndex); try { var.ChangeType(VT_I4); } catch (_com_error &) { return E_INVALIDARG; } long i = var.lVal;
if ((i < 0) || (i >= m_map.size())) return E_INVALIDARG;
t_map::iterator it = m_map.begin();
while (i--) it++;
*pppropset = (*it).second;
if (*pppropset != NULL) (*pppropset)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertySets::get_ItemWithName(BSTR bstrName, IMetaPropertySet **pppropset) { ENTER_API { ValidateIn(bstrName); ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
t_map::iterator it = m_map.find(bstrName); if (it == m_map.end()) return E_INVALIDARG;
*pppropset = (*it).second; (*pppropset)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertySets::get_Lookup(BSTR bstrName, IMetaPropertyType **ppproptype) { ENTER_API { HRESULT hr; ValidateIn(bstrName); ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
if (bstrName == NULL) return E_INVALIDARG;
wchar_t *szDot = wcschr(bstrName, L'.'); if (szDot == NULL) return E_INVALIDARG; _bstr_t bstrPropTypeName(szDot+1);
_bstr_t bstrPropSetName = SysAllocStringLen(bstrName, szDot - bstrName);
CComPtr<IMetaPropertySet> ppropset; hr = get_AddNew(bstrPropSetName, &ppropset); if (FAILED(hr)) return hr;
CComPtr<IMetaPropertyTypes> pproptypes; hr = ppropset->get_MetaPropertyTypes(&pproptypes); if (FAILED(hr)) return hr; CComPtr<IMetaPropertyType> pproptype; _variant_t varNil; hr = pproptypes->get_AddNew(0, bstrPropTypeName, &pproptype); if (FAILED(hr)) return hr;
*ppproptype = pproptype.Detach();
return S_OK; } LEAVE_API }
HRESULT CMetaPropertySets::Cache(long id, BSTR bstrName, CMetaPropertySet **pppropset) { CComPtr<CMetaPropertySet> ppropset = NULL;
t_map::iterator it = m_map.find(bstrName); if (it != m_map.end()) { ppropset = (*it).second; } else { ppropset = NewComObject(CMetaPropertySet);
if (ppropset == NULL) return E_OUTOFMEMORY;
ppropset->Init(m_pdb, id, bstrName);
BSTR bstrNameT = SysAllocString(bstrName); if (bstrNameT == NULL) return E_OUTOFMEMORY; ppropset.CopyTo(&m_map[bstrNameT]); }
*pppropset = ppropset.Detach();
return S_OK; }
STDMETHODIMP CMetaPropertySets::get_AddNew(BSTR bstrName, IMetaPropertySet **pppropset) { ENTER_API { ValidateIn(bstrName); ValidateOutPtr<IMetaPropertySet>(pppropset, NULL);
HRESULT hr;
hr = get_ItemWithName(bstrName, pppropset); if (SUCCEEDED(hr)) return hr;
static long idCur = 1; long id; if (m_pdb == NULL) id = idCur++; else { ADODB::_RecordsetPtr prs; hr = m_pdb->get_PropSetsRS(&prs); if (FAILED(hr)) return hr;
// Create a new record.
hr = prs->AddNew();
prs->Fields->Item["Name"]->Value = bstrName;
hr = prs->Update();
id = prs->Fields->Item["id"]->Value; } CMetaPropertySet *ppropset; hr = Cache(id, bstrName, &ppropset); *pppropset = ppropset;
return hr; } LEAVE_API }
/////////////////////////////////////////////////////////////////////////////
// CMetaPropertyType
STDMETHODIMP CMetaPropertyType::get_MetaPropertySet(IMetaPropertySet **pppropset) { ENTER_API { ValidateOutPtr<IMetaPropertySet>(pppropset, m_ppropset);
(*pppropset)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyType::get_ID(long *pid) { ENTER_API { ValidateOut<long>(pid, m_idPropType);
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyType::get_Name(BSTR *pbstrName) { ENTER_API { ValidateOut(pbstrName);
*pbstrName = m_bstrName.copy(); return S_OK; } LEAVE_API }
HRESULT CMetaPropertyType::GetNew(long idProvider, long lang, VARIANT varValue, IMetaProperty **ppprop) { ENTER_API { ValidateOutPtr<IMetaProperty>(ppprop, NULL);
CComPtr<CMetaProperty> pprop = NewComObject(CMetaProperty);
if (pprop == NULL) return E_OUTOFMEMORY;
pprop->Init(m_pdb, m_id, idProvider, lang, varValue);
*ppprop = pprop.Detach();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyType::get_Cond(BSTR bstrCond, long lang, VARIANT varValue, IMetaPropertyCondition **pppropcond) { ENTER_API { ValidateIn(bstrCond); ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
if (bstrCond == NULL) return E_INVALIDARG;
HRESULT hr; CComPtr<IMetaProperty> pprop;
hr = get_New(lang, varValue, &pprop); if (FAILED(hr)) return hr;
return pprop->get_Cond(bstrCond, pppropcond); } LEAVE_API }
/////////////////////////////////////////////////////////////////////////////
// CMetaPropertyTypes
STDMETHODIMP CMetaPropertyTypes::get_Count(long *plCount) { ENTER_API { ValidateOut<long>(plCount, m_map.size());
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyTypes::get_Item(VARIANT varIndex, IMetaPropertyType **ppproptype) { ENTER_API { ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
if (varIndex.vt == VT_BSTR) return get_ItemWithName(varIndex.bstrVal, ppproptype);
_variant_t var(varIndex);
try { var.ChangeType(VT_I4); } catch (_com_error &) { return E_INVALIDARG; } long i = var.lVal;
if ((i < 0) || (i >= m_map.size())) return E_INVALIDARG;
t_map::iterator it = m_map.begin();
while (i--) it++;
*ppproptype = (*it).second;
if (*ppproptype != NULL) (*ppproptype)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyTypes::get_MetaPropertySet(IMetaPropertySet **pppropset) { ENTER_API { ValidateOutPtr<IMetaPropertySet>(pppropset, m_ppropset);
if (*pppropset != NULL) (*pppropset)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyTypes::get_ItemWithName(BSTR bstrName, IMetaPropertyType **ppproptype) { ENTER_API { ValidateIn(bstrName); ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
t_map::iterator it = m_map.find(bstrName); if (it == m_map.end()) return E_INVALIDARG;
(*ppproptype = (*it).second)->AddRef();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyTypes::get_ItemWithID(long id, IMetaPropertyType **ppproptype) { ENTER_API { ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
for (t_map::iterator it = m_map.begin(); it != m_map.end(); it++) { CComPtr<IMetaPropertyType> pproptype = (*it).second; long idCur;
pproptype->get_ID(&idCur);
if (idCur == id) { *ppproptype = pproptype.Detach(); return S_OK; } }
return E_INVALIDARG; } LEAVE_API }
HRESULT CMetaPropertyTypes::Cache(long id, long idPropType, BSTR bstrName, CMetaPropertyType **ppproptype) { CComPtr<CMetaPropertyType> pproptype;
t_map::iterator it = m_map.find(bstrName); if (it != m_map.end()) { pproptype = (*it).second; } else { pproptype = NewComObject(CMetaPropertyType);
if (pproptype == NULL) return E_OUTOFMEMORY;
pproptype->Init(m_pdb, m_ppropset, id, idPropType, bstrName);
BSTR bstrT = SysAllocString(bstrName); pproptype.CopyTo(&m_map[bstrT]);
m_pdb->put_MetaPropertyType(id, pproptype); }
*ppproptype = pproptype.Detach();
return S_OK; }
STDMETHODIMP CMetaPropertyTypes::get_AddNew(long idProp, BSTR bstrName, IMetaPropertyType **ppproptype) { ENTER_API { ValidateIn(bstrName); ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
HRESULT hr;
hr = get_ItemWithName(bstrName, ppproptype); if (SUCCEEDED(hr)) return hr;
CComPtr<CMetaPropertyType> pproptype;
static long idCur = 1; long id;
if (m_pdb == NULL) id = idCur++; else { ADODB::_RecordsetPtr prs; hr = m_pdb->get_PropTypesRS(&prs); if (FAILED(hr)) return hr;
// Create a new record.
hr = prs->AddNew();
prs->Fields->Item["idPropSet"]->Value = m_ppropset->GetID(); prs->Fields->Item["idProp"]->Value = idProp; prs->Fields->Item["Name"]->Value = bstrName;
hr = prs->Update();
id = prs->Fields->Item["id"]->Value; } hr = Cache(id, idProp, bstrName, &pproptype);
if (FAILED(hr)) return hr; *ppproptype = pproptype.Detach();
return S_OK; } LEAVE_API }
/////////////////////////////////////////////////////////////////////////////
// CMetaProperty
STDMETHODIMP CMetaProperty::get_MetaPropertyType(IMetaPropertyType **ppproptype) { ENTER_API { ValidateOutPtr<IMetaPropertyType>(ppproptype, NULL);
return m_pdb->get_MetaPropertyType(m_idPropType, ppproptype); } LEAVE_API }
STDMETHODIMP CMetaProperty::get_Language(long *pidLang) { ENTER_API { ValidateOut<long>(pidLang, m_idLang);
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaProperty::get_Value(VARIANT *pvarValue) { ENTER_API { ValidateOut(pvarValue);
return VariantCopy(pvarValue, &m_varValue); } LEAVE_API }
STDMETHODIMP CMetaProperty::put_Value(VARIANT varValue) { ENTER_API { // Changing the value, so must reset the provider.
m_idProvider = m_pdb->GetIDGuideDataProvider();
return PutValue(varValue); } LEAVE_API }
STDMETHODIMP CMetaProperty::PutValue(VARIANT varValue) { HRESULT hr; ADODB::_RecordsetPtr prs;
m_varValue = varValue;
hr = m_pdb->get_PropsIndexed(&prs); if (FAILED(hr)) return hr;
hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj, m_idPropType, FALSE, m_idProvider, m_idLang); if (FAILED(hr)) { hr = AddNew(prs); if (FAILED(hr)) return hr; }
hr = SaveValue(prs); if (FAILED(hr)) { prs->CancelUpdate(); return hr; }
hr = prs->Update(); if (FAILED(hr)) return hr; m_pdb->Broadcast_ItemChanged(m_idObj);
return hr; }
STDMETHODIMP CMetaProperty::get_QueryClause(long &i, TCHAR *szOp, _bstr_t *pbstr) { TCHAR *szFieldName; TCHAR *szValue = NULL;
switch (m_varValue.vt) { default: return E_INVALIDARG;
case VT_EMPTY: return E_NOTIMPL; //Special case
case VT_I2: case VT_I4: { szFieldName = _T("lValue");
int cb = 32; szValue = new TCHAR [cb]; if (szValue == NULL) return E_OUTOFMEMORY;
_sntprintf(szValue, cb, _T("%d"), (long) m_varValue); } break; case VT_R4: case VT_R8: { szFieldName = _T("fValue");
int cb = 32; szValue = new TCHAR [cb]; if (szValue == NULL) return E_OUTOFMEMORY;
_sntprintf(szValue, cb, _T("%.17f"), (double) m_varValue); } break;
case VT_DATE: { szFieldName = _T("fValue");
_variant_t varT;
::VariantChangeTypeEx(&varT, &m_varValue, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, VT_BSTR);
long cb = SysStringLen(varT.bstrVal) + 3; szValue = new TCHAR [cb]; if (szValue == NULL) return E_OUTOFMEMORY;
_sntprintf(szValue, cb, _T("#%s#"), (const TCHAR *) varT.bstrVal); } break; case VT_BSTR: {
_bstr_t bstr = m_varValue.bstrVal; int cb = bstr.length() + 3; // Add on 2 quotes and null terminator
szValue = new TCHAR [cb]; if (szValue == NULL) return E_OUTOFMEMORY;
if (bstr.length() < 255) { szFieldName = _T("sValue"); _sntprintf(szValue, cb, _T("\"%s\""), (const TCHAR *) bstr); } else { delete [] szValue; return E_INVALIDARG; //UNDONE: What to do?
} } break; }
int cb = -1; int cbBuf = 128; TCHAR *sz = NULL; while (cb < 0) { delete [] sz; sz = new TCHAR [cbBuf]; if (sz == NULL) return E_OUTOFMEMORY;
cb = _sntprintf(sz, cbBuf, _T("(Props_%i.idPropType = %i) AND (Props_%i.%s %s %s)"), i, m_idPropType, i, szFieldName, szOp, szValue); cbBuf *= 2; }
i++; *pbstr = sz; delete [] sz; delete [] szValue; return S_OK; }
STDMETHODIMP CMetaProperty::get_Cond(BSTR bstrCond, IMetaPropertyCondition **pppropcond) { ENTER_API { ValidateIn(bstrCond); ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
if (bstrCond == NULL) return E_INVALIDARG;
CComPtr<CMetaPropertyCondition1Prop> ppropcond = NULL;
if (wcscmp(bstrCond, L"=") == 0) { ppropcond = NewComObject(CMetaPropertyConditionEQ); } else if ((wcscmp(bstrCond, L"!=") == 0) || (wcscmp(bstrCond, L"<>") == 0)) { ppropcond = NewComObject(CMetaPropertyConditionNE); } else if (_wcsicmp(bstrCond, L"LIKE") == 0) { ppropcond = NewComObject(CMetaPropertyConditionLike); } else if (_wcsicmp(bstrCond, L"NOT LIKE") == 0) { ppropcond = NewComObject(CMetaPropertyConditionNotLike); } else if (wcscmp(bstrCond, L"<") == 0) { ppropcond = NewComObject(CMetaPropertyConditionLT); } else if (wcscmp(bstrCond, L"<=") == 0) { ppropcond = NewComObject(CMetaPropertyConditionLE); } else if (wcscmp(bstrCond, L">") == 0) { ppropcond = NewComObject(CMetaPropertyConditionGT); } else if (wcscmp(bstrCond, L">=") == 0) { ppropcond = NewComObject(CMetaPropertyConditionGE); } else { return E_INVALIDARG; }
if (ppropcond == NULL) return E_OUTOFMEMORY;
ppropcond->Init(this);
*pppropcond = ppropcond.Detach();
return S_OK; } LEAVE_API }
HRESULT CMetaProperty::AddNew(ADODB::_RecordsetPtr prs) { HRESULT hr;
// Create a new record.
hr = prs->AddNew(); if (FAILED(hr)) return hr;
prs->Fields->Item["idObj"]->Value = m_idObj; prs->Fields->Item["idPropType"]->Value = m_idPropType; prs->Fields->Item["idProvider"]->Value = m_idProvider; prs->Fields->Item["idLanguage"]->Value = m_idLang;
return S_OK; }
HRESULT CMetaProperty::SaveValue(ADODB::_RecordsetPtr prs) { HRESULT hr; try { VARTYPE vt = m_varValue.vt; IUnknown *punk; switch (vt) { default: return E_INVALIDARG;
case VT_EMPTY: break;
case VT_I2: case VT_I4: prs->Fields->Item["lValue"]->Value = m_varValue; break; case VT_R4: case VT_R8: case VT_DATE: prs->Fields->Item["fValue"]->Value = m_varValue; break; case VT_BSTR_BLOB: case VT_BSTR: prs->Fields->Item["sValue"]->Value = m_varValue; break; case VT_DISPATCH: case VT_UNKNOWN: #if 0
hr = SaveObjectToField(m_varValue, prs->Fields->Item["oValue"]); if (FAILED(hr)) return hr; #else
punk = m_varValue.punkVal; goto SaveObj; #endif
break; case VT_BYREF | VT_UNKNOWN: punk = *m_varValue.ppunkVal; vt = VT_UNKNOWN; SaveObj: { // Temporarily set to NULL
prs->Fields->Item["ValueType"]->Value = _variant_t((long) VT_UNKNOWN); prs->Fields->Item["lValue"]->Value = _variant_t((long) NULL);
if (punk != NULL) { hr = prs->Update(); long idObj; hr = m_pdb->SaveObject(punk, &idObj); if (FAILED(hr)) return hr; // Seek back and fix it up.
hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj, m_idPropType, FALSE, m_idProvider, m_idLang); if (FAILED(hr)) return hr; prs->Fields->Item["lValue"]->Value = idObj; } } break; }
prs->Fields->Item["ValueType"]->Value = _variant_t((long) vt); } catch (_com_error & e) { return e.Error(); }
return S_OK; }
HRESULT CMetaProperty::LoadValue(ADODB::_RecordsetPtr prs) { HRESULT hr; _variant_t varType = prs->Fields->Item["ValueType"]->Value;
try { varType.ChangeType(VT_I4); } catch (_com_error &) { return E_INVALIDARG; } switch (varType.lVal) { default: return E_INVALIDARG;
case VT_EMPTY: m_varValue.Clear(); break;
case VT_I2: case VT_I4: m_varValue = prs->Fields->Item["lValue"]->Value; break; case VT_R4: case VT_R8: case VT_DATE: m_varValue = prs->Fields->Item["fValue"]->Value; break; case VT_BSTR_BLOB: case VT_BSTR: m_varValue = prs->Fields->Item["sValue"]->Value; m_varValue.vt = varType.lVal; break; case VT_UNKNOWN: #if 0
hr = LoadObjectFromField(prs->Fields->Item["oValue"], &m_varValue); if (FAILED(hr)) return hr; #else
{ CComPtr<IUnknown> punk; long idObj = prs->Fields->Item["lValue"]->Value; if (idObj != NULL) { hr = m_pdb->CacheObject(idObj, (long) 0, &punk); if (FAILED(hr)) return hr; } m_varValue = punk; } #endif
break; }
return S_OK; }
/////////////////////////////////////////////////////////////////////////////
// CMetaProperties
STDMETHODIMP CMetaProperties::get_Count(long *plCount) { ENTER_API { ValidateOut<long>(plCount, 0);
HRESULT hr; ADODB::_RecordsetPtr prs;
hr = m_pdb->get_PropsIndexed(&prs); prs->MoveFirst(); TCHAR szFind[32]; wsprintf(szFind, _T("idObj = %d"), m_idObj); hr = prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward); if (FAILED(hr)) return S_OK;
if (m_idPropType != 0) { wsprintf(szFind, _T("idPropType = %d"), m_idPropType); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
if (prs->EndOfFile) return S_OK; }
// UNDONE: This is not the most efficient, but it's what works for now.
while (!prs->EndOfFile) { long idObj2 = prs->Fields->Item["idObj"]->Value; if (m_idObj != idObj2) break; if (m_idPropType != 0) { long idPropType = prs->Fields->Item["idPropType"]->Value; if (m_idPropType != idPropType) break; } (*plCount)++; hr = prs->MoveNext(); if (FAILED(hr)) return hr; } return S_OK; } LEAVE_API }
HRESULT CMetaProperties::Load(long idPropType, ADODB::_RecordsetPtr prs, IMetaProperty **ppprop) { HRESULT hr; CComPtr<IMetaPropertyType> pproptype; CComPtr<IMetaProperty> pprop;
hr = m_pdb->get_MetaPropertyType(idPropType, &pproptype); if (FAILED(hr)) return hr; long idLang = prs->Fields->Item["idLanguage"]->Value; long idProvider = prs->Fields->Item["idProvider"]->Value;
CComQIPtr<CMetaPropertyType> pproptypeT(pproptype); _variant_t varValue; hr = pproptypeT->GetNew(idProvider, idLang, varValue, &pprop);
if (FAILED(hr)) return hr; CComQIPtr<CMetaProperty> ppropT(pprop);
ppropT->SetObjectID(m_idObj);
hr = ppropT->LoadValue(prs); if (FAILED(hr)) return hr; *ppprop = pprop.Detach(); return S_OK; }
STDMETHODIMP CMetaProperties::get_Item(VARIANT varIndex, IMetaProperty **ppprop) { ENTER_API { ValidateOutPtr<IMetaProperty>(ppprop, NULL);
HRESULT hr;
if (varIndex.vt == VT_BSTR) { CComPtr<IMetaPropertyType> pproptype; hr = m_pdb->get_MetaPropertyType(varIndex.bstrVal, &pproptype); if (FAILED(hr)) return E_INVALIDARG; hr = get_ItemWith(pproptype, 0, ppprop); if (FAILED(hr)) { CComPtr<IGuideDataProvider> pprovider; m_pdb->get_GuideDataProvider(&pprovider);
_variant_t varNil; hr = get_AddNew(pproptype, pprovider, 0, varNil, ppprop); } return hr; }
_variant_t var(varIndex);
try { var.ChangeType(VT_I4); } catch (_com_error &) { return E_INVALIDARG; } if (var.lVal < 0) return E_INVALIDARG;
ADODB::_RecordsetPtr prs;
hr = m_pdb->get_PropsIndexed(&prs);
prs->MoveFirst(); TCHAR szFind[32]; wsprintf(szFind, _T("idObj = %d"), m_idObj); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
if (prs->EndOfFile) return E_INVALIDARG;
if (m_idPropType != 0) { wsprintf(szFind, _T("idPropType = %d"), m_idPropType); prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
if (prs->EndOfFile) return E_INVALIDARG; } if (var.lVal > 0) { hr = prs->Move(var.lVal); if (FAILED(hr)) return hr; }
if (prs->EndOfFile) return E_INVALIDARG;
long idObj2 = prs->Fields->Item["idObj"]->Value; if (m_idObj != idObj2) return E_INVALIDARG;
long idPropType = prs->Fields->Item["idPropType"]->Value; if (m_idPropType != 0 && (m_idPropType != idPropType)) return E_INVALIDARG;
return Load(idPropType, prs, ppprop); } LEAVE_API }
HRESULT CMetaProperties::get_AddNew(IMetaPropertyType *pproptype, IGuideDataProvider *pprovider, long lang, VARIANT varValue, IMetaProperty **ppprop) { ENTER_API { ValidateInPtr<IMetaPropertyType>(pproptype); ValidateOutPtr<IMetaProperty>(ppprop, NULL); HRESULT hr;
CComQIPtr<CMetaPropertyType> pproptypeT(pproptype);
long idProvider = 0;
if (pprovider != NULL) pprovider->get_ID(&idProvider);
hr = pproptypeT->GetNew(idProvider, lang, varValue, ppprop);
if (FAILED(hr)) return hr; return Add(*ppprop); } LEAVE_API }
STDMETHODIMP CMetaProperties::get_AddNew(IMetaPropertyType *pproptype, long lang, VARIANT varValue, IMetaProperty **ppprop) { ENTER_API { ValidateInPtr<IMetaPropertyType>(pproptype); ValidateOutPtr<IMetaProperty>(ppprop, NULL);
HRESULT hr = pproptype->get_New(lang, varValue, ppprop);
if (FAILED(hr)) return hr; return Add(*ppprop); } LEAVE_API }
#if 0
STDMETHODIMP CMetaProperties::get_UpdateOrAddNew(IMetaPropertyType *pproptype, long lang, VARIANT varValue, IMetaProperty **ppprop) { HRESULT hr; CComPtr<IMetaProperty> pprop;
hr = get_ItemWith(pproptype, lang, &pprop); if (FAILED(hr)) return AddNew(pproptype, lang, varValue, ppprop);
hr = pprop->put_Value(varValue); if (FAILED(hr)) return hr; *ppprop = pprop.Detach();
return S_OK; } #endif
STDMETHODIMP CMetaProperties::Add(IMetaProperty *pprop) { HRESULT hr; if (pprop == NULL) return E_FAIL;
ADODB::_RecordsetPtr prs;
m_pdb->get_PropsRS(&prs);
CComQIPtr<CMetaProperty> ppropT(pprop);
hr = ppropT->SetObjectID(m_idObj); if (FAILED(hr)) return hr;
hr = ppropT->AddNew(prs); if (FAILED(hr)) return hr; hr = ppropT->SaveValue(prs); if (FAILED(hr)) { prs->CancelUpdate(); return hr; }
hr = prs->Update(); if (FAILED(hr)) return hr;
m_pdb->Broadcast_ItemChanged(m_idObj);
return hr; }
STDMETHODIMP CMetaProperties::get_ItemWithTypeProviderLang(IMetaPropertyType *pproptype, IGuideDataProvider *pprovider, long idLang, IMetaProperty **ppprop) { ENTER_API { ValidateInPtr<IMetaPropertyType>(pproptype); ValidateOutPtr<IMetaProperty>(ppprop, NULL);
long idProvider = 0; if (pprovider != NULL) pprovider->get_ID(&idProvider);
return get_ItemWithTypeProviderLang(pproptype, FALSE, idProvider, idLang, ppprop); } LEAVE_API }
HRESULT CMetaProperties::get_ItemWithTypeProviderLang(IMetaPropertyType *pproptype, boolean fAnyProvider, long idProvider, long idLang, IMetaProperty **ppprop) { HRESULT hr; ADODB::_RecordsetPtr prs;
CComQIPtr<CMetaPropertyType> pproptypeT(pproptype);
long idPropType = pproptypeT->GetID();
hr = m_pdb->get_PropsIndexed(&prs);
hr = SeekPropsRS(prs, m_pdb->FSQLServer(), m_idObj, idPropType, fAnyProvider, idProvider, idLang); if (FAILED(hr)) return hr;
return Load(idPropType, prs, ppprop); }
STDMETHODIMP CMetaProperties::get_ItemWith(IMetaPropertyType *pproptype, long idLang, IMetaProperty **ppprop) { ENTER_API { ValidateInPtr<IMetaPropertyType>(pproptype); ValidateOutPtr<IMetaProperty>(ppprop);
long idProvider = m_pdb->GetIDGuideDataProvider(); return get_ItemWithTypeProviderLang(pproptype, TRUE, idProvider, idLang, ppprop); } LEAVE_API }
STDMETHODIMP CMetaProperties::get_ItemsWithMetaPropertyType(IMetaPropertyType *ptype, IMetaProperties **ppprops) { ENTER_API { ValidateInPtr<IMetaPropertyType>(ptype); ValidateOutPtr<IMetaProperties>(ppprops, NULL); CComQIPtr<CMetaPropertyType> ptypeT(ptype);
if (ptypeT == NULL) return E_POINTER;
long idPropType;
idPropType = ptypeT->GetID();
CComPtr<CMetaProperties> pprops = NewComObject(CMetaProperties); if (pprops != NULL) pprops->Init(m_idObj, idPropType, m_pdb); *ppprops = pprops.Detach(); return S_OK; } LEAVE_API }
/////////////////////////////////////////////////////////////////////////////
// CMetaPropertyCondition
STDMETHODIMP CMetaPropertyCondition::get_And(IMetaPropertyCondition *ppropcond2, IMetaPropertyCondition **pppropcond) { ENTER_API { ValidateInPtr<IMetaPropertyCondition>(ppropcond2); ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
CComPtr<CMetaPropertyConditionAnd> ppropcond = NewComObject(CMetaPropertyConditionAnd);
if (ppropcond == NULL) return E_OUTOFMEMORY;
ppropcond->Init(this, ppropcond2);
*pppropcond = ppropcond.Detach();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyCondition::get_Or(IMetaPropertyCondition *ppropcond2, IMetaPropertyCondition **pppropcond) { ENTER_API { ValidateInPtr<IMetaPropertyCondition>(ppropcond2); ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
CComPtr<CMetaPropertyConditionOr> ppropcond = NewComObject(CMetaPropertyConditionOr);
if (ppropcond == NULL) return E_OUTOFMEMORY;
ppropcond->Init(this, ppropcond2);
*pppropcond = ppropcond.Detach();
return S_OK; } LEAVE_API }
#if 0
STDMETHODIMP CMetaPropertyCondition::get_Not(IMetaPropertyCondition **pppropcond) { ENTER_API { ValidateOutPtr<IMetaPropertyCondition>(pppropcond, NULL);
CComPtr<CMetaPropertyConditionNot> ppropcond = NewComObject(CMetaPropertyConditionNot);
if (ppropcond == NULL) return E_OUTOFMEMORY;
ppropcond->Init(this);
*pppropcond = ppropcond.Detach();
return S_OK; } LEAVE_API }
STDMETHODIMP CMetaPropertyCondition::get_Test(IMetaProperties *pprops, BOOL *pfOk) { ENTER_API { ValidateInPtr<IMetaProperties>(pprops); ValidateOut<BOOL>(pfOk, FALSE);
return S_OK; } LEAVE_API } #endif
|