How to get author of oldValue - ibm-doors

Is there any way we can get author of oldValue using history in dxl?
I want to extract the name of author who has written the oldValue (previous to current history record) for a Object in DOORS.

The old value of which attribute? I assume "Object Text" or "Object Heading".
The general idea is: iterate over all history entries (e.g. History h) of the Object in question (backwards in time), until you find a history entry with h.type being modifyObject and with the h.attrName being "Object Text" (or "Object Heading" or whatever attribute you are interested in). This is the entry that changed h.oldValue to h.newValue. If you found the entry you see the old Value in h.oldValue. Then you will go further backwards in time until you find the next entry with h.type == modifyObject and h.attrName == "Object Text", which will be the entry that you are looking for, the one that changed "very old value" to the "old value". Of this one you will want to get h.author.
If there are no two such history entry in the current Module, it could be that either the Object has just been created (then you are looking for the history entry with h.type == createObject), or that the Object has been modified / created in a previous baseline. In that case, you have to iterate over all Baselines of the Module (backwards in time), load each baseline and repeat the process.
On http://www.smartdxl.com/content/?page_id=125 there is a good script "Smart History Viewer" by Tony Goodman which does exactly that. In that script you will find all the code snippets that you need.

Related

Updating firebase path if it exists

My app has bits of information that exist for 24 hrs. This information has the potential to be voted on by other users. The number of votes is recorded in the database. If someone votes on a piece of information, I want it to be updated only if the path currently exists, as the data may have reached the 24 hour limit and been deleted since the display time and the vote time.
The problem with using something like Datasnapshot.hasChild is that I will need to write 2 separate read and write instructions. The data may exist for the read instruction but then may reach the 24 hour mark and be deleted before the write instruction.
This is the structure of my database, the node status is duplicated in another part of the database in order to reduce the amount of reads. If this node becomes nil, the other one still exists, but this node is here so that I can do one write to obtain all the newest statuses that are less than 24 hours old.
I would like a rule that does not allow the value of votes to change if the key of status has changed, or if status is no longer a node.
There are a couple of ways to approach this.
One way is to leverage Firebase Rules. Before doing that, let me first say this to keep the Firebasers happy:
Rules are not filters
However, you can craft a rule that will prevent a write if a certain node does not exist. I would need to know your specific structure and use case to suggest a solution but Rules are pretty well covered in the Firebase Rules Docs andReferencing Data In Other Paths is a place to start.
But, a super clean an easy option is the following code that will only write to a node if it exists. One read and write.
func onlyWriteIfNodeExists() {
let ref = your_firebase.ref.child("may_not_exist")
ref.observeSingleEvent(of: .value, with: { snapshot in
if snapshot.exists() {
snapshot.ref.setValue("updated value")
} else {
print("node didn't exist")
}
})
}
and the structure would be
firebase_root
may_not_exist: "some value"
so if the node may_not_exist exists, "some value" will be replaced with "updated value" otherwise will will print "node didn't exist" to console.
That being said, if the intention is to not allow users to vote on items that don't exist, the UI should reflect that. In other words, if the app presents topics to vote on and a topic goes out of scope, the app should receive an event of that and perhaps remove it from the UI or draw a line through the topic heading to indicate it's no longer available.

SSRS Stored Procedure CASE statement not being returned to dataset

I have a report that is using a Stored Procedure as the dataset. I have a simple case statement in my stored procedure that manipulates a set of captions based on the results in the record.
CASE
WHEN CWLI.CAPTION='Hypo Tax – Medical'
THEN 'Medical Tax'
WHEN CWLI.CAPTION='Hypo Tax Social'
THEN 'Social Tax'
ELSE CWLI.CAPTION
END AS CAPTION,
CASE
WHEN CWD.CAPTION='Hypo Tax – Medical'
THEN 'Medical Tax'
WHEN CWD.CAPTION='Hypo Tax Social'
THEN 'Social Tax'
ELSE CWD.CAPTION
END AS CWDCAPTION,
I see the expected results when I execute the stored procedure in SSMS, as below:
However, in my report I still see "Hypo Tax Social"
I have closed BIDS. I deleted the dataset and added it as a new data set. I have also changed my config file RSReportDesigner.config and changed CacheDataForPreview to false and deleted my .data file.
What could be going wrong?
I searched for rdl.data files and did not return anything. Though I changed my RSReportDesigner.config file Add Key="CacheDataForPreview" Value="false" , I would still expect to find residual .data files. Nevertheless, I rolled back this change to Add Key="CacheDataForPreview" Value="true"
I deleted my data source, my dataset and recreated from within VSS. I then created an external tool to delete these files for me. I get this message when I use my tool.
Could Not Find C:\Users\Pennie\Documents\Visual Studio 2008\Projects\Client*.rdl.data
I still see the correct results (the new CASE captions) in SSMS and the old captions in my report.
I really want to handle this in the Stored Procedure, but I have a deliverable.
Can I manipulate the captions in the expression of my tablix? Currently
the expression is looking for the value from two fields. One field is at a company level of my application (these could be blank). Fields!CAPTION.Value, the other is at the system level (these will never be blank) Fields!CWDCAPTION.Value
Here is my current expression w/o the additional case.
=Iif(Fields!CAPTION.Value="",Fields!CWDCAPTION.Value,Fields!CAPTION.Value)
When I try to add an additional Iif in this expression. I just return True or False.
Thank again.
Pennie
Well this lesson has taught me quite a bit about cache and .data... but the issue was that the idiot developer (me) was calling my test SP in my report.. My test SP did not contain the case statement. Wish I had more exciting news but the truth is easy to prove ;-)
I'm all set.
Pennie
Sounds like you have added the CASE statement after you initially created the dataset. If that is the case you need to re-create the dataset again. Just to be clear not only delete the dataset from the report but also the dataset itself.

