diff --git a/pkg/gordio/database/calls.sql.go b/pkg/gordio/database/calls.sql.go index 4ae32bc..2d1bf6e 100644 --- a/pkg/gordio/database/calls.sql.go +++ b/pkg/gordio/database/calls.sql.go @@ -33,19 +33,19 @@ RETURNING id, submitter, system, talkgroup, call_date, audio_name, audio_blob, a ` type AddCallParams struct { - Submitter pgtype.Int4 - System int32 - Talkgroup int32 - CallDate pgtype.Timestamp - AudioName pgtype.Text - AudioBlob []byte - AudioType pgtype.Text - AudioUrl pgtype.Text - Frequency pgtype.Int4 - Frequencies []byte - Patches []byte - TgLabel pgtype.Text - Source pgtype.Text + Submitter *int32 `json:"submitter"` + System int `json:"system"` + Talkgroup int `json:"talkgroup"` + CallDate pgtype.Timestamp `json:"call_date"` + AudioName *string `json:"audio_name"` + AudioBlob []byte `json:"audio_blob"` + AudioType *string `json:"audio_type"` + AudioUrl *string `json:"audio_url"` + Frequency *int32 `json:"frequency"` + Frequencies []byte `json:"frequencies"` + Patches []byte `json:"patches"` + TgLabel *string `json:"tg_label"` + Source *string `json:"source"` } func (q *Queries) AddCall(ctx context.Context, arg AddCallParams) (Call, error) { @@ -89,7 +89,7 @@ const setCallTranscript = `-- name: SetCallTranscript :exec UPDATE calls SET transcript = $2 WHERE id = $1 ` -func (q *Queries) SetCallTranscript(ctx context.Context, iD uuid.UUID, transcript pgtype.Text) error { +func (q *Queries) SetCallTranscript(ctx context.Context, iD uuid.UUID, transcript *string) error { _, err := q.db.Exec(ctx, setCallTranscript, iD, transcript) return err } diff --git a/pkg/gordio/database/models.go b/pkg/gordio/database/models.go index 0b83f76..84152f4 100644 --- a/pkg/gordio/database/models.go +++ b/pkg/gordio/database/models.go @@ -10,79 +10,79 @@ import ( ) type ApiKey struct { - ID int32 - Owner pgtype.Int4 - CreatedAt pgtype.Timestamp - Expires pgtype.Timestamp - Disabled pgtype.Bool - ApiKey uuid.UUID + ID int32 `json:"id"` + Owner *int32 `json:"owner"` + CreatedAt pgtype.Timestamp `json:"created_at"` + Expires pgtype.Timestamp `json:"expires"` + Disabled *bool `json:"disabled"` + ApiKey uuid.UUID `json:"api_key"` } type Call struct { - ID uuid.UUID - Submitter pgtype.Int4 - System int32 - Talkgroup int32 - CallDate pgtype.Timestamp - AudioName pgtype.Text - AudioBlob []byte - AudioType pgtype.Text - AudioUrl pgtype.Text - Frequency pgtype.Int4 - Frequencies []byte - Patches []byte - TgLabel pgtype.Text - Source pgtype.Text - Transcript pgtype.Text + ID uuid.UUID `json:"id"` + Submitter *int32 `json:"submitter"` + System int `json:"system"` + Talkgroup int `json:"talkgroup"` + CallDate pgtype.Timestamp `json:"call_date"` + AudioName *string `json:"audio_name"` + AudioBlob []byte `json:"audio_blob"` + AudioType *string `json:"audio_type"` + AudioUrl *string `json:"audio_url"` + Frequency *int32 `json:"frequency"` + Frequencies []byte `json:"frequencies"` + Patches []byte `json:"patches"` + TgLabel *string `json:"tg_label"` + Source *string `json:"source"` + Transcript *string `json:"transcript"` } type Incident struct { - ID uuid.UUID - Name string - Description pgtype.Text - StartTime pgtype.Timestamp - EndTime pgtype.Timestamp - Location []byte - Metadata []byte + ID uuid.UUID `json:"id"` + Name string `json:"name"` + Description *string `json:"description"` + StartTime pgtype.Timestamp `json:"start_time"` + EndTime pgtype.Timestamp `json:"end_time"` + Location []byte `json:"location"` + Metadata []byte `json:"metadata"` } type IncidentsCall struct { - IncidentID uuid.UUID - CallID uuid.UUID - Notes []byte + IncidentID uuid.UUID `json:"incident_id"` + CallID uuid.UUID `json:"call_id"` + Notes []byte `json:"notes"` } type Setting struct { - Name string - UpdatedBy pgtype.Int4 - Value []byte + Name string `json:"name"` + UpdatedBy *int32 `json:"updated_by"` + Value []byte `json:"value"` } type System struct { - ID int32 - Name string + ID int `json:"id"` + Name string `json:"name"` } type Talkgroup struct { - SystemID int32 - Tgid int32 - Name pgtype.Text - Frequency pgtype.Int4 - AutoCreated pgtype.Bool - Metadata []byte + SystemID int `json:"system_id"` + Tgid int `json:"tgid"` + Name *string `json:"name"` + Frequency *int32 `json:"frequency"` + AutoCreated *bool `json:"auto_created"` + Metadata []byte `json:"metadata"` } type TalkgroupsTag struct { - SystemID int32 - TalkgroupID int32 - Tags []string + SystemID int `json:"system_id"` + TalkgroupID int `json:"talkgroup_id"` + Tags []string `json:"tags"` } type User struct { - ID int32 - Username string - Password string - Email string - IsAdmin pgtype.Bool - Prefs []byte + ID int32 `json:"id"` + Username string `json:"username"` + Password string `json:"password"` + Email string `json:"email"` + IsAdmin *bool `json:"is_admin"` + Prefs []byte `json:"prefs"` } diff --git a/pkg/gordio/database/talkgroups.sql.go b/pkg/gordio/database/talkgroups.sql.go index b005664..740aa11 100644 --- a/pkg/gordio/database/talkgroups.sql.go +++ b/pkg/gordio/database/talkgroups.sql.go @@ -14,7 +14,7 @@ SELECT tags FROM talkgroups_tags WHERE talkgroup_id = $1 ` -func (q *Queries) GetTalkgroupTags(ctx context.Context, talkgroupID int32) ([]string, error) { +func (q *Queries) GetTalkgroupTags(ctx context.Context, talkgroupID int) ([]string, error) { row := q.db.QueryRow(ctx, getTalkgroupTags, talkgroupID) var tags []string err := row.Scan(&tags) @@ -27,8 +27,8 @@ WHERE tags && ARRAY[$1] ` type GetTalkgroupsWithAllTagsRow struct { - SystemID int32 - TalkgroupID int32 + SystemID int `json:"system_id"` + TalkgroupID int `json:"talkgroup_id"` } func (q *Queries) GetTalkgroupsWithAllTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAllTagsRow, error) { @@ -57,8 +57,8 @@ WHERE tags @> ARRAY[$1] ` type GetTalkgroupsWithAnyTagsRow struct { - SystemID int32 - TalkgroupID int32 + SystemID int `json:"system_id"` + TalkgroupID int `json:"talkgroup_id"` } func (q *Queries) GetTalkgroupsWithAnyTags(ctx context.Context, tags []string) ([]GetTalkgroupsWithAnyTagsRow, error) { @@ -86,7 +86,7 @@ INSERT INTO talkgroups_tags(system_id, talkgroup_id, tags) VALUES($1, $2, $3) ON CONFLICT (system_id, talkgroup_id) DO UPDATE SET tags = $3 ` -func (q *Queries) SetTalkgroupTags(ctx context.Context, systemID int32, talkgroupID int32, tags []string) error { +func (q *Queries) SetTalkgroupTags(ctx context.Context, systemID int, talkgroupID int, tags []string) error { _, err := q.db.Exec(ctx, setTalkgroupTags, systemID, talkgroupID, tags) return err } diff --git a/pkg/gordio/database/users.sql.go b/pkg/gordio/database/users.sql.go index 3d03a5f..b135a3d 100644 --- a/pkg/gordio/database/users.sql.go +++ b/pkg/gordio/database/users.sql.go @@ -23,7 +23,7 @@ INSERT INTO api_keys( RETURNING id, owner, created_at, expires, disabled, api_key ` -func (q *Queries) CreateAPIKey(ctx context.Context, owner pgtype.Int4, expires pgtype.Timestamp, disabled pgtype.Bool) (ApiKey, error) { +func (q *Queries) CreateAPIKey(ctx context.Context, owner *int32, expires pgtype.Timestamp, disabled *bool) (ApiKey, error) { row := q.db.QueryRow(ctx, createAPIKey, owner, expires, disabled) var i ApiKey err := row.Scan( @@ -48,10 +48,10 @@ RETURNING id, username, password, email, is_admin, prefs ` type CreateUserParams struct { - Username string - Password string - Email string - IsAdmin pgtype.Bool + Username string `json:"username"` + Password string `json:"password"` + Email string `json:"email"` + IsAdmin *bool `json:"is_admin"` } func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) { diff --git a/pkg/gordio/server/calls.go b/pkg/gordio/server/calls.go index b32bb01..4cc6065 100644 --- a/pkg/gordio/server/calls.go +++ b/pkg/gordio/server/calls.go @@ -11,6 +11,8 @@ import ( "dynatron.me/x/stillbox/pkg/gordio/database" "github.com/google/uuid" + "github.com/jackc/pgtype" + "github.com/rs/zerolog/log" ) type callUploadRequest struct { @@ -32,6 +34,29 @@ type callUploadRequest struct { TalkgroupTag string `form:"talkgroupTag"` } +type AddCallParams struct { + Submitter pgtype.Int4 `json:"submitter"` + System int32 `json:"system"` + Talkgroup int32 `json:"talkgroup"` + CallDate pgtype.Timestamp `json:"call_date"` + AudioName pgtype.Text `json:"audio_name"` + AudioBlob []byte `json:"audio_blob"` + AudioType pgtype.Text `json:"audio_type"` + AudioUrl pgtype.Text `json:"audio_url"` + Frequency pgtype.Int4 `json:"frequency"` + Frequencies []byte `json:"frequencies"` + Patches []byte `json:"patches"` + TgLabel pgtype.Text `json:"tg_label"` + Source pgtype.Text `json:"source"` +} + +func (car *callUploadRequest) ToAddCallParams(submitter int) database.AddCallParams { + return database.AddCallParams{ + Submitter: submitter, + System: car.System, + } +} + func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) { err := r.ParseMultipartForm(1024 * 1024 * 2) // 2MB if err != nil { @@ -44,7 +69,8 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) { http.Error(w, "cannot parse key "+err.Error(), http.StatusBadRequest) return } - apik, err := s.db.GetAPIKey(r.Context(), keyUuid) + db := database.FromCtx(r.Context()) + apik, err := db.GetAPIKey(r.Context(), keyUuid) if err != nil { if database.IsNoRows(err) { http.Error(w, "bad key", http.StatusUnauthorized) @@ -57,6 +83,7 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) { if apik.Disabled.Bool || (apik.Expires.Valid && time.Now().After(apik.Expires.Time)) { http.Error(w, "disabled", http.StatusUnauthorized) + log.Error().Str("key", apik.ApiKey.String()).Msg("key disabled") return } @@ -67,7 +94,12 @@ func (s *Server) routeCallUpload(w http.ResponseWriter, r *http.Request) { return } - w.Write([]byte(fmt.Sprintf("%#v", call))) + dbCall, err := db.AddCall(r.Context(), call.ToAddCallParams()) + if err != nil { + http.Error(w, "internal error", http.StatusInternalServerError) + log.Error().Err(err).Msg("add call") + return + } } func (car *callUploadRequest) fill(r *http.Request) error { diff --git a/sql/sqlc.yaml b/sql/sqlc.yaml index d4ae746..2fc6f1a 100644 --- a/sql/sqlc.yaml +++ b/sql/sqlc.yaml @@ -9,9 +9,16 @@ sql: out: "../pkg/gordio/database" sql_package: "pgx/v5" query_parameter_limit: 3 + emit_json_tags: true + emit_pointers_for_null_types: true overrides: - db_type: "uuid" go_type: import: "github.com/google/uuid" type: "UUID" + - db_type: "pg_catalog.int4" + go_type: "int" + - db_type: "pg_catalog.serial4" + go_type: "int" +