dr. squid
dr. squid

Reputation: 826

Updating a value from a struct in Golang

I am struggling updating a field coming from Gorm. I am loading all carousels from the database, and have a ticker that checks the field "LastRun", and I want to set a new time.Now() value when it is run.

For now, I only need the loaded struct to be updated, so I know this does not write the changes to the DB at this moment.

How do I update the field carousel.LastRun in func Sequencer() in this example? It keeps having the old value from the DB whatever I do...

package main

import (
    "fmt"
    "github.com/jinzhu/gorm"
    _ "github.com/jinzhu/gorm/dialects/sqlite"
    "sync"
    "time"
)

var (
    db *gorm.DB
    wg = &sync.WaitGroup{}
)

type Carousel struct {
    gorm.Model
    Name        string
    Description string
    Duration    uint
    LastRun     time.Time
    Index       uint8
    State       State
}

type State struct {
    Type string
}

func main() {
    path := "pkg/database/database.db"
    db, err := gorm.Open("sqlite3", path)
    if err != nil {
        panic("failed to connect database")
    }
    defer db.Close()

    db.AutoMigrate(&Carousel{})

    var carousels []Carousel
    db.Find(&carousels)
    wg.Add(1)
    Sequencer(&carousels)
    wg.Wait()
}

func Sequencer(carousels *[]Carousel) {

    ticker := time.NewTicker(1000 * time.Millisecond)
    for range ticker.C {
        for _, carousel := range *carousels {
            next := carousel.LastRun.Add(time.Millisecond * time.Duration(carousel.Duration))
            if next.Sub(time.Now()) <= 0 {
                fmt.Println("Carousel: ", carousel.Name, "Last run: ", time.Since(carousel.LastRun))
                carousel.LastRun = time.Now()
                /* How do I update the carousel.LastRun ? */
            }
        }
    }
}

Upvotes: 0

Views: 1785

Answers (1)

Aditya Satyavada
Aditya Satyavada

Reputation: 1058

To update the carouselstruct, you can do this:

func Sequencer(carousels []*Carousel) {

ticker := time.NewTicker(1000 * time.Millisecond)
for range ticker.C {
    for i, _ := range carousels {
        carousel = carousels[i]
        next := carousel.LastRun.Add(time.Millisecond * time.Duration(carousel.Duration))
        if next.Sub(time.Now()) <= 0 {
            fmt.Println("Carousel: ", carousel.Name, "Last run: ", time.Since(carousel.LastRun))
            carousel.LastRun = time.Now()
        }
    }
  }
}

When using range, the value used(for the carousel var in your case) is a copy of the element in the slice. Hence, even by updating it, it will not update the element in the actual list.

To do so, you need to access the index of the slice you need to update and then perform your changes.

Upvotes: 0

Related Questions