2021.09 v1.11

九月份 Leoric 发布了 v1.9 - v1.11 多个版本,主要增加了 SQLite 连接池、修复对象条件表达式中的逻辑操作符处理方式、完善 d.ts 信息等等。本月有多位程序员给 Leoric 提交代码,保持这个节奏到年底,或者就是时候将它提交到 https://github.com/alibaba 组织了。

SQLite 连接池及其他

Leoric 目前没有给客户端提供通用的连接池管理,而是客户端有什么就用什么,所以 MySQL 用的是 mysql 或者 mysql2 自带的 Pool,PostgreSQL 也是如此,而 node-sqlite3 提供的库比较裸,之前只是封装了一个 Connection 来处理调用队列。

本月给 SQLite 增加了连接池类 Pool,接口设计与 mysql 相若,通过它我们可以比较优雅地处理 sqlcipher 这种需要在所有查询之前先执行某些指令来配置 session 的场景:

const Realm = require('leoric');
const realm = new Realm({
  dialect: 'sqlite',
  client: '@journeyapps/sqlcipher',
  database: '/tmp/foo.sqlite3',
}):

// 配置数据库初始化信息
realm.driver.pool.on('connection', function(connection) {
  connection.query('PRAGMA key = "Riddikulus!"');
});

await realm.connect();

此外,我们还完善了 SQLite 调用异常时的调用栈展示逻辑:

  1) => SQLite driver.query()
       should support async stack trace:
     Error: SQLITE_ERROR: no such table: missing
  --> in Database#all('SELECT * FROM missing', undefined, [Function: Leoric_all])
      at /Users/nil/Projects/cyjake/leoric/src/drivers/sqlite/connection.js:48:21
      at new Promise (<anonymous>)
      at Connection.all (src/drivers/sqlite/connection.js:47:12)
      at Connection.query (src/drivers/sqlite/connection.js:39:33)
      at SqliteDriver.query (src/drivers/sqlite/index.js:46:33)
      at async Context.<anonymous> (test/unit/drivers/sqlite/index.test.js:181:7)

​ 推荐阅读本月更新的《SQLite 配置》一文了解更多有关通过 Leoric 操作 SQLite 数据库的帮助信息。​

BINARY、VARBINARY、以及 BLOB 类型

v1.11 新增三种二进制数据类型,目前仅支持在模型中声明、配置属性,在查询结果返回后调用对应的逻辑转换数据,但不支持在查询表达式中通过这几个类型的字段筛选(除非是 IS NULL 之类)。目前支持的使用方式:​

const { Bone, DataTypes } = require('leoric');
const { BLOB, STRING, BIGINT } = DataTypes;

class Attachment extends Bone {
  static attributes = {
    id: BIGINT,
    name: STRING,
    file: BLOB,
  }
}

对象表达式中的逻辑操作符

Leoric 支持使用类似 MongoDB 中的 BSON 语法来编写条件表达式,但之前的支持程度比较有限,比如逻辑操作符只能用比较接近 AST 的方式来写:

await Post.where({
  $or: [
    { title: 'Nephalem' },
    { title: { $like: 'Angel%' },
  ],
});

上述代码等价于:

SELECT * FROM `articles` WHERE `title` = 'Nephalem' OR `title` LIKE 'Angel%';

但有的时候反过来写会更加符合程序员的直觉(效果等同于上面的代码):

await Post.where({
  title: {
    $or: [
      'Nephalem',
      { $like: 'Angel%' },
    ],
  },
});

因此这次我们针对各种调用情况做了重构,不仅支持两种编写方式,也允许条件操作符嵌套。相关调用示例可以参考 QueryObject 的实现和单测文件,详细的使用文档还在编写中。​

更友好的 TypeScript 支持

Leoric 很早就开始提供 d.ts 文件,但经历 v1 重构之后,相关类型声明已经过时,而且和 JSDoc 注释中的类型也没有完全对应。九月份我们小幅重构了 d.ts 文件,并且补上了针对性的单测,确保在 TypeScript 中调用不会有编译问题,感谢 https://github.com/nightink 提交代码。​

目前使用的 TypeScript 测试代码如下:

import * as assert from 'assert';

import Realm, { Bone, DataTypes } from '../../../types/index';

const { STRING, DATE } = DataTypes;

class User extends Bone {
  static attributes = {
    name: STRING,
    created_at: DATE,
    updated_at: DATE,
  }
}

async function main() {
  const userBone = await User.create({ name: 'Stranger' });
  assert.strictEqual(userBone.toJSON().name, userBone.toObject().name);

  const user = await User.first;
  await user.update({ name: 'Tyrael' });

  const realm = new Realm({
    dialect: 'sqlite',
    database: '/tmp/leoric.sqlite3',
  });
  await realm.query('SELECT * FROM sqlite_master');
}

main().catch(err => console.error(err))

了解更多

推荐阅读我们的官方用户手册,或者访问 Leoric 的 Github 发布记录,欢迎试用 Leoric。