TFS SDK : Get Child Branches - tfs-sdk

What I want to do is to get the available branches that I can merge to. Pretty much the same as the dropdown when you say merge in TFS2008 and you select the destination branch.
However, it's been very hard to find how.
Below code is a merge between some of the resources I've found in the web, but none seem to work. My guess is that if VS2008 can do it, I can do it thru the SDK, right?.
The below code always give me the same result all the time.
My repository is something like this:
Development
Version1
Code
Version2
Code
Version3
Code
Main
Code
And normally I branch Main > Version X. So the merging can be done Main > Version X and Version X to Main.
The below code always gives me the children of the Main, even if I'm querying (tfsParentBranchPath) with Version3 folder.
Is this because perhaps I used TFS2010 web service but pointing to TFS2008 (that's why I marked some methods that do not work in the code)?
Well please let me know, if someone knows the answer.
Thanks!
public string[] GetChildBranchesToMerge(string tfsParentBranchPath)
{
var versionControl = teamFoundationServer.GetService<VersionControlServer>();
//not supported by tfs2008
//ItemIdentifier[] identifiers = versionControl.QueryMergeRelationships(tfsParentBranchPath);
//var allBranches = versionControl.QueryBranchObjects(new ItemIdentifier(tfsParentBranchPath), RecursionType.OneLevel);
List<string> childs = new List<string>();
ItemSpec[] specs = new ItemSpec[] { new ItemSpec(tfsParentBranchPath, RecursionType.OneLevel) };
BranchHistoryTreeItem[][] branchHistoryTree = versionControl.GetBranchHistory(specs, VersionSpec.Latest);
if (branchHistoryTree.Length > 0 && branchHistoryTree[0].Length > 0)
{
var treeItem = branchHistoryTree[0][0];
if (treeItem.Children.Count > 0)
{
foreach (BranchHistoryTreeItem tia in treeItem.Children)
{
childs.Add(tia.Relative.BranchToItem.ServerItem);
}
}
}
return childs.OrderBy((s) =>
{
return s;
}).ToArray();
}

Finally, this is the last version that works!.
First, I stopped using VS2010 assemblies and it's much faster now.
Second, the big difference is this line:
var treeItem = branchHistoryTree[0][0].GetRequestedItem();
I really dont know why the difference, but it seems without that method, the item returned is a generic one.
public string[] GetChildBranchesToMerge(string tfsParentBranchPath)
{
DoLog("Getting child branches for {0} ...", tfsParentBranchPath);
VersionControlServer vcs = (VersionControlServer)teamFoundationServer.GetService(typeof(VersionControlServer));
List<string> childs = new List<string>();
ItemSpec[] specs = new ItemSpec[] { new ItemSpec(tfsParentBranchPath, RecursionType.OneLevel) };
BranchHistoryTreeItem[][] branchHistoryTree = vcs.GetBranchHistory(specs, VersionSpec.Latest);
if (branchHistoryTree.Length > 0 && branchHistoryTree[0].Length > 0)
{
var treeItem = branchHistoryTree[0][0].GetRequestedItem();
AddChildBranch(childs, treeItem, tfsParentBranchPath);
if (treeItem.Children != null && treeItem.Children.Count > 0)
{
foreach (BranchHistoryTreeItem tia in treeItem.Children)
{
AddChildBranch(childs, tia, tfsParentBranchPath);
}
}
}
DoLog("{0} child branches found", childs.Count);
return childs.OrderBy((s) =>
{
return s;
}).ToArray();
}
private void AddChildBranch(List<string> list, BranchHistoryTreeItem itemToCheck, string tfsParentBranchPath)
{
if (itemToCheck.Relative.BranchFromItem != null && itemToCheck.Relative.BranchFromItem.DeletionId == 0 && itemToCheck.Relative.BranchFromItem.ServerItem != tfsParentBranchPath)
list.Add(itemToCheck.Relative.BranchFromItem.ServerItem);
if (itemToCheck.Relative.BranchToItem != null && itemToCheck.Relative.BranchToItem.DeletionId == 0 && itemToCheck.Relative.BranchToItem.ServerItem != tfsParentBranchPath)
list.Add(itemToCheck.Relative.BranchToItem.ServerItem);
}

Related

Update context in SQL Server from ASP.NET Core 2.2

_context.Update(v) ;
_context.SaveChanges();
When I use this code then SQL Server adds a new record instead of updating the
current context
[HttpPost]
public IActionResult PageVote(List<string> Sar)
{
string name_voter = ViewBag.getValue = TempData["Namevalue"];
int count = 0;
foreach (var item in Sar)
{
count = count + 1;
}
if (count == 6)
{
Vote v = new Vote()
{
VoteSarparast1 = Sar[0],
VoteSarparast2 = Sar[1],
VoteSarparast3 = Sar[2],
VoteSarparast4 = Sar[3],
VoteSarparast5 = Sar[4],
VoteSarparast6 = Sar[5],
};
var voter = _context.Votes.FirstOrDefault(u => u.Voter == name_voter && u.IsVoted == true);
if (voter == null)
{
v.IsVoted = true;
v.Voter = name_voter;
_context.Add(v);
_context.SaveChanges();
ViewBag.Greeting = "رای شما با موفقیت ثبت شد";
return RedirectToAction(nameof(end));
}
v.IsVoted = true;
v.Voter = name_voter;
_context.Update(v);
_context.SaveChanges();
return RedirectToAction(nameof(end));
}
else
{
return View(_context.Applicants.ToList());
}
}
You need to tell the DbContext about your entity. If you do var vote = new Vote() vote has no Id. The DbContext see this and thinks you want to Add a new entity, so it simply does that. The DbContext tracks all the entities that you load from it, but since this is just a new instance, it has no idea about it.
To actually perform an update, you have two options:
1 - Load the Vote from the database in some way; If you get an Id, use that to find it.
// Loads the current vote by its id (or whatever other field..)
var existingVote = context.Votes.Single(p => p.Id == id_from_param);
// Perform the changes you want..
existingVote.SomeField = "NewValue";
// Then call save normally.
context.SaveChanges();
2 - Or if you don't want to load it from Db, you have to manually tell the DbContext what to do:
// create a new "vote"...
var vote = new Vote
{
// Since it's an update, you must have the Id somehow.. so you must set it manually
Id = id_from_param,
// do the changes you want. Be careful, because this can cause data loss!
SomeField = "NewValue"
};
// This is you telling the DbContext: Hey, I control this entity.
// I know it exists in the DB and it's modified
context.Entry(vote).State = EntityState.Modified;
// Then call save normally.
context.SaveChanges();
Either of those two approaches should fix your issue, but I suggest you read a little bit more about how Entity Framework works. This is crucial for the success (and performance) of your apps. Especially option 2 above can cause many many issues. There's a reason why the DbContext keep track of entities, so you don't have to. It's very complicated and things can go south fast.
Some links for you:
ChangeTracker in Entity Framework Core
Working with Disconnected Entity Graph in Entity Framework Core

Registering plugin on quick find in Dynamics CRM 2013

I have to register a plugin on Quick Find search on "Artilce" entity. When user enter any thing in quick find text box on Article entity at that time my plugin execute and return filter the data based on our business logic.
1.What event is fired when we find using quick find.
2.What message passes when this event is fired.
I have tried registering the plugin on RetrieveMultiple message but this is not triggered when we click on search in quick find.
Please help.
We have a Plugin registered on the RetrieveMultiple. We had a business requirement to search for the records, using WildCard by default.
Plugin Registration Details:
Message: RetrieveMultiple
Primary Entity:None
Secondary Entity:None
Pre-Operation
Code:
public const String QueryLiteral = "Query";
public const String LIKE = "%";
public void Execute(IServiceProvider serviceProvider)
{
String ParentEntity = String.Empty;
String OriginalSearch = String.Empty;
// Obtain the execution context from the service provider.
var ContextInstance = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// Get a reference to the Organization service.
IOrganizationService ServiceInstance =
((IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory))).
CreateOrganizationService(ContextInstance.InitiatingUserId);
// Critical Point here - NOTICE that the InputParameters Contains the word Query
if (ContextInstance.Depth < 2 && ContextInstance.InputParameters.Contains(QueryLiteral) &&
ContextInstance.InputParameters[QueryLiteral] is QueryExpression)
{
QueryExpression QueryPointer = (ContextInstance.InputParameters[QueryLiteral] as QueryExpression);
//Verify the conversion worked as expected - if not, everything else is useless
if (null != QueryPointer)
{
// Check if the request is coming from any Search View
// We know this b/c Criteria isn't null and the Filters Count > 1
if (null != QueryPointer.Criteria && QueryPointer.Criteria.Filters.Count > 1)
{
ParentEntity = ContextInstance.PrimaryEntityName;
OriginalSearch = QueryPointer.Criteria.Filters[1].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
}
ConditionExpression NewCondition = null;
FilterExpression NewFilter = null;
if (null != QueryPointer.Criteria)
{
//Change the default 'BeginsWith'Operator to 'Contains/Like' operator in the basic search query
foreach (FilterExpression FilterSet in QueryPointer.Criteria.Filters)
{
foreach (ConditionExpression ConditionSet in FilterSet.Conditions)
{
if (ConditionSet.Operator == ConditionOperator.Like)
{
if (OriginalSearch != "")
ConditionSet.Values[0] = OriginalSearch;
else
{
OriginalSearch = QueryPointer.Criteria.Filters[0].Conditions[0].Values[0].ToString();
OriginalSearch = String.Format(CultureInfo.CurrentCulture,
"{0}{1}", LIKE, OriginalSearch);
ConditionSet.Values[0] = OriginalSearch;
}
}
}
}
}
}
ContextInstance.InputParameters[QueryLiteral] = QueryPointer;
}
}
Check details on this Post: http://www.williamgryan.mobi/?p=596
We have raised a ticket with Microsoft to address this situaation.
The solution they provided was to modify the Database to make the message
SearchByTitleKbArticleRequest available in the plugin registration tool.
I currently dont remember the table that we updated a flag against these messages.
After updating the table we were able to register the plugin against the message
SearchByTitleKbArticleRequest
Then the plugin triggered and we modified the entity collection returned from there.

