Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag "omitempty" to avoid passing zero values #260

Open
dgellow opened this issue Oct 28, 2020 · 1 comment
Open

Tag "omitempty" to avoid passing zero values #260

dgellow opened this issue Oct 28, 2020 · 1 comment

Comments

@dgellow
Copy link

dgellow commented Oct 28, 2020

Is your feature request related to a problem? Please describe.

I have a postgres table with a column of type serial (which is not the primary key, if that matters).

Suppose I have a reform type:

//reform:files
type File struct {
	ID    string `reform:"id,pk"`
	IncID int64  `reform:"inc_id"` // <== column of type 'serial'
}

I then insert it using this way:

record := MyRecord{
  ID: myID,
}
err := db.Insert(&record)

Here I would like the value for inc_id to be ignored during INSERT statements as I would like to use the column default (i.e: the next value of the serial's sequence). Unfortunately when using the Go zero value reform does the insert with the actual value 0. The result in a row with the column set to 0 instead of the result of Postgres' nextval().

Describe the solution you'd like

I would like to be able to mark a field as reform:"inc_id,omitempty", similar to what the official json package does. When the tag "omitempty" is present, reform will not pass the field during calls to Insertor Update.

Given this reform type:

//reform:files
type File struct {
	ID    string `reform:"id,pk"`
	IncID int64  `reform:"inc_id,omitempty"` // <== column of type 'serial'
}

And this insert:

record := MyRecord{
  ID: 123,
}
err := db.Insert(&record)

Something equivalent to the following SQL code should be generated:

INSERT INTO (id) values (123) RETURNING id, inc_id

Describe alternatives you've considered

Other options:

  1. We could use a tag readonly instead, that would specify that the column is never passed during UPDATE or INSERT, but is used for SELECT, without a need for logic based on zero values.

  2. What I would like is currently possible this way:

cols := record.Table().Columns()
i := 0
for i = range cols {
	if cols[i] == "inc_id" {
		break
	}
}
cols = append(cols[:i], cols[i+1:]...)
err := tx.InsertColumns(&record, cols...)

So an alternative that doesn't require to add new tags would be to add a method InsertWithout(&record, "inc_id") that would do the opposite of InsertColumns (insert everything but the specified columns).

@AlekSi
Copy link
Member

AlekSi commented Feb 2, 2022

#146 (comment)

readonly tag sounds interesting…

The last option is covered by #100.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants