Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Jul 31, 2024
1 parent 76fba3e commit 87a5a82
Show file tree
Hide file tree
Showing 22 changed files with 1,345 additions and 104 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/website.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Sample workflow for building and deploying a VitePress site to GitHub Pages
#
name: Deploy FlexTree website to Pages

on:
# Runs on pushes targeting the `main` branch. Change this to `master` if you're
# using the `master` branch as the default branch.
push:
branches: [master]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: pages
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
# - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm
# - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Install pnpm
run:
npm install -g pnpm
- name: Install dependencies
run: pnpm install # or npm ci / yarn install / bun install /
- name: Install turbo
run: pnpm add -w -D turbo
- name: Build packages
run: pnpm build:all
- name: pnpm docs:build
run: |
pnpm docs:build # or npm run docs:build / yarn docs:build / bun run docs:build
touch docs/.vitepress/dist/.nojekyll
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: docs/.vitepress/dist

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
13 changes: 6 additions & 7 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ export default defineConfig({
// https://vitepress.dev/reference/default-theme-config
nav: [
{ text: '首页', link: '/' },
{ text: '指南', link: '/guide' },
{ text: 'API', link: '/api' },
{ text: '指南', link: '/guide' }
],

sidebar: [
{ text: '关于', link: '/intro/about' },
{ text: '快速入门', link: '/intro/get-starts' },
{ text: '快速入门', link: '/intro/get-started' },
{ text: '工作原理', link: '/intro/principle' },
{ text: '常见问题', link: '/intro/question' },
{ text: '更新历史', link: '/intro/history' },
Expand All @@ -42,14 +41,14 @@ export default defineConfig({
{ text: '节点关系', link: '/guide/relation' },
{ text: 'FlexTree', link: '/guide/flextree' },
{ text: '校验', link: '/guide/verify' },
{ text: '多树表', link: '/guide/multitree' },
{ text: '导出', link: '/guide/export' },
{ text: '自定义', link: '/guide/custom' },
{ text: '数据库', link: '/guide/adapters' },
{ text: '自定义', link: '/guide/custom' },
{ text: '多树表', link: '/guide/multitree' },
{ text: '数据库适配', link: '/guide/adapters' },
],
},
{
text: '数据库适配',
text: '适配器',
items: [
{ text: 'Sqlite', link: '/adapters/sqlite' },
{ text: 'Prisma', link: '/adapters/prisma' },
Expand Down
136 changes: 122 additions & 14 deletions docs/guide/adapters.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,134 @@
# 数据库适配器
# 适配器

`FlexTree`本质上就是将对树的查询、删除、移动、更新等操作转换为`SQL`,然后交给数据库引擎去执行。所以`FlexTree`是一个抽象的树存储库,它并不直接操作数据库,而是通过数据库适配器来操作数据库。

## 查询方式
## 适配器接口

`FlexTree`提供了`2`种查询树的方式,包括:
当用户调用`FlexTree`的API后,会调用数据库适配器的方法来操作数据库。数据库适配器是一个实现了`IFlexTreeAdapter`接口的对象,它负责执行`SQL`语句并返回结果。

### 使用FlexTreeManager查询
`IFlexTreeAdapter`接口定义如下:

```ts
interface IFlexTreeAdapter {
// 当数据库打开准备就绪时
ready: boolean
// 绑定树管理器
bind: (treeManager: manager.FlexTreeManager) => void
// 执行sql,并返回结果
exec: (sqls: string | string[]) => Promise<void>
// 执行查询并返回结果
getRows: (sql: string) => Promise<any[]>
// 执行查询并返回标量
getScalar: <T = number>(sql: string) => Promise<T>
open: (config?: any) => Promise<any>
// 返回一个数据库实例对象
db: any
}
```


### ready

当数据库适配器准备就绪时,`ready`属性为`true`,否则为`false`

### bind

`bind`方法用于绑定树管理器,当`FlexTree`创建时,会调用`bind`方法将树管理器绑定到适配器上。

### exec

执行`SQL`语句,`exec`方法接收一个`SQL`语句或`SQL`语句数组,然后执行`SQL`语句。

### getRows

执行查询并返回结果集,`getRows`方法接收一个`SQL`语句,然后执行查询并返回结果集。

### getScalar

执行查询并返回标量,`getScalar`方法接收一个`SQL`语句,然后执行查询并返回标量。


### open

`FlexTree`初始化时,会调用`open`方法打开数据库连接。

### db

返回一个数据库实例对象,仅仅在测试中使用。


## 适配器实现示例

以下是`flextree-sqlite-adapter`的实现代码。

通过核心的`FlexTreeManager`类来执行树的各种查询。

```ts
import type { FlexTreeManager, IFlexTreeAdapter } from 'flextree'
import Database from 'better-sqlite3'

export type SqliteDatabase = Database.Database
export default class SqliteAdapter implements IFlexTreeAdapter {
_db?: SqliteDatabase
_options: Database.Options
_ready: boolean = false
_filename?: string
_treeManager?: FlexTreeManager
constructor(filename?: string, options?: Database.Options) {
this._options = Object.assign({}, options)
this._filename = filename || ':memory:'
}

get ready() { return this._ready }
get db() { return this._db! as SqliteDatabase }
get treeManager() { return this._treeManager! }
get tableName() { return this.treeManager.tableName }
bind(treeManager: FlexTreeManager) {
this._treeManager = treeManager
}
open(options?: Database.Options) {
return new Promise((resolve, reject) => {
try {
this._db = new Database(this._filename, Object.assign({}, this._options, options))
this._ready = true
resolve(this._db)
} catch (e: any) {
this._ready = false
reject(e)
}
})
}

import { FlexTreeManager } from "felxtree"
import SqliteAdapter from 'flextree-sqlite-adapter';
const sqliteAdapter = new SqliteAdapter("org.db")
assertDbIsOpen() {
if (!this.db) {
throw new Error('Sqlite database is not opened.')
}
}

const treeManager = new FlexTreeManager({
adapter: sqliteAdapter
})
async getRows<T>(sql: string): Promise<T[]> {
this.assertDbIsOpen()
return await this.db.prepare<unknown[], T>(sql).all()
}

async getScalar<T>(sql: string): Promise<T> {
this.assertDbIsOpen()
return await this.db.prepare(sql).pluck().get() as T
}

async exec(sqls: string | string[]) {
this.assertDbIsOpen()
if (typeof sqls === 'string') {
sqls = [sqls]
}
const stmts = sqls.map(sql => this.db.prepare(sql))
const trans = this.db.transaction(() => {
for (const stmt of stmts) {
stmt.run()
}
})
trans()
}
}

```

- 通过`FlexTreeManager`实例方法来查询树
- 上例中使用`flextree-sqlite-adapter`来示例如,如果您使用`MySQL``PostgreSQL``MongoDB``Redis`等数据库,可以使用
`prisma`等适配器,只需将`SqliteAdapter`替换为`PrismaAdapter`即可。

67 changes: 67 additions & 0 deletions docs/guide/custom.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,69 @@
# 自定义

`FlexTree`允许自定义关键字段和扩展节点字段。

## 关键字段

`FlexTree`中,默认情况下,每一个节点均具`id``level``leftValue``rightValue``name`这五个关键字段,如果要在一个表中存储多棵树,还需要加上`treeId`字段。


可以通过以下方法自定义关键字段,方法如下:

```ts

const tree = new FlexTreeManager<{},
// 泛型参数:节点扩展字段
{
id:['pk',string], // id字段名称和类型
treeId:['tree',number],
name:string
}
>('tree', {
// 自定义字段名称
fields:{
id:'pk',
treeId:'tree',
name:'title',
leftValue:'lft',
rightValue:"rgt",
level:'lv'
}
})

```

- 以上将`id`字段改为`pk``treeId`字段改为`tree``name`字段改为`title``leftValue`字段改为`lft``rightValue`字段改为`rgt``level`字段改为`lv`
- 通过泛型参数重新声明关键字段的名称和类型。


## 扩展字段


除了`id``level``leftValue``rightValue``name`这五个关键字段,还可以通过第一个泛型参数声明其他字段,比如:

```ts

const tree = new FlexTreeManager<{
size:number
color:string
icon:string
},
// 泛型参数:节点扩展字段
{
id:['pk',string], // id字段名称和类型
treeId:['tree',number],
name:string
}
>('tree', {
// 自定义字段名称
fields:{
id:'pk',
treeId:'tree',
name:'title',
leftValue:'lft',
rightValue:"rgt",
level:'lv'
}
})

```
Loading

0 comments on commit 87a5a82

Please sign in to comment.