How to update information in an existing node instead of creating a new one using Dgraph? - dgraph

I am writing a Golang application using Dgraph for persisting objects. From the documentation, I can infer that a new UID and hence a new node is created everytime I mutate an object/run the code.
Is there a way to update the same node data instead for creating a new node?
I tried changing the UID to use "_:name" for the UID field but even this creates a new node everytime the application is run. I wish to be able to update the existing node if it is already present in the DB instead of creating a new node for it.

Unfortunately the docs aren't very beginner friendly yet :/
To modify / mutate existing data you have to run a set operation and supply a rdf-triple like <uid> <predicate> "value" / <objectYouWantToModify> <attributeYouWantToModify> "quotedStringValue". If it is not an attribute but an edge, the value has to be another <uid>.
The full mutation would be for example
{
set {
<0x2> <name> "modified-name" .
}
}
The . terminates the sequence and there is an optional fourth parameter you can use to also assign a label.
Check https://www.w3.org/TR/n-quads/ for further details.

Related

Replacing the duplicate function for the 'unique' plugin

I am trying to write my own $.jstree.defaults.unique.duplicate function and replace it.
I tried doing so in the following jsFiddle (line: 68):
$.jstree.defaults.unique.duplicate = function(name, counter){
return name + "_test";
};
Steps to test:
Select Devices
Create Node called Node1
Create Another node under Devices called Node1
It will use the jstree default method to replace it with the default node name vs what my function provides
http://jsfiddle.net/2mbq86at/
Am I doing something wrong? Thanks in advance.
In your code you specify text to use in course of creating a new node.
Take out the pre-defined text and things will start to work as desired for your function $.jstree.defaults.unique.duplicate !
self.createFileNode = function (data) {
//Below code only allows files to be created within folders.
//Structure it as per createFolder method to create files at root
var data = {
//'id': 'tempId',
//'text': 'iOS 8'
}
....
In that case of course a new node's text will be the default 'New node'.
The best is to set a unique node name right upfront on creating a new node, like "text" : "OS_" + (new Date).getTime().
Still for the case of renaming nodes and duplicates: using the unique plugin, on renaming and choosing a duplicate text the node's text will fall back to the original one. If that is not what is desired, things get more complicated as the rename_node.jstree event will not be fired in that case.

Deleting a property in AEM 5

I am trying to delete a property of a node. I could manually do it in the crx explorer but there is just way to many properties that I need to delete. Below is the sample code that is currently working. However just changing its value will not solve what I am trying to accomplish. Therefore my question is:
How can I delete a property of a node?
void deleteJob(Node node, Session jcr) throws RepositoryException {
Node jobDescNode = (Node)jcr.getItem(node.getPath() + "/jcr:content/contentpar/jobsdescription");
if(jobDescNode.hasProperty("foo")) {
jobDescNode.setProperty("foo", "null");
jcr.save();
}
}
It looks like you are setting the value of the property to "null" instead of removing the property.
Use
jobDescNode.setProperty("foo", (String)null);
Check the Node API for more info.

How do I add properties to a js-data object that I don't want persisted?

I'm using js-data (and js-data-angular) in conjunction with sockets via sails.js. When a new item is created/updated via sockets I want to call attention to it in my ui.
I'd like to add an "updated" property to the object, but don't want to inadvertently persist it to the DB.
Is there a way to hang non-persisting properties on a js-data object?
Yes.
You can set this globally on the data store or per-resource by using the omit configuration setting. For instance, when instancing your data store, you can instruct JSData to ignore all properties that begin with an underscore:
var store = new JSData.DS({ omit: [ /^_/ ] });
The documentation for the meta property of the options passed to store.defineResource says:
Put anything you want here. It will never be used by the API.

CQ5 / AEM5.6 Workflow: Access workflow instance properties from inside OR Split

TL;DR version:
In CQ workflows, is there a difference between what's available to the OR Split compared to the Process Step?
Is it possible to access the /history/ nodes of a workflow instance from within an OR Split?
How?!
The whole story:
I'm working on a workflow in CQ5 / AEM5.6.
In this workflow I have a custom dialog, which stores a couple of properties on the workflow instance.
The path to the property I'm having trouble with is: /workflow/instances/[this instance]/history/[workItem id]/workItem/metaData and I've called the property "reject-or-approve".
The dialog sets the property fine (via a dropdown that lets you set it to "reject" or "approve"), and I can access other properties on this node via a process step (in ecma script) using:
var actionReason;
var history = workflowSession.getHistory(workItem.getWorkflow());
// loop backwards through workItems
// and as soon as we find a Action Reason that is not empty
// store that as 'actionReason' and break.
for (var index = history.size() - 1; index >= 0; index--) {
var previous = history.get(index);
var tempActionReason = previous.getWorkItem().getMetaDataMap().get('action-message');
if ((tempActionReason != '')&&(tempActionReason != null)) {
actionReason = tempActionReason;
break;
}
}
The process step is not the problem though. Where I'm having trouble is when I try to do the same thing from inside an OR Split.
When I try the same workflowSession.getHistory(workItem.getWorkflow()) in an OR Split, it throws an error saying workItem is not defined.
I've tried storing this property on the payload instead (i.e. storing it under the page's jcr:content), and in that case the property does seem to be available to the OR Split, but my problems with that are:
This reject-or-approve property is only relevant to the current workflow instance, so storing it on the page's jcr:content doesn't really make sense. jcr:content properties will persist after the workflow is closed, and will be accessible to future workflow instances. I could work around this (i.e. don't let workflows do anything based on the property unless I'm sure this instance has written to the property already), but this doesn't feel right and is probably error-prone.
For some reason, when running through the custom dialog in my workflow, only the Admin user group seems to be able to write to the jcr:content property. When I use the dialog as any other user group (which I need to do for this workflow design), the dialog looks as though it's working, but never actually writes to the jcr:content property.
So for a couple of different reasons I'd rather keep this property local to the workflow instance instead of storing it on the page's jcr:content -- however, if anyone can think of a reason why my dialog isn't setting the property on the jcr:content when I use any group other than admin, that would give me a workaround even if it's not exactly the solution I'm looking for.
Thanks in advance if anyone can help! I know this is kind of obscure, but I've been stuck on it for ages.
a couple of days ago i ran into the same issue. The issue here is that you don't have the workItem object, because you don't really have an existing workItem. Imagine the following: you are going through the workflow, you got a couple of workItems, with means, either process step, either inbox item. When you are in an or split, you don't have existing workItems, you can ensure by visiting the /workItems node of the workflow instance. Your workaround seems to be the only way to go through this "issue".
I've solved it. It's not all that elegant looking, but it seems to be a pretty solid solution.
Here's some background:
Dialogs seem to reliably let you store properties either on:
the payload's jcr:content node (which wasn't practical for me, because the payload is locked during the workflow, and doesn't let non-admins write to its jcr:content)
the workItem/metaData for the current workflow step
However, Split steps don't have access to workItem. I found a fairly un-helpful confirmation of that here: http://blogs.adobe.com/dmcmahon/2013/03/26/cq5-failure-running-script-etcworkflowscriptscaworkitem-ecma-referenceerror-workitem-is-not-defined/
So basically the issue was, the Dialog step could store the property, but the OR Split couldn't access it.
My workaround was to add a Process step straight after the Dialog in my workflow. Process steps do have access to workItem, so they can read the property set by the Dialog. I never particularly wanted to store this data on the payload's jcr:content, so I looked for another location. It turns out the workflow metaData (at the top level of the workflow instance node, rather than workItem/metaData, which is inside the /history sub-node) is accessible to both the Process step and the OR Split. So, my Process step now reads the workItem's approveReject property (set by the Dialog), and then writes it to the workflow's metaData node. Then, the OR Split reads the property from its new location, and does its magic.
The way you access the workflow metaData from the Process step and the OR Split is not consistent, but you can get there from both.
Here's some code: (complete with comments. You're welcome)
In the dialog where you choose to approve or reject, the name of the field is set to rejectApprove. There's no ./ or anything before it. This tells it to store the property on the workItem/metaData node for the current workflow step under /history/.
Straight after the dialog, a Process step runs this:
var rejectApprove;
var history = workflowSession.getHistory(workItem.getWorkflow());
// loop backwards through workItems
// and as soon as we find a rejectApprove that is not empty
// store that as 'rejectApprove' and break.
for (var index = history.size() - 1; index >= 0; index--) {
var previous = history.get(index);
var tempRejectApprove = previous.getWorkItem().getMetaDataMap().get('rejectApprove');
if ((tempRejectApprove != '')&&(tempRejectApprove != null)) {
rejectApprove = tempRejectApprove;
break;
}
}
// steps up from the workflow step into the workflow metaData,
// and stores the rejectApprove property there
// (where it can be accessed by an OR Split)
workItem.getWorkflowData().getMetaData().put('rejectApprove', rejectApprove);
Then after the Process step, the OR Split has the following in its tabs:
function check() {
var match = 'approve';
if (workflowData.getMetaData().get('rejectApprove') == match) {
return true;
} else {
return false;
}
}
Note: use this for the tab for the "approve" path, then copy it and replace var match = 'approve' with var match = 'reject'
So the key here is that from a Process step:
workItem.getWorkflowData().getMetaData().put('rejectApprove', rejectApprove);
writes to the same property that:
workflowData.getMetaData().get('rejectApprove') reads from when you execute it in an OR Split.
To suit our business requirements, there's more to the workflow I've implemented than just this, but the method above seems to be a pretty reliable way to get values that are entered in a dialog, and access them from within an OR Split.
It seems pretty silly that the OR Split can't access the workItem directly, and I'd be interested to know if there's a less roundabout way of doing this, but for now this has solved my problem.
I really hope someone else has this same problem, and finds this useful, because it took me waaay to long to figure out, to only apply it once!

