Omitempty
This commit is contained in:
parent
9b3743e79a
commit
4b8a5475a6
3 changed files with 183 additions and 84 deletions
1
Makefile
1
Makefile
|
@ -25,6 +25,7 @@ generate:
|
||||||
sqlc generate -f sql/sqlc.yaml
|
sqlc generate -f sql/sqlc.yaml
|
||||||
protoc -I=pkg/pb/ --go_out=pkg/ pkg/pb/stillbox.proto
|
protoc -I=pkg/pb/ --go_out=pkg/ pkg/pb/stillbox.proto
|
||||||
go generate ./...
|
go generate ./...
|
||||||
|
go run ./util/omitempty/omitempty.go
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
golangci-lint run
|
golangci-lint run
|
||||||
|
|
|
@ -14,115 +14,115 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Alert struct {
|
type Alert struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
Time pgtype.Timestamptz `json:"time"`
|
Time pgtype.Timestamptz `json:"time,omitempty"`
|
||||||
TGID int `json:"tgid"`
|
TGID int `json:"tgid,omitempty"`
|
||||||
SystemID int `json:"system_id"`
|
SystemID int `json:"system_id,omitempty"`
|
||||||
Weight *float32 `json:"weight"`
|
Weight *float32 `json:"weight,omitempty"`
|
||||||
Score *float32 `json:"score"`
|
Score *float32 `json:"score,omitempty"`
|
||||||
OrigScore *float32 `json:"orig_score"`
|
OrigScore *float32 `json:"orig_score,omitempty"`
|
||||||
Notified bool `json:"notified"`
|
Notified bool `json:"notified,omitempty"`
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApiKey struct {
|
type ApiKey struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
Owner int `json:"owner"`
|
Owner int `json:"owner,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
Expires pgtype.Timestamp `json:"expires"`
|
Expires pgtype.Timestamp `json:"expires,omitempty"`
|
||||||
Disabled *bool `json:"disabled"`
|
Disabled *bool `json:"disabled,omitempty"`
|
||||||
ApiKey string `json:"api_key"`
|
ApiKey string `json:"api_key,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Call struct {
|
type Call struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id,omitempty"`
|
||||||
Submitter *int32 `json:"submitter"`
|
Submitter *int32 `json:"submitter,omitempty"`
|
||||||
System int `json:"system"`
|
System int `json:"system,omitempty"`
|
||||||
Talkgroup int `json:"talkgroup"`
|
Talkgroup int `json:"talkgroup,omitempty"`
|
||||||
CallDate pgtype.Timestamptz `json:"call_date"`
|
CallDate pgtype.Timestamptz `json:"call_date,omitempty"`
|
||||||
AudioName *string `json:"audio_name"`
|
AudioName *string `json:"audio_name,omitempty"`
|
||||||
AudioBlob []byte `json:"audio_blob"`
|
AudioBlob []byte `json:"audio_blob,omitempty"`
|
||||||
Duration *int32 `json:"duration"`
|
Duration *int32 `json:"duration,omitempty"`
|
||||||
AudioType *string `json:"audio_type"`
|
AudioType *string `json:"audio_type,omitempty"`
|
||||||
AudioUrl *string `json:"audio_url"`
|
AudioUrl *string `json:"audio_url,omitempty"`
|
||||||
Frequency int `json:"frequency"`
|
Frequency int `json:"frequency,omitempty"`
|
||||||
Frequencies []int `json:"frequencies"`
|
Frequencies []int `json:"frequencies,omitempty"`
|
||||||
Patches []int `json:"patches"`
|
Patches []int `json:"patches,omitempty"`
|
||||||
TGLabel *string `json:"tg_label"`
|
TGLabel *string `json:"tg_label,omitempty"`
|
||||||
TGAlphaTag *string `json:"tg_alpha_tag"`
|
TGAlphaTag *string `json:"tg_alpha_tag,omitempty"`
|
||||||
TGGroup *string `json:"tg_group"`
|
TGGroup *string `json:"tg_group,omitempty"`
|
||||||
Source int `json:"source"`
|
Source int `json:"source,omitempty"`
|
||||||
Transcript *string `json:"transcript"`
|
Transcript *string `json:"transcript,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Incident struct {
|
type Incident struct {
|
||||||
ID uuid.UUID `json:"id"`
|
ID uuid.UUID `json:"id,omitempty"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name,omitempty"`
|
||||||
Description *string `json:"description"`
|
Description *string `json:"description,omitempty"`
|
||||||
StartTime pgtype.Timestamp `json:"start_time"`
|
StartTime pgtype.Timestamp `json:"start_time,omitempty"`
|
||||||
EndTime pgtype.Timestamp `json:"end_time"`
|
EndTime pgtype.Timestamp `json:"end_time,omitempty"`
|
||||||
Location []byte `json:"location"`
|
Location []byte `json:"location,omitempty"`
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IncidentsCall struct {
|
type IncidentsCall struct {
|
||||||
IncidentID uuid.UUID `json:"incident_id"`
|
IncidentID uuid.UUID `json:"incident_id,omitempty"`
|
||||||
CallID uuid.UUID `json:"call_id"`
|
CallID uuid.UUID `json:"call_id,omitempty"`
|
||||||
Notes []byte `json:"notes"`
|
Notes []byte `json:"notes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Setting struct {
|
type Setting struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name,omitempty"`
|
||||||
UpdatedBy *int32 `json:"updated_by"`
|
UpdatedBy *int32 `json:"updated_by,omitempty"`
|
||||||
Value []byte `json:"value"`
|
Value []byte `json:"value,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type System struct {
|
type System struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Talkgroup struct {
|
type Talkgroup struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
SystemID int32 `json:"system_id"`
|
SystemID int32 `json:"system_id,omitempty"`
|
||||||
TGID int32 `json:"tgid"`
|
TGID int32 `json:"tgid,omitempty"`
|
||||||
Name *string `json:"name"`
|
Name *string `json:"name,omitempty"`
|
||||||
AlphaTag *string `json:"alpha_tag"`
|
AlphaTag *string `json:"alpha_tag,omitempty"`
|
||||||
TGGroup *string `json:"tg_group"`
|
TGGroup *string `json:"tg_group,omitempty"`
|
||||||
Frequency *int32 `json:"frequency"`
|
Frequency *int32 `json:"frequency,omitempty"`
|
||||||
Metadata jsontypes.Metadata `json:"metadata"`
|
Metadata jsontypes.Metadata `json:"metadata,omitempty"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
Alert bool `json:"alert"`
|
Alert bool `json:"alert,omitempty"`
|
||||||
AlertConfig rules.AlertRules `json:"alert_config"`
|
AlertConfig rules.AlertRules `json:"alert_config,omitempty"`
|
||||||
Weight float32 `json:"weight"`
|
Weight float32 `json:"weight,omitempty"`
|
||||||
Learned bool `json:"learned"`
|
Learned bool `json:"learned,omitempty"`
|
||||||
Ignored bool `json:"ignored"`
|
Ignored bool `json:"ignored,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TalkgroupVersion struct {
|
type TalkgroupVersion struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
Time pgtype.Timestamptz `json:"time"`
|
Time pgtype.Timestamptz `json:"time,omitempty"`
|
||||||
CreatedBy *int32 `json:"created_by"`
|
CreatedBy *int32 `json:"created_by,omitempty"`
|
||||||
SystemID *int32 `json:"system_id"`
|
SystemID *int32 `json:"system_id,omitempty"`
|
||||||
TGID *int32 `json:"tgid"`
|
TGID *int32 `json:"tgid,omitempty"`
|
||||||
Name *string `json:"name"`
|
Name *string `json:"name,omitempty"`
|
||||||
AlphaTag *string `json:"alpha_tag"`
|
AlphaTag *string `json:"alpha_tag,omitempty"`
|
||||||
TGGroup *string `json:"tg_group"`
|
TGGroup *string `json:"tg_group,omitempty"`
|
||||||
Frequency *int32 `json:"frequency"`
|
Frequency *int32 `json:"frequency,omitempty"`
|
||||||
Metadata []byte `json:"metadata"`
|
Metadata []byte `json:"metadata,omitempty"`
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
Alert *bool `json:"alert"`
|
Alert *bool `json:"alert,omitempty"`
|
||||||
AlertConfig []byte `json:"alert_config"`
|
AlertConfig []byte `json:"alert_config,omitempty"`
|
||||||
Weight *float32 `json:"weight"`
|
Weight *float32 `json:"weight,omitempty"`
|
||||||
Learned *bool `json:"learned"`
|
Learned *bool `json:"learned,omitempty"`
|
||||||
Ignored *bool `json:"ignored"`
|
Ignored *bool `json:"ignored,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id,omitempty"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username,omitempty"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password,omitempty"`
|
||||||
Email string `json:"email"`
|
Email string `json:"email,omitempty"`
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"is_admin,omitempty"`
|
||||||
Prefs []byte `json:"prefs"`
|
Prefs []byte `json:"prefs,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
98
util/omitempty/omitempty.go
Normal file
98
util/omitempty/omitempty.go
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// This is here until https://github.com/sqlc-dev/sqlc/pull/3117 is merged.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"go/ast"
|
||||||
|
"go/format"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const filePath = "./pkg/database/models.go"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Parse the source code
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
f, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the AST
|
||||||
|
ast.Inspect(f, func(n ast.Node) bool {
|
||||||
|
switch x := n.(type) {
|
||||||
|
case *ast.StructType:
|
||||||
|
for _, field := range x.Fields.List {
|
||||||
|
if field.Tag == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if field.Tag.Value == "" || field.Tag.Kind != token.STRING {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
field.Tag.Value = modifyJSONTag(field.Tag.Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
// Write the output back to the original file
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = format.Node(&buf, fset, f)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
outputFile, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer outputFile.Close()
|
||||||
|
_, err = outputFile.Write(buf.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func modifyJSONTag(tagValue string) string {
|
||||||
|
tagValue = strings.Trim(tagValue, "`")
|
||||||
|
|
||||||
|
tags := strings.Split(tagValue, " ")
|
||||||
|
var modifiedTags []string
|
||||||
|
|
||||||
|
for _, tag := range tags {
|
||||||
|
// Only modify JSON tags, leave others as they are.
|
||||||
|
if !strings.HasPrefix(tag, "json:") {
|
||||||
|
modifiedTags = append(modifiedTags, tag)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonQuoted := tag[5:] // Remove "json:" prefix
|
||||||
|
jsonValue := strings.Trim(jsonQuoted, "\"") // Remove quotes
|
||||||
|
jsonOptions := strings.Split(jsonValue, ",") // Split options
|
||||||
|
|
||||||
|
// Check if "omitempty" is already present
|
||||||
|
hasOmitempty := false
|
||||||
|
for _, opt := range jsonOptions {
|
||||||
|
if opt == "omitempty" {
|
||||||
|
hasOmitempty = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add "omitempty" if not present and the field is not ignored
|
||||||
|
if !hasOmitempty && jsonOptions[0] != "-" {
|
||||||
|
jsonOptions = append(jsonOptions, "omitempty")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconstruct the JSON tag
|
||||||
|
newJSONTag := "json:\"" + strings.Join(jsonOptions, ",") + "\""
|
||||||
|
modifiedTags = append(modifiedTags, newJSONTag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconstruct the full tag
|
||||||
|
return "`" + strings.Join(modifiedTags, " ") + "`"
|
||||||
|
}
|
Loading…
Reference in a new issue