Home > database >  How to create .csv every day
How to create .csv every day

Time:09-13

In my application, I listen to nats and the output I get is a map with data. I need to generate a daily csv file using the data from the map. Now the data from the map is written to the file continuously. How can I write data to the file only at the end of each day?

type Hits struct {
    HitMap      map[string]map[SearchRequestKey]uint32 
    Mu          sync.RWMutex
    Log         zerolog.Logger
    TimeStart   time.Time
    MinHits     int
    WasDelete   map[string]int64
    Cnt1        float32
    Version     int
    QQMap       map[string]struct{}
    GitlabToken string
}

type SearchRequestKey struct {
    Query string
    Date  string
}

func FileAdd(hits *models.Hits) {
    file, err := os.OpenFile("query-hits.csv", os.O_CREATE|os.O_RDWR, 0644)
    if err != nil {
        fmt.Println(err)
    }

    writer := csv.NewWriter(file)
    writer.Comma = '|'

    for key, value := range hits.HitMap {
        for query, shard := range value {
            err := writer.Write([]string{query.Query, key, strconv.Itoa(int(shard))})
            if err != nil {
                fmt.Println(err)
            }
        }
    }
}

CodePudding user response:

In order to create a .csv file daily, you need to run the code in a loop and make the current time as the starting point. After 24 hours the function will generate the file again. Finally the way with time.AfterFunc() helped. Don't forget to use mutex.

type Hits struct {
    HitMap      map[string]map[SearchRequestKey]uint32 
    Mu          sync.RWMutex
    Log         zerolog.Logger
    TimeStart   time.Time
    MinHits     int
    WasDelete   map[string]int64
    Cnt1        float32
    Version     int
    QQMap       map[string]struct{}
    GitlabToken string
}

type SearchRequestKey struct {
    Query string
    Date  string
}

func FileAdd(hits *models.Hits) {
    hits.Mu.Lock()
    defer hits.Mu.Unlock()

    for {
        year, month, day := time.Now().Date()
        file := strconv.Itoa(year)   month.String()   strconv.Itoa(day)

        fileName, err := os.Create(file)
        if err != nil {
            fmt.Println(err)
        }

        writer := csv.NewWriter(fileName)
        writer.Comma = '|'

        for key, value := range hits.HitMap {
            for query, shard := range value {
                err := writer.Write([]string{query.Query, key, strconv.Itoa(int(shard))})
                if err != nil {
                    fmt.Println(err)
                }
            }
        }
        time.Sleep(24 * time.Hour) //only after 24 hours
    }

}

func FuncThatStart (hits *models.Hits) {
    hits.Mu.Lock()
    defer hits.Mu.Unlock()

    // generate for one day
    today := time.Now()
    tomorrow := today.Add(24 * time.Hour) // same time as in time.Sleep()

    time.AfterFunc(time.Until(tomorrow), func() {
        go storage.FileAdd(hits) //goroutine handle one time per day
    })
}

Thanks for comments

  • Related