Closed MohamedKHALILRouissi closed 9 months ago
var query struct {
SchemaEvent []struct {
ID int `json:"id"`
} `graphql:"schema_event(where: {contractaddress: {_eq: $ca}, network: {_eq: $nt}})"`
}
variables := map[string]interface{}{
"ca": sc.ContractAddress,
"nt": sc.Network,
"tp": string(jsondata), // this variable is redundant
}
The query struct only has 2 variables $ca
and $nt
. the $tp
variable should be removed
thanks for response , but am trying to search in the graphql based on those topics to narrow the research and find duplicated event with the same topics
sorry for the mistake the graph should be like this
`graphql:"schema_event(where: { topics: {_contained_in: $tp}, contractaddress: {_eq: $ca}, network: {_eq: $nt}})"
`where $tp is jsonb
{efgh-5678-abcd-1234 avalanche 0x1234567890123456789012345678901234567890 false [0x1111111111111111111111111111111111111111111111111111111111111111 0x2222222222222222222222222222222222222222222222222222222222222222 0x5e4f3d2c1b0a9988776d6554433221100]} map[ca:0x1234567890123456789012345678901234567890 nt:avalanche tp:["0x1111111111111111111111111111111111111111111111111111111111111111","0x2222222222222222222222222222222222222222222222222222222222222222","0x5e4f3d2c1b0a9988776d6554433221100"]]Message: variable 'tp' is declared as 'String!', but used where 'jsonb' is expected, Locations: [], Extensions: map[code:validation-failed path:$.selectionSet.schema_event.args.where.topics._contained_in]inside the qyeryschema[GIN] 2023/11/21 - 16:07:54 | 500 | 649.984312ms | ::1 | POST "/api/v1/subscribe"
hasura test query MyQuery($ca: String, $nt: String, $tp: jsonb) { schema_event(where: {topics: {_contained_in: $tp}, contractaddress: {_eq: $ca}, network: {_eq: $nt}}) { id } } ------- data {"ca": "0x1234567890123456789012345678901234567890", "nt": "eth", "tp": [ "0x1111111111111111111111111111111111111111111111111111111111111113","0x3333333333333333333333333333333333333333333333333333333333333333","0x2222222222222222222222222222222222222222222222222222222222222222" ] }
------ return { "data": { "schema_event": [ { "id": 3 } ] } }
Please format the code to be easy to debug. You need to define a type alias so the library can convert it to GraphQL type.
type jsonb interface{}
variables := map[string]interface{}{
"ca": sc.ContractAddress,
"nt": sc.Network,
"tp": jsonb(sc.Topics),
}
No need to marshal the slice to bytes. The library will encode it later
`package graphql
import ( "context" "fmt" "net/http"
"github.com/hasura/go-graphql-client"
)
// first we need to query the schema of the event
// if found add the user uuid to a schema mapping
// if not found add the schema
type Variables_schema struct {
ID int json:"id"
// Assuming you're setting this on insert or update
ContractAddress string json:"contractaddress"
Topics []string json:"topics"
Network string json:"network"
}
type Variables_subscription struct {
User string json:"user"
Event_id int json:"event_id"
}
const ( serverEndpoint = "xxxxxxxx" adminSecret = "xxxxx" xHasuraAdminSecret = "x-hasura-admin-secret" )
type headerRoundTripper struct { setHeaders func(req *http.Request) rt http.RoundTripper }
func (h headerRoundTripper) RoundTrip(req http.Request) (http.Response, error) { h.setHeaders(req) return h.rt.RoundTrip(req) }
func startgraphqlconnection() *graphql.Client {
client := graphql.NewClient(serverEndpoint, &http.Client{
Transport: headerRoundTripper{
setHeaders: func(req *http.Request) {
req.Header.Set(xHasuraAdminSecret, adminSecret)
},
rt: http.DefaultTransport,
},
})
return client
}
func InsertSchema(sc Variables_schema) (int, error) { / mutation MyMutation($ca: String , $nt: String , $tp: json) { insert_schema_event(objects: {contractaddress: $ca, network: $nt, topics: $tp}) { returning { id } } } /
// start graphql connection
client := startgraphqlconnection()
// create the returning mutation schema
var mutation struct {
InsertSchemaEvent struct {
Returning []struct {
ID int `json:"id"`
} `json:"returning"`
} `graphql:"insert_schema_event(objects: {id: $id, contractaddress: $contractaddress, topics: $topics, network: $network})"`
}
// Define your variables
variables := map[string]interface{}{
"id": sc.ID,
"contractaddress": sc.ContractAddress,
"topics": sc.Topics,
"network": sc.Network,
}
// Run the mutation
err := client.Mutate(context.Background(), &mutation, variables)
if err != nil {
// error inserting
return 0, err
} else {
if len(mutation.InsertSchemaEvent.Returning) == 0 {
return 0, fmt.Errorf("no data returned")
}
// success insert and return id
id := mutation.InsertSchemaEvent.Returning[0].ID
return id, nil
}
}
func QuerySchema(sc Variables_schema) (int, error) { / query MyQuery($ca: String, $nt: String , $tp: jsonb) { schema_event(where: {topics: {_contained_in: $tp}, contractaddress: {_eq: $ca}, network: {_eq: $nt}}) { id } } /
client := startgraphqlconnection()
var query struct {
SchemaEvent []struct {
ID int `json:"id"`
} `graphql:"schema_event(where: {topics: {_contained_in: $tp},contractaddress: {_eq: $ca}, network: {_eq: $nt}})"`
}
type jsonb interface{}
variables := map[string]interface{}{
"ca": sc.ContractAddress,
"nt": sc.Network,
"tp": jsonb(sc.Topics), // this variable is redundant
}
fmt.Print(variables)
if err := client.Query(context.Background(), &query, variables); err != nil {
fmt.Print(err)
return 0, err
} else {
if len(query.SchemaEvent) == 0 {
fmt.Print("am here")
// not found logic
return 0, nil
} else {
fmt.Print("am here 2")
fmt.Print(query)
return query.SchemaEvent[0].ID, nil
}
}
}
func InsertUserEventSubscription(sc Variables_subscription) (string, int, error) { client := startgraphqlconnection()
var mutation struct {
InsertUserEventSubscription struct {
Returning []struct {
EventUUID string `json:"event_uuid"`
ID int `json:"id"`
} `json:"returning"`
} `graphql:"insert_user_event_subscription(objects: {user: $user, event_id: $event_id})"`
}
variables := map[string]interface{}{
"user": sc.User,
"event_id": sc.Event_id,
}
if err := client.Mutate(context.Background(), &mutation, variables); err != nil {
return "", 0, err
}
// Check if the mutation has any returning results
if len(mutation.InsertUserEventSubscription.Returning) == 0 {
return "", 0, fmt.Errorf("no data returned")
}
// Access the fields from the first element of the returning slice
eventUUID := mutation.InsertUserEventSubscription.Returning[0].EventUUID
id := mutation.InsertUserEventSubscription.Returning[0].ID
return eventUUID, id, nil
}
`
am still getting the error {efgh-5678-abcd-1234 avalanche 0x1234567890123456789012345678901234567890 false [0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d 0x5e4f3d2c1b0a9988776d6554433221100]} map[ca:0x1234567890123456789012345678901234567890 nt:avalanche tp:[0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d 0x5e4f3d2c1b0a9988776d6554433221100]]Message: variable 'tp' is declared as '[String!]!', but used where 'jsonb' is expected, Locations: [], Extensions: map[code:validation-failed path:$.selectionSet.schema_event.args.where.topics._contained_in]inside the qyeryschema[GIN] 2023/11/21 - 16:32:11 | 500 | 546.184897ms | ::1 | POST "/api/v1/subscribe"
am using the same data as always
{ "uuid": "efgh-5678-abcd-1234", "network": "avalanche", "address": "0x1234567890123456789012345678901234567890", "rulechain": false, "topics": [ "0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d", "0x5e4f3d2c1b0a9988776d6554433221100" ] }
sorry about the formatting am not use to it and thanks for you time again sir
You may be wrong about the _contained_in
operator https://hasura.io/docs/latest/queries/postgres/filters/jsonb-operators/#_contained_in
To avoid confusion about inner types, you can use the type of where
object that is usually <table>_bool_exp
var query struct {
SchemaEvent []struct {
ID int `json:"id"`
} `graphql:"schema_event(where: $where)"`
}
type schema_event_bool_exp map[string]interface{}
variables := map[string]interface{} {
"where": schema_event_bool_exp{
"topics": map[string]interface{} {
"_contained_in": map[string]interface{} {
"value": sc.Topics,
},
},
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress
},
"network": {
"_eq": sc.Network
}
}
}
variables := map[string]interface{}{
"where": schema_event_bool_exp{
"topics": map[string]interface{}{
"_contained_in": map[string]interface{}{
"value": sc.Topics,
},
},
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress,
},
"network": map[string]interface{}{
"_eq": sc.Network,
},
},
}
is this the right declaration of variables?
Yes, this is. It is equivalent to the below query
query MyQuery($where: schema_event_bool_exp) {
schema_event(where: $where) {
id
}
}
You can test the query on the Hasura console
the code is functional but it always returning empty data , tried it with correct data set and still return nothing , but in the hasura console return the correct id
{efgh-5678-abcd-1234 eth 0x1234567890123456789012345678901234567890 false [0x1111111111111111111111111111111111111111111111111111111111111111 0x2222222222222222222222222222222222222222222222222222222222222222 0x3333333333333333333333333333333333333333333333333333333333333333]} map[where:map[contractaddress:map[_eq:0x1234567890123456789012345678901234567890] network:map[_eq:eth] topics:map[_contained_in:map[value:[0x1111111111111111111111111111111111111111111111111111111111111111 0x2222222222222222222222222222222222222222222222222222222222222222 0x3333333333333333333333333333333333333333333333333333333333333333]]]]] {[]} [GIN] 2023/11/21 - 17:40:58 | 500 | 317.416892ms | ::1 | POST "/api/v1/subscribe"
thanks again sir hgiasac for all the help and am sorry
tested on the console it work fine but in this script it doesn't ` func QuerySchema(sc Variables_schema) (int, error) { client := startgraphqlconnection()
var query struct {
SchemaEvent []struct {
ID int `json:"id"`
} `graphql:"schema_event(where: $where)"`
}
type schema_event_bool_exp map[string]interface{}
variables := map[string]interface{}{
"where": schema_event_bool_exp{
"topics": map[string]interface{}{
"_contained_in": map[string]interface{}{
"value": sc.Topics,
},
},
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress,
},
"network": map[string]interface{}{
"_eq": sc.Network,
},
},
}
fmt.Println(variables)
if err := client.Query(context.Background(), &query, variables); err != nil {
fmt.Println(err)
return 0, err
} else {
fmt.Println(query)
return 0, err
}
} `
on hasura
{"where": { "contractaddress": {"_eq": "0x1234567890123456789012345678901234567890"} , "network": {"_eq": "eth"} , "topics": { "_contained_in": ["0x1111111111111111111111111111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222222222222222222222222222" , "0x3333333333333333333333333333333333333333333333333333333333333333"] } } }
return
{
"data": {
"schema_event": [
{
"id": 1
}
]
}
}
You can try to remove value
in _contained_in
to see if it works
"_contained_in": sc.Topics,
`
variables := map[string]interface{}{
"where": schema_event_bool_exp{
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress,
},
"network": map[string]interface{}{
"_eq": sc.Network,
},
},
}
return a valid value
{efgh-5678-abcd-1234 eth 0x1234567890123456789012345678901234567890 false [0x1111111111111111111111111111111111111111111111111111111111111111 0x2222222222222222222222222222222222222222222222222222222222222222 0x3333333333333333333333333333333333333333333333333333333333333333]}
map[where:map[contractaddress:map[_eq:0x1234567890123456789012345678901234567890] network:map[_eq:eth]]]
{[{1} {2} {3} {6}]}
but if i remove the value in the _contained_in nothing is returned
variables := map[string]interface{}{
"where": schema_event_bool_exp{
"topics": map[string]interface{}{
"_contained_in": map[string]interface{}{},
},
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress,
},
"network": map[string]interface{}{
"_eq": sc.Network,
},
},
}
returned data
2 0x3333333333333333333333333333333333333333333333333333333333333333]}
map[where:map[contractaddress:map[_eq:0x1234567890123456789012345678901234567890] network:map[_eq:eth] topics:map[_contained_in:map[]]]]
{[]}
correct code is
variables := map[string]interface{}{
"where": schema_event_bool_exp{
"topics": map[string]interface{}{
"_contained_in": sc.Topics,
},
"contractaddress": map[string]interface{}{
"_eq": sc.ContractAddress,
},
"network": map[string]interface{}{
"_eq": sc.Network,
},
},
}
again thanks you sir for you time and help , if this could be added to the documentation
{ "uuid": "efgh-5678-abcd-1234", "network": "avalanche", "address": "0x9876543210987654321098765432109876543210", "rulechain": false, "topics": [ "0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6", "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d", "0x5e4f3d2c1b0a99887766554433221100" ] }
i have data to be send like this func QuerySchema(sc Variables_schema) (int, error) { / query MyQuery($ca: String, $nt: String , $tp: jsonb) { schema_event(where: {topics: {_contained_in: $tp}, contractaddress: {_eq: $ca}, network: {_eq: $nt}}) { id } } /
}
am always getting this return map[ca:0x9876543210987654321098765432109876543210 nt:avalanche tp:["0xa1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6","0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d","0x5e4f3d2c1b0a99887766554433221100"]]Message: unexpected variables in variableValues: tp, Locations: [], Extensions: map[code:validation-failed path:$]inside the qyeryschema[GIN] 2023/11/21 - 13:41:21 | 500 | 558.581868ms | ::1 | POST "/api/v1/subscribe"