Make a linked list using cypher neo4j - neo4j

Is there any possible way to make a linked list in cypher within one transaction ?
Iv'e tried ForEach with Match but according to neo4jClien it is not possible to set Match in ForEach.
My approach :
public static void save(List<Post> nodes)
{
var gclient = graphdb.getConnection();
var create1 = gclient.Cypher.Create("(p:Post {nodes})");
var match = gclient.Cypher.Match("((t)-[r:lastPost]->(last))");
var create3 = gclient.Cypher.Create("t-[:lastPost]->p, p-[:next]->last");
var delete = gclient.Cypher.Delete("r");
string query = create1.Query.QueryText + " " + match.Query.QueryText + " "
+ create3.Query.QueryText + " " + delete.Query.QueryText;
gclient.Cypher
.Match("(t:Tmp)")
.WithParam("nodes", nodes)
.ForEach("(newPost in {nodes} | " + query + ")")
.ExecuteWithoutResults();
}
Thanks in advance .

this should do the trick.
static Neo4jClient.Cypher.ICypherFluentQuery addnode<T>(Neo4jClient.Cypher.ICypherFluentQuery q, IList<T> items, int idx, string label)
{
string sq = string.Format("({0}:{1} {{{2}}})", "c" + idx, label, "a" + idx);
q = q.Create(sq).WithParam("a" + idx, items[idx]);
return q;
}
static Neo4jClient.Cypher.ICypherFluentQuery addlink<T>(Neo4jClient.Cypher.ICypherFluentQuery q, int idx1, int idx2)
{
string sq = string.Format("{0}-[:LINKEDTO]->{1}", "c" + idx1, "c" + idx2);
q = q.Create(sq);
return q;
}
public static void Sample<T>(List<T> items, GraphClient client)
{
Neo4jClient.Cypher.ICypherFluentQuery q = client.Connection.Cypher;
for (int i = 1; i < items.Count; i++)
{
q = addnode<T>(q, items, i-1, "MYITEM");
if(i>1)
q = addlink<T>(q, i-2, i-1);
}
q.ExecuteWithoutResults();
}

Related

Unable to understand firstTerm = secondTerm; secondTerm = nextTerm; in fibonacci series

class Main {
public static void main(String[] args) {
int n = 5, firstTerm = 0, secondTerm = 1;
System.out.println("Fibonacci Series till " + n + " terms:");
for (int i = 1; i <= n; ++i) {
System.out.print(firstTerm + " ");
// compute the next term
int nextTerm = firstTerm + secondTerm;
firstTerm = secondTerm;
secondTerm = nextTerm;
}
}
}
//Q) Unable to understand why firstTerm = secondTerm;
secondTerm = nextTerm; statement is written, can anyone explain me this concept
The fibonnaci sequence is defined by
F(0) = 0 // This is our first term
F(1) = 1 // This is the second term
F(n) = F(n - 1) + F(n - 2)
To calculate a term that is neither the first term, nor the second term, we need to sum, the two previous terms.
This is the reason why while iterating, the second term value is assigned to the first term and so on
You will have more details here

Dart: how to convert a column letter into number