SearchManager.GetIndex is not working - using lucene search

I am applying search functionality in my system using Sitecore 7.0 (actually I am converting my code from Sitecore 6.5 to sitecore 7.0). When I try to get index using Sitecore.Search.SearchManager.GetIndex method, I find configuration property with null value.
My sample code in 6.5 is as below
webDb = Sitecore.Context.Database;
Sitecore.Data.Indexing.Index indx = webDb.Indexes["system"]; //Getting warning - deprecated method
Item bucketItem = Sitecore.Context.Item;
IndexSearcher indexSearcher = indx.GetSearcher(webDb);
topDocs = GetContent(keyWords, webDb, indexSearcher, year, regionName);
if (topDocs != null)
{
int totalMatchItemCount = topDocs.TotalHits;
if (totalMatchItemCount > 0)
{
returnValues = new Item[totalMatchItemCount];
int i = 0;
foreach (ScoreDoc scoreDoc in topDocs.ScoreDocs)
{
Document doc = indexSearcher.Doc(scoreDoc.Doc);
Item item = Index.GetItem(doc, webDb);//Getting warning - deprecated method
returnValues[i++] = item;
}
}
}
Its works fine but gives error of deprecated method on below lines,
Sitecore.Data.Indexing.Index indx = webDb.Indexes["system"];
and
Item item = Index.GetItem(doc, webDb);
My converted code of Sitecore 7.0 is as below,
var children = new List<Item>();
Sitecore.Search.Index searchIndx = Sitecore.Search.SearchManager.GetIndex("system");//Shows SearchManager._Configuration with NULL value, hence all methods and property getting with exception.
using (var searchContext = searchIndx.CreateSearchContext())
{
var ftQuery = new Sitecore.Search.FullTextQuery(keyWords);
var hits = searchContext.Search(ftQuery);
var results = hits.FetchResults(0, hits.Length);
foreach (Sitecore.Search.SearchResult result in results)
{
//My stuff
}
}
When I am trying to fetch value using Sitecore 7.0, get the below exception
Could not create instance of type: Lucene.Net.Analysis.Standard.StandardAnalyzer. No matching constructor was found.
Thanks.
I have a feeling this is because you're still using the pre-Sitecore 7 Sitecore.Search API rather than the newer Sitecore.ContentSearch.
Try this for some further help: Searching with the new Sitecore 7 API
Use below code to get index in Sitecore 7.
// Index
public static string IndexName
{
get
{
return (Sitecore.Context.Database.Name.ToLower()) == "master" ? "sitecore_master_index" : "sitecore_web_index";
}
}
public static ISearchIndex _index;
public static ISearchIndex Index
{
get
{
if (_index == null) { _index = ContentSearchManager.GetIndex(IndexName); }
return _index;
}
}
Could not create instance of type:
Lucene.Net.Analysis.Standard.StandardAnalyzer. No matching constructor
was found.
I've seen this error occur when there are DLLs from multiple Sitecore versions in your /bin folder, so I'd agree with #TwentyGotoTen: it sounds like you either missed out a step in the upgrade process, or you need to check your deploy process to make sure your solution isn't referencing older versions of Sitecore assemblies.

