Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/brainpoint/febs-db

a orm library for nodejs
https://github.com/brainpoint/febs-db

count database db mssql mysql nodejs orm sql sqlserver transaction

Last synced: 25 days ago
JSON representation

a orm library for nodejs

Awesome Lists containing this project

README

        

febs db库用于连接数据库,目前仅支持mysql

`febs-db是在[email protected]基础上进行开发, citong-db库已停止更新`

- [Install](#install)
- [Exception](#exception)
- [1.Define Table](#define-table)
- [2.Connect db](#connect-db)
- [3.Manipulate db](#manipulate-db)
- [Class database](#database)
- [Class table](#table)

# Install

Use npm to install:

```js
npm install febs-db --save
```
![](doc/framework.png)

febs-db是一个orm库, 3个主要的类为:

> `database`: 代表一个数据库; 可以用于创建新的数据库连接对象`database-connection`进行事务等操作.

> `table`: 代表一个数据库表; 针对表的操作在这个对象中完成

> `database_connection`: 表示一个连接对象, 在执行事务操作时, 需要使用database来向连接池中获取一个连接来进行.

# Exception

在错误发生时会抛出`exception`类型的异常

事务处理中发生异常将自动rollback.

定义了常用的错误代码.

```js
// @desc: 数据查询条件错误。参数语句问题.
exception.DB_ERROR_SQL
// @desc: 数据连接问题.
exception.DB_ERROR_CONNECT
// @desc: 数据执行错误.
exception.DB_ERROR
```

异常类如下
```js
/**
* @desc: 构造异常对象.
* @param msg: 异常消息
* @param code: 异常代码
* @param filename: 异常文件名
* @param line: 异常文件所在行
* @return:
*/
exception(msg, code, filename, line)
```
例子:
```js
var exception = require('.').exception;
try {
yield db.queryById(...);
} catch (e) {
if (e instanceof exception) {
// e.code == exception.DB_ERROR_SQL, 查询语句错误.
} else {
throw e;
}
}
```

# Define-table

操作一个数据表之前, 需要先对表结构进行定义, 与数据不匹配的定义在执行数据操作时会报错. 数据列可以仅列出需要操作的列.

```js
var table = require('.').table;

class TableDemo extends table {
constructor(db) {
super(
db, // database
'User', // table name.
'ID', // primary key.
{ // cols.
ID: {type: 'integer', size: 8, key: true}, // the auto-incrementing
Name: {type: 'text', size:10},
NumberCol:{type: 'number', size: 4},
IntCol: {type: 'integer', size: 4},
IntCol: {type: 'integer', size: 8}, // big int.
BoolCol: {type: 'boolean'}
}
);
}
}
```
## example:
```js
var database = require('febs-db').database;

var db = new database({});
var tableDemo = new TableDemo(db);
```

## combined primary key

```js
var table = require('.').table;

class TableDemo extends table {
constructor(dbclient) {
super(
dbclient, // database
'Admin', // table name.
['ID', 'IntCol'], // primary keys.
{ // cols.
ID: {type: 'integer', size: 8, key: true}, // the auto-incrementing
Name: {type: 'text', size:10},
NumberCol:{type: 'number', size: 4},
IntCol: {type: 'integer', size: 4},
IntCol: {type: 'integer', size: 8}, // big int.
BoolCol: {type: 'boolean'}
}
);
}
}
```

# Connect-db

mysql: see [mysql](https://www.npmjs.com/package/mysql#pool-options) pool-options.

```js
var database = require('febs-db').database;

var opt = {
waitForConnections: true,
connectTimeout : 5000,
acquireTimeout : 5000,
queueLimit : 20,
connectionLimit : 10,
supportBigNumbers : true,
bigNumberStrings : false, // number -> string only when number overflow in js.
host : '',
port : 3306,
user : '',
password : '',
database : '',
/* ext */
queryTimeout : 5000,
};

var db = new database('mysql', opt);
var table = new TableDemo(db);
```

# Manipulate-db

数据操作方法都存在同步方式和异步方式, 例如: `table.isExist()` 和 `table.isExistSync()`
所有的同步方式方法都是在末尾加上`Sync`

- [exist](#exist)
- [query](#query)
- [query-Lock-Row](#query-lock-row)
- [count](#count)
- [add](#add)
- [update](#update)
- [remove](#remove)
- [transaction](#transaction)

## exist

```js
let r;
// async.
r = yield table.isExist(1);
r = yield table.isExist({ID:1,Name:'xxx'}); // combined primary key.
r = yield table.isExistWhere("id=43");
// sync.
r = yield table.isExistSync(1, (err, r)=>{});
r = yield table.isExistWhereSync("id=43", (err, r)=>{});
```

## query

```js
let r;
// 通过主键查询.
r = yield table.queryById(1);
r = yield table.queryById(1, ['ID','Name']); // only query 'ID','Name' cols.
r = yield table.queryById({ID:1,IntCol:1}, ['ID','Name']); // if combined primary key.

// top.
r = yield table.queryTop("id = 43");
r = yield table.queryTop("id = 43", ['ID','Name']); // only query 'ID','Name' cols.

// 条件查询. 使用make_condition_xxx 方法构造条件, 能够自动检查数值类型.
let where = '';
where += table.make_condition('id', 43); // == " `id`=43 ".
where += 'AND';
where += table.make_condition_like('name', '%dfdfd%'); // == " `name` LIKE '%dfdfd%' ".
r = yield table.queryTop(where);

r = yield table.queryWhere(where, [0, 100], {ID:true}); // where id = 43 limit 0,100 order by id asc.
r = yield table.queryWhere(where, ['ID', 'Name']); // only query 'ID','Name' cols.
r = yield table.queryWhere(where, [0, 100], ['ID', 'Name']); // only query 'ID','Name' cols. limit 0,100
r = yield table.queryWhere(where, {ID:true}, ['ID', 'Name']); // only query 'ID','Name' cols. orderby ID
r = yield table.queryWhere(where, ['COUNT(ID) as x']);
```

## query-lock-row

锁行方式查询, 只能在事务中使用此方式. 在事务结束或update之后自动解锁.

`queryLockRow`方法的参数与`queryById`方法相同

```js
// 获取一个新连接用于事务执行.
var conn = yield db.getConnection();
if (conn)
{
// 执行事务
return yield conn.transaction(function*(){

// lock row id = 1, and unlock after update or exit transaction.
let r;
r = yield table.queryLockRow(1, conn);
// or.
r = yield table.queryLockRow(1, ['col1','col2'], conn);

return false; // will rollback.
return true; // will commit.
});
}
```

## count

```js
let r;
let where = table.make_condition('id', 43); // == " `id`=43 ".
r = yield table.count(where);
```

## add

```js
var r = yield table.add({ID:8,...});
```

## update

更新方法需传入一个对象, 其中必须附带`主键`, 执行后将更新其他在参数中的其他数据.

```js
var mod = {
ID: 1,
name: "name",
intCol: table.make_update_inc(1),
intCol2:table.make_origin_sql('`intCol2`+1')
};
var r = yield table.update(mod); // ID=1,name="name",intCol=intCol+1,intCol2=intCol2+1
```

## remove

```js
var r = yield table.remove(where);
```

## transaction

* 执行事务需要一个独立的连接对象 `datdatabase_connection`, 事务完成后连接对象将重新被插入到连接池中.
* 事务处理函数中, 所有的事务数据库操作方法都必须在最后带上这个`连接对象`
* 事务处理函数中, 返回`false` 将`rollback`, 返回`true`将`commit`
* 若发生异常, 事务将自动`rollback`.
* *事务嵌套调用未处理, 将在下一版本添加

```js
// 获取一个新的连接用于事务执行.
var conn = yield db.getConnection();
if (conn)
{
// 执行事务, 错误将返回false;
return yield conn.transaction(function*(){
// attach conn.
console.log((yield table.add(mod, conn)));

mod.id = 1;
mod.name = 'a1';
console.log((yield table.update(mod, conn)));

return false; // will rollback.
return true; // will commit.
});
}
```

# database

## 构造

```js
/*
* 构造
*/
constructor(dbtype, opt)
```
* dbtype: 数据库类型, 目前仅能为 `'mysql'`
* opt: 连接参数

mysql: see [mysql](https://www.npmjs.com/package/mysql#pool-options) pool-options.
```js
var opt = {
waitForConnections: true,
connectTimeout : 5000,
acquireTimeout : 5000,
queueLimit : 20,
connectionLimit : 10,
supportBigNumbers : true,
bigNumberStrings : false, // number -> string only when number overflow in js.
host : '',
port : 3306,
user : '',
password : '',
database : '',
/* ext */
queryTimeout : 5000,
};
```
## 方法
```js
/**
* @desc: 执行sql语句.
* @param values: 传递的参数.
* @return: 错误返回false. 正确返回结果.
*/
*query(sql, values, conn)
/**
* @param cb: cb(err, ret) {}
* @param values: 传递的参数.
* @return: void
*/
querySync( sql, value, cb, conn )
```

## 获取连接

从连接池中获取一个空闲的连接用于事务处理.
```js
/**
* @desc: get the connection for transaction.
* @return: database_connection.
*/
*getConnection() // * 表明此方法是一个异步方法
```

# table

所有的数据库查询方法都存在相应的同步调用方式, 如: queryWhereSync();

- [constructor](#table-constructor)
- [getConnection](#table-getconnection)
- [isExist](#table-isexist)
- [isExistWhere](#table-isexistwhere)
- [count](#table-count)
- [add](#table-add)
- [remove](#table-remove)
- [update](#table-update)
- [queryById](#table-querybyid)
- [queryLockRow](#table-querylockrow)
- [queryTop](#table-querytop)
- [queryWhere](#table-querywhere)
- [get_conn](#table-get_conn)
- [escape](#table-escape)

构造查询条件相关方法
- [make_condition](#table-make-condition)
- [make_condition_not_equal](#table-make-condition-not-equal)
- [make_condition_more](#table-make-condition-more)
- [make_condition_more_equal](#table-make-condition-more-equal)
- [make_condition_less_equal](#table-make-condition-less-equal)
- [make_condition_less](#table-make-condition-less)
- [make_condition_like](#table-make-condition-like)
- [make_update_inc](#table-make-update-inc)
- [make_origin_sql](#table-make-origin-sql)

### table-constructor
```js
/**
* @param db: 数据库对象.
* @param tablename: 本表名.
* @param idKeyName: 本表主键列表, 如果为单主键可以直接为字符串, 如果为联合多主键则需要为数组.
* @param model: 本表模型.
*/
*constructor(db, tablename, idKeyName, model)
```

> `model`的定义格式如下:

> {

colName: {`type`: 'integer', `size`: 8, `key`: true}, // the auto-incrementing

...

}

- `colName`: 表示列名称
- `type`: 表示列类型

| 类型 | 说明 | size |
|------|--------|----|
| 'integer' | 整型 | 指明字节长度 |
| 'text' | 字符串 | 指明字符长度 |
| 'number' | 浮点型 | 指明字节长度 |
| 'boolean' | 布尔型| 无意义 |

- `size`: 字段长度(字节长度), 例如: bigint 长度为8, int长度为4.
- `key`: 是否是自增键; (同一个表只能有一个自增键, 当指定多个自增键时, 只认为最后一个为自增)

### table-getConnection

```js
/**
* @desc: get a new connection for transaction.
* @return: database_connection.
*/
*getConnection() // * 表明此方法是一个异步方法
```

### table-isExist

```js
/**
* @desc: isExist
* id is Object if table is combined primary.
* the last param can be conn.
* @return: boolean.
*/
*isExist( id )
/**
* @desc: isExist
* id is Object if table is combined primary.
* the last param can be conn.
* @param id, cb
* - cb: function(err, r:boolean) {}
*/
isExistSync( id, cb )
```

### table-isExistWhere

```js
/**
* @desc: isExitWhere
* the last param can be conn.
* @return: boolean.
*/
*isExistWhere( where )
/**
* @desc: isExitWhere
* the last param can be conn.
* @param where, cb
* - cb: function(err, r:boolrean) {}
*/
isExistWhereSync()
```

### table-count

```js
/**
* @desc: count
* the last param can be conn.
* @param: where
* @return: int.
*/
*count()
/**
* @desc: count
* the last param can be conn.
* @param: where, cb
* - cb: function(err, ret:int) {}
*/
countSync()
```

### table-add

```js
/**
* @desc: add
* the last param can be conn.
* (insertId will set to item.id)
* @return: bool
*/
*add( item )
/**
* @param cb: cb(err, r:boolean) {}
* @return: void
*/
addSync( item, cb )
```

### table-remove

```js
/**
* @desc: remove
* the last param can be conn.
* @return: bool.
*/
*remove( where )
/**
* @param cb: cb(err, r:boolean) {}
* @return:.
*/
removeSync( where, cb )
```

### table-update

```js
/**
* @desc: update; where id = item.id
* if item.id is existed, sql condition is: 'id=value' AND (where)
* otherwise sql condition is: where
* the last param can be conn.
* @param item, where.
* @return: boolean.
*/
*update( item )
/**
* @desc: update; where id = item.id
* if item.id is existed, sql condition is: 'id=value' AND (where)
* otherwise sql condition is: where
* the last param can be conn.
* @param item, where, cb.
* - cb: function(err, r:boolrean) {}
* @return:.
*/
updateSync( item )
```

### table-queryById

```js
/**
* @desc: query by id.
* id is Object if table is combined primary.
* the last param can be conn.
* @param: id, [query_cols]
* query_cols: [col1,col2], the cols will be query.
* @return: mod.
*/
*queryById( id )
/**
* @desc: query by id.
* id is Array if table is combined primary.
* the last param can be conn.
* @param: id, [query_cols], cb
* - query_cols: [col1,col2], the cols will be query.
* - cb: function(err, ret:mod) {}
*/
queryByIdSync( id )
```

### table-queryLockRow

```js
/**
* @desc: query by id and lock row for update (use in transaction).
* id is Object if table is combined primary.
* the last param can be conn.
* @param: id, [query_cols]
* query_cols: [col1,col2], the cols will be query.
* @return: mod.
*/
*queryLockRow( id )
/**
* @desc: query by id and lock row for update (use in transaction).
* id is Object if table is combined primary.
* the last param can be conn.
* @param: id, [query_cols], cb
* - query_cols: [col1,col2], the cols will be query.
* - cb: function(err, ret:mod) {}
* @return: mod.
*/
queryLockRowSync( id )
```

### table-queryTop

```js
/**
* @desc: query top.
* the last param can be conn.
* @param: where, {orderby}, [query_cols]
* orderby: {key:true/false} true-means asc, false-means desc.
* query_cols: [col1,col2], the cols will be query.
* @return: mod.
*/
*queryTop( where )
/**
* @desc: query top.
* the last param can be conn.
* @param: where, {orderby}, [query_cols], cb
* - orderby: {key:true/false} true-means asc, false-means desc.
* - query_cols: [col1,col2], the cols will be query.
* - cb: function(err, ret:mod) {}
*/
queryTopSync( where )
```

### table-queryWhere

```js
/**
* @desc: query
* the last param can be conn.
* @param: where, [offset,limit], {orderby}, [query_cols]
* - orderby: {key:true/false} true means asc, false means desc.
* - query_cols: [col1,col2], the cols will be query. e.g. ['id', 'name']
* @return: [mod,mod,...].
*/
*queryWhere( where )
/**
* @desc: query
* the last param can be conn.
* @param: where, [offset,limit], {orderby}, [query_cols]
* - orderby: {key:true/false} true means asc, false means desc.
* - query_cols: [col1,col2], the cols will be query. e.g. ['id', 'name']
* -cb: function(err, ret:Array) {}
*/
queryWhereSync( where )
```

### table-get_conn
```js
/**
* @desc: 获得最后一个参数,如果为 database_connection则返回.否则返回null.
* @return:
*/
get_conn(arguments)
```

### table-escape

```js
/**
* @desc: escape
* @return: str.
*/
escape( v )
```

### table-make_condition

```js
/**
* @desc: 构造一个 key=value的sql条件语句.
* @return: sql;
*/
make_condition( key, value )
```

### table-make_condition_not_equal

```js
/**
* @desc: 构造一个 key<>value的sql条件语句.
* @return: sql;
*/
make_condition_not_equal( key, value )
```

### table-make_condition_more

```js
/**
* @desc: 构造一个 key>value的sql条件语句.
* @return: sql;
*/
make_condition_more( key, value )
```

### table-make_condition_more_equal

```js
/**
* @desc: 构造一个 key>=value的sql条件语句.
* @return: sql;
*/
make_condition_more_equal( key, value )
```

### table-make_condition_less_equal

```js
/**
* @desc: 构造一个 key<=value的sql条件语句.
* @return: sql;
*/
make_condition_less_equal( key, value )
```

### table-make_condition_less

```js
/**
* @desc: 构造一个 key