0.0.2 • Published 3 years ago

typeq v0.0.2

Weekly downloads
-
License
ISC
Repository
github
Last release
3 years ago

type

简单、易用的轻量级 ORM ,适用于 Postgresql 和 CockroachDB 数据库。

特性

  • 基于 pg 模块开发,兼容 pg 模块;

  • 支持为 JSON、JSONB 类型的字段建模,提供对 JSON 数据结构的深度校验与 SQL 合成;

  • 支持自动为 JSONB 数组、对象类型创建独立的自增序列,为嵌套数据提供唯一索引;

  • 支持数据模型、客户端分离设计模式,为分布式、多数据库、多租户场景提供更灵活的模型切换与复用支持;

  • 支持数据模型与数据库客户端分离部署,在 Serverless 环境下,可降低冷启动延时,并提高连接池的复用率;

  • 支持创建虚拟模型,即在已有的数据模型基础上创建新的虚拟模型,用于将单表或多表映射、裁切为新的表模型;

  • 支持表结构同步,通过数据模型将字段类型、索引等信息同步至实体表;

  • 保留了类似 SQL 的语法特征,使用函数链风格的查询表达式,简洁、直观、易于读写;

  • 支持扩展自定义运算符函数、自定义数据类型验证器;

为什么要做这个项目?

由于主流 ORM 倾向于广泛兼容各种类型的数据库,但是受 SQL 语法兼容性、复杂性、数据库版本差异等诸多因素的影响,不得不在功能和兼容性之间做出取舍,也只能做到跨平台一部分代码兼容。在实际应用中,很多通用 ORM 在面对某些复杂的或边缘查询用例时可读性差,代码看起来也显得很鸡肋。因此,typeq 不打算追求大而全,未来将专注于以 Postgresql 数据库作为主要的适配目标,优化常见的高频查询用例,期望在性能和开发体验之间找到合适的平衡点,对于复杂用例建议使用 SQL 查询。

Install

npm install typeq

Example

import { Schema, Model, queue, operator } from "typepg";
import pgclient from 'typepg/pgclient';

queue.use(pgclient({
   default: {
      host: 'localhost',
      database: 'demo',
      username: 'postgres',
      password: '******',
      port: 5432,
      logger: true,
   }
}));

const { integer, string, boolean, email, jsonb } = Schema.types;

