public void Merge(IBinaryDataListEntry toMerge, out string error) { error = string.Empty; if (IsRecordset && toMerge.IsRecordset) { IIndexIterator ii = toMerge.FetchRecordsetIndexes(); while (ii.HasMore()) { int next = ii.FetchNextIndex(); // merge toMerge into this foreach (IBinaryDataListItem item in toMerge.FetchRecordAt(next, out error)) { TryAppendRecordItem(item, out error); } } } else if (!IsRecordset && !toMerge.IsRecordset) { TryPutScalar(toMerge.FetchScalar(), out error); // over write this with toMerge } else { error = "Type mis-match, one side is Recordset while the other is a scalar"; } }
internal Dev2DataListEvaluateIterator(IBinaryDataListEntry entry) { _entry = entry; if (_entry.IsRecordset) { _idxItr = entry.FetchRecordsetIndexes(); } }
/// <summary> /// Processes the record set. /// </summary> /// <param name="entry">The entry.</param> /// <param name="error">The error.</param> /// <returns></returns> private string ProcessRecordSet(IBinaryDataListEntry entry, out string error) { StringBuilder result = new StringBuilder(); error = string.Empty; // MAKE RS START ;) result.Append("\""); result.Append(entry.Namespace); result.Append("\" : ["); IIndexIterator idxItr = entry.FetchRecordsetIndexes(); int rsCnt = 0; while (idxItr.HasMore() && !entry.IsEmpty()) { int idx = idxItr.FetchNextIndex(); IList <IBinaryDataListItem> rowData = entry.FetchRecordAt(idx, out error); result.Append("{"); int colIdx = 0; foreach (IBinaryDataListItem col in rowData) { result.Append("\""); result.Append(col.FieldName); result.Append("\":\""); result.Append(col.TheValue); result.Append("\""); // add , if need be ;) colIdx++; if (colIdx < rowData.Count) { result.Append(","); } } result.Append("}"); // append , for row data ;) rsCnt++; if (rsCnt < idxItr.Count) { result.Append(", "); } } // END RS ;) result.Append("]"); return(result.ToString()); }
/// <summary> /// Binds the compiled expression. /// </summary> /// <returns></returns> public IBinaryDataListEntry BindCompiledExpression() { // very short circuit if no items ;) if (_internalKeyMap.Keys.Count == 0) { CompiledExpression = null; return(null); } // short circuit the long eval for mix mode data ;) if (_internalMap.Keys.Count <= 1 && FetchEvaluationIterationCount(Expression) == 1 && CompiledExpression.Length == 3) { return(_internalKeyMap.Values.FirstOrDefault()); } var replaceValue = string.Empty; // Right now we assume there are not ;) foreach (var idx in _internalMap.Keys) { var token = BuildSubToken(idx); var otherKey = _internalMap[idx]; IBinaryDataListEntry value; if (_internalKeyMap.TryGetValue(otherKey, out value)) { if (value != null) { if (!value.IsRecordset) { var scalar = value.FetchScalar(); if (scalar != null) { if (_result == null) { var toReplace = scalar.TheValue; CompiledExpression = CompiledExpression.Replace(token, toReplace); } else { var itr = _result.FetchRecordsetIndexes(); string replaceVal; try { replaceVal = scalar.TheValue; } catch (NullValueInVariableException) { replaceVal = null; } while (itr.HasMore()) { var val = itr.FetchNextIndex(); // Fetch the next value from result ;) try { string error; string template = _result.TryFetchRecordsetColumnAtIndex(GlobalConstants.EvaluationRsField, val, out error).TheValue; Errors.AddError(error); template = template.Replace(token, replaceVal); _result.TryPutRecordItemAtIndex(new BinaryDataListItem(template, _ns, GlobalConstants.EvaluationRsField, val), val, out error); Errors.AddError(error); } catch (NullValueInVariableException) { //Do nothing got null } } CompiledExpression = CompiledExpression.Replace(token, replaceVal); } } } else { string error; // build up the complex expression result - this means debug will be out of sync of complex expressions ;) if (_result == null) { IList <Dev2Column> cols = new List <Dev2Column> { new Dev2Column(GlobalConstants.EvaluationRsField, enDev2ColumnArgumentDirection.Both) }; _result = Dev2BinaryDataListFactory.CreateEntry(_ns, string.Empty, cols, BinaryDataList.UID); var max = _internalKeyMap.Values.OrderByDescending(c => c.ItemCollectionSize()).FirstOrDefault(); if (max != null) { var itrToVal = max.ItemCollectionSize(); if (itrToVal == 0) { itrToVal = 1; } for (int i = 0; i < itrToVal; i++) { int idxT = (i + 1); _result.TryPutRecordItemAtIndex(new BinaryDataListItem(CompiledExpression, _ns, GlobalConstants.EvaluationRsField, idxT), idxT, out error); Errors.AddError(error); } } if (IsDebug) { // attach audit object for debug ;) _result.ComplexExpressionAuditor = new ComplexExpressionAuditor(); } } var idxItr = value.FetchRecordsetIndexes(); int expIdx = 1; // we need to treat this as a scalar ;) if (idxItr.Count == 1) { int curVal = idxItr.FetchNextIndex(); int amt = _result.ItemCollectionSize(); // ensure we always iterate once ;) if (amt == 0) { amt = 1; } idxItr = new LoopedIndexIterator(curVal, amt); } // else iterate across the recordset cuz it had a star ;) while (idxItr.HasMore()) { try { var val = idxItr.FetchNextIndex(); // Fetch the next value from result ;) var template = _result.TryFetchRecordsetColumnAtIndex(GlobalConstants.EvaluationRsField, expIdx, out error).TheValue; Errors.AddError(error); var binaryValue = value.TryFetchIndexedRecordsetUpsertPayload(val, out error); Errors.AddError(error); // now bind this result row with the correct data list data ;) if (binaryValue != null) { var preTemplate = template; var toReplace = binaryValue.TheValue; template = template.Replace(token, toReplace); // In cases when [[[{0}]] is the result, we need to inject the template value // In cases when [[rec({0}).a]] we need to replace the template pattern ;) var tmp = CompiledExpression.Replace("[", "").Replace("]", "").Replace(token, string.Empty); // ReSharper disable ConvertIfStatementToConditionalTernaryExpression if (tmp.Length > 0) // ReSharper restore ConvertIfStatementToConditionalTernaryExpression { // we have a [[rec({0}.a]] case ;) replaceValue = toReplace; } else { replaceValue = template; } _result.TryPutRecordItemAtIndex(new BinaryDataListItem(template, _ns, GlobalConstants.EvaluationRsField, expIdx), expIdx, out error); Errors.AddError(error); if (IsDebug) { var displayValue = DataListUtil.AddBracketsToValueIfNotExist(binaryValue.DisplayValue); _result.ComplexExpressionAuditor.AddAuditStep(preTemplate, displayValue, token, idx, template, Expression); _result.ComplexExpressionAuditor.SetMaxIndex(expIdx); } } expIdx++; // inc result index ;) } catch (NullValueInVariableException) { //Do Nothing got null value } } replaceValue = DataListUtil.RemoveLanguageBrackets(replaceValue); CompiledExpression = CompiledExpression.Replace(token, replaceValue); } } else { CompiledExpression = CompiledExpression.Replace(token, string.Empty); } } } return(_result); }
public void AddAlias(Guid dlId, string parentColumn, string parentNamespace, string childColumn, out ErrorResultTO errors) { errors = new ErrorResultTO(); // TODO : This needs to change so we can track at all levels what the root alias is ;) IDataListCompiler compiler = DataListFactory.CreateDataListCompiler(); Guid masterId = dlId; string masterRs = parentNamespace; string masterCol = parentColumn; Guid searchId = dlId; IBinaryDataListEntry masterEntry = null; int aliasSearchRounds = 0; BinaryDataListAlias binaryDataListAlias = null; while (searchId != Guid.Empty) { ErrorResultTO invokeErrors; var bdl = compiler.FetchBinaryDataList(searchId, out invokeErrors); errors.MergeErrors(invokeErrors); if (bdl != null) { string error; bdl.TryGetEntry(masterRs, out masterEntry, out error); errors.AddError(error); if (masterEntry != null) { var aliases = masterEntry.FetchAlias(); if (aliases.TryGetValue(masterCol, out binaryDataListAlias)) { // we have a hit ;) masterId = binaryDataListAlias.MasterKeyID; searchId = masterId; masterRs = binaryDataListAlias.MasterNamespace; masterCol = binaryDataListAlias.MasterColumn; aliasSearchRounds++; } else { // ensure we copy over the alias entry's keys ;) if (IsEmtpy) { var keyItr = masterEntry.FetchRecordsetIndexes(); _myKeys = new IndexList(keyItr.FetchGaps(), keyItr.MaxIndex(), keyItr.MinIndex()); IsEmtpy = false; } searchId = Guid.Empty; // signal end ;) } } else { if (aliasSearchRounds == 0) { throw new Exception("Missing Entry"); } // we hit the bottom earlier, handle it ;) if (binaryDataListAlias != null) { masterEntry = binaryDataListAlias.MasterEntry; } searchId = Guid.Empty; // signal end ;) } } else { throw new Exception("Missing DataList"); } } // Check MasterKeyID to see if it contains an alias, if so keep bubbling until we at end ;) _keyToAliasMap[childColumn] = new BinaryDataListAlias { MasterKeyID = masterId, ChildKey = GenerateKeyPrefix(Namespace, DataListKey), MasterKey = GenerateKeyPrefix(masterRs, masterId), MasterColumn = masterCol, MasterNamespace = masterRs, MasterEntry = masterEntry }; }
IList <IDebugItemResult> CreateRecordsetDebugItems(string expression, IBinaryDataListEntry dlEntry, string value, int iterCnt, string labelText) { var results = new List <IDebugItemResult>(); if (dlEntry.ComplexExpressionAuditor == null) { string initExpression = expression; string fieldName = DataListUtil.ExtractFieldNameFromValue(expression); enRecordsetIndexType indexType = DataListUtil.GetRecordsetIndexType(expression); if (indexType == enRecordsetIndexType.Blank && string.IsNullOrEmpty(fieldName)) { indexType = enRecordsetIndexType.Star; } if (indexType == enRecordsetIndexType.Star || indexType == enRecordsetIndexType.Numeric) { IIndexIterator idxItr = dlEntry.FetchRecordsetIndexes(); while (idxItr.HasMore()) { GetValues(dlEntry, value, iterCnt, idxItr, indexType, results, initExpression, labelText, fieldName); } } } else { // Complex expressions are handled differently ;) ComplexExpressionAuditor auditor = dlEntry.ComplexExpressionAuditor; enRecordsetIndexType indexType = DataListUtil.GetRecordsetIndexType(expression); foreach (ComplexExpressionAuditItem item in auditor.FetchAuditItems()) { int grpIdx = -1; try { grpIdx = Int32.Parse(DataListUtil.ExtractIndexRegionFromRecordset(item.TokenBinding)); } // ReSharper disable EmptyGeneralCatchClause catch (Exception) // ReSharper restore EmptyGeneralCatchClause { // Best effort ;) } if (indexType == enRecordsetIndexType.Star) { string displayExpression = item.Expression.Replace(item.Token, item.RawExpression); results.Add(new DebugItemResult { Type = DebugItemResultType.Variable, Value = displayExpression, GroupName = displayExpression, GroupIndex = grpIdx }); results.Add(new DebugItemResult { Type = DebugItemResultType.Label, Value = GlobalConstants.EqualsExpression, GroupName = displayExpression, GroupIndex = grpIdx }); results.Add(new DebugItemResult { Type = DebugItemResultType.Value, Value = item.BoundValue, GroupName = displayExpression, GroupIndex = grpIdx }); } } } return(results); }
/// <summary> /// Depths the merge. /// </summary> /// <param name="depth">The depth.</param> /// <param name="cloned">The cloned.</param> /// <param name="key"></param> /// <param name="errors">The errors.</param> private void DepthMerge(enTranslationDepth depth, IBinaryDataListEntry cloned, string key, out IList<string> errors) { errors = new List<string>(); if(key != null) { if(depth == enTranslationDepth.Data || depth == enTranslationDepth.Data_With_Blank_OverWrite) { // safe to add if(cloned.IsRecordset) { // Inject into the intellisense options... CreateIntelliseneResult(key, cloned.Columns); //Massimo.Guerrera - 21-01-2013 - Added for the DeleteRecordOperation, it need to over write the data with blank values. if(depth == enTranslationDepth.Data_With_Blank_OverWrite) { _templateDict[key] = cloned; } else { // merge all the cloned rows into this reference #pragma warning disable 219 // ReSharper disable NotAccessedVariable int insertIdx = 1; // always default to start of recordset // ReSharper restore NotAccessedVariable #pragma warning restore 219 // fetch last row id and build from there IBinaryDataListEntry tmpRec; bool isFound = _templateDict.TryGetValue(key, out tmpRec); // verify that the key exist first ;) IIndexIterator ii = cloned.FetchRecordsetIndexes(); while(ii.HasMore()) { int next = ii.FetchNextIndex(); string error; IList<IBinaryDataListItem> cols = cloned.FetchRecordAt(next, out error); if(error != string.Empty) { errors.Add(error); } if(!isFound) { // we need to boot strap the recordset ;) // intellisense takecare of with template method ;) TryCreateRecordsetTemplate(cloned.Namespace, cloned.Description, cloned.Columns, true, out error); if(error != string.Empty) { errors.Add(error); } isFound = true; } foreach(IBinaryDataListItem itm in cols) { _templateDict[key].TryPutRecordItemAtIndex(itm, next, out error); if(error != string.Empty) { errors.Add(error); } } insertIdx++; } } } else { IBinaryDataListEntry thisTmp; // we have an entry, better check clone for empty if(_templateDict.TryGetValue(key, out thisTmp)) { string theValue = null; try { theValue = cloned.FetchScalar().TheValue; } catch(Exception e) { Dev2Logger.Log.Error(e); } if(theValue != string.Empty && depth == enTranslationDepth.Data) { // The clone has data, over write it on the merge ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } else if(depth == enTranslationDepth.Data_With_Blank_OverWrite) { // The user wants to over-write Blank data on the right with existing data on the left ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } } else { // no entry, just place it there as there is no harm ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } } } else if(depth == enTranslationDepth.Shape) { _templateDict[key] = cloned; // set blank data ;) // Inject into the intellisense options... CreateIntelliseneResult(key); } } }
/// <summary> /// Depths the merge. /// </summary> /// <param name="depth">The depth.</param> /// <param name="cloned">The cloned.</param> /// <param name="key"></param> /// <param name="errors">The errors.</param> private void DepthMerge(enTranslationDepth depth, IBinaryDataListEntry cloned, string key, out IList <string> errors) { errors = new List <string>(); if (key != null) { if (depth == enTranslationDepth.Data || depth == enTranslationDepth.Data_With_Blank_OverWrite) { // safe to add if (cloned.IsRecordset) { // Inject into the intellisense options... CreateIntelliseneResult(key, cloned.Columns); //Massimo.Guerrera - 21-01-2013 - Added for the DeleteRecordOperation, it need to over write the data with blank values. if (depth == enTranslationDepth.Data_With_Blank_OverWrite) { _templateDict[key] = cloned; } else { // merge all the cloned rows into this reference #pragma warning disable 219 int insertIdx = 1; // always default to start of recordset #pragma warning restore 219 // fetch last row id and build from there IBinaryDataListEntry tmpRec; bool isFound = _templateDict.TryGetValue(key, out tmpRec); // verify that the key exist first ;) IIndexIterator ii = cloned.FetchRecordsetIndexes(); while (ii.HasMore()) { int next = ii.FetchNextIndex(); string error; IList <IBinaryDataListItem> cols = cloned.FetchRecordAt(next, out error); if (error != string.Empty) { errors.Add(error); } if (!isFound) { // we need to boot strap the recordset ;) // intellisense takecare of with template method ;) TryCreateRecordsetTemplate(cloned.Namespace, cloned.Description, cloned.Columns, true, out error); if (error != string.Empty) { errors.Add(error); } isFound = true; } foreach (IBinaryDataListItem itm in cols) { _templateDict[key].TryPutRecordItemAtIndex(itm, next, out error); if (error != string.Empty) { errors.Add(error); } } insertIdx++; } } } else { IBinaryDataListEntry thisTmp; // we have an entry, better check clone for empty if (_templateDict.TryGetValue(key, out thisTmp)) { string theValue = null; try { theValue = cloned.FetchScalar().TheValue; } catch (Exception e) { Dev2Logger.Log.Error(e); } if (theValue != string.Empty && depth == enTranslationDepth.Data) { // The clone has data, over write it on the merge ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } else if (depth == enTranslationDepth.Data_With_Blank_OverWrite) { // The user wants to over-write Blank data on the right with existing data on the left ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } } else { // no entry, just place it there as there is no harm ;) _templateDict[key] = cloned; // Inject into the intellisense options... CreateIntelliseneResult(key); } } } else if (depth == enTranslationDepth.Shape) { _templateDict[key] = cloned; // set blank data ;) // Inject into the intellisense options... CreateIntelliseneResult(key); } } }
IList<IDebugItemResult> CreateRecordsetDebugItems(string expression, IBinaryDataListEntry dlEntry, string value, int iterCnt, string labelText) { var results = new List<IDebugItemResult>(); if(dlEntry.ComplexExpressionAuditor == null) { string initExpression = expression; string fieldName = DataListUtil.ExtractFieldNameFromValue(expression); enRecordsetIndexType indexType = DataListUtil.GetRecordsetIndexType(expression); if(indexType == enRecordsetIndexType.Blank && string.IsNullOrEmpty(fieldName)) { indexType = enRecordsetIndexType.Star; } if(indexType == enRecordsetIndexType.Star || indexType == enRecordsetIndexType.Numeric) { IIndexIterator idxItr = dlEntry.FetchRecordsetIndexes(); while(idxItr.HasMore()) { GetValues(dlEntry, value, iterCnt, idxItr, indexType, results, initExpression, labelText, fieldName); } } } else { // Complex expressions are handled differently ;) ComplexExpressionAuditor auditor = dlEntry.ComplexExpressionAuditor; enRecordsetIndexType indexType = DataListUtil.GetRecordsetIndexType(expression); foreach(ComplexExpressionAuditItem item in auditor.FetchAuditItems()) { int grpIdx = -1; try { grpIdx = Int32.Parse(DataListUtil.ExtractIndexRegionFromRecordset(item.TokenBinding)); } // ReSharper disable EmptyGeneralCatchClause catch(Exception) // ReSharper restore EmptyGeneralCatchClause { // Best effort ;) } if(indexType == enRecordsetIndexType.Star) { string displayExpression = item.Expression.Replace(item.Token, item.RawExpression); results.Add(new DebugItemResult { Type = DebugItemResultType.Variable, Value = displayExpression, GroupName = displayExpression, GroupIndex = grpIdx }); results.Add(new DebugItemResult { Type = DebugItemResultType.Label, Value = GlobalConstants.EqualsExpression, GroupName = displayExpression, GroupIndex = grpIdx }); results.Add(new DebugItemResult { Type = DebugItemResultType.Value, Value = item.BoundValue, GroupName = displayExpression, GroupIndex = grpIdx }); } } } return results; }
/// <summary> /// Processes the record set. /// </summary> /// <param name="entry">The entry.</param> /// <param name="error">The error.</param> /// <returns></returns> private string ProcessRecordSet(IBinaryDataListEntry entry, out string error) { StringBuilder result = new StringBuilder(); error = string.Empty; // MAKE RS START ;) result.Append("\""); result.Append(entry.Namespace); result.Append("\" : ["); IIndexIterator idxItr = entry.FetchRecordsetIndexes(); int rsCnt = 0; while(idxItr.HasMore() && !entry.IsEmpty()) { int idx = idxItr.FetchNextIndex(); IList<IBinaryDataListItem> rowData = entry.FetchRecordAt(idx, out error); result.Append("{"); int colIdx = 0; foreach(IBinaryDataListItem col in rowData) { result.Append("\""); result.Append(col.FieldName); result.Append("\":\""); result.Append(col.TheValue); result.Append("\""); // add , if need be ;) colIdx++; if(colIdx < rowData.Count) { result.Append(","); } } result.Append("}"); // append , for row data ;) rsCnt++; if(rsCnt < idxItr.Count) { result.Append(", "); } } // END RS ;) result.Append("]"); return result.ToString(); }