beego api post insert data - api

First of all. I use postman to POST data. How to take data from the postman key.
It works by using this way (in my code I set it by myself).
I want to get firstname, lastname, email in form-data.
I want to use as below.
func InsertOneUser(user User) *User {
o := orm.NewOrm()
qs := o.QueryTable(new(User))
i, _ := qs.PrepareInsert()
var u User
user.FirstName = "firstname" <----- this
user.LastName = "lastname" <----- this
user.Email = "something#yahoo.com" <----- this
user.Password, _ = hashPassword(user.Password)
user.RegDate = time.Now()
id, err := i.Insert(&user)
return &u
}

You need beego.Controller in func. if func has beego.Controller, there are two ways(key, parseform).
package main
import (
"fmt"
"github.com/astaxie/beego"
)
type User struct {
Firstname string `form:"firstname"`
Lastname string `form:"lastname"`
Email string `form:"email"`
}
type MainController struct {
beego.Controller
}
func (this *MainController) Post() {
// using key
firstname := this.GetString("firstname")
lastname := this.GetString("lastname")
email := this.GetString("email")
// using Parseform
u := User{}
if err := this.ParseForm(&u); err != nil {
fmt.Println(err)
}
fmt.Println(u)
this.Ctx.WriteString(fmt.Sprintf("%s %s %s", firstname, lastname, email))
}
func main() {
beego.Router("/api/v1/user", &MainController{})
beego.Run()
}

Related

What is it CHECK constraint failed: subject <> ''?

What is it CHECK constraint failed: subject <> '' ?
I get an error with stmt, err_execontext := s.db.ExecContext(ctx, insert, subject, description).
How can I solve this?
type TODOService struct {
db *sql.DB
}
// NewTODOService returns new TODOService.
func NewTODOService(db *sql.DB) *TODOService {
return &TODOService{
db: db,
}
}
// CreateTODO creates a TODO on DB.
func (s *TODOService) CreateTODO(ctx context.Context, subject, description string) (*model.TODO, error) {
const (
insert = `INSERT INTO todos(subject, description) VALUES(?, ?)`
confirm = `SELECT subject, description, created_at, updated_at FROM todos WHERE id = ?`
)
stmt, err_execontext := s.db.ExecContext(ctx, insert, subject, description)
if err_execontext != nil {
log.Fatal("server/todo.go 31行目", err_execontext)
}
created_id, err_iserid := stmt.LastInsertId()
if err_iserid != nil {
log.Fatal("server/todo.go 35行目", err_iserid)
}
var todo model.TODO
err := s.db.QueryRowContext(ctx, confirm, created_id).Scan(&todo.Subject, &todo.Description, &todo.CreatedAt, &todo.UpdatedAt)
switch {
case err == sql.ErrNoRows:
log.Fatalf("no todo with id %d", created_id)
case err != nil:
log.Fatal(err)
}
return &todo, err
}
type TODOHandler struct {
svc *service.TODOService
}
// NewTODOHandler returns TODOHandler based http.Handler.
func NewTODOHandler(svc *service.TODOService) *TODOHandler {
return &TODOHandler{
svc: svc,
}
}
// Create handles the endpoint that creates the TODO.
func (h *TODOHandler) Create(ctx context.Context, req *model.CreateTODORequest) (*model.CreateTODOResponse, error) {
created_todo, err := h.svc.CreateTODO(ctx, req.Subject, req.Description)
if err != nil {
log.Fatal("Failed to", err)
}
return &model.CreateTODOResponse{TODO: *created_todo}, nil
}
type (
// A TODO expresses ...
TODO struct{
ID int `json:"id"`
Subject string `json:"subject"`
Description string `json:"description"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"UpdatedAt"`
}
// A CreateTODORequest expresses ...
CreateTODORequest struct{
Subject string `json:"subject"`
Description string `json:"description"`
}
// A CreateTODOResponse expresses ...
CreateTODOResponse struct{
TODO TODO `json:"todo"`
}
)
What is it CHECK constraint failed: subject <> '' ?
I get an error with stmt, err_execontext := s.db.ExecContext(ctx, insert, subject, description).
How can I solve this?
CREATE TABLE IF NOT EXISTS todos (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
subject TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
created_at DATETIME NOT NULL DEFAULT (DATETIME('now')),
updated_at DATETIME NOT NULL DEFAULT (DATETIME('now')),
CHECK(subject <> '')
);
CREATE TRIGGER IF NOT EXISTS trigger_todos_updated_at AFTER UPDATE ON todos
BEGIN
UPDATE todos SET updated_at = DATETIME('now') WHERE id == NEW.id;
END;

