How to compare UINT (not uint64 or uint32) with string [closed] - rest

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have written following code and want to check if typed URL in REST API is same with user_id in header to grant the access or return a failure message, but there is following error:
"invalid operation: userId != vars["user_id"] (mismatched types uint and string)"
func UserIdAutentication(w http.ResponseWriter,r *http.Request) {
id := r.Context().Value("user").(uint)
vars:=mux.Vars(r)
if userId != vars["user_id"] {
response := u.Message(false, "User not Autorized to fetch other users data")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
} else {
return
}
}

You should convert user_id to uint before compare to another unit.
id := r.Context().Value("user").(uint)
vars:=mux.Vars(r)
userID, err := strconv.ParseUint(vars["user_id"], 0, 64)
if err != nil {
// Do something with eror
}
if userId!=uint(userID){
response := u.Message(false, "User not Autorized to fetch other users data")
w.WriteHeader(http.StatusForbidden)
w.Header().Add("Content-Type", "application/json")
u.Respond(w, response)
return
}else {
return
}

Related

question about inserting a variable into a mongodb

I need help. I am a self learner and I am trying to understand how to insert a variable that I read from a csv. I want to use that variable and insert it into the mongo db repeatedly again until it finishes reading the csv file. The code is like this. I would really appreciate the help. I am going crazy looking over all the info and on stack overflow. if i can get this right so i can build some confidence in coding with go. thank you
reader, err := csvreader.Read()
if err == io.EOF {
break
} else if err != nil {
panic(err)
}
fmt.Println(reader)
type Event struct {
event_id string `json: "event_id"`
date_added string `bson: time.time`
}
var event = Event{
event_id: {}string reader,
date_added: time.Now().Format("2006-01-02 15:04"),
}
result, err := cli.InsertOne(ctx, event)
fmt.Println(result)```

Validation using golang, gin and gorm with postgres like email already exist in database

I have something like this and I would like to check if email already exist in DB:
func RegisterUser(c *gin) {
var user models.User
if err := c.ShouldBindJSON(&user); err != nil {
c.JSON(http.StatusBadRequest, gin.H{
"messAge": err.Error(),
"data": "",
})
return
}
// **I TRIED SOEMTHING LIKE THIS**
err := database.DB.Find(&user.Email).Error
if err != nil {
c.JSON(401, gin.H{"MESSAGE": "Email ALREADY exist",
return
}
// **but is not working, because ANY mail it give me error**
if !strings.Contains(user.Email, "#") {
c.JSON(400, gin.H{"MESSAGE": utils.ErrEmailWrong})
return
}
if len(user.Password) < 4 {
c.JSON(400, gin.H{"MESSAGE": utils.ErrPasswordLength})
return
}
database.DB.Create(&user)
c.JSON(200, gin.H{
"MESSAGE": "CREATED",
})
}
With this code, every time is telling me that : Email already exist, only works for the first time.
plase read the document:
https://gorm.io/docs/query.html
var userFind models.User
database.DB.Where("email = ?", user.Email).First(&userFind)
Since, your struct object is not a slice. You should use ErrRecordNotFound.
Note : ErrRecordNotFound only works with First, Last, Take which is expected to return some result. And RecordNotFound is removed in V2.
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound){
c.JSON(401, gin.H{"MESSAGE": "Email Not Found",
return
}
c.JSON(401, gin.H{"MESSAGE": "Your Message",
return
}
OR
If you want to avoid the ErrRecordNotFound error, you could use Find like db.Limit(1).Find(&user), the Find method accepts both struct and slice data. And check like this :
result.RowsAffected // returns count of records found
For better understanding refer the link here : https://gorm.io/docs/v2_release_note.html#ErrRecordNotFound and https://gorm.io/docs/query.html
And, If you want to add record in DB though email exist then you should remove unique constraint and also check the error while creating the record. If record successfully created then return success response else return the appropriate error message.
you should validate the input after binding and before db queries
alter your email column to be unique
try to insert the validated data to db
if success => 200 (there was no similar email)
if err => check err code
for example:
func IsUniqueContraintViolation(err error) bool {
if pgError, ok := err.(*pgconn.PgError); ok && errors.Is(err, pgError) {
if pgError.Code == "23505" {
return true
}
}
return false
}
For more Information, you should look GoDoc pg lib and Possible Error Codes
and then, then you can return a suitable error code
btw. hopefully you don't save clear passwords to db :D
ITS FINALLY WORKING ! Thanks for everyone thats answered !

Return postgres errors in api response

I have two simple api methods in my code. Method with endpoind /api/user/create creates user. Field username is unique. When i trying to create user with same username that already exists in database, i have an error in console:
(/home/andrej/go/src/go_contacts/models/users.go:19)
[2020-12-23 22:03:10] pq: duplicate key value violates unique constraint "users_username_key"
I want to show this error in response to user, or somehow identify type of error in my code, to show different error messages for user. I know only that if i have error user returns me id=0. But it doesnt seems like a good message for user.
main.go
package main
import (
"fmt"
"go_contacts/controllers"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)
func main() {
godotenv.Load(".env")
router := mux.NewRouter()
router.HandleFunc("/", controllers.ReturnHello).Methods("GET")
router.HandleFunc("/api/user/create", controllers.CreateUser).Methods("POST")
port := os.Getenv("PORT")
if port == "" {
port = "8000"
}
err := http.ListenAndServe(":"+port, router)
if err != nil {
fmt.Print(err)
}
}
models.go with user struct:
package models
import (
u "go_contacts/utils"
"github.com/jinzhu/gorm"
)
// User base model
type User struct {
gorm.Model
Username string `json:"username" gorm:"unique"`
Password string `json:"password"`
Email string `json:"email"`
}
// Create new user
func (user *User) Create() map[string]interface{} {
GetDB().Create(user)
if user.ID <= 0 {
return u.Message(false, "Failed to create user, connection error.")
}
response := u.Message(true, "Account has been created")
response["user"] = user
return response
}
As for pq v1.5.2 and gorm v1.9.12
First, you need to identify whether create method call returns error or not. Like so
err := GetDB().Create(user).Error
if err != nil {
// code to handle error
}
Then the pq package has special type which maps to postgres server error. It contains fields which can help you to identify the error severity, it's code, table which related to error etc.
Full list of psql fields identifiers can be found here in
Error and Notice Message Fields
https://www.postgresql.org/docs/current/protocol-error-fields.html
To resolve your issue as an option we can use field
Code
Which is a string type representation of error code. But firstly, we need to cast an error and check type cast was successful. Like so
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// code to handle specific error code
}
List of error codes can be found both in the official postgresql docs https://www.postgresql.org/docs/9.3/errcodes-appendix.html
And actual go pq specific mappings to the error in the github.com/lib/pq/error.go as for pq library
And finally we can handle error as duplicate by code
err := GetDB().Create(user).Error
if err != nil {
pqErr, ok := err.(pq.Error)
if !ok {
log.Fatal(err)
}
// note that type casting here is redundant and used for showing specific
// string type from pq library
if pqErr.Code == pq.ErrorCode("23505") { // 23505 is unique_violation error code for psql
// now you can create error and write it to a message to return it for
// a client
}
}
As per the comments gorm provides access to database errors from the Create record function as follows:
result := GetDB().Create(user)
if result.Error != nil {
// Do something with the error
}
Please note that checking the error string is likely to make your application database specific (but this may not be an issue for you). The answers to this question may provide further assistance.

Proper way to query to check if credentials already exist [duplicate]

This question already has answers here:
Scan function by reference or by value
(1 answer)
I want to check if record exist and if not exist then i want to insert that record to database using golang
(4 answers)
Closed 2 years ago.
I currently have:
func foo (w http.ResponseWriter, req *http.Request) {
chekr := `SELECT FROM public."Users" WHERE email=$1`
err = db.QueryRow(chekr, usr.Email).Scan()
if err != sql.ErrNoRows {
data, err := json.Marshal("There is already a user with this email")
if err != nil { w.Write(data) }
}
// code that should run if email isn't found
}
However, I find it never working and always passing the if block.
As the above comment stated, I forgot the */1. QueryRow works, I just had another error somewhere. As others have stated there's others errors, this is just for one case to test.

Go batch insert Returning ID not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I want to batch insert some rows and get their ids with golang, this is my attempt in doing so
import (
"database/sql"
"fmt"
_ "github.com/bmizerany/pq"
"log"
)
func main() {
conn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=require", host, user, password, dbname)
d, err := sql.Open("postgres", conn)
rows, err := d.Query("INSERT INTO MYTABLE(MYCOLUMN) VALUES(1),(2),(3) RETURNING ID")
defer rows.Close()
var ids []int
for rows.Next() {
var id int
scan_err := rows.Scan(&id)
fmt.Println(scan_err)
if scan_err != nil {
log.Fatal(scan_err)
}
ids = append(ids, id)
fmt.Printf("id %d\n", id)
}
}
my problem is ids is always empty even if the values are inserted correctly in the database.
what's interesting is that the following works
var id int
db.QueryRow("INSERT INTO MYTABLE(MYCOLUMN) VALUES(1) RETURNING ID").Scan(&id)
How do solve this?