# mbaas-js-sdk-alipay

## Install

npm i mbaas-js-sdk-alipay

## Usage

``` js
import MBaasSDK from '@aliyun/mbaas-js-sdk-xx'

MBaasSDK.init(config)

MBaasSDK.login({ username, password }, (error, res) => {
  if (error) {
    console.error(error)
    return
  }
  MBaasSDK.db('foo').get(callbackFoo)
})

function callbackFoo(error, res) {
  // ...
}
```

## API

### 初始化

#### `MBaasSDK.init(config)`

初始化 SDK。这个方法必须在初始化时调用。

This method must be called before any other calls on the SDK itself.

__Arguments__

- `config`: `SDKConfig` an `object` with keys below:
  - `appId` `required` 小程序应用ID，从控制台获取
  - `secret` `required` 小程序应用秘钥，从控制台获取
  - `envId` `required` 小程序应用环境ID，从控制台获取

__DEMO__

```
sdk.init({
  "appId": 123456,
  "secret": "this is your secret",
  "envId": "test"
});
```

#### `MBaasSDK.login(callback)`

登录接口，向控制台同步用户信息。

__Arguments__

- `callback`: `CallbackFunction` a `function` with the arguments below:
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__

```
sdk.login(function (err, res) {
  if (err) {
    console.error(err);
    return;
  }
  // continue with res
});
```

__Tips__

(@todo: tips -> CallbackFunction below)

### 云数据库

#### `MBaasSDK.db(name): MBaasDatabase`

Get a database manager

__Arguments__

- `name`: `string` 数据表名 / the name of the db you want to use

__Returns__: `MBaasDatabase` 数据表实例 / the database instance


当你获得一个数据表实例时，你可以调用以下属性或方法：

When you get the collection instance, you can access its members below:

##### `MBaasDatabase#name`

获取数据表名

Get the name of the db

__Returns__: `string` 数据表名 / the name of the db

__DEMO__

```
sdk.db('test').name
// print test
```

##### `MBaasDatabaseCollection#get(condition?, callback)`

查询数据库

Query entries with a certain condition.

__Arguments__

- `condition？`: `Object` (可选)查询条件 / `Query` an object that describe the condition you want to query
- `callback`: 回调函数 / `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
// 不带查询条件的查询
sdk.db('test').get(function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "name": "李四", "score": 40}, {"objectId": 2, "name": "张三", "score": 60}, {"objectId": 3, "name": "王五", "score": 98}] }
});
```

__查询条件__
###### 基本查询
在 `Query` 中使用 `where` 表示查询条件，以 keyvalue 的形式。

__DEMO__
```
// 带 where 的查询
sdk.db('test').get({
 where: {"name": "李四"}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "name": "李四"}]}
});
```

除此之外，查询语句还支持以下更复杂的操作：

关键词 | 操作
--- | ---
$lt | 少于
$lte | 少于等于
$gt | 多于
$gte | 多于等于
$ne | 不等于
$in | 包含
$nin | 不包含
$exists | 存在某个字段
$select | 符合子查询条件
$dontSelect | 不符合子查询条件
$all | 全部含有
$regex | 某个字段的值符合相应的正则
$text | 在有索引的字段上执行文字匹配

__DEMO__
```
// 返回分数大于等于1000，并小于等于3000的记录
sdk.db('test').get({
 where: {"score": {"$gte": 1000, "$lte": 3000}}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});

// 返回分数等于1，3，5，7，9的记录
sdk.db('test').get({
 where: {"score": {"in": [1, 3, 5, 7, 9]}}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});

// 返回名字不为 Jonathan Walsh，Dario Wunsch，Shawn Simon 的记录
sdk.db('test').get({
 where: {"playerName": {
   "nin": ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]
 }}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});

// 返回有 score 字段的记录
sdk.db('test').get({
 where: {"score": { "$exists": true }}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});

// 返回含有符合子查询条件的记录
sdk.db('test').get({
 where: {"hometown":{"$select":
  {"query":{"className":"Team","where":{"winPct":{"$gt":0.5}}},"key":"city"}}
 }
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});
```

除了 `where` 语句，我们还有一些用于限制返回结果的属性：


字段 | 作用
--- | ---
order | 排序
limit | 限制每次返回数量
skip | 起始间隔数量
keys | 返回的记录字段

__DEMO__

```
// 返回以 score 字段升序排列的记录
sdk.db('test').get({
 order: "score"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 返回以 score 字段降序排列的记录
sdk.db('test').get({
 order: "-score"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 返回以 score 字段升序排列，name 降序排列的记录
sdk.db('test').get({
 order: "score,-name"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 返回从 401 开始的后续 200 条记录
sdk.db('test').get({
 limit: 200,
 skip: 400
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 返回只包含 score 和 playerName 的记录
sdk.db('test').get({
 keys: "score,playerName"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 组合起来使用
sdk.db('test').get({
 where: {"playerName": {
   "nin": ["Jonathan Walsh", "Dario Wunsch", "Shawn Simon"]
 }},
 order: "score,-name",
 limit: 200,
 skip: 400,
 keys: "score,playerName"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { results: [{"objectId": 1, "score": 2083}]}
});
```

###### 文本查询

