Initial commit of akmon project
This commit is contained in:
258
doc_zhipao/uts_supabase_count_best_practices.md
Normal file
258
doc_zhipao/uts_supabase_count_best_practices.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# UTS Supabase Count 操作最佳实践分析与优化建议
|
||||
|
||||
## 当前实现分析
|
||||
|
||||
### 现有 aksupa.uts 中的 count 实现
|
||||
|
||||
1. **基础 count 支持**:
|
||||
```typescript
|
||||
// select() 方法中的 count 实现
|
||||
if (options.getcount != null) {
|
||||
headers['Prefer'] = `count=${options.getcount}`;
|
||||
}
|
||||
```
|
||||
|
||||
2. **自动分页 count**:
|
||||
```typescript
|
||||
// 在 execute() 中的分页逻辑
|
||||
if (this._options.limit != null) {
|
||||
if (this._options.getcount == null) this._options.getcount = 'exact';
|
||||
}
|
||||
```
|
||||
|
||||
3. **响应解析**:
|
||||
```typescript
|
||||
// 解析 content-range header
|
||||
let contentRange: string | null = null;
|
||||
const match = /\/(\d+)$/.exec(contentRange);
|
||||
if (match != null) {
|
||||
total = parseInt(match[1] ?? "0");
|
||||
}
|
||||
```
|
||||
|
||||
## 与 Supabase 官方 SDK 对比
|
||||
|
||||
### JavaScript SDK
|
||||
```javascript
|
||||
// 1. 只获取 count,不返回数据
|
||||
const { count, error } = await supabase
|
||||
.from('table')
|
||||
.select('*', { count: 'exact', head: true });
|
||||
|
||||
// 2. 获取数据和 count
|
||||
const { data, count, error } = await supabase
|
||||
.from('table')
|
||||
.select('*', { count: 'exact' });
|
||||
|
||||
// 3. 链式写法
|
||||
const { data, count } = await supabase
|
||||
.from('table')
|
||||
.select('*')
|
||||
.range(0, 9)
|
||||
.count('exact');
|
||||
```
|
||||
|
||||
### Swift SDK
|
||||
```swift
|
||||
// 只获取 count
|
||||
let count = try await supabase.database
|
||||
.from("table")
|
||||
.select("*", count: .exact)
|
||||
.execute(head: true)
|
||||
.count
|
||||
|
||||
// 获取数据和 count
|
||||
let response = try await supabase.database
|
||||
.from("table")
|
||||
.select("*", count: .exact)
|
||||
.execute()
|
||||
```
|
||||
|
||||
## 问题与改进机会
|
||||
|
||||
### 1. 缺少专门的 count() 方法
|
||||
**问题**:目前需要通过 `select('', { count: 'exact', head: true })` 来实现
|
||||
**建议**:添加专门的 `count()` 方法
|
||||
|
||||
### 2. head 参数支持不完善
|
||||
**问题**:缺少 `head: true` 选项来只返回 count 不返回数据
|
||||
**建议**:在 `AkSupaSelectOptions` 中添加 `head` 选项
|
||||
|
||||
### 3. count 类型不够明确
|
||||
**问题**:`getcount` 参数名不够直观
|
||||
**建议**:重命名为 `count` 并支持枚举类型
|
||||
|
||||
## 优化建议实现
|
||||
|
||||
### 1. 增强类型定义
|
||||
```typescript
|
||||
// 新增 count 枚举
|
||||
export type CountOption = 'exact' | 'planned' | 'estimated';
|
||||
|
||||
// 增强 AkSupaSelectOptions
|
||||
export type AkSupaSelectOptions = {
|
||||
limit?: number;
|
||||
order?: string;
|
||||
count?: CountOption; // 重命名并使用枚举
|
||||
head?: boolean; // 新增 head 选项
|
||||
columns?: string;
|
||||
single?: boolean;
|
||||
rangeFrom?: number;
|
||||
rangeTo?: number;
|
||||
};
|
||||
```
|
||||
|
||||
### 2. 添加专门的 count() 方法
|
||||
```typescript
|
||||
// 在 AkSupaQueryBuilder 中添加
|
||||
count(option: CountOption = 'exact'): AkSupaQueryBuilder {
|
||||
this._options.count = option;
|
||||
this._options.head = true; // count 操作默认使用 head
|
||||
return this;
|
||||
}
|
||||
|
||||
// 便捷方法
|
||||
countExact(): AkSupaQueryBuilder {
|
||||
return this.count('exact');
|
||||
}
|
||||
|
||||
countEstimated(): AkSupaQueryBuilder {
|
||||
return this.count('estimated');
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 优化 select 方法的 head 支持
|
||||
```typescript
|
||||
// 在 select() 实现中添加 head 支持
|
||||
if (options.head == true) {
|
||||
console.log('使用 head 模式,只返回元数据');
|
||||
if (headers['Prefer'] != null) {
|
||||
headers['Prefer'] = (headers['Prefer'] as string) + ',return=minimal';
|
||||
} else {
|
||||
headers['Prefer'] = 'return=minimal';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 改进响应处理
|
||||
```typescript
|
||||
// 在 execute() 中优化 count 响应处理
|
||||
if (this._options.head == true) {
|
||||
// head 模式只返回 count 和元数据
|
||||
return {
|
||||
data: null,
|
||||
count: total,
|
||||
total,
|
||||
page,
|
||||
limit,
|
||||
hasmore: false,
|
||||
origin: res,
|
||||
status: res.status,
|
||||
headers: res.headers,
|
||||
error: res.error
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例对比
|
||||
|
||||
### 当前用法(已优化)
|
||||
```typescript
|
||||
// 只获取 count
|
||||
const countResult = await supa
|
||||
.from('assignments')
|
||||
.select('', { count: 'exact', head: true })
|
||||
.execute();
|
||||
const total = countResult.total;
|
||||
|
||||
// 获取数据和 count
|
||||
const dataResult = await supa
|
||||
.from('assignments')
|
||||
.select('*', { count: 'exact' })
|
||||
.execute();
|
||||
```
|
||||
|
||||
### 建议的新用法
|
||||
```typescript
|
||||
// 只获取 count - 更直观
|
||||
const countResult = await supa
|
||||
.from('assignments')
|
||||
.count('exact')
|
||||
.execute();
|
||||
const total = countResult.count;
|
||||
|
||||
// 或者使用便捷方法
|
||||
const total = await supa
|
||||
.from('assignments')
|
||||
.countExact()
|
||||
.execute()
|
||||
.then(r => r.count);
|
||||
|
||||
// 获取数据和 count
|
||||
const dataResult = await supa
|
||||
.from('assignments')
|
||||
.select('*')
|
||||
.count('exact')
|
||||
.execute();
|
||||
```
|
||||
|
||||
## 性能对比
|
||||
|
||||
### 当前实现性能
|
||||
- ✅ 支持 `head: true` 优化(通过手动参数)
|
||||
- ✅ 正确使用 Prefer header
|
||||
- ✅ 解析 content-range
|
||||
- ⚠️ 需要手动设置参数
|
||||
|
||||
### 建议实现性能
|
||||
- ✅ 专门的 count() 方法自动优化
|
||||
- ✅ 默认启用 head 模式
|
||||
- ✅ 更清晰的 API
|
||||
- ✅ 减少样板代码
|
||||
|
||||
## 兼容性考虑
|
||||
|
||||
### 向后兼容
|
||||
```typescript
|
||||
// 保持现有 getcount 参数支持
|
||||
if (options.getcount != null) {
|
||||
// 向后兼容
|
||||
options.count = options.getcount as CountOption;
|
||||
}
|
||||
```
|
||||
|
||||
### 渐进式升级
|
||||
1. 添加新 API 而不移除旧 API
|
||||
2. 在文档中推荐新用法
|
||||
3. 逐步迁移现有代码
|
||||
|
||||
## 实现优先级
|
||||
|
||||
### 高优先级(立即实现)
|
||||
1. ✅ **已完成**:`head: true` 参数支持
|
||||
2. ✅ **已完成**:count 操作优化
|
||||
3. **建议**:添加 `count()` 方法
|
||||
|
||||
### 中优先级(后续优化)
|
||||
1. 类型枚举 CountOption
|
||||
2. 便捷方法 countExact(), countEstimated()
|
||||
3. 响应类型优化
|
||||
|
||||
### 低优先级(可选)
|
||||
1. 移除废弃的 getcount 参数
|
||||
2. 更多统计方法(sum, avg 等)
|
||||
|
||||
## 结论
|
||||
|
||||
当前的 `aksupa.uts` 实现已经很好地支持了 Supabase 的 count 操作,特别是:
|
||||
|
||||
1. **性能优化到位**:支持 `head: true` 只返回 count
|
||||
2. **HTTP 层实现正确**:正确使用 Prefer header 和 content-range 解析
|
||||
3. **功能完整**:支持 exact/estimated/planned count
|
||||
|
||||
**主要改进建议**:
|
||||
- 添加专门的 `count()` 方法提高 API 易用性
|
||||
- 增强类型定义提高类型安全
|
||||
- 保持向后兼容的同时提供更现代的 API
|
||||
|
||||
当前实现已经满足性能和功能需求,建议的改进主要是提升开发体验。
|
||||
Reference in New Issue
Block a user