PersistenceManager
The low-level API: you write the statement, Drivine runs it, maps the rows and manages the transaction.
const people = await pm.query(new QuerySpecification<Person>('MATCH (p:Person) RETURN properties(p)').transform(Person));const person = await pm.getOne(spec); // exactly one, or it throwsconst maybe = await pm.maybeGetOne(spec); // one or undefinedawait pm.execute(spec); // no resultsQuerySpecification
Section titled “QuerySpecification”new QuerySpecification<Person>() .withStatement('MATCH (p:Person {city: $city}) RETURN properties(p)') .bind({ city: 'Sydney' }) // named parameters, or a list for $1, $2, … .transform(Person) // map each row to a class .filter((it) => it.age >= 18) .map((it) => it.firstName) .skip(10) .limit(10);Transactions
Section titled “Transactions”@Injectable()export class UserService { @Transactional() // join the current transaction, or start one; commit on success, roll back on a throw async register(person: Person): Promise<void> { await this.people.create(person); await this.audit.record(person); }}A transaction spans every database the method touches. Outside a request, run code in Drivine’s context with
inDrivineContext().withTransaction({ rollback: true }).run(async () => …), or call
runInTransaction(fn) inside one.
Cursors
Section titled “Cursors”Stream a large result without holding it in memory:
const cursor = await pm.openCursor(new CursorSpecification<Route>().withStatement(statement).batchSize(100).transform(Route));for await (const route of cursor) { // …}cursor.asStream().pipe(destination); // or as a Node streamStatements in Files
Section titled “Statements in Files”Keep statements in files beside your code, and inject them:
constructor( @InjectCypher(__dirname, 'routesBetween') readonly routesBetween: CypherStatement, @InjectSql(__dirname, 'report') readonly report: SqlStatement) {}
