Skip to content

Commit

Permalink
zero dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
windyrobin committed Apr 1, 2013
1 parent 16f8485 commit b6a4e3b
Show file tree
Hide file tree
Showing 52 changed files with 4,290 additions and 728 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ TESTS = test/unit/*.js
REPORTER = spec
test: clean
@npm install
@./node_modules/pegjs/bin/pegjs peg/mquery.pegjs ./lib/mquery.js
@./node_modules/pegjs/bin/pegjs peg/nquery.pegjs ./base/nquery.js
@./node_modules/mocha/bin/mocha $(TESTS)

clean:
Expand Down
126 changes: 123 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,124 @@
mquery
======
## ![logo](http://nquery.org/images/robin-small.jpg) nQuery

Generecic SQL engine for Web and Big-data.

## Install

NodeJS Version 0.8.0+

```
npm install node-query
```

## Introduction

it could be used in some typical scenarios:
* As a SQL frontend, do syntax checking and formating.
* As a SQL engine for your KV databass like hbase or anything like that.
* Providing a SQL interface for your HTTP/WEB service.
* Do data merging and intergration among many differecnt datasources like Oracle, MySQL, HBase etc.


## Demo &Test
to run the demo, type the command:

```
node demo/demo.js
```
for the test , type the command:

```
make
```

read the demo carefully and then you could write own loader/adapter,
there are also many test cases in `test/unit`, they would be great heleful to you.


## Usage

please read the demo files `demo/demo.js`

for a KV Strorage engine ,what you need to do is providing the query interfaces like:

* `singleQuery`,
* `rangeQuery`,
* `likeQuery`

for a SQL Strorage engine, you should realize a function like :

```js
function query(str, function(err, data) {
...
})
```

then you could execute SQL like that : (code snippet from `demo.js`)

```js
var sqls = [
"SELECT * FROM kv.user WHERE id IN ('01', '03')",
"SELECT * FROM kv.user WHERE id LIKE '1%'",
"SELECT type, MAX(age), COUNT(id) FROM kv.user WHERE id BETWEEN '03' AND '10' GROUP BY type ORDER BY MAX(age) DESC",
"SELECT * from mysql.shop where shop_id > 5"
]

var concurrentJoinSQL = [
"$a := select * from kv.user where id BETWEEN '03' and '10'",
"$b := select * from mysql.shop where shop_id > 5",
"$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'",
"return $c"
]

var sequentialJoinSQL = [
"$a := select * from kv.user where id BETWEEN '03' and '10'",
//you could also use `unique` do filter firstly
//"$type := UNIQUE($a.type)",
//"$b := select * from mysql.shop where type = $type",
"$b := select * from mysql.shop where type in $a.type",
"$c := select a.type , a.id ,b.name, b.title from $a INNER JOIN $b ON a.type = b.type WHERE a.id > '04'",
"return [$b, $c]"
]
```

As you see ,besides as a SQL computation level built on top of KV storage engine, it could do
join operation among kv data-source, sql sources, HTTP services now

## nSQL Definition

The 'a little strange' sql as you see above, nSQL realize a subset of SQL92, and it
also has some procedure features, it supports variables, it addes types of `var`
/ `array` / `table`, and also keyword `return`, for the details, please see the
specification of `peg/nquery.pgejs`.


## Task Scheduling

As you could see in `concurrentJoinSQL` ,we know that the tasks `$a`, `$b` have no
relations, so nQuery would do them concurrently, but for the procedure of `sequentialJoinSQL`,
`$b` is depending on `$a`,so task `$b` would be executed after the time `$a` completed

## KeyWord `return`

In traditional SQL, the query result is a 2-D table , but In nSQL ,we add types of `array`
/ `table`,so now you could return complicated results like

```
return [$b, $c, 'hello', [1, 2]]
```


###Just Enjoy It!


### Acknowledgements

* PegJS : http://pegjs.majda.cz/
* NodeJS : http://nodejs.org/
* BigQuery : https://developers.google.com/bigquery/docs/query-reference
* PL/SQL : http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/fundamentals.htm#autoId0
* MySQL : http://dev.mysql.com/doc/refman/5.1/en/sql-syntax.html
* Impala : https://github.com/cloudera/impala/blob/master/fe/src/main/cup/sql-parser.y
* PgSQL : http://www.postgresql.org/docs/9.2/interactive/sql-syntax.html
* ql.io : http://ql.io

multiple query interface for data source(mysql, ots, hbase, pgsql, http, ...)
14 changes: 11 additions & 3 deletions lib/aggregation.js → base/aggregation.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
var Tool = require('./tool');
var AstHelper = require('./ast_helper');
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

var runExpr = AstHelper.run;
// Author :windyrobin <[email protected]>

var Tool = require('../lib/tool');
var Engine = require('../lib/engine');
var AstHelper = require('../lib/ast_helper');

var runExpr = Engine.run;
var getSelRefCols = AstHelper.getSelRefCols;
var getRefColInfo = AstHelper.getRefColInfo;

Expand Down
17 changes: 13 additions & 4 deletions lib/column.js → base/column.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
var Tool = require('./tool');
var Adapter = require('./adapter');
var AstHelper = require('./ast_helper');
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

// Author :windyrobin <[email protected]>

var Tool = require('../lib/tool');
var Engine = require('../lib/engine');
var Adapter = require('../lib/adapter');
var AstHelper = require('../lib/ast_helper');

var doGroupby = require('./groupby');
var doAggregation = require('./aggregation');

var runExpr = AstHelper.run;
var runExpr = Engine.run;

var checkAggrOp = AstHelper.checkAggrOp;
var getRefColPos = AstHelper.getRefColPos;
Expand Down
10 changes: 8 additions & 2 deletions lib/distinct.js → base/distinct.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

// Author :windyrobin <[email protected]>

/**
* @param {Object} dc like :{
Expand Down Expand Up @@ -35,9 +41,9 @@ function distinct(data){
}

function debug(str){
console.log(str);
//console.log(str);
}

function inspect(obj){
console.log(require('util').inspect(obj));
//console.log(require('util').inspect(obj));
}
28 changes: 16 additions & 12 deletions lib/groupby.js → base/groupby.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

// Author :windyrobin <[email protected]>


var AstHelper = require('../lib/ast_helper');

module.exports = doGroupby;

function debug(str){
//console.log(str);
}
Expand All @@ -6,6 +18,8 @@ function inspect(obj){
//console.log(require("util").inspect(obj, false, 10));
}

var getRefColPos = AstHelper.getRefColPos;

function genGbKey(args){
var keys = [];
for(var i = 0; i < args.length; i++){
Expand All @@ -15,23 +29,14 @@ function genGbKey(args){
return keys.join('__');
}

module.exports = doGroupby;

function doGroupby(dc, gb) {
var i, j;
var columns = dc.columns;
var data = dc.data;

var gbPos = [];
for(i = 0; i < gb.length; i++){
var gCol = gb[i]
for(j = 0; j < columns.length; j++){
if(columns[j].indexOf(gCol) >= 0){
gbPos[i] = j;
break;
}
}
}
gbPos = getRefColPos(gb, columns);

var res = {};
for (i = 0; i < data.length; i++) {
var gCols = [];
Expand All @@ -49,6 +54,5 @@ function doGroupby(dc, gb) {
}
res[key].data.push(d);
}

return res;
}
6 changes: 6 additions & 0 deletions lib/limit.js → base/limit.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

// Author :windyrobin <[email protected]>

module.exports = filter;
/** @param {Array} limit [2,0] or []
Expand Down
9 changes: 8 additions & 1 deletion lib/mcache.js → base/mcache.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// (C) 2011-2013 Alibaba Group Holding Limited.
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.

// Author :windyrobin <[email protected]>

function debug(str){
console.log(str);
//console.log(str);
}

module.exports = Cache;
Expand Down
48 changes: 48 additions & 0 deletions base/merger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
var Table = require('../lib/table');
var leftJoin = require('../lib/join').leftJoin;
var innerJoin = require('../lib/join').innerJoin;

function debug(str) {
//console.log(str);
}

function inspect(obj) {
//console.log(require('util').inspect(obj, false, 10));
}

exports.join = function (ltb, rtb, op, ons ) {
//debug('ons:')
//inspect(ons);
//debug('ops:')
//inspect(op);
var fn = leftJoin;
if (!op || op == '' || op == 'JOIN' || op == 'INNER JOIN'){
fn = innerJoin;
}
//inspect(onParam);
var table = fn(ltb, rtb, ons);
return table;
}

exports.union = function(dArr) {
if (dArr.length == 1) {
return dArr[0];
}

var lCols = [];
for(var i = 0; i < dArr.length; i++){
lCols = dArr[i].getColNames();
if(lCols.length > 0) break;
}
var cols = [].concat(lCols);
var data = [];
for(var i = 0; i < dArr.length; i++){
var cData = dArr[i].getRows();
data = data.concat(cData);
}

return new Table({
columns : cols,
data : data
});
}
Loading

0 comments on commit b6a4e3b

Please sign in to comment.