Currently using Dart with gsheets_api, which don't seem to have a function to convert column letters to numbers (column index)
As an example , this is what I use with AppScript (input: column letter, output: column index number):
function Column_Nu_to_Letter(column_nu)
{
var temp, letter = '';
while (column_nu > 0)
{
temp = (column_nu - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column_nu = (column_nu - temp - 1) / 26;
}
return letter;
};
This is the code I came up for Dart, it works, but I am sure there is a more elegant or correct way to do it.
String colLetter = 'L'; //Column 'L' as example
int c = "A".codeUnitAt(0);
int end = "Z".codeUnitAt(0);
int counter = 1;
while (c <= end) {
//print(String.fromCharCode(c));
if(colLetter == String.fromCharCode(c)){
print('Conversion $colLetter = $counter');
}
counter++;
c++;
}
// this output L = 12
Do you have any suggestions on how to improve this code?
First we need to agree on the meaning of the letters.
I believe the traditional approach is "A" is 1, "Z" is 26, "AA" is 27, "AZ" is 52, "BA" is 53, etc.
Then I'd probably go with something like these functions for converting:
int lettersToIndex(String letters) {
var result = 0;
for (var i = 0; i < letters.length; i++) {
result = result * 26 + (letters.codeUnitAt(i) & 0x1f);
}
return result;
}
String indexToLetters(int index) {
if (index <= 0) throw RangeError.range(index, 1, null, "index");
const _letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (index < 27) return _letters[index - 1];
var letters = <String>[];
do {
index -= 1;
letters.add(_letters[index.remainder(26)]);
index ~/= 26;
} while (index > 0);
return letters.reversed.join("");
}
The former function doesn't validate that the input only contains letters, but it works correctly for strings containing only letters (and it ignores case as a bonus).
The latter does check that the index is greater than zero.
A simplified version base on Irn's answer
int lettersToIndex(String letters) =>
letters.codeUnits.fold(0, (v, e) => v * 26 + (e & 0x1f));
String indexToLetters(int index) {
var letters = '';
do {
final r = index % 26;
letters = '${String.fromCharCode(64 + r)}$letters';
index = (index - r) ~/ 26;
} while (index > 0);
return letters;
}

Send Vote options with Microsoft Graph API

Is there a way, in Microsoft Graph API, using singleValueExtendedProperties or multiValueExtendedProperties, to send an email with voting options?
I can do it with using Microsoft.Exchange.WebServices and the following code, but I need a way to do it in Microsoft Graph API
public byte[] StringToByteArray(string hex)
{
if (hex.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[hex.Length >> 1];
for (int i = 0; i < hex.Length >> 1; ++i)
{
arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
}
return arr;
}
public int GetHexVal(char hex)
{
int val = (int)hex;
//For uppercase A-F letters:
//return val - (val < 58 ? 48 : 55);
//For lowercase a-f letters:
//return val - (val < 58 ? 48 : 87);
//Or the two combined, but a bit slower:
return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}
public void TestEmail()
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials("xxxxxx#xxxxxx.xxx", "xxxxxxxxx");
service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add("xxx#xxxxxxx.xxx");
email.Subject = "Approval test from C#";
email.ReplyTo.Add("xxx#xxxxxxx.xxx");
string Header = "02010600000000000000";
string ReplyToAllHeader = "055265706C790849504D2E4E6F7465074D657373616765025245050000000000000000";
string ReplyToAllFooter = "0000000000000002000000660000000200000001000000";
string ReplyToHeader = "0C5265706C7920746F20416C6C0849504D2E4E6F7465074D657373616765025245050000000000000000";
string ReplyToFooter = "0000000000000002000000670000000300000002000000";
string ForwardHeader = "07466F72776172640849504D2E4E6F7465074D657373616765024657050000000000000000";
string ForwardFooter = "0000000000000002000000680000000400000003000000";
string ReplyToFolderHeader = "0F5265706C7920746F20466F6C6465720849504D2E506F737404506F737400050000000000000000";
string ReplyToFolderFooter = "00000000000000020000006C00000008000000";
string ApproveOption = "0400000007417070726F76650849504D2E4E6F74650007417070726F766500000000000000000001000000020000000200000001000000FFFFFFFF";
string RejectOtion = "040000000652656A6563740849504D2E4E6F7465000652656A65637400000000000000000001000000020000000200000002000000FFFFFFFF";
string VoteOptionExtras = "0401055200650070006C00790002520045000C5200650070006C007900200074006F00200041006C006C0002520045000746006F007200770061007200640002460057000F5200650070006C007900200074006F00200046006F006C00640065007200000741007000700072006F00760065000741007000700072006F007600650006520065006A0065006300740006520065006A00650063007400";
string DisableReplyAllVal = "00";
string DisableReplyVal = "00";
string DisableForwardVal = "00";
string DisableReplyToFolderVal = "00";
email.Body = new MessageBody();
email.Body.BodyType = BodyType.HTML;
email.Body.Text = "Body";
ExtendedPropertyDefinition VOTE_DEF = new ExtendedPropertyDefinition(Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet.Common, 0x8520, Microsoft.Exchange.WebServices.Data.MapiPropertyType.Binary);
byte[] bytes = StringToByteArray(Header + ReplyToAllHeader + DisableReplyAllVal + ReplyToAllFooter + ReplyToHeader + DisableReplyVal + ReplyToFooter + ForwardHeader + DisableForwardVal + ForwardFooter + ReplyToFolderHeader + DisableReplyToFolderVal + ReplyToFolderFooter + ApproveOption + RejectOtion + VoteOptionExtras);
email.SetExtendedProperty(VOTE_DEF, bytes);
email.SendAndSaveCopy();
}
Yes using EWS API you can do this. But i failed to notice any documentation how to do so. Being said that i remember a related thread talks about this and see how you can use MAPI extended properties. If nothing works, consider filing an uservoice item(feature request) with Microsoft Graph team, so that they can consider implementing it.

QueryBuilder update with concat

I have the following raw SQL query:
UPDATE mySock s1
LEFT JOIN mySock s2
ON s1.parentId = s2.id
SET
s1.status = 1
s1.mylevel = (s2.mylevel + 1),
s1.parentString = CONCAT(s2.parentString, ':' CONCT(s1.id as char))
WHERE
s1.zz = 0;
and in create in Symfony 3.2
public function updateParentNew($idParent)
{
return $this->createQueryBuilder('s1')
->update('MyBundle:Stock', 's1')
->leftJoin(''MyBundle:Stock', 's2', 'WITH', 's2.id = s1.parentId')
->set('s1.zz', 1)
->set('s1.leveltask', 's2.leveltask + 1')
->set('s1.parentString', '?par2_string')
->where('s1.zz = 0')
->andWhere('s1.parentId = ?par1')
->setParameter('par1', $idParent)
->setParameter('par2_string', s2.parentString + ':' + (string)s1.id)
->getQuery()
->getSingleScalarResult();
}
It doesn't work. What is the way to Concat values (string and number)?
I would try something like this:
public function updateParentNew($idParent)
{
$qb = $this->createQueryBuilder('s1')
->update('MyBundle:Stock', 's1')
->leftJoin('MyBundle:Stock', 's2', 'WITH', 's2.id = s1.parentId')
;
$qb->set('s1.zz', 1)
->set('s1.leveltask', $qb->expr()->sum('s2.leveltask', 1))
->set('s1.parentString',
$qb->expr()->concat(
$qb->expr()->literal('s2.parentString'),
$qb->expr()->concat(':', $qb->expr()->literal('s1.id'))
))
->where('s1.zz = 0')
->andWhere('s1.parentId = :par1')
->setParameter('par1', $idParent)
->getQuery()
->getSingleScalarResult()
;
return $qb;
}

More efficient way to execute this jquery script

Is there a more efficient way to execute the following jquery script? I need to access the 4 individual variables once the script has run, which I will then send to my database using ajax
var column_1 = $('#column-1').sortable("toArray");
for ( var i = 0, n = column_1.length; i < n; i++ ) {
var v = $('#' + column_1[i] ).find('.inner').is(':visible');
column_1[i] = column_1[i] + ":" + v;
}
var column_2 = $('#column-2').sortable("toArray");
for ( var i = 0, n = column_2.length; i < n; i++ ) {
var v = $('#' + column_2[i] ).find('.inner').is(':visible');
column_2[i] = column_2[i] + ":" + v;
}
var column_3 = $('#column-3').sortable("toArray");
for ( var i = 0, n = column_3.length; i < n; i++ ) {
var v = $('#' + column_3[i] ).find('.inner').is(':visible');
column_3[i] = column_3[i] + ":" + v;
}
var column_4 = $('#column-4').sortable("toArray");
for ( var i = 0, n = column_4.length; i < n; i++ ) {
var v = $('#' + column_4[i] ).find('.inner').is(':visible');
column_4[i] = column_4[i] + ":" + v;
}
This code has not been tested. But should work fine, does what you need it to do. ^^
function x ()
{
var columns = new Array();
columns.push({
column_1 : $('#column-1').sortable("toArray"),
column_2 : $('#column-2').sortable("toArray"),
column_3 : $('#column-3').sortable("toArray"),
column_4 : $('#column-4').sortable("toArray")
});
$.each(columns, function (key, item)
{
SaveToDatabase(item);
});
}
function SaveToDatabase (yourArray)
{
$.each(yourArray, function (key, item) {
var v = $('#' + item).find('.inner').is(':visible');
item = item + ":" + v;
});
}

Resources