How to connect to the CDP WebSocket server in Golang?

I want to send CDP commands to WebSocket server exposed by chrome browser.
For example, I create a new session on selenium and get WebSocket url as -> ws://172.20.10.2:4444/session/335d5805e9d98f3c37af004fa91e0f6e/se/cdp
Now I want to send CDP commands to this WebSocket connection and get results.
Sample client code :
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/websocket"
"log"
"net/url"
)
type message1 struct {
Id int `json:"id"`
Result Result `json:"result"`
}
type Result struct {
TargetInfo []TargetInfo `json:"targetInfos"`
}
type TargetInfo struct {
TargetId string `json:"targetId"`
}
type message2 struct {
Id int `json:"id"`
Method string `json:"method"`
Params Parameter `json:"params"`
}
type Parameter struct {
TargetId string `json:"targetId"`
Flatten bool `json:"flatten"`
}
type message3 struct {
Id int `json:"id"`
Method string `json:"method"`
SessionId string `json:"sessionId"`
Parameters EmulationParameter `json:"params"`
}
type EmulationParameter struct {
Width int `json:"width"`
Height int `json:"height"`
DeviceScaleFactor int `json:"deviceScaleFactor"`
Mobile bool `json:"mobile"`
}
type Response2 struct {
Method string `json:"method"`
Parameter SessionResponse `json:"params"`
}
type SessionResponse struct {
SessionId string `json:"sessionId"`
}
type message4 struct {
Id int `json:"id"`
Method string `json:"method"`
SessionId string `json:"sessionId"`
Parameters ScreenshotParameter `json:"params"`
}
type ScreenshotParameter struct {
Width int `json:"width,omitempty"`
}
func main() {
hostURL := "172.20.10.2:4444"
pathURL := "/session/dd44b246de3261c405cb9fcb017ab59a/se/cdp"
u := url.URL{Scheme: "ws", Host: hostURL, Path: pathURL}
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
messageChannel := make(chan string)
go func() {
for {
_, message, err := c.ReadMessage()
//err = c.ReadJSON(p)
if err != nil {
log.Println("read:", err)
return
}
messageChannel <- string(message)
fmt.Println(string(message))
}
}()
message := "{\"id\":1,\"method\":\"Target.getTargets\"}"
//err = c.WriteJSON(websocket.TextMessage, []byte(message))
err = c.WriteMessage(websocket.TextMessage, []byte(message))
if err != nil {
log.Println("write:", err)
return
}
response := <-messageChannel
fmt.Println(response)
decodedResponse := message1{}
json.Unmarshal([]byte(response), &decodedResponse)
fmt.Println(decodedResponse)
fmt.Println(decodedResponse.Result.TargetInfo[0].TargetId)
temp := message2{}
temp.Id = 2
temp.Method = "Target.attachToTarget"
temp.Params.Flatten = true
temp.Params.TargetId = decodedResponse.Result.TargetInfo[0].TargetId
event2, _ := json.Marshal(temp)
err = c.WriteMessage(websocket.TextMessage, event2)
if err != nil {
log.Println("write:", err)
return
}
response2 := <-messageChannel
fmt.Println(response2)
decodedResponse2 := Response2{}
json.Unmarshal([]byte(response2), &decodedResponse2)
fmt.Println("The session Id is")
fmt.Println(decodedResponse2.Parameter.SessionId)
width := 645
height := 9651
scale := 2
temp2 := message3{}
temp2.Id = 1
temp2.SessionId = decodedResponse2.Parameter.SessionId
temp2.Method = "Emulation.setDeviceMetricsOverride"
temp2.Parameters.DeviceScaleFactor = scale
temp2.Parameters.Height = height
temp2.Parameters.Width = width
temp2.Parameters.Mobile = false
event3, _ := json.Marshal(temp2)
err = c.WriteMessage(websocket.TextMessage, event3)
if err != nil {
log.Println("write:", err)
return
}
response3 := <-messageChannel
fmt.Println(response3)
temp3 := message4{}
temp3.Id = 1
temp3.SessionId = decodedResponse2.Parameter.SessionId
temp3.Method = "Page.captureScreenshot"
event4, _ := json.Marshal(temp3)
err = c.WriteMessage(websocket.TextMessage, event4)
if err != nil {
log.Println("write:", err)
return
}
response4 := <-messageChannel
fmt.Println(response4)
}
I wasn't able to reuse this part of the code to send CDP commands to the WebSocket. I want a simple example CDP command.

