6.1 KiB
6.1 KiB
UTS Supabase Count 操作最佳实践分析与优化建议
当前实现分析
现有 aksupa.uts 中的 count 实现
-
基础 count 支持:
// select() 方法中的 count 实现 if (options.getcount != null) { headers['Prefer'] = `count=${options.getcount}`; } -
自动分页 count:
// 在 execute() 中的分页逻辑 if (this._options.limit != null) { if (this._options.getcount == null) this._options.getcount = 'exact'; } -
响应解析:
// 解析 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
// 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
// 只获取 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. 增强类型定义
// 新增 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() 方法
// 在 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 支持
// 在 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. 改进响应处理
// 在 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
};
}
使用示例对比
当前用法(已优化)
// 只获取 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();
建议的新用法
// 只获取 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
- ✅ 减少样板代码
兼容性考虑
向后兼容
// 保持现有 getcount 参数支持
if (options.getcount != null) {
// 向后兼容
options.count = options.getcount as CountOption;
}
渐进式升级
- 添加新 API 而不移除旧 API
- 在文档中推荐新用法
- 逐步迁移现有代码
实现优先级
高优先级(立即实现)
- ✅ 已完成:
head: true参数支持 - ✅ 已完成:count 操作优化
- 建议:添加
count()方法
中优先级(后续优化)
- 类型枚举 CountOption
- 便捷方法 countExact(), countEstimated()
- 响应类型优化
低优先级(可选)
- 移除废弃的 getcount 参数
- 更多统计方法(sum, avg 等)
结论
当前的 aksupa.uts 实现已经很好地支持了 Supabase 的 count 操作,特别是:
- 性能优化到位:支持
head: true只返回 count - HTTP 层实现正确:正确使用 Prefer header 和 content-range 解析
- 功能完整:支持 exact/estimated/planned count
主要改进建议:
- 添加专门的
count()方法提高 API 易用性 - 增强类型定义提高类型安全
- 保持向后兼容的同时提供更现代的 API
当前实现已经满足性能和功能需求,建议的改进主要是提升开发体验。