func (s *DatastoreStorage) LoadAccess(code string) (*osin.AccessData, error) { log.Infof(s.ctx, "LoadAccess(%s)\n", code) k := datastore.NewKey(s.ctx, "Access", code, 0, nil) data := AccessData{} //data := new(AccessData) typeOfPropertyLoadSaver := reflect.TypeOf((*datastore.PropertyLoadSaver)(nil)).Elem() v := reflect.ValueOf(data) t := v.Type() log.Infof(s.ctx, "********** type = %v", t) if reflect.PtrTo(t).Implements(typeOfPropertyLoadSaver) { log.Infof(s.ctx, "*** %v implements %v", t, typeOfPropertyLoadSaver) } else { log.Infof(s.ctx, "*** %v does NOT implement %v", t, typeOfPropertyLoadSaver) } if err := datastore.Get(s.ctx, k, &data); err != nil { log.Errorf(s.ctx, "!!!!!! Error reading access data: %v", err.Error()) return nil, err } else { log.Infof(s.ctx, ">>>>> Retrieved Access (%v) = %v", k, data) } return data.AccessData, nil }
func handleResult(c context.Context, w http.ResponseWriter, r *http.Request, uuid string, successChannel, errorChannel chan []byte, timeoutVal uint16, action string) { for { select { case success, ok := <-successChannel: if !ok { log.Infof(c, "success!OK") break } if string(success) != "[]" { log.Infof(c, "success:", string(success)) sendResponseToChannel(w, string(success), r, uuid) } return case failure, ok := <-errorChannel: if !ok { log.Infof(c, "fail1:", string("failure")) break } if string(failure) != "[]" { log.Infof(c, "fail:", string(failure)) sendResponseToChannel(w, string(failure), r, uuid) } return } } }
func refreshToggles(c context.Context) error { appConfig, err := dao.getAppConfig(c) if err == appConfigPropertyNotFound { // Nothing in Memcache, nothing in Datastore! // Then, init default (hard-coded) toggle values and persist them. initToggles() log.Infof(c, "Saving default Toggles to Datastore...") err := dao.saveAppConfig(c, ApplicationConfig{Id: 0, Toggles: toggles}) if err == nil { log.Infof(c, "Default Toggles saved to Datastore.") configTime = time.Now().Format("2006-01-02_15-04") } return err } if err != nil { log.Errorf(c, "Error while loading ApplicationConfig from datastore: %v", err) return err } toggles = appConfig.Toggles configTime = time.Now().Format("2006-01-02_15-04") log.Infof(c, "Updated Toggles from memcached or datastore\n") // _ = appConfig return err }
func (api *GithubAPI) getCommitSummaryStats(since time.Time) (CommitStats, error) { var stats CommitStats // list organizations: GET /user/orgs organizations, err := api.getOrganizations() if err != nil { return stats, err } for _, organization := range organizations { // list repositories: GET /orgs/:org/repos repositories, err := api.getRepositories(organization) if err != nil { return stats, err } log.Infof(api.ctx, "REPOSITORIES:%v", repositories) for _, repository := range repositories { // list all commits for repository: GET /repos/:owner/:repo/commits shas, err := api.getUserCommitShas(organization, repository, since) if err != nil { return stats, err } log.Infof(api.ctx, "SHAS:%v", shas) for _, sha := range shas { // get a single commit: GET /repos/:owner/:repo/commits/:sha cs, err := api.getCommitStats(organization, repository, sha) if err != nil { return stats, err } stats.Additions += cs.Additions stats.Deletions += cs.Deletions } } } return stats, nil }
func sendTweet(c context.Context, title string, path string, tags []string) error { spreadsheetsID := "1Vk83CXQacadLSBgguE9UJ1_l5_qX072cmy4ieiwh7HU" sheetID := "1373105893" sheet, err := gapps.GetSpreadsheet(c, spreadsheetsID, sheetID) if err != nil { return err } log.Infof(c, title) consumerKey := sheet.Table.Rows[1].C[0].V consumerSecret := sheet.Table.Rows[1].C[1].V accessToken := sheet.Table.Rows[1].C[2].V accessTokenSecret := sheet.Table.Rows[1].C[3].V tagString := "" for _, tag := range tags { if strings.HasPrefix(tag, "@") { tagString += " " + tag } else { tagString += " #" + tag } } anaconda.SetConsumerKey(consumerKey) anaconda.SetConsumerSecret(consumerSecret) api := anaconda.NewTwitterApi(accessToken, accessTokenSecret) api.HttpClient.Transport = &urlfetch.Transport{Context: c} _, err = api.PostTweet(title+" "+path+tagString, nil) if err != nil { log.Infof(c, err.Error()) } return nil }
func getID(res http.ResponseWriter, req *http.Request) (string, error) { ctx := appengine.NewContext(req) var id, origin string var cookie *http.Cookie origin = "cookerino" cookie, err := req.Cookie("session-id") if err == http.ErrNoCookie { origin = "URL" id := req.FormValue("id") if id == "" { origin = "Usercreated via logout" log.Infof(ctx, "ID created by: %s", origin) http.Redirect(res, req, "/logout", http.StatusSeeOther) return id, errors.New("error logged out manually") } cookie = &http.Cookie{ Name: "session-id", Value: id, // Secure: true, HttpOnly: true, } http.SetCookie(res, cookie) } id = cookie.Value log.Infof(ctx, "ID CAME FROM %s", origin) return id, nil }
/** gets the id from cookie firstly, if there is no cookie then searches in the url, if no id whatsoever then generates a new id and redirects to logout page. if there exists an id then store it in cookie or you can say in some cases updated the old one */ func getAvailableId(res http.ResponseWriter, req *http.Request) (string, error) { ctx := appengine.NewContext(req) var id, origin string var cookie *http.Cookie // getting id from cookie firstly origin = "COOKIE" cookie, err := req.Cookie("session-id") if err == http.ErrNoCookie { //no cookie set try to get id from url origin = "URL" id := req.FormValue("id") if id == "" { //no id whatsoever lets generate a new one and redirect to logout page //tracking our origin for id origin = "BRAND NEW VIA LOGOUT" log.Infof(ctx, "ID CAME FROM: %s", origin) //using the status code names is a good habit giving a readability of code http.Redirect(res, req, "/logout", http.StatusSeeOther) return id, errors.New("ERROR: redirect to /logout because no session id accessible") } // update the cookie storing id for later usages cookie = &http.Cookie{ Name: "session-id", Value: id, //for development usages secure has been turned off // Secure: true, HttpOnly: true, } http.SetCookie(res, cookie) } id = cookie.Value //checking out the origin from where our cookie is generated log.Infof(ctx, "ID CAME FROM %s", origin) return id, nil }
func fing(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) // get session memItem, err := getSession(req) if err != nil { log.Infof(ctx, "Attempt to see following from logged out user") http.Error(res, "You must be logged in", http.StatusForbidden) return } var sd SessionData if err == nil { // logged in json.Unmarshal(memItem.Value, &sd) sd.LoggedIn = true } // Get followees // get the datastore key for the follower followerKey := datastore.NewKey(ctx, "Users", sd.UserName, 0, nil) var XF []F _, err = datastore.NewQuery("Follows").Ancestor(followerKey).Project("Following").GetAll(ctx, &XF) log.Infof(ctx, "here is type %T \n and value %v", XF, XF) if err != nil { log.Errorf(ctx, "error getting followees: %v", err) http.Error(res, err.Error(), 500) return } sd.Following = XF tpl.ExecuteTemplate(res, "follow.html", &sd) }
func wordCheck(res http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) // retrieve the incoming word as it is typed. var w Word bs, err := ioutil.ReadAll(req.Body) // log.Infof(ctx, "Received information: %v", string(bs)) // if err != nil { log.Infof(ctx, err.Error()) } w.Name = string(bs) log.Infof(ctx, "ENTERED wordCheck - w.Name: %v", w.Name) // check the incoming word against what is currently in the datastore key := datastore.NewKey(ctx, "Dictionary", w.Name, 0, nil) err = datastore.Get(ctx, key, &w) if err != nil { io.WriteString(res, "false") return } io.WriteString(res, "true") }
//ServeHTTP recives and processes a request from the web. Expects a parameter //q which is the query string. func (mb MapBuilder) ServeHTTP(writer http.ResponseWriter, request *http.Request) { //Create a context mb.c = appengine.NewContext(request) log.Infof(mb.c, "Starting Tweet Harvest.") //Get the query string and validate that it is not an error query, err := getQuery(request, mb.c) if err != nil { log.Errorf(mb.c, "Failed to get query from querystring.") http.Error(writer, err.Error(), http.StatusInternalServerError) } mb.query = query cutoff := getNewestTweet(mb.c) log.Infof(mb.c, "Newest Tweet in datastore is dated: %v", cutoff.String()) rawTweets := make(chan anaconda.Tweet) shortLinkTweets := make(chan anaconda.Tweet) //longLinkTweets := make(chan LinkTweet, 15) retriever := &TweetRetriever{context: mb.c, out: rawTweets} var wg sync.WaitGroup wg.Add(4) go retriever.getTweets(query, cutoff, &wg) go mb.extractLinks(rawTweets, shortLinkTweets, &wg) wg.Wait() writer.WriteHeader(http.StatusOK) }
func showList(res http.ResponseWriter, req *http.Request, params httprouter.Params) { tpl, err := template.ParseFiles("assets/templates/templates.gohtml") if err != nil { panic(err) } ctx := appengine.NewContext(req) qp := datastore.NewQuery("ToDo") ToDos := []ToDo{} _, error := qp.GetAll(ctx, &ToDos) if error != nil { log.Infof(ctx, "%v", error.Error()) } log.Infof(ctx, "HERE IS THE SLICE: %v", ToDos) log.Infof(ctx, "HERE IS THE SLICE LENGTH: %v", len(ToDos)) if len(ToDos) == 0 { ToDos = nil } else { json.NewEncoder(res).Encode(ToDos) } err = tpl.ExecuteTemplate(res, "todo-list", ToDos) if err != nil { http.Error(res, err.Error(), 500) } }
// Update the database if the lastPullTime is more than 6 hours before the current time func updateDB(db *sql.DB, ctx context.Context, lastPullTime int64) int64 { // If the last pull was more than 6 hours ago if lastPull < time.Now().Add(-1*timeout).Unix() { log.Infof(ctx, "Updating database") // Remove deleted questions from the database log.Infof(ctx, "Removing deleted questions from db") if err := backend.RemoveDeletedQuestions(db, ctx); err != nil { log.Warningf(ctx, "Error removing deleted questions: %v", err.Error()) return lastPullTime } // Setting time frame to get new questions. toDate := time.Now() fromDate := time.Unix(lastPull, 0) // Collect new questions from SO questions, err := backend.GetNewQns(fromDate, toDate) if err != nil { log.Warningf(ctx, "Error getting new questions: %v", err.Error()) return lastPullTime } // Add new questions to database log.Infof(ctx, "Adding new questions to db") if err := backend.AddQuestions(db, ctx, questions); err != nil { log.Warningf(ctx, "Error adding new questions: %v", err.Error()) return lastPullTime } lastPullTime = time.Now().Unix() log.Infof(ctx, "New questions added") } return lastPullTime }
// Handler for adding a new question to the database upon submission // It is returned as a stringified JSON object in the request body // The string is unmarshalled into a stackongo.Question type, and added to an array // to be added into the database using the AddQuestions function in backend/databasing.go func addNewQuestionToDatabaseHandler(w http.ResponseWriter, r *http.Request, ctx context.Context) { body, err := ioutil.ReadAll(r.Body) if err != nil { log.Infof(ctx, "%v", err) } var f interface{} err = json.Unmarshal(body, &f) if err != nil { log.Infof(ctx, "%v", err) } m := f.(map[string]interface{}) question := m["Question"] state := m["State"] if err != nil { log.Infof(ctx, "%v", err) } var qn stackongo.Question json.Unmarshal([]byte(question.(string)), &qn) log.Infof(ctx, "%v", qn) user := getUser(w, r, ctx) log.Infof(ctx, "%v", user.User_id) if err := backend.AddSingleQuestion(db, qn, state.(string), user.User_id); err != nil { log.Warningf(ctx, "Error adding new question to db:\t", err) } backend.UpdateTableTimes(db, ctx, "question") }
func createUser(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) NewUser := User{ Email: req.FormValue("email"), UserName: req.FormValue("userName"), Password: req.FormValue("password"), } q := datastore.NewQuery("Users").Filter("Email =", req.FormValue("email")) var count int = 0 for t := q.Run(ctx); ; { var x User count++ _, err1 := t.Next(&x) if err1 == datastore.Done { log.Infof(ctx, "ERR: %v", err1) log.Infof(ctx, "ERR: %v", count) break } } if count <= 1 { key := datastore.NewKey(ctx, "Users", NewUser.UserName, 0, nil) key, err := datastore.Put(ctx, key, &NewUser) if err != nil { log.Errorf(ctx, "error adding todo: %v", err) http.Error(res, err.Error(), 500) return } http.Redirect(res, req, "/", 302) } else { http.Redirect(res, req, "/fail", 302) } }
func (a *GaeDatastoreAccessor) unindexAll(c context.Context) error { log.Infof(c, "Unindexing everything (from the text search indexes)") // Must remove 1 by 1 (Index has no batch methods) for _, indexName := range []string{ "idioms", "impls", "cheatsheets", } { log.Infof(c, "Unindexing items of [%v]", indexName) index, err := gaesearch.Open(indexName) if err != nil { return err } it := index.List(c, &gaesearch.ListOptions{IDsOnly: true}) for { docID, err := it.Next(nil) if err == gaesearch.Done { break } if err != nil { log.Errorf(c, "Error getting next indexed object to unindex: %v", err) return err } err = index.Delete(c, docID) if err != nil { return err } } } return nil }
func handler(w http.ResponseWriter, r *http.Request) { ctx := appengine.NewContext(r) // [START intro_2] // Create an Item item := &memcache.Item{ Key: "lyric", Value: []byte("Oh, give me a home"), } // Add the item to the memcache, if the key does not already exist if err := memcache.Add(ctx, item); err == memcache.ErrNotStored { log.Infof(ctx, "item with key %q already exists", item.Key) } else if err != nil { log.Errorf(ctx, "error adding item: %v", err) } // Change the Value of the item item.Value = []byte("Where the buffalo roam") // Set the item, unconditionally if err := memcache.Set(ctx, item); err != nil { log.Errorf(ctx, "error setting item: %v", err) } // Get the item from the memcache if item, err := memcache.Get(ctx, "lyric"); err == memcache.ErrCacheMiss { log.Infof(ctx, "item not in the cache") } else if err != nil { log.Errorf(ctx, "error getting item: %v", err) } else { log.Infof(ctx, "the lyric is %q", item.Value) } // [END intro_2] }
func registerHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) log.Infof(c, "Register") u := user.Current(c) r.ParseForm() userKey := r.FormValue("UserKey") log.Infof(c, "UserKey:%s", userKey) if existUser(r, userKey) { log.Infof(c, "Exists") return } rtn := User{ UserKey: userKey, Size: 0, } _, err := datastore.Put(c, datastore.NewKey(c, "User", u.ID, 0, nil), &rtn) if err != nil { panic(err) } //Profile Page meRender(w, "./templates/me/profile.tmpl", rtn) }
// bool means 'found' func BytesFromShardedMemcache(c context.Context, key string) ([]byte, bool) { keys := []string{} for i := 0; i < 32; i++ { keys = append(keys, fmt.Sprintf("=%d=%s", i*chunksize, key)) } if items, err := memcache.GetMulti(c, keys); err != nil { log.Errorf(c, "fdb memcache multiget: %v", err) return nil, false } else { b := []byte{} for i := 0; i < 32; i++ { if item, exists := items[keys[i]]; exists == false { break } else { log.Infof(c, " #=== Found '%s' !", item.Key) b = append(b, item.Value...) } } log.Infof(c, " #=== Final read len: %d", len(b)) if len(b) > 0 { return b, true } else { return nil, false } } }
func getSoldCounter(c context.Context) int { var cachedCounter int _, err := memcache.JSON.Get(c, "sold", &cachedCounter) if err == nil { log.Infof(c, "[counter] Cache hit") return cachedCounter } if err != memcache.ErrCacheMiss { log.Infof(c, "[counter] Unexpected error") web.LogError(c, err, "Error accessing counter in memcache") } else { log.Infof(c, "[counter] Cache miss") } sold := new(Counter) key := datastore.NewKey(c, "Counter", "sold", 0, nil) err = datastore.Get(c, key, sold) if err != nil && err != datastore.ErrNoSuchEntity { web.LogError(c, err, "Error reading counter from datastore") return 0 } err = memcache.JSON.Set(c, &memcache.Item{ Key: "sold", Object: &sold.Value, }) if err != nil { web.LogError(c, err, "Error storing counter in memcache") } return sold.Value }
func retrieveMemc(id string, req *http.Request) (model, error) { var m model ctx := appengine.NewContext(req) item, err := memcache.Get(ctx, id) if err != nil { // get data from datastore log.Infof(ctx, "VALUE FROM DATASTORE: %s", err) m, err = retrieveDstore(id, req) if err != nil { return m, err } // put data in memcache storeMemc(m, id, req) return m, nil } // unmarshal from JSON log.Infof(ctx, "VALUE FROM MEMCACHE") err = json.Unmarshal(item.Value, &m) if err != nil { log.Errorf(ctx, "ERROR retrieveMemc unmarshal: %s", err) return m, err } return m, nil }
// count active users in channel with channels.info then users.getPresence // very slow due to network func activeUsersInChannel(c context.Context, channelId string) (users []string, err error) { bot := bot.WithClient(urlfetch.Client(c)) members, err := bot.ChannelsInfo(channelId) l.Infof(c, "check %v", members) active := make(chan string, len(members)) var wg sync.WaitGroup for i := range members { wg.Add(1) go func(user string, active chan string, wg *sync.WaitGroup) { defer wg.Done() l.Infof(c, "begin "+user) if p, err := bot.UsersGetPresence(user); err != nil { l.Errorf(c, "%s", err) return } else if p == "active" { active <- user } l.Infof(c, "done "+user) }(members[i], active, &wg) } wg.Wait() l.Infof(c, "done wait") close(active) users = make([]string, len(members)) for user := range active { users = append(users, user) } return }
func sendTweet(c context.Context, spreadsheetsID string, sheetID string, title string, path string, tags []string) error { sheet, error := gapps.GetSpreadsheet(c, spreadsheetsID, sheetID) if error != nil { return error } log.Infof(c, title) consumerKey := sheet.Table.Rows[1].C[0].V consumerSecret := sheet.Table.Rows[1].C[1].V accessToken := sheet.Table.Rows[1].C[2].V accessTokenSecret := sheet.Table.Rows[1].C[3].V tagString := "" for _, tag := range tags { tagString += " #" + tag } anaconda.SetConsumerKey(consumerKey) anaconda.SetConsumerSecret(consumerSecret) api := anaconda.NewTwitterApi(accessToken, accessTokenSecret) api.HttpClient.Transport = &urlfetch.Transport{Context: c} _, error = api.PostTweet(title+" "+path+tagString, nil) if error != nil { log.Infof(c, error.Error()) } return nil }
func (s *MigrationService) RunAll(ctx context.Context) error { span := trace.FromContext(ctx).NewChild("trythings.migration.RunAll") defer span.Finish() su, err := IsSuperuser(ctx) if err != nil { return err } if !su { return errors.New("must run migrations as superuser") } latest, err := s.latestVersion(ctx) if err != nil { return err } log.Infof(ctx, "running all migrations. latest is %s", latest) for _, m := range migrations { if m.Version.After(latest) { log.Infof(ctx, "running migration version %s", m.Version) err = s.run(ctx, m) if err != nil { return err } } } return nil }
func getID(res http.ResponseWriter, req *http.Request) (string, error) { ctx := appengine.NewContext(req) var id, origin string var cookie *http.Cookie origin = "COOKIE" cookie, err := req.Cookie("session-id") if err == http.ErrNoCookie { // try to get the id from the URL origin = "URL" id := req.FormValue("id") if id == "" { origin = "BRAND NEW VIA LOGOUT" log.Infof(ctx, "ID CAME FROM: %s", origin) http.Redirect(res, req, "/logout", http.StatusSeeOther) return id, errors.New("ERROR: redirect to /logout because no session id accessible") } cookie = &http.Cookie{ Name: "session-id", Value: id, // Secure: true, HttpOnly: true, } http.SetCookie(res, cookie) } id = cookie.Value log.Infof(ctx, "ID CAME FROM %s", origin) return id, nil }
func init() { delayedGetStats = delay.Func( "my-favorite-dog", func(ctx context.Context, accessToken, username string) error { log.Infof(ctx, "delayedGetStats CALLED") api := &GithubAPI{ ctx: ctx, accessToken: accessToken, username: username, } since := time.Now().Add(-time.Hour * 24 * 30) stats, err := api.getCommitSummaryStats(since) if err != nil { return err } log.Infof(ctx, "STATS: %v", stats) key := datastore.NewKey(ctx, "Stats", username, 0, nil) _, err = datastore.Put(ctx, key, &stats) if err != nil { return err } return nil }, ) }
func (a *MinecraftCronApi) deleteInstance(ctx context.Context, is *compute.InstancesService, world string) <-chan error { log.Infof(ctx, "Delete Instance Target World Name = %s", world) receiver := make(chan error) go func() { var minecraft Minecraft key := datastore.NewKey(ctx, "Minecraft", world, 0, nil) err := datastore.Get(ctx, key, &minecraft) if err == datastore.ErrNoSuchEntity { log.Infof(ctx, "Minecraft Entity Not Found. world = %s", world) receiver <- nil return } if err != nil { receiver <- nil return } minecraft.Key = key _, err = deleteInstance(ctx, is, minecraft) receiver <- err }() return receiver }
func tweetProcess(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) memItem, err := getSession(req) if err != nil { log.Infof(ctx, "Attempt to post tweet from logged out user") http.Error(res, "You must be logged in", http.StatusForbidden) return } // declare a variable of type user // initialize user with values from memcache item var user User json.Unmarshal(memItem.Value, &user) // declare a variable of type tweet // initialize it with values log.Infof(ctx, user.UserName) tweet := Tweet{ Msg: req.FormValue("tweet"), Time: time.Now(), UserName: user.UserName, } // put in datastore err = putTweet(req, &user, &tweet) if err != nil { log.Errorf(ctx, "error adding todo: %v", err) http.Error(res, err.Error(), 500) return } // redirect time.Sleep(time.Millisecond * 500) // This is not the best code, probably. Thoughts? http.Redirect(res, req, "/", 302) }
// create snapshot func (a *MinecraftCronApi) createSnapshot(ctx context.Context, ds *compute.DisksService, world string) error { sn := fmt.Sprintf("minecraft-world-%s-%s", world, time.Now().Format("20060102-150405")) log.Infof(ctx, "create snapshot %s", sn) var minecraft Minecraft key := datastore.NewKey(ctx, "Minecraft", world, 0, nil) err := datastore.Get(ctx, key, &minecraft) if err == datastore.ErrNoSuchEntity { log.Infof(ctx, "Minecraft Entity Not Found. world = %s", world) return nil } if err != nil { return nil } minecraft.Key = key s := &compute.Snapshot{ Name: sn, } disk := fmt.Sprintf("minecraft-world-%s", world) ope, err := ds.CreateSnapshot(PROJECT_NAME, minecraft.Zone, disk, s).Do() if err != nil { log.Errorf(ctx, "ERROR insert snapshot: %s", err) return err } WriteLog(ctx, "INSTNCE_SNAPSHOT_OPE", ope) tq := ServerTQApi{} _, err = tq.CallDeleteInstance(ctx, minecraft.Key, ope.Name, sn) return err }
func chargeAccount(ctx context.Context, stripeToken string) error { // because we're on app engine, use a custom http client // this is being set globally, however // if we wanted to do it this way, we'd have to use a lock // https://youtu.be/KT4ki_ClX2A?t=1018 hc := urlfetch.Client(ctx) stripe.SetHTTPClient(hc) id, _ := uuid.NewV4() for { chargeParams := &stripe.ChargeParams{ Amount: 100 * 200000, Currency: "usd", Desc: "Charge for [email protected]", } chargeParams.IdempotencyKey = id.String() chargeParams.SetSource(stripeToken) ch, err := charge.New(chargeParams) // https://youtu.be/KT4ki_ClX2A?t=1310 if err != nil { if nerr, ok := err.(net.Error); ok && nerr.Temporary() { time.Sleep(time.Second) continue } return err } log.Infof(ctx, "CHARGE: %v", ch) log.Infof(ctx, "IDEMPOTENCY: %v", chargeParams.IdempotencyKey) return nil } }
// Function to update the questions in qns in the database func UpdateQns(db *sql.DB, ctx context.Context, qn int, originalState string, state string, userId int, lastUpdate int64) error { applog.Infof(ctx, "Updating database") if qn == 0 { return nil } defer func(db *sql.DB, ctx context.Context) { //Update the table on SQL keeping track of table modifications UpdateTableTimes(db, ctx, "questions") applog.Infof(ctx, "Database updated") }(db, ctx) //Update the database, setting the state and the new user/owner of that question. stmts, err := db.Prepare("UPDATE questions SET state=?,user=?,time_updated=? WHERE question_id=? AND state=?") if err != nil { return fmt.Errorf("Update prepare failed: %v", err.Error()) } if state == "unanswered" { userId = 0 } _, err = stmts.Exec(state, userId, lastUpdate, qn, originalState) if err != nil { return fmt.Errorf("Update execution failed: %v", err.Error()) } return nil }