Filtering and sorting an SQL query to recreate a nested struct

I am new to Go and I'm trying to populate a struct called Reliefworker from an SQL query which I can send as a JSON payload.
Essentially I have a Reliefworker who may be assigned to many communities and the community can consist of multiple regions.
I suspect there is a clever way of doing this other than what I intend which is a primitive solution that will add a sort to the SQL (by Community) and create a function that detects if the community being added is different to the previous one, in which case I would create a new community struct type object to be appended.
type Reliefworker struct {
Name string `json:"name"`
Communities []Community `json:"community"`
Deployment_id string `json:"deployment_id"`
}
type Community struct{
Name string `json:"name"`
community_id string `json:"community_id"`
Regions []Region `json:"regions"`
}
type Region struct{
Name string `json:"name"`
Region_id string `json:"region_id"`
Reconstruction_grant string `json:"reconstruction_grant"`
Currency string `json:"currency"`
}
Currently I have created a struct that reflects what I am actually getting from SQL whilst pondering my next move. Perhaps this might be a good stepping stone instead of attempting an on-the-fly transformation ?
type ReliefWorker_community_region struct {
Deployment_id string
Community_title int
Region_name string
Reconstruction_grant int
}
func GetReliefWorkers(deployment_id string) []Reliefworker {
fmt.Printf("Confirm I have a deployment id:%v\n", deployment_id)
rows, err := middleware.Db.Query("select deployment_id, community_title, region_name, reconstruction_grant WHERE Deployment_id=$1", brand_id)
if err != nil {
return
}
for rows.Next() {
reliefworker := Reliefworker{}
err = rows.Scan(&deployment_id, &community_title, &region_name, &reconstruction_grant)
if err != nil {
return
}
}
rows.Close()
return
}
I think a sort makes a lot of sense, primitive solutions can be the most efficient:
func GetReliefWorkers(deployment_id string) []Reliefworker {
// Added sort to query
q := "select worker_name, community_title, region_name, reconstruction_grant WHERE deployment_id=? ORDER BY community_title"
rows, err := middleware.Db.Query(q, deployment_id)
if err != nil {
return
}
defer rows.Close() // So rows get closed even on an error
c := Community{} // To keep track of the current community
cmatrix := [][]string{[]string{}} // Matrix of communities and workers
communities := []Community{} // List of communities
workers := make(map[string]Reliefworker) // Map of workers
var ccount int // Index of community in lists
for rows.Next() {
w := Reliefworker{Deployment_id: deployment_id}
r := Region{}
var ctitle string // For comparison later
err = rows.Scan(&w.Name, &ctitle, &r.Name, &r.Reconstruction_grant)
if err != nil {
return
}
if ctitle != c.Name {
communities = append(communities, c)
c = Community{}
c.Name = ctitle
ccount++
cmatrix = append(cmatrix, []string{})
}
c.Regions = append(c.Regions, r)
cmatrix[ccount] = append(cmatrix[ccount], w.Name)
workers[w.Name] = w
}
for i, c := range communities {
for _, id := range cmatrix[i] {
w := workers[id] // To avoid error
w.Communities = append(w.Communities, c)
workers[id] = w
}
}
out := []Reliefworker{}
for _, w := range workers {
out = append(out, w)
}
return out
}
Though it might make even more sense to create seperate tables for communities, regions, and workers, then query them all with a JOIN: https://www.w3schools.com/sql/sql_join_inner.asp
UPDATE: Since you only want to retrieve one Reliefworker, would something like this work?
type ReliefWorker struct {
Name string `json:"name"`
Communities []Community `json:"community"`
}
type Community struct {
Name string `json:"name"`
Regions []Region `json:"regions"`
}
type Region struct {
Name string `json:"name"`
Region_id string `json:"region_id"`
Reconstruction_grant int `json:"reconstruction_grant"`
Currency string `json:"currency"`
}
func GetReliefWorkers(deployment_id string) Reliefworker {
reliefworker := Reliefworker{}
communities := make(map[string]Community)
rows, err := middleware.Db.Query("select name, community_title, region_name, region_id, reconstruction_grant WHERE Deployment_id=$1", deployment_id)
if err != nil {
if err == sql.ErrNoRows {
fmt.Printf("No records for ReliefWorker:%v\n", deployment_id)
}
panic(err)
}
defer rows.Close()
for rows.Next() {
c := Community{}
r := Region{}
err = rows.Scan(&reliefworker.Name, &c.Name, &r.Name, &r.Region_id, &r.Reconstruction_grant)
if err != nil {
panic(err)
}
if _, ok := communities[c.Name]; ok {
c = communities[c.Name]
}
c.Regions = append(c.Regions, r)
communities[c.Name] = c
}
for _, c := range commmunities {
reliefworker.Communities = append(reliefworker.Communities, c)
}
return reliefworker
}
Ok, my crude solution doesn't contain a shred of the intelligence #Absentbird demonstrates but I'm here to learn.
#Absentbird I love your use of maps and multidimensional arrays to hold a matrix of communities and workers. I will focus on making this part of my arsenal over the weekend.
I can accept and adapt #Absentbird's solution once I have a solution to why it gives the error "cannot assign to struct field workers[id].Communities in mapcompilerUnaddressableFieldAssign" for the line workers[id].Communities = append(workers[id].Communities, c)
Firstly apologies as I had to correct two things. Firstly I only needed to return ReliefWorkers (not an array of ReliefWorkers). Secondly ReliefWorker struct did not need to contain the Deployment_id since I already knew it.
I am new to Go so I'd really appreciate feedback on what I can do to better leverage the language and write more concise code.
My structs and solution is currently as follows:
type ReliefWorker struct {
Name string `json:"name"`
Communities []Community `json:"community"`
}
type Community struct {
Name string `json:"name"`
Regions []Region `json:"regions"`
}
type Region struct {
Name string `json:"name"`
Region_id string `json:"region_id"`
Reconstruction_grant int `json:"reconstruction_grant"`
Currency string `json:"currency"`
}
type ReliefWorker_community_region struct {
Name string
Community_title string
Region_name string
Reconstruction_grant int
}
func GetReliefWorkers(deployment_id string) Reliefworker {
var reliefworker Reliefworker
var communitiesOnly []string
var name string
var allReliefWorkerData []ReliefWorker_community_region
rows, err := middleware.Db.Query("select name, community_title, region_name, reconstruction_grant WHERE Deployment_id=$1", deployment_id)
for rows.Next() {
reliefWorker_community_region := ReliefWorker_community_region{}
err = rows.Scan(&reliefWorker_community_region.Name, &reliefWorker_community_region.Community_title, &reliefWorker_community_region.Region_name, &reliefWorker_community_region.Reconstruction_grant)
if err != nil {
panic(err)
}
name = reliefWorker_community_region.Name
allReliefWorkerData = append(allReliefWorkerData, reliefWorker_community_region)
communitiesOnly = append(communitiesOnly, reliefWorker_community_region.Community_title) //All communities go in here, even duplicates, will will create a unique set later
}
rows.Close()
if err != nil {
if err == sql.ErrNoRows {
fmt.Printf("No records for ReliefWorker:%v\n", deployment_id)
}
panic(err)
}
var unique []string //Use this to create a unique index of communities
for _, v := range communitiesOnly {
skip := false
for _, u := range unique {
if v == u {
skip = true
break
}
}
if !skip {
unique = append(unique, v)
}
}
fmt.Println(unique)
reliefworker.Name = name
var community Community
var communities []Community
for _, v := range unique {
community.Name = v
communities = append(communities, community)
}
// Go through each record from the database held within allReliefWorkerData and grab every region belonging to a Community, when done append it to Communities and finally append that to ReliefWorker
for j, u := range communities {
var regions []Region
for i, v := range allReliefWorkerData {
if v.Community_title == u.Name {
var region Region
region.Name = v.Region_name
region.Reconstruction_grant = v.Reconstruction_grant
regions = append(regions, region)
}
}
communities[j].Regions = regions
}
reliefworker.Communities = communities
return reliefworker
}

