Files
akmon/doc_zhipao/uts_supabase_count_best_practices.md
2026-01-20 08:04:15 +08:00

6.1 KiB
Raw Permalink Blame History

UTS Supabase Count 操作最佳实践分析与优化建议

当前实现分析

现有 aksupa.uts 中的 count 实现

  1. 基础 count 支持

    // select() 方法中的 count 实现
    if (options.getcount != null) {
        headers['Prefer'] = `count=${options.getcount}`;
    }
    
  2. 自动分页 count

    // 在 execute() 中的分页逻辑
    if (this._options.limit != null) {
        if (this._options.getcount == null) this._options.getcount = 'exact';
    }
    
  3. 响应解析

    // 解析 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;
}

渐进式升级

  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

当前实现已经满足性能和功能需求,建议的改进主要是提升开发体验。