3.0.2 • Published 9 years ago
nepq v3.0.2
Nep Query (nepq; NepQ)
Nep Query is a query language that was inspired by Facebook's GraphQL and MongoDB.
Syntax
{method} {name}({params}) {retrieve_flag}{
{retrieves}
}
will be parsed into object:
interface NepQ {
method: string;
name: string;
params: any[];
retrieves: any;
$_: number; // retrieve flag :- 1 (inclusion), 0 (exclusion), null (no flag)
}
Params Syntax
{id}: {value}, {id}: {value}, ...
# or json
{"{id}": {value}, ...}
# or json with JavaScript style (ignore `"` for keys)
{{id}: {value}, ...}
# or arguments
{value}, {value}, ...
Retrieves Syntax
{id}({params}) {
{retrieves}
},
{id}({params}) {
{retrieves}
},
...
Retrieve Flag
''
or '+'
: inclusion flag
'-'
: exclusion flag
'*'
: no flag
Example
Basic
with inclusion :
read stock.product(id: 10) { name, price }
{
"method": "read",
"name": "stock.product",
"params": [
{
"id": 10
}
],
"retrieves": {
"name": 1,
"price": 1
},
"$_": 1
}
--
with exclusion :
read stock.product(id: 10) -{ price }
{
"method": "read",
"name": "stock.product",
"params": [
{
"id": 10
}
],
"retrieves": {
"price": 1
},
"$_": 0
}
Use json as parameter :
create db.user.customer({
"user": "cust1",
"email": "cust1@email.com",
"tel": "+661234567",
"address": {
"province": "Bangkok",
"zip": "12345",
"country": "TH"
}
}) {}
{
"method": "create",
"name": "db.user.customer",
"params": [
{
"user": "cust1",
"email": "cust1@email.com",
"tel": "+661234567",
"address": {
"province": "Bangkok",
"zip": "12345",
"country": "TH"
}
}
],
"retrieves": 0,
"$_": 1
}
--
or JavaScript style :
create db.user.customer({
user: "cust1",
email: "cust1@email.com",
tel: "+661234567",
address: {
province: "Bangkok",
zip: "12345",
country: "TH"
}
})
{
"method": "create",
"name": "db.user.customer",
"params": [
{
"user": "cust1",
"email": "cust1@email.com",
"tel": "+661234567",
"address": {
"province": "Bangkok",
"zip": "12345",
"country": "TH"
}
}
],
"retrieves": 1,
"$_": 1
}
Nested retrieves :
read db.user.customer(email: "cust1@email.com") {
id,
user,
email,
address {
zip,
country
}
}
{
"method": "read",
"name": "db.user.customer",
"params": [
{
"email": "cust1@email.com"
}
],
"retrieves": {
"id": 1,
"user": 1,
"email": 1,
"address": {
"zip": 1,
"country": 1
}
},
"$_": 1
}
Parameters :
update user({ id: 1234 }, { email: "new_mail@email.com" }) -{}
{
"method": "update",
"name": "user",
"params": [
{
"id": 1234
},
{
"email": "new_mail@email.com"
}
],
"retrieves": 1,
"$_": 0
}
--
flatten :
calc sum(...[10, 20, 30, 40]) *{ result(0) }
{
"method": "calc",
"name": "sum",
"params": [
10,
20,
30,
40
],
"retrieves": {
"result.$": [
0
]
},
"$_": null
}
Inclusion retrieves with parameters :
calc sum(10, 20, 30, 40) {
result(0)
}
{
"method": "calc",
"name": "sum",
"params": [
10,
20,
30,
40
],
"retrieves": {
"result": 1,
"result.$": [
0
]
},
"$_": 1
}
Retrieves with parameters :
calc sum(10, 20, 30, 40) *{
result(0)
}
{
"method": "calc",
"name": "sum",
"params": [
10,
20,
30,
40
],
"retrieves": {
"result.$": [
0
]
},
"$_": null
}
Some can be ignored :
empty string
{
"method": "",
"name": "",
"params": [],
"retrieves": 1,
"$_": 1
}
--
read
{
"method": "read",
"name": "",
"params": [],
"retrieves": 1,
"$_": 1
}
--
read stock.product
{
"method": "read",
"name": "stock.product",
"params": [],
"retrieves": 1,
"$_": 1
}
--
read stock.product { name }
{
"method": "read",
"name": "stock.product",
"params": [],
"retrieves": {
"name": 1
},
"$_": 1
}
--
{
find(10) {
name,
price
}
}
{
"method": "",
"name": "",
"params": [],
"retrieves": {
"find": {
"name": 1,
"price": 1
},
"find.$": [
10
]
},
"$_": 1
}
Hardcore :
q test(prefix: "123") {
id,
obj(2) -{
name(1, 2) +{
first
},
tel
},
result *{
res(0),
obj +{
ok
}
}
}
{
"method": "q",
"name": "test",
"params": [
{
"prefix": "123"
}
],
"retrieves": {
"id": 1,
"obj": {
"name": {
"first": 1
},
"name.$": [
1,
2
],
"name.$_": 1,
"tel": 1
},
"obj.$": [
2
],
"obj.$_": 0,
"result": {
"res.$": [
0
],
"obj": {
"ok": 1
},
"obj.$_": 1
},
"result.$_": null
},
"$_": 1
}
API
export interface NepQ {
method: string;
name: string;
params: any[];
retrieves: any;
$_: number;
}
export var parser: {
parse: (input: string) => NepQ;
};
export function parse(input: string): NepQ;
export function response(nq: NepQ, obj: any, cb?: (result: any) => void): void;
export function bodyParser(opt?: {
encoding?: string;
}): (req, res, next) => void;
Example
$ npm init
$ npm install express nepq lodash
import express = require('express');
import nepq = require('nepq');
var app = express();
var db: { [key: string]: any[] } = {};
var _id = 0;
app.use(nepq.bodyParser());
app.use((req, res) => {
let nq: nepq.NepQ = req.body;
if (nq == null) return res.sendStatus(400);
console.log(nq);
let get = id => db[nq.name].reduce((p, v, i) => {
return p === null && v._id === id ? i : p;
}, null);
let response = result => nepq.response(nq, result, r => res.json(r));
let i, d;
switch (nq.method) {
case 'create':
if (!db[nq.name]) db[nq.name] = [];
nq.params[0]._id = _id++;
db[nq.name].push(nq.params[0]);
response(nq.params[0]);
break;
case 'read':
if (!db[nq.name]) return response(null);
if (nq.params.length === 0) {
return response(db[nq.name]);
}
response(db[nq.name].filter(x => x._id === nq.params[0])[0] || null);
break;
case 'update':
if (!db[nq.name]) return response(null);
i = get(nq.params[0]);
if (i === null) return response(null);
nq.params[1]._id = db[nq.name][i]._id;
db[nq.name][i] = nq.params[1];
response(nq.params[1]);
break;
case 'delete':
if (!db[nq.name]) return response(null);
i = get(nq.params[0]);
if (i === null) return response(null);
d = db[nq.name][i];
delete db[nq.name][i];
response(d);
break;
case 'calc':
switch (nq.name) {
case 'sum':
response({
result: ([init]) => nq.params.reduce((p, v) => p + v, init)
});
break;
default:
res.sendStatus(501);
}
break;
default:
res.sendStatus(501);
}
});
app.listen(8000);
$ curl localhost:8000
> Bad Request
$ curl --header "content-type: application/nepq" localhost:8000
> Not Implemented
$ curl --header "content-type: application/nepq" --data "create contact({name: \"n1\"})" localhost:8000
> {"name":"n1","_id":0}
$ curl --header "content-type: application/nepq" --data "create contact(name: \"n2\") { _id }" localhost:8000
> {"_id":1}
$ curl --header "content-type: application/nepq" --data "read contact(0) -{ _id }" localhost:8000
> {"name":"n1"}
$ curl --header "content-type: application/nepq" --data "update contact(0, {name: \"new n1\"})" localhost:8000
> {"name":"new n1","_id":0}
$ curl --header "content-type: application/nepq" --data "read contact { name }" localhost:8000
> [{"name":"new n1"},{"name":"n2"}]
$ curl --header "content-type: application/nepq" --data "calc sum(10, 20, 30, 40) { result(0) }" localhost:8000
> {"result":100}
$ curl --header "content-type: application/nepq" --data "calc sum(10, 20, 30, 40) { result(\"\") }" localhost:8000
> {"result":"10203040"}
3.0.2
9 years ago
3.0.1
9 years ago
3.0.0
9 years ago
3.0.0-alpha.7
9 years ago
3.0.0-alpha.6
9 years ago
3.0.0-alpha.5
9 years ago
3.0.0-alpha.4
9 years ago
3.0.0-alpha.3
10 years ago
3.0.0-alpha.2
10 years ago
3.0.0-alpha.1
10 years ago
3.0.0-alpha.0
10 years ago
2.1.0
10 years ago
2.0.0
10 years ago
1.0.5
10 years ago
1.0.4
10 years ago
1.0.3
10 years ago
1.0.2
10 years ago
1.0.1
10 years ago
1.0.0
10 years ago
0.3.3
10 years ago
0.3.2
10 years ago
0.3.1
10 years ago
0.2.0
10 years ago
0.1.1
10 years ago
0.1.0
10 years ago
0.0.3
10 years ago
0.0.2
10 years ago