Symfony form gets messy when calling getObject() in form configuration

I have a Strain model that has a belongsTo relationship with a Sample model, i. e. a strain belongs to a sample.
I am configuring a hidden field in the StrainForm configure() method this way:
$defaultId = (int)$this->getObject()->getSample()->getTable()->getDefaultSampleId();
$this->setWidget('sample_id', new sfWidgetFormInputHidden(array('default' => $defaultId)));
Whenever I create a new Strain, the $form->save() fails. The debug toolbar revealed that it tries to save a Sample object first and I do not know why.
However, if I retrieve the default sample ID using the table it works like a charm:
$defaultId = (int)Doctrine_Core::getTable('Sample')->getDefaultSampleId();
$this->setWidget('sample_id', new sfWidgetFormInputHidden(array('default' => $defaultId)));
My question here is what can be happening with the getObject()->getSample()... sequence of methods that causes the StrainForm to think it has to save a Sample object instead of Strain.
I tried to debug with xdebug but I cannot came up with a clear conclusion.
Any thoughts?
Thanks!!
When you call getSample its creating a Sample instance. This is automatically attached to the Strain object, thus when you save you also save the Sample.
An altenrative to calling getSample would be to chain through Strain object to the Sample table since i assume youre only doing this so your not hardcodeing the Sample's name in related form:
// note Sample is the alias not necessarily the Model name
$defaultId = Doctrine_Core::getTable($this->getObject()->getTable()->getRelation('Sample')->getModel())->getDefaultId();
Your solution probably falls over because you can't use getObject() on a new form (as at that stage the object simply doesn't exist).
Edit: Why don't you pass the default Sample in via the options array and then access it from within the form class via $this->getOption('Sample') (if I remember correctly)?