Skip to content

Commit

Permalink
Add support for dynamic labels in set and remove
Browse files Browse the repository at this point in the history
  • Loading branch information
angrykoala committed Dec 3, 2024
1 parent e39d6c7 commit 1c671f1
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 4 deletions.
15 changes: 15 additions & 0 deletions .changeset/hip-kings-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@neo4j/cypher-builder": minor
---

Add support for dynamic labels by passing an expression to `node.label`:

```javascript
new Cypher.Match(new Cypher.Pattern(movie)).set(movie.label(Cypher.labels(anotherNode)));
```

```cypher
MATCH (this0)
SET
this0:$(labels(this1))
```
13 changes: 13 additions & 0 deletions src/clauses/sub-clauses/Remove.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ REMOVE this0:NewLabel"
expect(queryResult.cypher).toMatchInlineSnapshot(`
"MATCH (this0)-[]->(this1)
REMOVE this0:NewLabel, this1:\`Another Label\`"
`);

expect(queryResult.params).toMatchInlineSnapshot(`{}`);
});

test("Remove dynamic labels", () => {
const movie = new Cypher.Node();
const clause = new Cypher.Match(new Cypher.Pattern(movie)).remove(movie.label(Cypher.labels(movie)));

const queryResult = clause.build();
expect(queryResult.cypher).toMatchInlineSnapshot(`
"MATCH (this0)
REMOVE this0:$(labels(this0))"
`);

expect(queryResult.params).toMatchInlineSnapshot(`{}`);
Expand Down
14 changes: 14 additions & 0 deletions src/clauses/sub-clauses/Set.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,18 @@ SET

expect(queryResult.params).toMatchInlineSnapshot(`{}`);
});

test("Set dynamic labels", () => {
const movie = new Cypher.Node();
const clause = new Cypher.Match(new Cypher.Pattern(movie)).set(movie.label(Cypher.labels(movie)));

const queryResult = clause.build();
expect(queryResult.cypher).toMatchInlineSnapshot(`
"MATCH (this0)
SET
this0:$(labels(this0))"
`);

expect(queryResult.params).toMatchInlineSnapshot(`{}`);
});
});
23 changes: 22 additions & 1 deletion src/references/Label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* limitations under the License.
*/

import type { Expr } from "..";
import { CypherASTNode } from "../CypherASTNode";
import type { CypherEnvironment } from "../Environment";
import type { NodeRef } from "../references/NodeRef";
Expand All @@ -28,7 +29,7 @@ import { escapeLabel } from "../utils/escape";
* @example `:Movie`
*/
export class Label extends CypherASTNode {
private readonly node: NodeRef;
protected readonly node: NodeRef;
private readonly label: string;

/**
Expand All @@ -51,3 +52,23 @@ export class Label extends CypherASTNode {
return addLabelToken(env.config.labelOperator, escapeLabel(this.label));
}
}

export class DynamicLabel extends Label {
private readonly expr: Expr;

/**
* @hidden
*/
constructor(node: NodeRef, expr: Expr) {
super(node, "");
this.expr = expr;
}

/** @internal */
public getCypher(env: CypherEnvironment): string {
const nodeId = this.node.getCypher(env);
const exprStr = `$(${this.expr.getCypher(env)})`;
const labelStr = addLabelToken(env.config.labelOperator, exprStr);
return `${nodeId}${labelStr}`;
}
}
11 changes: 8 additions & 3 deletions src/references/NodeRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
* limitations under the License.
*/

import type { Expr } from "..";
import { HasLabel } from "../expressions/HasLabel";
import type { LabelExpr } from "../expressions/labels/label-expressions";
import { Label } from "./Label";
import { DynamicLabel, Label } from "./Label";
import type { NamedReference } from "./Variable";
import { Variable } from "./Variable";

Expand All @@ -44,8 +45,12 @@ export class NodeRef extends Variable {
}
}

public label(label: string): Label {
return new Label(this, label);
public label(label: string | Expr): Label {
if (typeof label === "string") {
return new Label(this, label);
} else {
return new DynamicLabel(this, label);
}
}
}

Expand Down

0 comments on commit 1c671f1

Please sign in to comment.