We retriever data and sending a data into database, but its not working - arrays

Actually, i create a for loop
(for _, data := range b.CabinBookingRecords )
*, for the pointing array of *CabinBookingRecords *. from this object we retrieving data and sending a data into a data base ,But its not working ,yaa that's it. ***
I'm trying that, pointing bcabinbooking *,In that im using array of pointer *CabinBookingRecords []CabinBookingDetails in this we create a struct CabinBookingDetails in this we create many objects. Problem is their controllers not goes to for loop i think for loop getting something wrong
func (b *CabinBooking) UpdateCabinBooking(id int16, id1 int16) error {
dt := time.Now()
for _, data := range b.CabinBookingRecords {
cBD := new(CabinBookingDetails)
cBD.CityId = data.CityId
cBD.BuildingId = data.BuildingId
cBD.FloorId = data.FloorId
cBD.CabinBookingId = data.CabinBookingId
cBD.CabinId = data.CabinId
cBD.BookingDate = data.BookingDate
cBD.BookedBy = data.BookedBy
cBD.BookingSlot = data.BookingSlot
cBD.BookingSlotHrs = data.BookingSlotHrs
cBD.CancelledBy = data.CancelledBy
cBD.Active = data.Active
fmt.Println(id, " cabinBookingId", id1, "cabinBookingDetailsId", " slot", cBD.BookingSlot, cBD.BookingSlotHrs)
query := "UPDATE cabin_booking_details SET city_id=$1, building_id=$2, floor_id=$3, cabin_id=$4,booking_date=$5, booked_by=$6, booking_slot=$7,booking_slot_hrs=$8, updated_at=$9 WHERE id=$10 AND cabin_booking_id = $11"
d := migration.DbPool.QueryRow(
context.Background(), query, cBD.CityId, cBD.BuildingId, cBD.FloorId, cBD.CabinId, cBD.BookingDate, cBD.BookedBy, cBD.BookingSlot, cBD.BookingSlotHrs, dt, id1, id,
)
err := d.Scan(&b.Id, &b.CreatedAt, &b.UpdatedAt)
if err != nil {
return err
}
}
return nil
}`
func UpdateCabinBooking(c *fiber.Ctx) error {
id := c.Query("cabin_booking_id")
id1 := c.Query("id") //cabin_booking_details_id
i, e := strconv.Atoi(id)
j, e1 := strconv.Atoi(id1)
if e != nil || e1 != nil {
return c.Status(400).SendString(e.Error())
}
cabinBookingId := int16(i)
cabinBookingDetailsId := int16(j)
workspaceParams := new(model.CabinBooking)
workspaceParams.UpdateCabinBooking(cabinBookingId, cabinBookingDetailsId)
fmt.Println("working")
if err := c.JSON(&fiber.Map{
"success": true,
"message": "Cabin Booking successfully updated",
}); err != nil {
return utility.ErrResponse(c, "Error in response", 500, err)
}
return nil
}
and this router......
api.Put("/cabin_workspace", func(c *fiber.Ctx) error {
user := c.Locals("verify")
if user == "true" {
return controller.UpdateCabinBooking(c)
}
return c.SendStatus(fiber.StatusForbidden)
})
type CabinBooking struct {
Id int16 `json:"id"`
BookingDates []string `json:"booking_dates"`
CabinBookingRecords []*CabinBookingDetails `json:"cabin_booking_records"`
Active bool `json:"active"`
BookedBy int16 `json:"booked_by"` //userID
CancelledBy int16 `json:"cancelled_by"` //userID
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type CabinBookingDetails struct {
Id int16 `json:"id"`
CabinBookingId int16 `json:"cabin_booking_id"`
CabinId int16 `json:"cabin_id"`
CityId int16 `json:"city_id"`
BuildingId int16 `json:"building_id"`
FloorId int16 `json:"floor_id"`
BookingDate string `json:"booking_date"`
BookedBy int16 `json:"booked_by"` //userID
CancelledBy int16 `json:"cancelled_by"` //userID
BookingSlot string `json:"booking_slot"`
BookingSlotHrs int16 `json:"booking_slot_hrs"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
we sending(retrieving) input from postman(api testing), but update the data base:-
{  
"booking_dates": ["2022-12-30",
               "2022-12-31",
            "2022-12-27"
            ],
    "cabin_booking_records" : [
       {
    "booking_date": "2022-12-30",
        "cabin_id": 1,
        "city_id": 1,
        "building_id" : 1,
        "floor_id" : 1,
        "booking_slot": "First_half",
        "booking_slot_hrs":4,
        "active" : true,
        "booked_by" : 5,
        "canceled_by" : 0
        }
    ],
      "active" : true, 
       "booked_by" : 5,
        "canceled_by" : 0
}

