Skip to content

Commit c4bb0f8

Browse files
committed
Add procedure call expression to cypher QB
1 parent 45f248d commit c4bb0f8

File tree

1 file changed

+42
-17
lines changed
  • src/core/database/query-augmentation

1 file changed

+42
-17
lines changed
Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,53 @@
1-
import { Query } from 'cypher-query-builder';
1+
import { entries } from '@seedcompany/common';
2+
import { Clause, Query } from 'cypher-query-builder';
3+
import { Parameter } from 'cypher-query-builder/dist/typings/parameter-bag';
4+
import { isExp, variable } from '../query';
25

36
declare module 'cypher-query-builder/dist/typings/query' {
47
interface Query {
58
/**
6-
* Apply custom query modifications while maintaining the fluent chain.
9+
* Call a procedure.
710
*
8-
* @deprecated Use {@link apply}() instead.
9-
*
10-
* In the future this could be changed to utilize native neo4j call logic.
11+
* Args can be an array of positional args, or an object of named args.
12+
* Objects are still converted to positional args, so the order matters.
13+
* Objects allow the query parameters to be named for better readability.
1114
*/
12-
call<A extends any[], R extends this | Query<any> | void>(
13-
fn: (query: this, ...args: A) => R,
14-
...args: A
15-
): R extends void ? this : R;
15+
call(procedure: ProcedureCall): this;
16+
call(procedureName: string, args?: ProcedureArgs): this;
1617
}
1718
}
1819

19-
Query.prototype.call = function call<
20-
A extends any[],
21-
R extends Query<any> | void,
22-
>(
20+
Query.prototype.call = function call(
2321
this: Query,
24-
fn: (q: Query, ...args: A) => R,
25-
...args: A
26-
): R extends void ? Query : R {
27-
return (fn(this, ...args) || this) as Exclude<R, void>;
22+
procedure: ProcedureCall | string,
23+
args?: ProcedureArgs,
24+
) {
25+
const clause =
26+
typeof procedure === 'string'
27+
? new Procedure(procedure, args ?? [])
28+
: new Procedure(procedure.name, procedure.args);
29+
return this.continueChainClause(clause);
2830
};
31+
32+
interface ProcedureCall {
33+
name: string;
34+
args: ProcedureArgs;
35+
}
36+
type ProcedureArgs = Record<string, any> | any[];
37+
38+
class Procedure extends Clause {
39+
private readonly params: Parameter[];
40+
constructor(public name: string, public args: Record<string, any> | any[]) {
41+
super();
42+
this.params = (
43+
Array.isArray(args)
44+
? args.map((value) => [undefined, value] as const)
45+
: entries(this.args as Record<string, any>)
46+
).map(([key, value]) =>
47+
isExp(value) ? variable(value) : this.addParam(value, key),
48+
);
49+
}
50+
build() {
51+
return `CALL ${this.name}(${this.params.join(', ')})`;
52+
}
53+
}

0 commit comments

Comments
 (0)