使用 `where` 中 `$regex` 和 `$text` 可以实现文本查询。

其中 `$text` 的格式为： `{"$text": {"$search": {parameter}}}`，参数名如下：

参数 | 作用
--- | ---
$term | 定义搜索的文本（必须）
$language | Determines the list of stop words and the rules for tokenizer.
$caseSensitive | 是否开启大小写
$diacriticSensitive | Enable or disable diacritic sensitive search


__DEMO__
```
// 通过正则匹配查找
sdk.db('test).get({
 where: {"name": {"$regex": "^Big Daddy"}}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});

// 通过 text 进行更有效的查询
sdk.db('test).get({
 where: {"name": {"$text": {"$search": {"$term": "Daddy"}}}}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
});
```

###### 查询总数

你可以通过 `count` 查询记录总数，可以通过设置 `limit` 为 0 避免记录的查询。

__DEMO__
```
sdk.db('test).get({
 where: {"name": "good"},
 count: 1,
 limit: 0
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { "results": [], "count": 1000 }
});
```

###### 组合查询

你可以使用 `$or` 对查询条件进行组合。

__DEMO__
```
sdk.db('test).get({
 where: {"or": [{"wins": {"$gt": 150}}, {"wins": {"lt": 5}}]}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { "results": [], "count": 1000 }
});
```

###### 唯一查询

使用 `distinct` 支持指定字段选取唯一值。

__DEMO__
```
sdk.db('test).get({
 where: {"playerName": "Sean Plott"},
 distinct: "score"
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { "results": [], "count": 1000 }
});
```

###### 聚合查询

使用 `group` 参数：`$sum`, `$avg`, `$max`, `$min` 对记录进行聚合操作，使用方法类似于 `distinct`。

__DEMO__
```
sdk.db('test).get({
 group: {"objectId": null, "total": {"$sum": "$score"}}
}, function(err, res) {
  if (err) {
     console.error(err);
     return;
  }
  console.log(res);
  // print { "results": [], "count": 1000 }
});
```

##### `MBaasDatabase#add(entry, callback)`

向数据库插入一条记录

__Arguments__

- `entry`: `Entry` 插入的记录
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
coll.add({
  "score": 435, // type Number
  "playerName": "Tim", // type String
  "cheatMode": false, // type Boolean
  "addr": null, // type Null
  "birthday": { "__type": "Date", iso: "1995-01-01T00:00:00Z" }, // type Date
  "habbits": ["swimming", "football"], // type Array
  "parents": {
    "father": "John",
    "mother": "Marry"
  } // type Object
}, (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(res);
});
```

__Tips__

请确保先在控制台创建好数据表，否则会失败。

##### `MBaasDatabase#addMany(entries, callback)`

向数据库插入多条记录

__Arguments__

- `entries`: `Array<Entry>` 插入的数据
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果，注意此处是数组，对应每条记录的状态

__DEMO__
```
coll.add([{
  "score": 435, // type Number
  "playerName": "Tim", // type String
  "cheatMode": true, // type Boolean
}, {
  "score": 100, // type Number
  "playerName": "Sam", // type String
  "cheatMode": false, // type Boolean
}], (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(res);
});
```

##### `MBaasDatabase#updateById(entryId, entry, callback)`

通过记录 ID 修改记录

__Arguments__

- `entryId`: `string` 记录的 objectId
- `entry`: `Entry` 修改内容
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
const coll = sdk.db('test')
coll.get({
      where: { playerName: "Sean Plott" },
    }, (err: any, res: any) => {
      const id = res.results[0].objectId;
      coll.updateById(id, { score: 0 }, (err: any, res: any) => {
      });
    });
```

##### `MBaasDatabase#deleteById(entryId, callback)`

通过记录 ID 删除记录

__Arguments__

- `entryId`: `string` 记录的 objectId
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
const coll = sdk.db('test')
coll.get({
      where: { playerName: "Sean Plott" },
    }, (err: any, res: any) => {
      const id = res.results[0].objectId;
      coll.deleteById(id, (err: any, res: any) => {
      });
    });
```

### 云存储

#### `MBaasSDK.file(): MBaasFile`

Get a file manager

__Returns__: `MBaasDatabase` the file manager

The file manager has two methods below:

##### `MBaasFile#uploadFile(filepath, callback)`

通过指定的文件路径上传一个文件

__Arguments__

- `filepath`: `string` 文件路径
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
const file = sdk.file();
file.uploadFile('./waiting.png', (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(res);
});
```

__Tips__

建议配合相关平台的文件选择使用

##### `MBaasFile#deleteFile(entryId, callback)`

通过指定的 ID 删除文件

__Arguments__

- `entryId`: `string` 文件记录ID
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
const file = sdk.file();
file.deleteFile('1232324', (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(res);
});
```

##### `MBaasFile#getTempUrl(entryId, callback)`

通过指定的 ID 获取临时访问 url，有效期半天

__Arguemtns__

- `entryId`: `string` 文件记录ID
- `callback`: `CallbackFunction`
  - `error`: `Error` 如果请求有错误，返回该错误；否则为空
  - `res`: `any` 返回请求结果

__DEMO__
```
const file = sdk.file();
file.getTempUrl('1232324', (err, res) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(res.url);
});
```