package main


import (

"database/sql"

"fmt"

"math/rand"

"strings"

"sync"

"time"


_ "github.com/go-sql-driver/mysql"

)


type Tag struct {

ID   int    `json:"id"`

Name string `json:"name"`

}


type Job struct {

id   int

name string

}

type Result struct {

job         Job

sumofdigits int

}


var jobs = make(chan Job, 10)

var results = make(chan Result, 10)


func initData(name string) int {

db, err := sql.Open("mysql", "root:linuxer@tcp(127.0.0.1:3306)/study")

if err != nil {

panic(err.Error())

}

defer func() {

db.Close()

}()

strSql := strings.Join([]string{"INSERT INTO t(name) VALUES('", name, "')"}, "")

fmt.Println(strSql)

_, err = db.Query(strSql)


// handle error

if err != nil {

panic(err)

}


fmt.Print("Successfully  Inserted\n")

return 0

}


func worker(wg *sync.WaitGroup) {

for job := range jobs {

output := Result{job, initData(job.name)}

results <- output

}

wg.Done()

}


func createWorkerPool(noOfWorkers int) {

var wg sync.WaitGroup

for i := 0; i < noOfWorkers; i++ {

wg.Add(1)

go worker(&wg)

}

wg.Wait()

close(results)

}


func allocate(noOfJobs int) {

for i := 0; i < noOfJobs; i++ {

name := RandStringBytes(5)

job := Job{i, name}

jobs <- job

}

close(jobs)

}

func result(done chan bool) {

for result := range results {

fmt.Printf("Job id %d, input random no %d , sum of digits %d\n", result.job.id, result.job.name, result.sumofdigits)

}

done <- true

}


const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"


func RandStringBytes(n int) string {

b := make([]byte, n)

for i := range b {

b[i] = letterBytes[rand.Intn(len(letterBytes))]

}

return string(b)

}


func main() {

startTime := time.Now()

noOfJobs := 20

go allocate(noOfJobs)

done := make(chan bool)

go result(done)

noOfWorkers := 3

createWorkerPool(noOfWorkers)

<-done

endTime := time.Now()

diff := endTime.Sub(startTime)

fmt.Println("total time taken ", diff.Seconds(), "seconds")

}