如何将文本列的值指定为字符串联合类型?

huangapple go评论65阅读模式
英文:

How to specify a text column's value as a string union?

问题

我有一个名为Document的结构体:

type Document struct {
	ID               entity.EntityID
	Type             string
	ContentType      files.MIMEType
	URL              string
	UploadedByUserID entity.EntityID
	CreatedAt        time.Time
}

type MIMEType string

const (
	MIMETypeJPG MIMEType = "image/jpeg"
	MIMETypePDF MIMEType = "application/pdf"
	MIMETypePNG MIMEType = "image/png"
	MIMETypeTXT MIMEType = "text/plain"
)

它映射到一个名为documents的表,其中ContentType列的类型为varchar(1024)

create table documents(
    id bigint not null default nextval('documents_id_seq') PRIMARY KEY,
    url varchar(1024) not null,
    type varchar(1024) not null,
    content_type varchar(1024) not null,
    uploaded_by_user_id bigint,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP not null
);

当我使用Create(&d),其中d是一个Document实例时,会出现错误:

[2.530ms] [rows:1] INSERT INTO "documents" ("type","content_type","url","uploaded_by_user_id","created_at") VALUES ('other_freight','image/png','https://lateralline-documents-dev.s3.us-west-2.amazonaws.com/doc-other_freight-2021_08_25__11_15_13_379569000.png','253608954016301056','2021-08-25 11:15:13.82') RETURNING "id"
interface conversion: interface {} is files.MIMEType, not string

我想告诉gorm,当我读取和写入documents.content_type字段时,它不仅仅是一个任意的字符串,而应该是一个files.MIMEType值。有没有办法做到这一点?我在其他ORM中看到过这种功能。

英文:

I have a struct Document:

type Document struct {
	ID               entity.EntityID
	Type             string
	ContentType      files.MIMEType
	URL              string
	UploadedByUserID entity.EntityID
	CreatedAt        time.Time
}

type MIMEType string

const (
	MIMETypeJPG MIMEType = "image/jpeg"
	MIMETypePDF MIMEType = "application/pdf"
	MIMETypePNG MIMEType = "image/png"
	MIMETypeTXT MIMEType = "text/plain"
)

It maps to a documents table where the ContentType column is of type varchar(1024):

create table documents(
    id bigint not null default nextval('documents_id_seq') PRIMARY KEY,
    url varchar(1024) not null,
    type varchar(1024) not null,
    content_type varchar(1024) not null,
    uploaded_by_user_id bigint,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP not null
);

Create(&d) where d is a Document instance gives me an error:

[2.530ms] [rows:1] INSERT INTO "documents" ("type","content_type","url","uploaded_by_user_id","created_at") VALUES ('other_freight','image/png','https://lateralline-documents-dev.s3.us-west-2.amazonaws.com/doc-other_freight-2021_08_25__11_15_13_379569000.png','253608954016301056','2021-08-25 11:15:13.82') RETURNING "id"
interface conversion: interface {} is files.MIMEType, not string

I want to tell gorm that when I read and write the documents.content_type field it is not just an arbitrary string, it should be a files.MIMEType value. Is there a way to do this? I've seen this functionality in other ORMs.

答案1

得分: 1

你可能想要查看go-gorm中的自定义类型(或查看这个答案)。

简而言之,你需要为你的MIMEType结构实现ScannerValuer接口。

func (m *MIMEType) Scan(value interface{}) error {
  val, ok := value.(string)
  if !ok {
    return errors.New(fmt.Sprint("Failed to unmarshal string value:", value))
  }
  
  *m = MIMEType(val)
  return nil
}

func (m MIMEType) Value() (driver.Value, error) {
  return string(m), nil
}
英文:

You might want to check out the custom types in go-gorm (or check this answer).

In short, you would need to implement the Scanner and Valuer interfaces for your MIMEType struct.

func (m *MIMEType) Scan(value interface{}) error {
  val, ok := value.(string)
  if !ok {
    return errors.New(fmt.Sprint("Failed to unmarshal string value:", value))
  }
  
  *m = MIMEType(val)
  return nil
}

func (m MIMEType) Value() (driver.Value, error) {
  return string(m), nil
}

huangapple
  • 本文由 发表于 2021年8月26日 02:23:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/68928083.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定