JIRA comment tag name

While commenting on JIRA tickets, #username can be used to tag a team member. The thing that bugs me is that when I try to tag any team member, there is a special encoded text appear (something like this [~gbuc13]) for every person you tag in.
Now its very difficult to find which member you tagged in your comment by seeing this code. Is there any way that this strange encoded name could be replaced with a proper, meaningful names so that when a user is being tagged, [mike] is appeared instead of [~gbuc13]? I know this change will have to be adopted by every team member to define their aliases, but I am wondering where this (alias?) could be set.
The change you describe is is the difference between the saved view and the edited view and can't be changed:
at edit time you see the alias
once saved you see the full user name (which links to the Jira profile page showing all their activity)

Ruby REXML: Get Value Of An XML Element

I am trying to put the values of some xml elements into an array using rexml. Here is an example of what I am doing:
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
However, that outputs:
[<title> ... </>, <title> ... </>]
How can I get it to output an array containing "This is one title" and "This is another title"?
Moving my comment to an answer, per request:
While puts may convert its argument its argument to a string anyway, you can have the XPath return the text node in the first place:
XPath.each(doc, "*/title/text()") {...
Are you sure about that? Here's a complete program:
#!/usr/bin/ruby
require 'rexml/document'
include REXML
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
Output:
This is one title
This is another title
Edit: It sounds like the OP has moved on, but I think there should be some clarification added here for future visitors. I upvoted #LarsH's good answer, but it should be noted that, given the OP's specific input, element.text should produce exactly the same output as would result from selecting the text() nodes in the first place. From the docs:
text( path = nil )
A convenience method which returns the String value
of the first child text element, if one exists, and nil otherwise.
The sample input given in the original question shows <title> elements containing only one text node in each case. Therefore, these two methods are the same (in this case).
However, pay attention to this important note:
Note that an element may have multiple Text elements, perhaps
separated by other children. Be aware that this method only returns
the first Text node.
You can get all of an element's child text nodes using texts() (plural).
What I suspect a lot of people are really looking for is an equivalent of the DOM's textContent (or its illegitimate cousin innerText). Here's how you might do that in Ruby:
XPath.each(doc, "*/title") { |el|
puts XPath.match(el,'.//text()').join
}
This joins all of the text descendants of each element into a single string.
The short answer is that there's no short answer. Which one of these you want, if any, is highly context-specific. The only requirement in the original question is to "put the values of some xml elements into an array", which isn't really much of a specification.

CAB file API clarification

Since I'm not really seeing any content anywhere that doesn't point back to the original Microsoft documents on this matter, or source code that really doesn't seem to answer the questions I'm having, I thought I might ask a few things here. (Delphi tag is there because that's what my dev environment is on the code I'm making from this)
That said, I had a few questions the API document wasn't answering. First one: fdi_notify messages. What is "my responsibility" is in coding these: fdintCABINET_INFO: fdintPARTIAL_FILE: fdintNEXT_CABINET: fdintENUMERATE: ? I'll illustrate what I mean by an example. For fdintCLOSE_FILE_INFO, "my responsibility" is to Close a file related to handle given me, and set the file's date and time according to the data passed in fdi_notify.
I figure I'm missing something since my code isn't handling extracting spanned CAB files...any thoughts on how to do this?
What you're more than likely running into is that FDICopy only reads the cab you passed in. It will use fdintNEXT_CABINET to get spanned data for any files you extract in response to fdintCOPY_FILE, but it only calls fdintCOPY_FILE for files that start on that first cab.
To get a directory listing for the entire set, you need to call FDICopy in a loop. Every time you get a fdintCABINET_INFO event, save off the psz1 parameter (next cab name). When FDICopy returns, check that. If it's an empty string you're done, if not call FDICopy again with the next cab as the new path.
fdintCABINET_INFO: The only responsibility for this is returning 0 to continue processing. You can use the information provided (the path of the next cabinet, next disk, path name, nad set ID), but you don't need to.
fdintPARTIAL_FILE: Depending on how you're processing your cabs, you can probably ignore this. You'll only see it for the second and later images in a set, and it's to tell you that the particular entry is continued from a previous cab. If you started at the first cab in the set you'll have already seen an fdintCOPY_FILE for the file. If you're processing random .cabs, you won't really be able to use it either, since you won't have the start of the file to extract.
fdintNEXT_CABINET: You can use this to prompt the user for a new directory for the next cabinet, but for simple spanning support just return 0 if the passed in filename is valid or -1 if it isn't. If you return 0 and the cab isn't valid, or is the wrong one, this will get called again. The easiest approach (if you don't request a new disk/directory), is just to check pfdin^.fdie. If it's FDIError_None it's equal the first time being called for the requested cab, so you can return 0. If it's anything else it's already tried to open the requested cab at least once, so you can return -1 as an error.
fdintENUMERATE: I think you can ignore this. It isn't covered in the documentation, and the two cab libraries I've looked at don't use it. It may be a leftover from a previous API version.

Resources