태그 값 추출 연습

w00j00ng351·2023년 4월 24일

Go

목록 보기
4/6
  • 참조: src/reflect/types.go (go 1.20.3) (Copyright 2009 The Go Authors. All rights reserved.)

내용

  • 구조체 태그 값에서 gorm 에 관련된 특정 값 추출

코드

package main

import (
	"log"
	"strconv"
	"strings"
)

// src/reflect/types.go (go 1.20.3) (Copyright 2009 The Go Authors. All rights reserved.)
func ParseTag(tag string, key string) string {
	// When modifying this code, also update the validateStructTag code
	// in cmd/vet/structtag.go.

	for tag != "" {
		// Skip leading space.
		i := 0
		for i < len(tag) && tag[i] == ' ' {
			i++
		}
		tag = tag[i:]
		if tag == "" {
			break
		}

		// Scan to colon. A space, a quote or a control character is a syntax error.
		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
		// as it is simpler to inspect the tag's bytes than the tag's runes.
		i = 0
		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
			i++
		}
		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
			break
		}
		name := string(tag[:i])
		tag = tag[i+1:]

		// Scan quoted string to find value.
		i = 1
		for i < len(tag) && tag[i] != '"' {
			if tag[i] == '\\' {
				i++
			}
			i++
		}
		if i >= len(tag) {
			break
		}
		qvalue := string(tag[:i+1])
		tag = tag[i+1:]

		if key == name {
			value, err := strconv.Unquote(qvalue)
			if err != nil {
				break
			}
			return value
		}
	}
	return ""
}

func GetGormTagValue(tag string, key string) string {
	gormTagValues := ParseTag(tag, "gorm")
	if gormTagValues == "" {
		return ""
	}
	for _, gormTagValue := range strings.Split(gormTagValues, ";") {
		gormTagValueKeyValue := strings.Split(gormTagValue, ":")
		if len(gormTagValueKeyValue) < 2 {
			continue
		}
		value := gormTagValueKeyValue[1]
		if key != gormTagValueKeyValue[0] {
			continue
		}
		return value
	}
	return ""
}

func GetColumnNameFromGormTag(tag string) string {
	return GetGormTagValue(tag, "column")
}

func GetColumnTypeFromGormTag(tag string) string {
	return GetGormTagValue(tag, "type")
}

func main() {
	log.SetFlags(0)

	exampleTags := []string{
		`gorm:"column:col1;type:TEXT"`,
		`gorm:"type:INTEGER;column:col2"`,
		`gorm:"column:col3"`,
		`gorm:"type:BOOLEAN"`,
		`gorm:"foreignKey:ID;references:ParentID"`,
	}

	for _, e := range exampleTags {
		log.Println(GetColumnNameFromGormTag(e), GetColumnTypeFromGormTag(e))
	}
}
  • 출력 결과
col1 TEXT
col2 INTEGER
col3 
 BOOLEAN
 
profile
시간이 만든 코드

0개의 댓글