Using boolean fields with Magento ORM

I am working on a backend edit page for my custom entity. I have almost everything working, including saving a bunch of different text fields. I have a problem, though, when trying to set the value of a boolean field.
I have tried:
$landingPage->setEnabled(1);
$landingPage->setEnabled(TRUE);
$landingPage->setEnabled(0);
$landingPage->setEnabled(FALSE);
None seem to persist a change to my database.
How are you supposed to set a boolean field using magento ORM?
edit
Looking at my database, mysql is storing the field as a tinyint(1), so magento may be seeing this as an int not a bool. Still can't get it to set though.
This topic has bring curiosity to me. Although it has been answered, I'd like to share what I've found though I didn't do intense tracing.
It doesn't matter whether the cache is enabled / disabled, the table schema will be cached.
It will be cached during save process.
Mage_Core_Model_Abstract -> save()
Mage_Core_Model_Resource_Db_Abstract -> save(Mage_Core_Model_Abstract $object)
Mage_Core_Model_Resource_Db_Abstract
public function save(Mage_Core_Model_Abstract $object)
{
...
//any conditional will eventually call for:
$this->_prepareDataForSave($object);
...
}
protected function _prepareDataForSave(Mage_Core_Model_Abstract $object)
{
return $this->_prepareDataForTable($object, $this->getMainTable());
}
Mage_Core_Model_Resource_Abstract
protected function _prepareDataForTable(Varien_Object $object, $table)
{
$data = array();
$fields = $this->_getWriteAdapter()->describeTable($table);
foreach (array_keys($fields) as $field) {
if ($object->hasData($field)) {
$fieldValue = $object->getData($field);
if ($fieldValue instanceof Zend_Db_Expr) {
$data[$field] = $fieldValue;
} else {
if (null !== $fieldValue) {
$fieldValue = $this->_prepareTableValueForSave($fieldValue, $fields[$field]['DATA_TYPE']);
$data[$field] = $this->_getWriteAdapter()->prepareColumnValue($fields[$field], $fieldValue);
} else if (!empty($fields[$field]['NULLABLE'])) {
$data[$field] = null;
}
}
}
}
return $data;
}
See the line: $fields = $this->_getWriteAdapter()->describeTable($table);
Varien_Db_Adapter_Pdo_Mysql
public function describeTable($tableName, $schemaName = null)
{
$cacheKey = $this->_getTableName($tableName, $schemaName);
$ddl = $this->loadDdlCache($cacheKey, self::DDL_DESCRIBE);
if ($ddl === false) {
$ddl = parent::describeTable($tableName, $schemaName);
/**
* Remove bug in some MySQL versions, when int-column without default value is described as:
* having default empty string value
*/
$affected = array('tinyint', 'smallint', 'mediumint', 'int', 'bigint');
foreach ($ddl as $key => $columnData) {
if (($columnData['DEFAULT'] === '') && (array_search($columnData['DATA_TYPE'], $affected) !== FALSE)) {
$ddl[$key]['DEFAULT'] = null;
}
}
$this->saveDdlCache($cacheKey, self::DDL_DESCRIBE, $ddl);
}
return $ddl;
}
As we can see:
$ddl = $this->loadDdlCache($cacheKey, self::DDL_DESCRIBE);
will try to load the schema from cache.
If the value is not exists: if ($ddl === false)
it will create one: $this->saveDdlCache($cacheKey, self::DDL_DESCRIBE, $ddl);
So the problem that occurred in this question will be happened if we ever save the model that is going to be altered (add column, etc).
Because it has ever been $model->save(), the schema will be cached.
Later after he add new column and "do saving", it will load the schema from cache (which is not containing the new column) and resulting as: the data for new column is failed to be saved in database
Delete var/cache/* - your DB schema is cached by Magento even though the new column is already added to the MySQL table.

How do I mock this value using Rhino Mocks

Here is the method I'm trying to test:
public override void CalculateReductionOnYield()
{
log.LogEnter();
if (illus.RpFundStreams.Count <= 0)
{
throw new InvalidDataException("No regular premium fund streams which are required in order to calculate reduction on yield");
}
// Add the individual ReductionOnYield classes to the collection.)
foreach (RegularPremiumFundStream fs in illus.RpFundStreams)
{
foreach (int i in ReductionOnYieldMonths)
{
ReductionOnYield roy = new ReductionOnYield(i);
roy.FundStream = fs;
ReductionsOnYield.Add(roy);
}
foreach (ReductionOnYield redOnYield in ReductionsOnYield)
{
if (redOnYield.Month == 0 || illus.RegularPremiumInPlanCurrency == 0M)
{
redOnYield.Reduction = 0M;
}
else
{
double[] regPremiums = new double[redOnYield.Month + 1];
for (int i = 1; i <= redOnYield.Month; i++)
{
regPremiums[i - 1] = Convert.ToDouble(-1*redOnYield.FundStream.FundStreamMonths[i].ValRegularPremium);
}
regPremiums[redOnYield.Month] = Convert.ToDouble(redOnYield.FundStream.GetFundStreamValue(redOnYield.Month));
redOnYield.Reduction = Convert.ToDecimal(Math.Pow((1 + Financial.IRR(ref regPremiums, 0.001D)), 12) - 1);
}
}
}
How do I mock all the required classes to test the value of redOnYield.Reduction to make sure that it working properly?
e.g. how do I mock redOnYield.FundStream.GetFundStreamValue(redOnYield.Month) and redOnYield.FundStream.FundStreamMonths[i].ValRegularPremium ?
Is this a valid test? Or am I going about this the wrong way?
without more info on your objects its hard to say, but you want something like:
var fundStream = MockRepository.GenerateStub<TFundStream>();
fundStream.Stub(f => f.GetFundStreamValue(60)).Return(220000M);
var redOnYeild = MockRepository.GenerateStub<TRedOnYeild>();
redOnYeild.Stub(r => r.FundStream).Return(fundStream);
redOnYield is an object returned from iterating ReductionsOnYield. I don't see where this is coming from. If we assume it's a virtual property, then you'll want to create a collection of mock ReductionOnYield objects and stub out ReductionsOnYield to return your mocked collection (or, to make it easier to test, have CalculateReductionOnYield accept an IEnumerable and operate on that collection).
Once you get the ReductionsOnYield issue resolved, Andrew's response of stubbing out the properties will get you where you want to be. Of course, this assumes that FundStream is virtual (so it can be mocked/stubbed) as well as RegularPremiumFundStream's GetFundStreamValue and FundStreamMonths.