lmdb-oql
Version:
A high level object query language for indexed LMDB databases
123 lines (113 loc) • 3.44 kB
JavaScript
import {open} from "lmdb";
import {operators,withExtensions,IDS} from "../index.js";
const {$mod,$gte} = operators;
class Person {
constructor(config={}) {
Object.assign(this,config);
}
}
class Employer {
constructor(config={}) {
Object.assign(this,config);
}
}
const db = withExtensions(open("test"));
db.clearSync();
db.defineSchema(Person);
db.defineSchema(Employer);
// typically you do no provide an id for a put of a an instance controlled by a schema
const personId = await db.put(null,new Person({name:"bill",age:21,employer:"ACME"}));
// but you can if you want to, so long as you at start it with the class name followed by @
await db.put("Employer@1",new Employer({name:"ACME",address:"123 Main St."}));
const person = await db.get(personId);
// if a return value is an object that is controlled by a schema,
// it will be an instance of the schema's class
console.log(person);
/*
Person {
name: 'bill',
age: 21,
employer: 'ACME',
'#': 'Person@850ad934-a449-493e-846a-96e00a1b6546'
}
*/
// you can use predefined operators in place of literal matches
console.log([...db.select().from(Person).where({Person:{age:$gte(21)}})]);
/*
[
{
Person: Person {
name: 'bill',
age: 21,
employer: 'ACME',
'#': 'Person@850ad934-a449-493e-846a-96e00a1b6546'
}
}
]
*/
// there are lots of operators, Person has an odd numbered age, could use $odd
console.log([...db.select().from(Person).where({Person:{age:$mod([2,1])}})]);
/*
[
{
Person: Person {
name: 'bill',
age: 21,
employer: 'ACME',
'#': 'Person@850ad934-a449-493e-846a-96e00a1b6546'
}
}
]
*/
// joins are performed using the class name as the key
// this example joins Person to Employer on Person.employer === Employer.name
console.log([...db.select().from(Person,Employer).where({Person:{employer: {Employer:{name:"ACME"}}}})]);
/*
[
{
Person: Person {
name: 'bill',
age: 21,
employer: 'ACME',
'#': 'Person@850ad934-a449-493e-846a-96e00a1b6546'
},
Employer: Employer {
name: 'ACME',
address: '123 Main St.',
'#': 'Employer@c5e07e94-4a94-4cfc-b167-65cb1dd7bd29'
}
}
]
*/
// class aliases are supported by providing two element arrays in 'from'
// with the first element being the class and the second being the alias
console.log([...db.select().from([Person, "P"],[Employer,"E"]).where({P:{employer: {E:{name:"ACME"}}}})]);
/*
[
{
Person: Person {
name: 'bill',
age: 21,
employer: 'ACME',
'#': 'Person@850ad934-a449-493e-846a-96e00a1b6546'
},
Employer: Employer {
name: 'ACME',
address: '123 Main St.',
'#': 'Employer@c5e07e94-4a94-4cfc-b167-65cb1dd7bd29'
}
}
]
*/
// you can select just the data you want and move it up a level
console.log([...db.select({P:{name(value,{root}) { root.name=value; }},E:{address(value,{root}){ root.workAddress=value; }}})
.from([Person, "P"],[Employer,"E"])
.where({P:{employer: {E:{name:"ACME"}}}})]);
/*
[ { name: 'bill', workAddress: '123 Main St.' } ]
*/
// you can select just ids
console.log([...db.select(IDS).from([Person, "P"],[Employer,"E"]).where({P:{employer: {E:{name:"ACME"}}}})])
/*
[ [ 'Person@64fc6554-066c-47dd-a99e-d0492dcb957c', 'Employer@1' ] ]
*/