Related

missing destination name field_name in struct model

I am using sqlx with mssql driver in golang
here is my struct model :
type Employee struct {
ID string `json:"id,omitempty" validate:"required"`
EmployeeNo int `json:"employeeno,omitempty" validate:"required"`
FullName string `json:"fullname,omitempty" validate:"required"`
}
and here is the rest of the code :
type EmployeeRepo interface {
GetEmployees() (*[]db_models.Employee, error)
}
type employeeRepo struct {
logger *zap.SugaredLogger
db db.DBFactory
}
var _ EmployeeRepo = (*employeeRepo)(nil)
func EmployeeRepoProvider(db db.DBFactory, logger *zap.SugaredLogger) EmployeeRepo {
return &employeeRepo{db: db, logger: logger}
}
func (e *employeeRepo) GetEmployees() (*[]db_models.Employee, error) {
fmt.Println("======= Getting Employees REPOO=======")
employees := &[]db_models.Employee{}
var err error
err = e.db.AuthDB.Select(employees, `SELECT * FROM testEmployees`)
if err != nil {
fmt.Println("err getting emp : ", err)
return nil, err
} else {
return employees, nil
}
}
whenever I try to get data from db I get this :
*missing destination name EmployeeNo in []db_models.Employee
already check issues 234 and 322 and did not work with me

How to insert an array in Postgresql with data from REST echo

I receive data into my echo rest api by post method. I have two arrays. I import pq library.
My structure is
type Lien struct {
LinkID int `json: "linkID"`
Linklabel string `json: "label"`
Linkaddress string `json: "address"`
Langs []string `json: "langs"`
Cats []int `json: "cats"`
}
My post function is
func createLink(c echo.Context) error {
l := new(Lien)
if err := c.Bind(l); err != nil {
return err
}
sqlStatement := "INSERT INTO link_test (label, address,langs, cats)VALUES ($1, $2, $3, $4)"
res, err := db.Query(sqlStatement, l.Linklabel, l.Linkaddress, pq.Array(l.Langs), pq.Array(l.Cats))
if err != nil {
fmt.Println(err)
} else {
fmt.Println(res)
return c.JSON(http.StatusCreated, l)
}
return c.String(http.StatusOK, "ok")
}
It works for the first two fields but not for the arrays, I always get a null value.

Unmarshaling array of objects in Go

