IMPLEMENT_DEBUG_FUNCENTRY_4(CGDODatabase,get_ObjectsDef,VARIANT, vIndex, VARIANT_BOOL, fCreate, BSTR, Type, ITRiASObjects**, ppIObjectsDef) { CHECKOUTPOINTER(ppIObjectsDef); COM_TRY { CHECK_INITIALIZED(); WTRiASObjects pTRiASObjects; CComVariant vItem; RETURN_FAILED_HRESULT(EnsureObjectsColl()); HRESULT hr = m_pGDOObjectsCollection -> Item (vIndex, CLEARED(vItem)); if (SUCCEEDED(hr)) pTRiASObjects = V_DISPATCH(&vItem); else if (TRIASDB_E_UNKNOWN_OBJECTS == hr && fCreate) { WTRiASObjectsCollection pTRiASObjectsCollection; ERROR_FAILED_HRESULT(m_pGDOObjectsCollection -> QueryInterface (pTRiASObjectsCollection.ppi()), E_FAIL); ERROR_FAILED_HRESULT(pTRiASObjectsCollection -> Add (V_BSTR(&vIndex), Type, pTRiASObjects.ppi()), E_FAIL); } else return hr; *ppIObjectsDef = pTRiASObjects.detach(); } COM_CATCH; return S_OK; }
HRESULT CTRiASOGCObjects::EnsureObjectsCount() { if (HasType (m_rgInitState, INITSTATE_CountsInitialized)) return S_OK; // wurden bereits geladen #pragma TODO("Sämtliche Objekte dieser Objektklasse zählen und Typen feststellen.") COM_TRY { WTRiASObjects BaseObjs; long lObjCount = 0; OBJECTTYPE rgTypes = OBJECTTYPE_Unknown; THROW_FAILED_HRESULT(m_BaseUnk -> QueryInterface (BaseObjs.ppi())); // BEGIN_SAMPLEDATA using namespace sample_data; LONG lCursor (GetPropertyFrom (BaseObjs, g_cbObjectsCursor, -1L)); _ASSERTE(0 < lCursor); lObjCount = g_ObjectClasses[lCursor-1] -> m_iObjectCount; rgTypes = g_ObjectClasses[lCursor-1] -> m_rgTypes; // END_SAMPLE_DATA // Ergebnis der schweißtreibenden Arbeit dem aggregierten Objekt mitteilen THROW_FAILED_HRESULT(BaseObjs -> put_Count (lObjCount)); // Basisklasse informieren THROW_FAILED_HRESULT(BaseObjs -> put_Types (rgTypes)); // Zähler sind jetzt initialisiert SetType (m_rgInitState, INITSTATE_CountsInitialized); } COM_CATCH; return S_OK; }
HRESULT CTRiASOGCObjects::EnsureObjectsLoaded() { if (HasType (m_rgInitState, INITSTATE_ObjectsInitialized)) return S_OK; // wurden bereits geladen #pragma TODO("Sämtliche Objekte dieser Objektklasse instantiieren und zum aggregierten Objekt hinzufügen.") COM_TRY { WTRiASObjects BaseObjs; THROW_FAILED_HRESULT(m_BaseUnk -> QueryInterface (BaseObjs.ppi())); // BEGIN_SAMPLEDATA using namespace sample_data; LONG lCursor (GetPropertyFrom (BaseObjs, g_cbObjectsCursor, -1L)); _ASSERTE(0 < lCursor); // alle Objekte durchgehen und instantiieren const OBJECTCLASS *pClass = g_ObjectClasses[lCursor-1]; WDispatch App; THROW_FAILED_HRESULT(BaseObjs -> get_Application (App.ppi())); for (int i = 0; i < pClass -> m_iObjectCount; i++) { int iObject = pClass -> m_pObjects[i]; _ASSERTE(0 <= iObject && iObject < g_iObjectCount); const OBJECT *pObject = g_Objects[iObject]; WTRiASObject Obj (CLSID_TRiASOGCObject); // fertig initialisieren THROW_FAILED_HRESULT(WPersistStreamInit(Obj) -> InitNew()); THROW_FAILED_HRESULT(Obj -> put_Application(App)); THROW_FAILED_HRESULT(Obj -> put_Parent(BaseObjs)); // Typ etc. setzen THROW_FAILED_HRESULT(Obj -> put_Type (pObject -> m_rgType)); THROW_FAILED_HRESULT(Obj -> put_Name (CComBSTR(pObject -> m_pcoleGuid))); // an dem erzeugten Objekt unsere Nummer (cursor) speichern THROW_FAILED_HRESULT(SetPropertyBy (Obj, g_cbObjectCursor, CComVariant(iObject+1), true)); // das neu instantiierte Objekt zu dieser Objektklasse hinzufügen THROW_FAILED_HRESULT(BaseObjs -> _Add (Obj, VARIANT_TRUE)); } // END_SAMPLE_DATA // Objekte sind jetzt initialisiert SetType (m_rgInitState, INITSTATE_ObjectsInitialized); // Features initialisieren THROW_FAILED_HRESULT(SetupFeatures (SETUPFEATURESMODE_Force)); } COM_CATCH; return S_OK; }
// eine neue Objekteigenschaft soll erzeugt werden STDMETHODIMP CFastdbFeatures::OnCreate (VARIANT Name, BSTR Type, FEATURETYPE rgType, ITRiASFeature **ppIFeat) { CHECKOUTPOINTER(ppIFeat); USES_CONVERSION; COM_TRY { // jetzt wirklich erzeugen CIID ClsId (Type, CIID::INITCIID_InitFromProgId); if (!ClsId) ClsId = CLSID_FastdbFeature; // default ClsId WTRiASFeatures BaseFeats; WDispatch Parent; THROW_FAILED_HRESULT(m_BaseUnk -> QueryInterface (BaseFeats.ppi())); THROW_FAILED_HRESULT(BaseFeats -> get_Parent (Parent.ppi())); // Parent muß hier Objektklasse sein WTRiASObjects Objs; THROW_FAILED_HRESULT(Parent -> QueryInterface (Objs.ppi())); // neuen Satz erzeugen und zu der Objektklasse hinzufügen LONG lCursor (GetPropertyFrom (Objs, g_cbObjectsCursor, 0L)); _ASSERTE(0 != lCursor); dbDatabase *pdb = GetRelatedDatabase(GetUnknown()); dbCursor<CDBClass> cursor (pdb); CDBClass *pClass = cursor.at (dbReference<CDBClass>(oid_t(lCursor))); if (NULL == pClass || cursor.isEmpty()) THROW_FAILED_HRESULT(FASTDB_E_OBJECTS_BADREFERENCE); CComVariant vVal; CDBFeatureDesc FDesc; THROW_FAILED_HRESULT(vVal.ChangeType (VT_BSTR, &Name)); FDesc.m_pName = OLE2A(V_BSTR(&vVal)); FDesc.m_rgType = rgType; FDesc.objclass = cursor.currentId(); dbCursor<CDBFeatureDesc> featuredesc (GetRelatedDatabase(GetUnknown())); featuredesc.at (pdb -> insert (FDesc)); THROW_FAILED_HRESULT(SetupFeature (ClsId, BaseFeats, featuredesc, Parent, ppIFeat)); } COM_CATCH; return S_OK; }
HRESULT DatenBasisObjekt::ModPBDDataIdent (HPROJECT hPr, PBDDATA *pData) { TX_ASSERT(IsTRiASDBBased()); HRESULT hr = S_OK; USES_CONVERSION; { // wiederauffinden des Objects-Objektes WTRiASObjects Objs; if (FAILED(GetObjectsFromMap (pData -> pbdCode, Objs))) { // Objektklasse existiert nicht, also neu erzeugen TX_ASSERT(pData -> pbdKTextLen > 0 && NULL != pData -> pbdKText); // KurzText muß gegeben sein // Objektmenge (Tabelle) muß neu angelegt werden if (HACTPROJECT != hPr) { // neue Tabelle in einer Datenquelle anlegen ErrCode RC = DB(hPr).ModPBDDataIdent (pData); return (EC_OKAY == RC) ? S_OK : HRESULT_FROM_ERRCODE(RC); } // neue übergreifende Objektmenge ggf. erzeugen RETURN_FAILED_HRESULT(m_Prj -> get_ObjectsDef (CComVariant(pData -> pbdKText), VARIANT_TRUE, CComBSTR(g_cbNil), Objs.ppi())); // das neue Objekt wenigstens von seinem Handle informieren if (0 != pData -> pbdCode) { RETURN_FAILED_HRESULT(Objs -> put_Handle (pData -> pbdCode)); } // reales, vergebenes Handle zurückliefern INT_PTR lHandle = 0; RETURN_FAILED_HRESULT(Objs -> get_Handle (&lHandle)); if (lHandle != pData -> pbdCode) { TX_TRACE2("TRiAS: ModPbdDataIdent: Changed IdentHandle %lx -> %lx !", pData -> pbdCode, lHandle); pData -> pbdCode = lHandle; // Notifikation rumschicken DEXN_FeatureSetModified(lHandle); return S_FALSE; } // Notifikation rumschicken DEXN_FeatureSetModified(pData -> pbdCode); } else { // Testen, ob der gegebene Ident zur geforderten Datenquelle paßt #if defined(_DEBUG) if (HACTCONNECTION != hPr) { HPROJECT hPrTarget = NULL; RETURN_FAILED_HRESULT(GetDatabaseOrProjectHandle (Objs, &hPrTarget)); TX_ASSERT(hPrTarget == hPr); // Ident aus anderer Datenquelle ? } #endif // defined(_DEBUG) // hier nur neuen KurzText (Namen) einstellen if (pData -> pbdKTextLen > 0 && NULL != pData -> pbdKText) RETURN_FAILED_HRESULT(Objs -> put_Name (CComBSTR(pData -> pbdKText))); } // LangText (BeschreibungsInfo) einstellen if (pData -> pbdLTextLen > 0 && NULL != pData -> pbdLText) { RETURN_FAILED_HRESULT(Objs -> put_Description (CComBSTR(pData -> pbdLText))); } else { RETURN_FAILED_HRESULT(Objs -> put_Description (CComBSTR(g_cbNil))); } } return hr; }
HRESULT CTRiASMIObjectsCollection::CreateObject ( VARIANT NameOrHandle, DWORD dwType, const CLSID *pClsId, ITRiASObjects **ppIObjs) { _ASSERTE(NULL != pClsId); if (NULL == pClsId) return E_POINTER; // diverse Vorbereitungen treffen WDispatch App; WDispatch Parent; WTRiASObjectsCollection BaseObjs; RETURN_FAILED_HRESULT(m_BaseUnk -> QueryInterface (BaseObjs.ppi())); RETURN_FAILED_HRESULT(BaseObjs -> get_Application (App.ppi())); // für neue Objektklasse RETURN_FAILED_HRESULT(BaseObjs -> get_Parent(Parent.ppi())); // ZugriffsHandle/Namen oder OKS aus NameOrHandle bestimmen LONG lHandle = 0; CComVariant v; bool fHasName = false; bool fHasOKS = false; CComBSTR bstrApp, bstrOKS; if (VT_BSTR != V_VT(&NameOrHandle) && SUCCEEDED(v.ChangeType (VT_I4, &NameOrHandle))) lHandle = V_I4(&v); else if (SUCCEEDED(v.ChangeType(VT_BSTR, &NameOrHandle))) { // feststellen, ob es ein OKS ist, evtl. Namen isolieren if (StringIsOKS(V_BSTR(&v), CLEARED(&bstrOKS), CLEARED(&bstrApp))) { if (bstrOKS.Length() > 0) fHasOKS = true; } else bstrApp = V_BSTR(&v); if (bstrApp.Length() > 0) fHasName = true; } else return E_INVALIDARG; // Objektklasse aus Handle/Name/OKS erzeugen HRESULT hr = S_OK; COM_TRY { WTRiASObjects Objs (*pClsId); // zu liefernde Objektklasse erzeugen THROW_FAILED_HRESULT(Objs -> put_Parent (Parent)); #pragma TODO("Neue Objektklasse in Datenbank erzeugen.") if (fHasName) // S_FALSE heißt: Objekt existiert bereits RETURN_FAILED_HRESULT(Objs -> put_Name (bstrApp)); if (fHasOKS) RETURN_FAILED_HRESULT(Objs -> put_OKS (bstrOKS)); // wenn Objektklasse bereits zu dieser Menge von Objektklassen gehört, dann liefert _Add den Wert S_FALSE hr = BaseObjs -> _Add (Objs, VARIANT_TRUE); if (SUCCEEDED(hr) && NULL != ppIObjs) *ppIObjs = Objs.detach(); // evtl. neue/gefundene Objektklasse liefern } COM_CATCH; return hr; }