// 定义表字段模型
const schema = new Schema({
   'id': integer({ primaryKey": true }),
   'uid': integer,
   'keywords': {
      'state': boolean,
      'area': string,
      "createdAt": timestamp,
   },
   'list': [{
      'id': integer({ sequence: true }),
      'state': boolean,
      'address': [{
         'id': integer({ sequence: true }),
         'name': string,
         'createdAt': timestamp({ default: 'now()' }),
         'updatedAt': timestamp({ default: 'now()' }),
      }],
      'test': {
        'state': boolean,
         'name': string,
      },
      'createdAt': timestamp({ default: 'now()' }),
      'updatedAt': timestamp({ default: 'now()' }),
   }],
   "area": string,
   'state': boolean({ 'default': true }),
   'modes': jsonb,
   'email': email,
   "createdAt": timestamp({ default: 'now()' }),
   "updatedAt": timestamp({ default: 'now()' }),
});

const tasks = new Model('tasks', schema); // 将模型添加至客户端实例

const { $as, $in } = operator; // 查询操作符

// 基于数据模型的结构化查询
const result = await tasks
   .select('id', 'email', 'keywords', $as("uid", "tid"))
   .where({ id: $in(50, 51) })
   .and({ keywords: {} })
   .or({ id: 5 })
   .order({
      "id": "desc",
      "uid": "desc"
   })
   .limit(10);

连接数据库

配置参数与 pg 模块兼容,更多参数细节请参考 node-postgres 文档

import { queue } from "typepg";
import pgclient from "typepg/pgclient";

queue.use(
  pgclient({
    default: {
      host: string, // 主机名
      database: string, // 数据库名
      username: string, // 用户名
      password: string, // 密码
      port: number, // 端口
      logger: boolean, // 打印 sql 日志,可选
      connectionString: string, // 字符串连接参数,可选
    },
  })
);

添加模型

const model = new Model(name: string, model: object);
  • name String - 模型名称
  • model Object - 模型

模型同步

模型与数据库表之间支持三种同步模式:

默认模式

无参数时会尝试创建新的数据表,当指定的表已存在时请求被拒绝,不做任何操作。

client().sync("public.user");

增量模式

在已有表上新增字段,该模式只会添加新的列,不改变已有列和数据。

client().sync("user", "increment");

重置模式(危险)

删除已有的数据表重新构建表结构。

示例

// 同步 schema 为public下的 user 表
client().sync("public.user");

// 使用重构模式,删除并重建 user 表(未指定 schema,默认为 public)
client().sync("public.user", "rebuild");

// 使用批量增量模式,批量同步 public.admin 下所有的表
client().syncAll("public.admin", "rebuild");

批量同步指定 public 中的所有模型

client().syncAll("public", "increment");

函数链

函数链提供了一种更加便捷、严谨和安全的 sql 编码方式,主要目的是尽可能避免 SQL 注入。

insert 函数链

model.insert(data)

插入新数据

find 函数链

model.find(and)

  • and Object - and 过滤条件

查询多条记录

model.findOne(and)

  • and Object - and 过滤条件

查询单条记录

model.findPk(id)

  • id Number - 主键 id

查询主键 id

model.order(options)

  • options Object - 排序字段

model.offset(value)

  • value Number - 限定查询结果的起始位置

model.limit(value)

  • value Number - 限制返回结果数量

update 函数链

model.update(data)

更新数据

model.updateMerge(data)

更新数据,用合并的方式更新 json、jsonb 类型

model.updatePk(id, data)

更新指定主键的数据

delete 函数链

model.delete(options)

删除多条数据

model.deletePk(id)

删除指定主键的数据

通用函数链

逻辑函数链 where(options).and(options).or(options)

逻辑函数链同时适用于 find、update、delete 操作。支持多个 options 参数,每个 options 内的子节点之间为 and 关系,options 与 options 之间为 or 关系

该设计方案的优点是结构简单、逻辑清晰、易解析。缺点是仅支持双层嵌套逻辑关系,但可满足大多数逻辑应用场景。

  • options Object - and 条件集合
model.where(options, ...).or(options, ...).and(options, ...);

return()、noReturn()

增删改查操作均支持 return()、noReturn()函数,用于定义返回列

操作符函数

查询函数

用于 options.where 属性中,作为数据筛选条件,包含逻辑运算符、比较运算符等。

原生 sql 运算符

Op.$sql()

添加原生 sql 子句,内置单引号转义。

比较运算符

Op.$eq()

Op.$ne()

Op.$gte()

Op.$gt()

Op.$lte()

Op.$lt()

其它操作符

Op.$not()

Op.$is()

Op.$in()

Op.$notIn()

Op.$like()

Op.$notIn()

Op.$notLike()

Op.$iLike()

Op.$notILike()

Op.$regexp()

Op.$regexp()

Op.$regexp()

Op.$regexp()

Op.$notRegexp()

Op.$iRegexp()

Op.$notIRegexp()

Op.$between()

Op.$notBetween()

Op.$overlap()

Op.$contains()

Op.$contained()

Op.$adjacent()

Op.$strictLeft()

Op.$strictRight()

Op.$noExtendRight()

Op.$noExtendLeft()

Op.$any()

Op.$all()

Op.$values()

Op.$col()

Op.$placeholder()

Op.$join()

Op.$raw()

Update 函数

用于 json 类型数据的插入、合并、删除操作

Op.$merge()

Op.$set()

Op.$insert()

Op.$insertByPath()

Op.$insertFirst()