in GO, I've tried to produce the following json :
[["my",257.14,257.24],["txt", 121.11, 65.555]]
from a struct that's undergo unmarshaling - and i'm failing to do so.
Here is what I tried:
x := []MyStruct{{Zero: map[int]string{0: "str"}, One: map[int]float32{1: 5.6}, Two: map[int]float32{1: 5.88}}}
where MyStruct is :
type Timestamp struct {
Zero map[int]string `json:"0"`
One map[int]float32 `json:"1"`
Two map[int]float32 `json:"2"`
}
this produces the wrong json structure:
"myStruct":[{"0":{"0":"has"},"1":{"1":5.6},"2":{"1":5.88}}]
tried this as well
any clue in the right direction will be highly appreciated.
Maybe this is your expected. It's possible to implement custom MarshalJSON/UnmarshalJSON.
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
)
type Timestamp struct {
Zero []string
One []float32
Two []float32
}
func (t *Timestamp) UnmarshalJSON(b []byte) error {
var arr [][3]interface{}
err := json.Unmarshal(b, &arr)
if err != nil {
return nil
}
t.Zero = nil
t.One = nil
t.Two = nil
for _, v := range arr {
if len(v) != 3 {
return errors.New("invalid json")
}
if s, ok := v[0].(string); ok {
t.Zero = append(t.Zero, s)
}
if f, ok := v[1].(float64); ok {
t.One = append(t.One, float32(f))
}
if f, ok := v[2].(float64); ok {
t.Two = append(t.Two, float32(f))
}
}
return nil
}
func (t *Timestamp) MarshalJSON() ([]byte, error) {
var arr [][3]interface{}
var max int
if max < len(t.Zero) {
max = len(t.Zero)
}
if max < len(t.One) {
max = len(t.One)
}
if max < len(t.Two) {
max = len(t.Two)
}
for i := 0; i < max; i++ {
var v [3]interface{}
if i < len(t.Zero) {
v[0] = t.Zero[i]
}
if i < len(t.One) {
v[1] = t.One[i]
}
if i < len(t.Two) {
v[2] = t.Two[i]
}
arr = append(arr, v)
}
return json.Marshal(arr)
}
const j = `[["my",257.14,257.24],["txt", 121.11, 65.555]]`
func main() {
var ts Timestamp
err := json.Unmarshal([]byte(j), &ts)
if err != nil {
log.Fatal(err)
}
b, err := json.Marshal(&ts)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
https://play.golang.org/p/WtVEja1JDY
The problem you are having is you're trying to unmarshal a map, and a map will correlate to a JSON object. Your desired output is a list, so you need to unmarshal an array or a slice to get a list as your values.
Try making an adapter.
Small example:
type Object struct {
Base float32
Radius float32
Height float32
X float32
Y float32
}
func (obj *Object) ToCircle() *Circle {
return &Circle{
Radius: obj.Radius,
X: obj.X,
Y: obj.Y,
}
}
func (obj *Object) ToRectangle() *Rectangle {
return &Rectangle{
Base: obj.Base,
Height: obj.Height,
X: obj.X,
Y: obj.Y,
}
}
In the example above, Object is converted to a Rectangle or a Circle using the ToRectangle() and ToCircle() adapters, respectively. In your case, you need to convert Timestamp to a []interface{}. Then you can unmarshal and you'll just get a list of whatever values are in that slice, which is your desired output in this case.
For intsance, the signature if your adapter could look like this:
func (t *Timestamp) ToFoo() []interface{} {
var ret []interface{}
// Do some stuff to take values of 't' and append to 'ret'
return ret
}
func main() {
var result []interface{}
json.Unmarshal(t.ToFoo(), &result)
// ...
}
I'll leave the implementation details for you.

go database/sql - strange connection and transaction behavior

Using Go and implementations of database drivers using database/sql, the behavior that I appear to be experiencing with transactions appears to be that the connection needs to be closed after every transaction. If I don't, the database runs out of connections and I receive the following error :
"Begin Transaction failed. Error = Error 1040: Too many connections". This happens after 101 commits.
I have tried using two different drivers from github - lib/pq and go-sql-driver/mysql with the same results.
This behavior appears strange to me. Is this to be expected, or am I perhaps doing something incorrectly?
As requested, the code is below :
package main
import (
"database/sql"
"fmt"
"time"
"os"
"bufio"
"strconv"
_ "github.com/lib/pq"
//// _ "github.com/go-sql-driver/mysql"
//// _ "github.com/arnehormann/mysql"
)
const C_CONN_RDBMS = "postgres"
const C_CONN_STR = "user=admin dbname=testdb password=admin sslmode=disable"
////const C_CONN_RDBMS = "mysql"
////const C_CONN_STR = "test:test#/testdb?charset=utf8"
var pogDbConn *sql.DB // Db connection
func main() {
fmt.Println("\ntestdb1 - small test on "+C_CONN_RDBMS+" driver")
println()
var iIters int = fGetIterations()
println()
var tCloseConn bool = fGetCloseConn()
tmeStart := time.Now()
fDbTestInserts(iIters, tCloseConn) // run test Insert
fmt.Printf("Elapsed Time to process = %s\n", time.Since(tmeStart))
if pogDbConn != nil {
pogDbConn.Close()
}
}
func fDbTestInserts(iIters int, tCloseConn bool) {
var iCommitted int = 0
var oOsError error
var poDbTxn *sql.Tx
println("Running test inserts .........")
defer func() {fRollback(poDbTxn, iCommitted)} ()
for iPos := 1; iPos <= iIters; iPos += 1 {
if pogDbConn == nil { // must open db
pogDbConn, oOsError = sql.Open(C_CONN_RDBMS, C_CONN_STR)
if oOsError != nil {
fmt.Printf("Failed to open Db Connection. Error = %s\n")
return
}
}
poDbTxn, oOsError := pogDbConn.Begin()
if oOsError != nil {
fmt.Printf("Begin Transaction failed. Error = %s\n", oOsError)
return
}
var sSql string = "INSERT INTO test01 " +
"(sName, dBalance)" +
" VALUES ('Bart Simpson', 999.99)"
_, oOsError = poDbTxn.Exec(sSql)
if oOsError != nil {
fmt.Printf("INSERT for Table failed. Error = %s\n", oOsError)
return
}
_, oOsError = poDbTxn.Exec("COMMIT")
if oOsError != nil {
fmt.Printf("COMMIT for Insert failed. Error = %s\n", oOsError)
return
}
poDbTxn = nil
iCommitted += 1
if iPos%100 == 0 {
fmt.Printf("Iteration = %d, Inserted = %d \n", iPos, iCommitted)
}
if tCloseConn {
pogDbConn.Close()
pogDbConn = nil
}
}
fmt.Printf("Inserts completed - committed = %d\n", iCommitted)
}
func fRollback(poDbTxn *sql.Tx, iCommitted int) {
println("In fDbRollbackTran\n")
fmt.Printf("Committed trans = %d\n", iCommitted)
if poDbTxn == nil {
println("No Rollback required")
} else {
if pogDbConn == nil {
print ("Unable to Rollback - no connection")
} else {
println("Attempting Rollback")
var oOsError error = poDbTxn.Rollback()
if oOsError != nil {
fmt.Printf("Rollback of Transaction failed. Error = %s\n", oOsError)
} else {
println("Rollback Succeeded")
}
}
}
}
func fGetIterations() int {
oBufReader := bufio.NewReader(os.Stdin)
for {
print("Number of Inserts to process : (1 to 10,000) or 'end' : ")
vLine, _, _ := oBufReader.ReadLine()
var sInput string = string(vLine)
if sInput == "end" || sInput == "END" {
os.Exit(1)
}
iTot, oError := strconv.Atoi(sInput)
if oError != nil {
println("Invalid number")
} else if iTot < 1 || iTot > 10000 {
println ("Number must be from 1 to 10,000")
} else {
return iTot
}
}
}
func fGetCloseConn() bool {
oBufReader := bufio.NewReader(os.Stdin)
for {
print("Close Connection every transaction? (y/n/end) : ")
vLine, _, _ := oBufReader.ReadLine()
sInput := string(vLine)
if sInput == "y" || sInput == "n" {
return (sInput == "y")
}
if sInput == "end" || sInput == "END" {
os.Exit(1)
}
}
}
Commit should be done as follows (as advised to me) :
oOsError = poDbTxn.Commit()

How to sort slices in GAE Go

I am trying to sort slices. How to this in gae using go?
I have struct
type courseData struct {
Key *datastore.Key
FormKey *datastore.Key
Selected bool
User string
Name string
Description string
Date time.Time
}
I would like to sort slice of this entity kind in the Name field.
q := datastore.NewQuery("Course")
var courses []*courseData
if keys, err := q.GetAll(c, &courses); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} else {
for i := range courses {
courses[i].Key = keys[i]
}
}
I tried the
Sort(data Interface)
but not sure how to use it.
Please help. Thanks!
For example,
package main
import (
"fmt"
"sort"
"time"
)
type Course struct {
Key string // *datastore.Key
FormKey string // *datastore.Key
Selected bool
User string
Name string
Description string
Date time.Time
}
type Courses []*Course
func (s Courses) Len() int { return len(s) }
func (s Courses) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type ByName struct{ Courses }
func (s ByName) Less(i, j int) bool { return s.Courses[i].Name < s.Courses[j].Name }
func main() {
var courses = Courses{
&Course{Name: "John"},
&Course{Name: "Peter"},
&Course{Name: "Jane"},
}
sort.Sort(ByName{courses})
for _, course := range courses {
fmt.Println(course.Name)
}
Output:
Jane
John
Peter
Course and Courses need to be exported for use by the sort package.
To avoid making the example dependent on GAE, type *datastore.Key was changed to string.
Why not just ask for the entities in the correct order from the datastore?
q := datastore.NewQuery("Course").Order("Name")

Resources