From 88f3d2d97ce8c17fdd1061c5a743b2865d2a8f69 Mon Sep 17 00:00:00 2001 From: Allyson-English Date: Wed, 26 Jul 2023 12:04:44 -0600 Subject: [PATCH 1/3] require aftermarket device fields owner, mintedAt --- graph/generated.go | 36 +++++++++----------- graph/model/models_gen.go | 4 +-- graph/schema.graphqls | 4 +-- internal/repositories/aftermarket_devices.go | 21 ++++++------ 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/graph/generated.go b/graph/generated.go index d580b881..0d10ddd9 100644 --- a/graph/generated.go +++ b/graph/generated.go @@ -643,11 +643,14 @@ func (ec *executionContext) _AftermarketDevice_owner(ctx context.Context, field return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*common.Address) + res := resTmp.(common.Address) fc.Result = res - return ec.marshalOAddress2ᚖgithubᚗcomᚋethereumᚋgoᚑethereumᚋcommonᚐAddress(ctx, field.Selections, res) + return ec.marshalNAddress2githubᚗcomᚋethereumᚋgoᚑethereumᚋcommonᚐAddress(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_AftermarketDevice_owner(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -766,11 +769,14 @@ func (ec *executionContext) _AftermarketDevice_mintedAt(ctx context.Context, fie return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*time.Time) + res := resTmp.(time.Time) fc.Result = res - return ec.marshalOTime2ᚖtimeᚐTime(ctx, field.Selections, res) + return ec.marshalNTime2timeᚐTime(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_AftermarketDevice_mintedAt(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3674,12 +3680,18 @@ func (ec *executionContext) _AftermarketDevice(ctx context.Context, sel ast.Sele out.Values[i] = ec._AftermarketDevice_address(ctx, field, obj) case "owner": out.Values[i] = ec._AftermarketDevice_owner(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "serial": out.Values[i] = ec._AftermarketDevice_serial(ctx, field, obj) case "imei": out.Values[i] = ec._AftermarketDevice_imei(ctx, field, obj) case "mintedAt": out.Values[i] = ec._AftermarketDevice_mintedAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -4988,22 +5000,6 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return res } -func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v interface{}) (*time.Time, error) { - if v == nil { - return nil, nil - } - res, err := graphql.UnmarshalTime(v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel ast.SelectionSet, v *time.Time) graphql.Marshaler { - if v == nil { - return graphql.Null - } - res := graphql.MarshalTime(*v) - return res -} - func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/graph/model/models_gen.go b/graph/model/models_gen.go index 54e1fefd..6bd9cbb3 100644 --- a/graph/model/models_gen.go +++ b/graph/model/models_gen.go @@ -11,10 +11,10 @@ import ( type AftermarketDevice struct { ID string `json:"id"` Address *common.Address `json:"address,omitempty"` - Owner *common.Address `json:"owner,omitempty"` + Owner common.Address `json:"owner"` Serial *string `json:"serial,omitempty"` Imei *string `json:"imei,omitempty"` - MintedAt *time.Time `json:"mintedAt,omitempty"` + MintedAt time.Time `json:"mintedAt"` } type AftermarketDeviceConnection struct { diff --git a/graph/schema.graphqls b/graph/schema.graphqls index c860b6a6..4b0e2f57 100644 --- a/graph/schema.graphqls +++ b/graph/schema.graphqls @@ -28,10 +28,10 @@ type VehicleEdge { type AftermarketDevice { id: ID! address: Address - owner: Address + owner: Address! serial: String imei: String - mintedAt: Time + mintedAt: Time! } type AftermarketDeviceConnection { diff --git a/internal/repositories/aftermarket_devices.go b/internal/repositories/aftermarket_devices.go index 647a1182..00426b25 100644 --- a/internal/repositories/aftermarket_devices.go +++ b/internal/repositories/aftermarket_devices.go @@ -13,6 +13,14 @@ import ( "github.com/volatiletech/sqlboiler/v4/queries/qm" ) +func BytesToAddr(addrB null.Bytes) *common.Address { + var addr *common.Address + if addrB.Valid { + addr = (*common.Address)(*addrB.Ptr()) + } + return addr +} + func (v *VehiclesRepo) GetOwnedAftermarketDevices(ctx context.Context, addr common.Address, first *int, after *string) (*gmodel.AftermarketDeviceConnection, error) { ownedADCount, err := models.AftermarketDevices( models.AftermarketDeviceWhere.Owner.EQ(null.BytesFrom(addr.Bytes())), @@ -70,22 +78,15 @@ func (v *VehiclesRepo) GetOwnedAftermarketDevices(ctx context.Context, addr comm var adEdges []*gmodel.AftermarketDeviceEdge for _, d := range ads { - var ownerAddr, deviceAddr *common.Address - if d.Address.Valid { - deviceAddr = (*common.Address)(*d.Address.Ptr()) - } - if d.Owner.Valid { - ownerAddr = (*common.Address)(*d.Owner.Ptr()) - } adEdges = append(adEdges, &gmodel.AftermarketDeviceEdge{ Node: &gmodel.AftermarketDevice{ ID: strconv.Itoa(d.ID), - Address: deviceAddr, - Owner: ownerAddr, + Address: BytesToAddr(d.Address), + Owner: common.BytesToAddress(d.Owner.Bytes), Serial: d.Serial.Ptr(), Imei: d.Imei.Ptr(), - MintedAt: d.MintedAt.Ptr(), + MintedAt: d.MintedAt.Time, }, Cursor: base64.StdEncoding.EncodeToString([]byte(strconv.Itoa(d.ID))), }, From 0a772d191e0ec5d8366ef06fd2509f6fbcffddbb Mon Sep 17 00:00:00 2001 From: Allyson-English Date: Wed, 26 Jul 2023 13:18:40 -0600 Subject: [PATCH 2/3] require fields in db --- internal/repositories/aftermarket_devices.go | 8 ++-- .../repositories/aftermarket_devices_test.go | 6 +-- .../services/contracts_events_consumer.go | 4 +- migrations/00006_required_ad_fields.sql | 27 +++++++++++ models/aftermarket_devices.go | 46 +++++++++++-------- models/psql_upsert.go | 3 ++ models/vehicles.go | 30 ------------ 7 files changed, 65 insertions(+), 59 deletions(-) create mode 100644 migrations/00006_required_ad_fields.sql diff --git a/internal/repositories/aftermarket_devices.go b/internal/repositories/aftermarket_devices.go index 00426b25..2e6038b4 100644 --- a/internal/repositories/aftermarket_devices.go +++ b/internal/repositories/aftermarket_devices.go @@ -23,7 +23,7 @@ func BytesToAddr(addrB null.Bytes) *common.Address { func (v *VehiclesRepo) GetOwnedAftermarketDevices(ctx context.Context, addr common.Address, first *int, after *string) (*gmodel.AftermarketDeviceConnection, error) { ownedADCount, err := models.AftermarketDevices( - models.AftermarketDeviceWhere.Owner.EQ(null.BytesFrom(addr.Bytes())), + models.AftermarketDeviceWhere.Owner.EQ(addr.Bytes()), ).Count(ctx, v.pdb.DBS().Reader) if err != nil { return nil, err @@ -46,7 +46,7 @@ func (v *VehiclesRepo) GetOwnedAftermarketDevices(ctx context.Context, addr comm } queryMods := []qm.QueryMod{ - models.AftermarketDeviceWhere.Owner.EQ(null.BytesFrom(addr.Bytes())), + models.AftermarketDeviceWhere.Owner.EQ(addr.Bytes()), // Use limit + 1 here to check if there's a next page. qm.Limit(limit + 1), qm.OrderBy(models.AftermarketDeviceColumns.ID + " DESC"), @@ -83,10 +83,10 @@ func (v *VehiclesRepo) GetOwnedAftermarketDevices(ctx context.Context, addr comm Node: &gmodel.AftermarketDevice{ ID: strconv.Itoa(d.ID), Address: BytesToAddr(d.Address), - Owner: common.BytesToAddress(d.Owner.Bytes), + Owner: common.BytesToAddress(d.Owner), Serial: d.Serial.Ptr(), Imei: d.Imei.Ptr(), - MintedAt: d.MintedAt.Time, + MintedAt: d.MintedAt, }, Cursor: base64.StdEncoding.EncodeToString([]byte(strconv.Itoa(d.ID))), }, diff --git a/internal/repositories/aftermarket_devices_test.go b/internal/repositories/aftermarket_devices_test.go index 01581301..d65e0104 100644 --- a/internal/repositories/aftermarket_devices_test.go +++ b/internal/repositories/aftermarket_devices_test.go @@ -19,7 +19,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" - "github.com/volatiletech/null/v8" "github.com/volatiletech/sqlboiler/v4/boil" ) @@ -104,8 +103,9 @@ func TestAftermarketDeviceNodeMintMultiResponse(t *testing.T) { for i := 1; i < 6; i++ { ad := models.AftermarketDevice{ - ID: i, - Owner: null.BytesFrom(aftermarketDeviceNodeMintedArgs.Owner.Bytes()), + ID: i, + Owner: aftermarketDeviceNodeMintedArgs.Owner.Bytes(), + MintedAt: time.Now(), } err := ad.Insert(ctx, pdb.DBS().Writer, boil.Infer()) diff --git a/internal/services/contracts_events_consumer.go b/internal/services/contracts_events_consumer.go index 93e00a2c..1d76a46c 100644 --- a/internal/services/contracts_events_consumer.go +++ b/internal/services/contracts_events_consumer.go @@ -202,8 +202,8 @@ func (c *ContractsEventsConsumer) handleAftermarketDeviceNodeMintedEvent(e *Cont ad := models.AftermarketDevice{ ID: int(args.TokenID.Int64()), Address: null.BytesFrom(args.AftermarketDeviceAddress.Bytes()), - Owner: null.BytesFrom(args.Owner.Bytes()), - MintedAt: null.TimeFrom(e.Block.Time), + Owner: args.Owner.Bytes(), + MintedAt: e.Block.Time, } if err := ad.Upsert(context.Background(), c.dbs.DBS().Writer, diff --git a/migrations/00006_required_ad_fields.sql b/migrations/00006_required_ad_fields.sql new file mode 100644 index 00000000..52abed2f --- /dev/null +++ b/migrations/00006_required_ad_fields.sql @@ -0,0 +1,27 @@ +-- +goose Up +-- +goose StatementBegin +SELECT 'up SQL query'; + +ALTER TABLE aftermarket_devices +ALTER COLUMN "owner" +SET NOT NULL; + +ALTER TABLE aftermarket_devices +ALTER COLUMN "minted_at" +SET NOT NULL; + +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +SELECT 'down SQL query'; + +ALTER TABLE aftermarket_devices +ALTER COLUMN "owner" +DROP NOT NULL; + +ALTER TABLE aftermarket_devices +ALTER COLUMN "minted_at" +DROP NOT NULL; + +-- +goose StatementEnd diff --git a/models/aftermarket_devices.go b/models/aftermarket_devices.go index 81a89b58..49bac2db 100644 --- a/models/aftermarket_devices.go +++ b/models/aftermarket_devices.go @@ -26,10 +26,10 @@ import ( type AftermarketDevice struct { ID int `boil:"id" json:"id" toml:"id" yaml:"id"` Address null.Bytes `boil:"address" json:"address,omitempty" toml:"address" yaml:"address,omitempty"` - Owner null.Bytes `boil:"owner" json:"owner,omitempty" toml:"owner" yaml:"owner,omitempty"` + Owner []byte `boil:"owner" json:"owner" toml:"owner" yaml:"owner"` Serial null.String `boil:"serial" json:"serial,omitempty" toml:"serial" yaml:"serial,omitempty"` Imei null.String `boil:"imei" json:"imei,omitempty" toml:"imei" yaml:"imei,omitempty"` - MintedAt null.Time `boil:"minted_at" json:"minted_at,omitempty" toml:"minted_at" yaml:"minted_at,omitempty"` + MintedAt time.Time `boil:"minted_at" json:"minted_at" toml:"minted_at" yaml:"minted_at"` R *aftermarketDeviceR `boil:"-" json:"-" toml:"-" yaml:"-"` L aftermarketDeviceL `boil:"-" json:"-" toml:"-" yaml:"-"` @@ -116,6 +116,15 @@ func (w whereHelpernull_Bytes) GTE(x null.Bytes) qm.QueryMod { func (w whereHelpernull_Bytes) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } func (w whereHelpernull_Bytes) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } +type whereHelper__byte struct{ field string } + +func (w whereHelper__byte) EQ(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } +func (w whereHelper__byte) NEQ(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } +func (w whereHelper__byte) LT(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } +func (w whereHelper__byte) LTE(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } +func (w whereHelper__byte) GT(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } +func (w whereHelper__byte) GTE(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } + type whereHelpernull_String struct{ field string } func (w whereHelpernull_String) EQ(x null.String) qm.QueryMod { @@ -154,44 +163,41 @@ func (w whereHelpernull_String) NIN(slice []string) qm.QueryMod { func (w whereHelpernull_String) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } func (w whereHelpernull_String) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } -type whereHelpernull_Time struct{ field string } +type whereHelpertime_Time struct{ field string } -func (w whereHelpernull_Time) EQ(x null.Time) qm.QueryMod { - return qmhelper.WhereNullEQ(w.field, false, x) +func (w whereHelpertime_Time) EQ(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.EQ, x) } -func (w whereHelpernull_Time) NEQ(x null.Time) qm.QueryMod { - return qmhelper.WhereNullEQ(w.field, true, x) +func (w whereHelpertime_Time) NEQ(x time.Time) qm.QueryMod { + return qmhelper.Where(w.field, qmhelper.NEQ, x) } -func (w whereHelpernull_Time) LT(x null.Time) qm.QueryMod { +func (w whereHelpertime_Time) LT(x time.Time) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } -func (w whereHelpernull_Time) LTE(x null.Time) qm.QueryMod { +func (w whereHelpertime_Time) LTE(x time.Time) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } -func (w whereHelpernull_Time) GT(x null.Time) qm.QueryMod { +func (w whereHelpertime_Time) GT(x time.Time) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } -func (w whereHelpernull_Time) GTE(x null.Time) qm.QueryMod { +func (w whereHelpertime_Time) GTE(x time.Time) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } -func (w whereHelpernull_Time) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } -func (w whereHelpernull_Time) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } - var AftermarketDeviceWhere = struct { ID whereHelperint Address whereHelpernull_Bytes - Owner whereHelpernull_Bytes + Owner whereHelper__byte Serial whereHelpernull_String Imei whereHelpernull_String - MintedAt whereHelpernull_Time + MintedAt whereHelpertime_Time }{ ID: whereHelperint{field: "\"identity_api\".\"aftermarket_devices\".\"id\""}, Address: whereHelpernull_Bytes{field: "\"identity_api\".\"aftermarket_devices\".\"address\""}, - Owner: whereHelpernull_Bytes{field: "\"identity_api\".\"aftermarket_devices\".\"owner\""}, + Owner: whereHelper__byte{field: "\"identity_api\".\"aftermarket_devices\".\"owner\""}, Serial: whereHelpernull_String{field: "\"identity_api\".\"aftermarket_devices\".\"serial\""}, Imei: whereHelpernull_String{field: "\"identity_api\".\"aftermarket_devices\".\"imei\""}, - MintedAt: whereHelpernull_Time{field: "\"identity_api\".\"aftermarket_devices\".\"minted_at\""}, + MintedAt: whereHelpertime_Time{field: "\"identity_api\".\"aftermarket_devices\".\"minted_at\""}, } // AftermarketDeviceRels is where relationship names are stored. @@ -212,8 +218,8 @@ type aftermarketDeviceL struct{} var ( aftermarketDeviceAllColumns = []string{"id", "address", "owner", "serial", "imei", "minted_at"} - aftermarketDeviceColumnsWithoutDefault = []string{"id"} - aftermarketDeviceColumnsWithDefault = []string{"address", "owner", "serial", "imei", "minted_at"} + aftermarketDeviceColumnsWithoutDefault = []string{"id", "owner", "minted_at"} + aftermarketDeviceColumnsWithDefault = []string{"address", "serial", "imei"} aftermarketDevicePrimaryKeyColumns = []string{"id"} aftermarketDeviceGeneratedColumns = []string{} ) diff --git a/models/psql_upsert.go b/models/psql_upsert.go index 1817cc98..a7c18b85 100644 --- a/models/psql_upsert.go +++ b/models/psql_upsert.go @@ -42,6 +42,9 @@ func buildUpsertQueryPostgres(dia drivers.Dialect, tableName string, updateOnCon buf.WriteString(") DO UPDATE SET ") for i, v := range update { + if len(v) == 0 { + continue + } if i != 0 { buf.WriteByte(',') } diff --git a/models/vehicles.go b/models/vehicles.go index d11aa286..86b0d00d 100644 --- a/models/vehicles.go +++ b/models/vehicles.go @@ -69,15 +69,6 @@ var VehicleTableColumns = struct { // Generated where -type whereHelper__byte struct{ field string } - -func (w whereHelper__byte) EQ(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.EQ, x) } -func (w whereHelper__byte) NEQ(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.NEQ, x) } -func (w whereHelper__byte) LT(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LT, x) } -func (w whereHelper__byte) LTE(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.LTE, x) } -func (w whereHelper__byte) GT(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GT, x) } -func (w whereHelper__byte) GTE(x []byte) qm.QueryMod { return qmhelper.Where(w.field, qmhelper.GTE, x) } - type whereHelpernull_Int struct{ field string } func (w whereHelpernull_Int) EQ(x null.Int) qm.QueryMod { @@ -116,27 +107,6 @@ func (w whereHelpernull_Int) NIN(slice []int) qm.QueryMod { func (w whereHelpernull_Int) IsNull() qm.QueryMod { return qmhelper.WhereIsNull(w.field) } func (w whereHelpernull_Int) IsNotNull() qm.QueryMod { return qmhelper.WhereIsNotNull(w.field) } -type whereHelpertime_Time struct{ field string } - -func (w whereHelpertime_Time) EQ(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.EQ, x) -} -func (w whereHelpertime_Time) NEQ(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.NEQ, x) -} -func (w whereHelpertime_Time) LT(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.LT, x) -} -func (w whereHelpertime_Time) LTE(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.LTE, x) -} -func (w whereHelpertime_Time) GT(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.GT, x) -} -func (w whereHelpertime_Time) GTE(x time.Time) qm.QueryMod { - return qmhelper.Where(w.field, qmhelper.GTE, x) -} - var VehicleWhere = struct { ID whereHelperint OwnerAddress whereHelper__byte From 6f89be3293d595fd08733bc432c935ab2689a345 Mon Sep 17 00:00:00 2001 From: Allyson-English Date: Wed, 26 Jul 2023 14:18:41 -0600 Subject: [PATCH 3/3] uncomment fields --- internal/loader/aftermarket_device_loader.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/loader/aftermarket_device_loader.go b/internal/loader/aftermarket_device_loader.go index 1aa809b6..4ea05482 100644 --- a/internal/loader/aftermarket_device_loader.go +++ b/internal/loader/aftermarket_device_loader.go @@ -8,6 +8,7 @@ import ( "github.com/DIMO-Network/identity-api/internal/repositories" "github.com/DIMO-Network/identity-api/models" "github.com/DIMO-Network/shared/db" + "github.com/ethereum/go-ethereum/common" "github.com/graph-gophers/dataloader/v7" ) @@ -56,12 +57,12 @@ func (ad *AftermarketDeviceLoader) BatchGetLinkedAftermarketDeviceByVehicleID(ct for _, device := range devices { v := &model.AftermarketDevice{ - ID: strconv.Itoa(device.ID), - Address: repositories.BytesToAddr(device.Address), - // Owner: repositories.BytesToAddr(device.Owner), - Serial: device.Serial.Ptr(), - Imei: device.Imei.Ptr(), - // MintedAt: device.MintedAt.Ptr(), + ID: strconv.Itoa(device.ID), + Address: repositories.BytesToAddr(device.Address), + Owner: common.BytesToAddress(device.Owner), + Serial: device.Serial.Ptr(), + Imei: device.Imei.Ptr(), + MintedAt: device.MintedAt, Beneficiary: repositories.BytesToAddr(device.Beneficiary), } results[keyOrder[device.VehicleID.Int]] = &dataloader.Result[*model.AftermarketDevice]{Data: v, Error: nil}