virtual void notify(SubscriptionId subid, const char *daliXpath, SDSNotifyFlags flags, unsigned valueLen, const void *valueData) { Linked<CDaliPackageWatcher> me = this; // Ensure that I am not released by the notify call (which would then access freed memory to release the critsec) Linked<ISDSSubscription> myNotifier; { CriticalBlock b(crit); if (traceLevel > 5) DBGLOG("Notification on %s (%s), %p", xpath.get(), daliXpath ? daliXpath : "", this); myNotifier.set(notifier); // allow crit to be released, allowing this to be unsubscribed, to avoid deadlocking when other threads via notify call unsubscribe } if (myNotifier) myNotifier->notify(subid, daliXpath, flags, valueLen, valueData); }
//MORE: Really this should create no_selects for the sub records, but pass on that for the moment. void DataSourceMetaData::gatherFields(IHqlExpression * expr, bool isConditional) { switch (expr->getOperator()) { case no_record: gatherChildFields(expr, isConditional); break; case no_ifblock: { OwnedITypeInfo boolType = makeBoolType(); OwnedITypeInfo voidType = makeVoidType(); isStoredFixedWidth = false; fields.append(*new DataSourceMetaItem(FVFFbeginif, NULL, NULL, boolType)); gatherChildFields(expr->queryChild(1), true); fields.append(*new DataSourceMetaItem(FVFFendif, NULL, NULL, voidType)); break; } case no_field: { if (expr->hasProperty(__ifblockAtom)) break; Linked<ITypeInfo> type = expr->queryType(); IAtom * name = expr->queryName(); IHqlExpression * nameAttr = expr->queryProperty(namedAtom); StringBuffer outname; if (nameAttr && nameAttr->queryChild(0)->queryValue()) nameAttr->queryChild(0)->queryValue()->getStringValue(outname); else outname.append(name).toLowerCase(); StringBuffer xpathtext; const char * xpath = NULL; IHqlExpression * xpathAttr = expr->queryProperty(xpathAtom); if (xpathAttr && xpathAttr->queryChild(0)->queryValue()) xpath = xpathAttr->queryChild(0)->queryValue()->getStringValue(xpathtext); if (isKey() && expr->hasProperty(blobAtom)) type.setown(makeIntType(8, false)); type_t tc = type->getTypeCode(); if (tc == type_row) { OwnedITypeInfo voidType = makeVoidType(); fields.append(*new DataSourceMetaItem(FVFFbeginrecord, outname, xpath, voidType)); gatherChildFields(expr->queryRecord(), isConditional); fields.append(*new DataSourceMetaItem(FVFFendrecord, outname, xpath, voidType)); } else if ((tc == type_table) || (tc == type_groupedtable)) { isStoredFixedWidth = false; fields.append(*new DataSourceDatasetItem(outname, xpath, expr)); } else if (tc == type_set) { isStoredFixedWidth = false; fields.append(*new DataSourceSetItem(outname, xpath, type)); } else { if (type->getTypeCode() == type_alien) { IHqlAlienTypeInfo * alien = queryAlienType(type); type.set(alien->queryPhysicalType()); } addSimpleField(outname, xpath, type); } break; } } }
//MORE: Really this should create no_selects for the sub records, but pass on that for the moment. void DataSourceMetaData::gatherFields(IHqlExpression * expr, bool isConditional, bool *pMixedContent) { switch (expr->getOperator()) { case no_record: gatherChildFields(expr, isConditional, pMixedContent); break; case no_ifblock: { OwnedITypeInfo boolType = makeBoolType(); OwnedITypeInfo voidType = makeVoidType(); isStoredFixedWidth = false; fields.append(*new DataSourceMetaItem(FVFFbeginif, NULL, NULL, boolType)); gatherChildFields(expr->queryChild(1), true, pMixedContent); fields.append(*new DataSourceMetaItem(FVFFendif, NULL, NULL, voidType)); break; } case no_field: { if (expr->hasAttribute(__ifblockAtom)) break; Linked<ITypeInfo> type = expr->queryType(); IAtom * name = expr->queryName(); IHqlExpression * nameAttr = expr->queryAttribute(namedAtom); StringBuffer outname; if (nameAttr && nameAttr->queryChild(0)->queryValue()) nameAttr->queryChild(0)->queryValue()->getStringValue(outname); else outname.append(name).toLowerCase(); StringBuffer xpathtext; const char * xpath = NULL; IHqlExpression * xpathAttr = expr->queryAttribute(xpathAtom); if (xpathAttr && xpathAttr->queryChild(0)->queryValue()) xpath = xpathAttr->queryChild(0)->queryValue()->getStringValue(xpathtext); unsigned flag = FVFFnone; if (isKey() && expr->hasAttribute(blobAtom)) { type.setown(makeIntType(8, false)); flag = FVFFblob; } type_t tc = type->getTypeCode(); if (tc == type_row) { OwnedITypeInfo voidType = makeVoidType(); Owned<DataSourceMetaItem> begin = new DataSourceMetaItem(FVFFbeginrecord, outname, xpath, voidType); //inherit mixed content from child row with xpath('') bool *pItemMixedContent = (pMixedContent && xpath && !*xpath) ? pMixedContent : &(begin->hasMixedContent); fields.append(*begin.getClear()); gatherChildFields(expr->queryRecord(), isConditional, pItemMixedContent); fields.append(*new DataSourceMetaItem(FVFFendrecord, outname, xpath, voidType)); } else if ((tc == type_dictionary) || (tc == type_table) || (tc == type_groupedtable)) { isStoredFixedWidth = false; Owned<DataSourceDatasetItem> ds = new DataSourceDatasetItem(outname, xpath, expr); if (pMixedContent && xpath && !*xpath) *pMixedContent = ds->queryChildMeta()->hasMixedContent; fields.append(*ds.getClear()); } else if (tc == type_set) { isStoredFixedWidth = false; if (pMixedContent && xpath && !*xpath) *pMixedContent = true; fields.append(*new DataSourceSetItem(outname, xpath, type)); } else { if (type->getTypeCode() == type_alien) { IHqlAlienTypeInfo * alien = queryAlienType(type); type.set(alien->queryPhysicalType()); } if (pMixedContent && xpath && !*xpath) *pMixedContent = true; addSimpleField(outname, xpath, type, flag); } break; } } }