功能:添加可空字段和标签格式支持

- 实现可空字段(nullable)功能
  - 支持 *int, *string 等指针类型
  - 添加 nullable 示例程序
  - 完善可空字段验证测试
- 添加标签格式(tag format)支持
  - 支持自定义字段标签
  - 添加 tag_format 示例程序
  - 增强 Schema 标签解析能力
- 优化 Schema 和 SSTable 处理逻辑
- 添加诊断工具测试用例
This commit is contained in:
2025-10-10 14:00:34 +08:00
parent fc1ad9832d
commit 8d750505fb
6 changed files with 1131 additions and 12 deletions

View File

@@ -247,30 +247,51 @@ func StructToFields(v any) ([]Field, error) {
comment := ""
if tag != "" {
// 使用分号分隔各部分
parts := strings.Split(tag, ";")
// 使用分号分隔各部分,与顺序无关
parts := strings.SplitSeq(tag, ";")
for idx, part := range parts {
for part := range parts {
part = strings.TrimSpace(part)
if part == "" {
continue
}
if idx == 0 && part != "" {
// 第一部分是字段名
fieldName = part
// 检查是否为 key:value 格式
if after, ok := strings.CutPrefix(part, "field:"); ok {
// field:字段名
fieldName = after
} else if after, ok := strings.CutPrefix(part, "comment:"); ok {
// comment:注释内容
comment = after
} else if part == "indexed" {
// indexed 标记
indexed = true
} else if part == "nullable" {
// nullable 标记
nullable = true
} else if after, ok := strings.CutPrefix(part, "comment:"); ok {
// comment:注释内容
comment = after
}
}
}
// 检测实际类型(处理指针类型)
actualType := field.Type
isPointer := false
// 检测指针类型 (*string, *int64, etc.)
if actualType.Kind() == reflect.Pointer {
isPointer = true
nullable = true // 指针类型自动推断为 nullable
actualType = actualType.Elem()
}
// 验证:如果 tag 显式标记了 nullable字段必须是指针类型
if nullable && !isPointer {
return nil, fmt.Errorf("field %s: nullable tag requires pointer type (e.g., *%s instead of %s)",
field.Name, actualType.String(), actualType.String())
}
// 映射 Go 类型到 FieldType
fieldType, err := goTypeToFieldType(field.Type)
fieldType, err := goTypeToFieldType(actualType)
if err != nil {
return nil, fmt.Errorf("field %s: %w", field.Name, err)
}