Scan array typed DB field into array/slice in Golang

tl; dr
I have an sql table users which includes an array field. How can I Scan it to variable in golang? My approach:
var id int
var username string
var activites []string
row := db.QueryRow("SELECT id, username, activities FROM users WHERE id = 1")
err := row.Scan(&id, &username, &activites)
Works fine for id, username.
As #mkopriva already pointed out, this can either be accomplished using the StringArray method or with the more flexible Array method (as it accepts an interface as the argument), both found within the "github.com/lib/pq" package.
As an aside, it is also a good practice to use prepared statements.
Full example:
var id int
var username string
var activities []string
sqlStatement := `
SELECT
id,
username,
activities
FROM
users
WHERE
id = $1
`
stmt, err := db.Prepare(sqlStatement)
if err != nil {
// handle err
}
defer stmt.Close()
row := stmt.QueryRow(1)
err = row.Scan(
&id,
&username,
pq.Array(&activities) // used here
)
if err == sql.ErrNoRows {
// handle err
}
if err != nil {
// handle err
}

Convert query result from struct to string for another Golang package

I have searched for a solution on the net and in SO, but found nothing that apply to return values. It is a simple sql query with several rows that I want to return. Error handling not included:
func Fetch(query string) (string) {
type User struct{
id string
name string
}
rows, err := db.Query(query)
users := make([]*User, 0)
for rows.Next() {
user := new(User)
err := rows.Scan(&user.id, &user.name)
users = append(users, user)
}
return(users)
}
I get this error when compiling:
cannot use users (type []*User) as type string in return argument
How should I do to get a correct return value?
The expected input is
JD John Doe --OR-- {id:"JD",name:"John Doe"}
Add this to your code:
type userSlice []*User
func (us userSlice) String() string{
var s []string
for _, u := range us {
if u != nil {
s = append(s, fmt.Sprintf("%s %s", u.id, u.name))
}
}
return strings.Join(s, "\n")
}
type User struct{
id string
name string
}
In your Fetch function replace the last return statement like this:
func Fetch(query string) (string) {
// Note that we declare the User type outside the function.
rows, err := db.Query(query)
users := make([]*User, 0)
for rows.Next() {
user := new(User)
err := rows.Scan(&user.id, &user.name)
users = append(users, user)
}
return(userSlice(users).String()) // Replace this line in your code
}
If you have to return a String you can use the encoding/json package to serialize your user object, but you have to use fields that begin with capital letters for them to be exported. See the full example:
import (
"encoding/json"
)
func Fetch(query string) (string) {
type User struct{
Id string // <-- CHANGED THIS LINE
Name string // <-- CHANGED THIS LINE
}
rows, err := db.Query(query)
users := make([]*User, 0)
for rows.Next() {
user := new(User)
err := rows.Scan(&user.id, &user.name)
users = append(users, user)
}
return(ToJSON(users)) // <-- CHANGED THIS LINE
}
func ToJSON(obj interface{}) (string) {
res, err := json.Marshal(obj)
if err != nil {
panic("error with json serialization " + err.Error())
}
return string(res)
}