func (w *DatabaseWorld) SaveThing(thing *Thing) (ok bool) { tabletext, err := json.Marshal(thing.Table) if err != nil { log.Println("Error serializing table data for thing", thing.Id, ":", err.Error()) return false } var parent sql.NullInt64 if thing.Parent != 0 { parent.Int64 = int64(thing.Parent) parent.Valid = true } var owner sql.NullInt64 if thing.Owner != 0 && thing.Type.HasOwner() { owner.Int64 = int64(thing.Owner) owner.Valid = true } var program sql.NullString if thing.Program != nil { program.String = thing.Program.Text program.Valid = true } // TODO: save the allow list _, err = w.db.Exec("UPDATE thing SET name = $1, parent = $2, owner = $3, adminlist = $4, denylist = $5, tabledata = $6, program = $7 WHERE id = $8", thing.Name, parent, owner, thing.AdminList, thing.DenyList, types.JsonText(tabletext), program, thing.Id) if err != nil { log.Println("Error saving a thing", thing.Id, ":", err.Error()) return false } return true }
func TestIntOrNull(t *testing.T) { var nullInt sql.NullInt64 var value driver.Value var err error // When the integer is zero nullInt = IntOrNull(0) // nullInt.Valid should be false assert.False(t, nullInt.Valid) // nullInt.Value() should return nil value, err = nullInt.Value() assert.Nil(t, err) assert.Nil(t, value) // When the integer is greater than zero nullInt = IntOrNull(1) // nullInt.Valid should be true assert.True(t, nullInt.Valid) // nullInt.Value() should return the integer value, err = nullInt.Value() assert.Nil(t, err) assert.Equal(t, int64(1), value) }
func TestPositiveIntOrNull(t *testing.T) { var ( nullInt sql.NullInt64 value driver.Value err error ) // When the number is negative nullInt = PositiveIntOrNull(-1) // nullInt.Valid should be false assert.False(t, nullInt.Valid) // nullInt.Value() should return nil value, err = nullInt.Value() assert.Nil(t, err) assert.Nil(t, value) // When the number is greater than zero nullInt = PositiveIntOrNull(1) // nullInt.Valid should be true assert.True(t, nullInt.Valid) // nullInt.Value() should return the integer value, err = nullInt.Value() assert.Nil(t, err) assert.Equal(t, int64(1), value) }
func AllAgents(db *sql.DB, simid []byte, proto string) (ags []AgentInfo, err error) { s := `SELECT AgentId,Kind,Spec,Prototype,ParentId,EnterTime,ExitTime,Lifetime FROM Agents WHERE Agents.SimId = ?` var rows *sql.Rows if proto != "" { s += ` AND Agents.Prototype = ?` rows, err = db.Query(s, simid, proto) } else { rows, err = db.Query(s, simid) } if err != nil { return nil, err } for rows.Next() { ai := AgentInfo{} var exit sql.NullInt64 if err := rows.Scan(&ai.Id, &ai.Kind, &ai.Impl, &ai.Proto, &ai.Parent, &ai.Enter, &exit, &ai.Lifetime); err != nil { return nil, err } if !exit.Valid { exit.Int64 = -1 } ai.Exit = int(exit.Int64) ags = append(ags, ai) } if err := rows.Err(); err != nil { return nil, err } return ags, nil }
func createLoginLog(succeeded bool, remoteAddr, login string, user *User) error { succ := 0 if succeeded { succ = 1 } var userId sql.NullInt64 if user != nil { userId.Int64 = int64(user.ID) userId.Valid = true mu.Lock() if succeeded { resetUserFailCount(user.ID) resetIpFailCount(remoteAddr) } else { incrUserFailCount(user.ID) incrIpFailCount(remoteAddr) } mu.Unlock() } _, err := db.Exec( "INSERT INTO login_log (`created_at`, `user_id`, `login`, `ip`, `succeeded`) "+ "VALUES (?,?,?,?,?)", time.Now(), userId, login, remoteAddr, succ, ) return err }
func addPublicAccess(app *app, houseID, html string) error { // Parse title of page title := titleReg.FindStringSubmatch(html)[1] if !validTitle(title) { // <title/> was invalid, so look for an <h1/> header := headerReg.FindStringSubmatch(html)[1] if validTitle(header) { // <h1/> was valid, so use that instead of <title/> title = header } } title = strings.TrimSpace(title) // Get thumbnail data := url.Values{} data.Set("url", fmt.Sprintf("%s/%s.html", app.cfg.HostName, houseID)) u, err := url.ParseRequestURI("https://peeper.html.house") u.Path = "/" urlStr := fmt.Sprintf("%v", u) client := &http.Client{} r, err := http.NewRequest("POST", urlStr, bytes.NewBufferString(data.Encode())) if err != nil { fmt.Printf("Error creating request: %v", err) } r.Header.Add("Content-Type", "application/x-www-form-urlencoded") r.Header.Add("Content-Length", strconv.Itoa(len(data.Encode()))) var thumbURL string resp, err := client.Do(r) if err != nil { fmt.Printf("Error requesting thumbnail: %v", err) return impart.HTTPError{http.StatusInternalServerError, "Couldn't generate thumbnail"} } else { defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) if resp.StatusCode == http.StatusOK { thumbURL = string(body) } } // Add to public houses table approved := sql.NullInt64{Valid: false} if app.cfg.AutoApprove { approved.Int64 = 1 approved.Valid = true } _, err = app.db.Exec("INSERT INTO publichouses (house_id, title, thumb_url, added, updated, approved) VALUES (?, ?, ?, NOW(), NOW(), ?) ON DUPLICATE KEY UPDATE title = ?, updated = NOW()", houseID, title, thumbURL, approved, title) if err != nil { return err } // Tweet about it tweet(app, houseID, title) return nil }
func tonullint64(d *int64) sql.NullInt64 { var n sql.NullInt64 n.Valid = (d != nil) if !n.Valid { return n } n.Int64 = *d return n }
func tonullint8(d *int8) sql.NullInt64 { var n sql.NullInt64 n.Valid = (d != nil) if n.Valid { return n } n.Int64 = int64(*d) return n }
func (w writer) writeMessage() error { start := time.Now() defer w.stats.recordWrite(start) channel := fmt.Sprintf("room-%d", rand.Int31n(int32(w.numChannels))) message := start.String() // TODO(bdarnell): retry only on certain errors. for { txn, err := w.db.Begin() if err != nil { continue } // TODO(bdarnell): make this a subquery when subqueries are supported on insert. row := txn.QueryRow(`select max(msg_id) from fakerealtime.messages where channel=$1`, channel) var maxMsgID sql.NullInt64 if err := row.Scan(&maxMsgID); err != nil { _ = txn.Rollback() continue } if !maxMsgID.Valid { maxMsgID.Int64 = 0 } newMsgID := maxMsgID.Int64 + 1 row = txn.QueryRow(`select max(update_id) from fakerealtime.updates`, channel) var maxUpdateID sql.NullInt64 if err := row.Scan(&maxUpdateID); err != nil { _ = txn.Rollback() continue } if !maxUpdateID.Valid { maxUpdateID.Int64 = 0 } newUpdateID := maxUpdateID.Int64 + 1 if _, err := txn.Exec(`insert into fakerealtime.messages (channel, msg_id, message) values ($1, $2, $3)`, channel, newMsgID, message); err != nil { _ = txn.Rollback() continue } if _, err := txn.Exec(`insert into fakerealtime.updates (update_id, channel, msg_id) values ($1, $2, $3)`, newUpdateID, channel, newMsgID); err != nil { _ = txn.Rollback() continue } if err := txn.Commit(); err == nil { return nil } } }
func checkIntForNull(eventInt string, event *sql.NullInt64) { var err error if eventInt == "" { event.Valid = false } else { event.Int64, err = strconv.ParseInt(eventInt, 10, 64) if err != nil { event.Valid = false return } event.Valid = true } }
func preparePutTweet(db *sql.DB) func(*twitter.Tweet) { putTweetStmt, err := db.Prepare(putTweetSql) if err != nil { panic(err) } return func(t *twitter.Tweet) { var retweetedStatusId sql.NullInt64 if t.RetweetedStatus != nil { retweetedStatusId.Int64 = t.RetweetedStatus.Id retweetedStatusId.Valid = true } putTweetStmt.Exec(t.Id, t.Text, t.CreatedAt.Time, t.InReplyToStatusId, t.InReplyToUserId, retweetedStatusId, t.Source, t.User.Id) } }
func createLoginLog(succeeded bool, remoteAddr, login string, user *User) error { succ := 0 if succeeded { succ = 1 } var userId sql.NullInt64 if user != nil { userId.Int64 = int64(user.ID) userId.Valid = true } _, err := prepareInsertLog.Exec(time.Now(), userId, login, remoteAddr, succ) return err }
// Scan a value into the Int64, error on nil or unparsable func (i *Int64) Scan(value interface{}) error { tmp := sql.NullInt64{} tmp.Scan(value) if tmp.Valid == false { // TODO: maybe nil should be simply allowed to be empty int64? return errors.New("Value should be a int64 and not nil") } i.Int64 = tmp.Int64 i.DoInit(func() { i.shadow = tmp.Int64 }) return nil }
func (r *repository) InsertLine(userID, convoID string, line *Line) error { var publicID string var convo convoRec err := r.getConvo.Get(&convo, struct{ UserID, PublicID string }{userID, convoID}) if err != nil { return errors.Trace(err) } for i := 0; i < maxInsertRetries; i++ { rv, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64)) if err != nil { return errors.Trace(err) } publicID = lineIDPrefix + strconv.FormatUint(rv.Uint64(), 36) var moodID sql.NullInt64 if line.mood.id != 0 { moodID.Int64 = int64(line.mood.id) moodID.Valid = true } _, err = r.insertLine.Exec(struct { PublicID, Animal, Text, MoodName string Think bool MoodID sql.NullInt64 ConversationID int }{ publicID, line.Animal, line.Text, line.MoodName, line.Think, moodID, convo.IntID, }) if err == nil { line.ID = publicID return nil } dbErr, ok := err.(*pq.Error) if !ok || dbErr.Code != dbErrDupUnique { return errors.Trace(err) } } return errors.New("Unable to insert a new, unique line") }
func TestNullTypeInt64(t *testing.T) { var userID sql.NullInt64 userID.Scan(nil) b := Eq{"user_id": userID} sql, args, err := b.ToSql() assert.NoError(t, err) assert.Empty(t, args) assert.Equal(t, "user_id IS NULL", sql) userID.Scan(int64(10)) b = Eq{"user_id": userID} sql, args, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, []interface{}{int64(10)}, args) assert.Equal(t, "user_id = ?", sql) }
func (s *scanner) Scan(src interface{}) error { var err error switch s.value.Type().Kind() { case reflect.Struct: nt := mysql.NullTime{} err := nt.Scan(src) if err != nil { return err } s.value.Set(reflect.ValueOf(nt.Time)) case reflect.Bool: nb := sql.NullBool{} err := nb.Scan(src) if err != nil { return err } s.value.SetBool(nb.Bool) case reflect.String: ns := sql.NullString{} err = ns.Scan(src) if err != nil { return err } s.value.SetString(ns.String) case reflect.Int64: ni := sql.NullInt64{} err = ni.Scan(src) if err != nil { return err } s.value.SetInt(ni.Int64) case reflect.Float64: ni := sql.NullFloat64{} err = ni.Scan(src) if err != nil { return err } s.value.SetFloat(ni.Float64) } return nil }
func createLoginLog(succeeded bool, remoteAddr, login string, user *User) error { succ := 0 if succeeded { succ = 1 } var userId sql.NullInt64 if user != nil { userId.Int64 = int64(user.ID) userId.Valid = true } _, err := db.Exec( "INSERT INTO login_log (`created_at`, `user_id`, `login`, `ip`, `succeeded`) "+ "VALUES (?,?,?,?,?)", time.Now(), userId, login, remoteAddr, succ, ) return err }
func createLoginLog(succeeded bool, remoteAddr, login string, user *User) { succ := 0 if succeeded { succ = 1 } now := time.Now() var userId sql.NullInt64 if user != nil { userId.Int64 = int64(user.ID) userId.Valid = true } go func() { db.Exec( "INSERT INTO login_log (`created_at`, `user_id`, `login`, `ip`, `succeeded`) "+ "VALUES (?,?,?,?,?)", now, userId, login, remoteAddr, succ, ) }() if user != nil { if succeeded { UserIdFailures[user.ID] = 0 IpFailtures[remoteAddr] = 0 LastLoginHistory[user.ID] = [2]LastLogin{ { Login: login, IP: remoteAddr, CreatedAt: now.Format("2006-01-02 15:04:05"), }, LastLoginHistory[user.ID][0], } } else { UserIdFailures[user.ID]++ IpFailtures[remoteAddr]++ } } }
func (w *DatabaseWorld) CreateThing(name string, tt ThingType, creator *Thing, parent *Thing) (thing *Thing) { thing = NewThing() thing.Name = name thing.Type = tt thing.Parent = parent.Id var creatorId sql.NullInt64 if creator != nil && thing.Type.HasOwner() { creatorId.Int64 = int64(creator.Id) thing.Creator = creator.Id thing.Owner = creator.Id } row := w.db.QueryRow("INSERT INTO thing (name, type, creator, owner, parent) VALUES ($1, $2, $3, $4, $5) RETURNING id, created", thing.Name, thing.Type.String(), creatorId, creatorId, thing.Parent) err := row.Scan(&thing.Id, &thing.Created) if err != nil { log.Println("Error creating a thing", name, ":", err.Error()) return nil } return }
func CreateNullInt64(v int64) sql.NullInt64 { var ni sql.NullInt64 ni.Valid = true ni.Int64 = v return ni }
func handlerErrors(w http.ResponseWriter, r *http.Request) error { r.ParseForm() if r.URL.Path != "/debug/errors" { return handlerNotFound(w, r) } tx, err := mail.DB.Begin() if err != nil { return err } defer tx.Rollback() us, err := getUserSession(r, tx) if err != nil { return err } if r.Method == "POST" { // User may or may not be logged in (eg: outside of site). var nullableUserID, nullableCookieID sql.NullInt64 if us.userID != 0 { nullableUserID.Int64 = int64(us.userID) nullableUserID.Valid = true selectCookieIDStmt := mail.TxStmt(sqlSelectCookieID, tx) defer selectCookieIDStmt.Close() err := selectCookieIDStmt.QueryRow(getCookie(r)).Scan(&nullableCookieID) if err != nil { return err } } postError, err := getBody(r) if err != nil { return err } insertErrorStmt := mail.TxStmt(sqlInsertError, tx) defer insertErrorStmt.Close() _, err = insertErrorStmt.Exec(nullableUserID, nullableCookieID, r.RequestURI, postError, r.Header.Get("Referer"), r.Header.Get("User-Agent")) if err != nil { return err } err = tx.Commit() if err != nil { return err } errorsPage := ErrorsPage{} errorsPage.ErrorLogged = true return tErrors.Execute(w, errorsPage) } if !us.isAdmin { errorsPage := ErrorsPage{} errorsPage.NoAccess = true return tErrors.Execute(newWSCollapser(&w), errorsPage) } selectErrorsStmt := mail.TxStmt(sqlSelectErrors, tx) defer selectErrorsStmt.Close() rows, err := selectErrorsStmt.Query() if err != nil { return err } defer rows.Close() errorsPage := ErrorsPage{} for rows.Next() { var email sql.NullString var url, e, referrer, userAgent string var t time.Time err = rows.Scan(&email, &url, &e, &referrer, &userAgent, &t) if err != nil { return err } errorsPage.Errors = append(errorsPage.Errors, ErrorItem{ email.String, url, e, referrer, userAgent, t.UTC().String()}) } err = rows.Err() // get any error encountered during iteration if err != nil { return err } return tErrors.Execute(newWSCollapser(&w), errorsPage) }
// Scan implements the Scanner interface. func (ns *UInt32) Scan(value interface{}) error { n := sql.NullInt64{Int64: int64(ns.UInt32)} err := n.Scan(value) ns.UInt32, ns.Valid = uint32(n.Int64), n.Valid return err }
func fetchResult(itemT reflect.Type, rows *sql.Rows, columns []string) (reflect.Value, error) { var item reflect.Value var err error switch itemT.Kind() { case reflect.Map: item = reflect.MakeMap(itemT) case reflect.Struct: item = reflect.New(itemT) default: return item, db.ErrExpectingMapOrStruct } expecting := len(columns) // Allocating results. values := make([]*sql.RawBytes, expecting) scanArgs := make([]interface{}, expecting) for i := range columns { scanArgs[i] = &values[i] } if err = rows.Scan(scanArgs...); err != nil { return item, err } // Range over row values. for i, value := range values { if value != nil { // Real column name column := columns[i] // Value as string. svalue := string(*value) var cv reflect.Value v, _ := to.Convert(svalue, reflect.String) cv = reflect.ValueOf(v) switch itemT.Kind() { // Destination is a map. case reflect.Map: if cv.Type() != itemT.Elem() { if itemT.Elem().Kind() == reflect.Interface { cv, _ = util.StringToType(svalue, cv.Type()) } else { cv, _ = util.StringToType(svalue, itemT.Elem()) } } if cv.IsValid() { item.SetMapIndex(reflect.ValueOf(column), cv) } // Destionation is a struct. case reflect.Struct: index := util.GetStructFieldIndex(itemT, column) if index == nil { continue } else { // Destination field. destf := item.Elem().FieldByIndex(index) if destf.IsValid() { if cv.Type() != destf.Type() { if destf.Type().Kind() != reflect.Interface { switch destf.Type() { case nullFloat64Type: nullFloat64 := sql.NullFloat64{} if svalue != `` { nullFloat64.Scan(svalue) } cv = reflect.ValueOf(nullFloat64) case nullInt64Type: nullInt64 := sql.NullInt64{} if svalue != `` { nullInt64.Scan(svalue) } cv = reflect.ValueOf(nullInt64) case nullBoolType: nullBool := sql.NullBool{} if svalue != `` { nullBool.Scan(svalue) } cv = reflect.ValueOf(nullBool) case nullStringType: nullString := sql.NullString{} nullString.Scan(svalue) cv = reflect.ValueOf(nullString) default: var decodingNull bool if svalue == "" { decodingNull = true } u, _ := indirect(destf, decodingNull) if u != nil { u.UnmarshalDB(svalue) if destf.Kind() == reflect.Interface || destf.Kind() == reflect.Ptr { cv = reflect.ValueOf(u) } else { cv = reflect.ValueOf(u).Elem() } } else { cv, _ = util.StringToType(svalue, destf.Type()) } } } } // Copying value. if cv.IsValid() { destf.Set(cv) } } } } } } return item, nil }
// SaveAccess writes osin.AccessData. // If RefreshToken is not blank, it must save in a way that can be loaded using LoadRefresh. func (s *OAuth2Storage) SaveAccess(accessData *osin.AccessData) error { var clientID uint64 var err error if clientID, err = strconv.ParseUint(accessData.Client.GetId(), 10, 64); err != nil { return errors.New("Invalid Client ID") } if err = s.isValidScope(accessData.Scope); err != nil { return fmt.Errorf("Saving Access: " + err.Error()) } var accessDataIDPtr sql.NullInt64 if accessData.AccessData != nil { var father OAuth2AccessData if err = Db().Model(OAuth2AccessData{}).Where(&OAuth2AccessData{AccessToken: accessData.AccessData.AccessToken}).Scan(&father); err != nil { return errors.New("Error fetching parent Access Data ID") } accessDataIDPtr.Int64, accessDataIDPtr.Valid = int64(father.ID), true } // required to fill the foreign key var authorizeDataIDPtr sql.NullInt64 if accessData.AuthorizeData != nil { var authorizeData OAuth2AuthorizeData if err = Db().Model(OAuth2AuthorizeData{}).Where(&OAuth2AuthorizeData{Code: accessData.AuthorizeData.Code}).Scan(&authorizeData); err != nil { return fmt.Errorf("SaveAccess: can't load authorize data with code: %s", accessData.AuthorizeData.Code) } authorizeDataIDPtr.Int64, authorizeDataIDPtr.Valid = int64(authorizeData.ID), true } tx := Db().Begin() var refreshTokenFK sql.NullInt64 oauthAccessData := &OAuth2AccessData{ AccessDataID: accessDataIDPtr, AccessToken: accessData.AccessToken, AuthorizeDataID: authorizeDataIDPtr, ClientID: clientID, //CreatedAt: accessData.CreatedAt, <- dbms handled ExpiresIn: uint64(accessData.ExpiresIn), RedirectURI: accessData.RedirectUri, Scope: accessData.Scope, UserID: accessData.UserData.(uint64)} if accessData.RefreshToken != "" { // Create refresh token var newRefreshToken OAuth2RefreshToken newRefreshToken.Token = accessData.RefreshToken if err := tx.Create(&newRefreshToken); err != nil { tx.Rollback() return err } refreshTokenFK.Int64 = int64(newRefreshToken.ID) refreshTokenFK.Valid = true } // Put refresh token id, into OAuth2AccessData.refreshtoken fk oauthAccessData.RefreshTokenID = refreshTokenFK if err := tx.Create(oauthAccessData); err != nil { tx.Rollback() return err } if err := tx.Commit(); err != nil { return err } return nil }
// Scan implements the Scanner interface. func (ns *Int) Scan(value interface{}) error { n := sql.NullInt64{Int64: int64(ns.Int)} err := n.Scan(value) ns.Int, ns.Valid = int(n.Int64), n.Valid return err }
func (db *SQLDB) CreateContainer(container Container, ttl time.Duration) (SavedContainer, error) { if !(isValidCheckID(container.ContainerIdentifier) || isValidStepID(container.ContainerIdentifier)) { return SavedContainer{}, ErrInvalidIdentifier } tx, err := db.conn.Begin() if err != nil { return SavedContainer{}, err } defer tx.Rollback() checkSource, err := json.Marshal(container.CheckSource) if err != nil { return SavedContainer{}, err } envVariables, err := json.Marshal(container.EnvironmentVariables) if err != nil { return SavedContainer{}, err } user := container.User interval := fmt.Sprintf("%d second", int(ttl.Seconds())) if container.PipelineName != "" && container.PipelineID == 0 { // containers that belong to some pipeline must be identified by pipeline ID not name return SavedContainer{}, errors.New("container metadata must include pipeline ID") } var pipelineID sql.NullInt64 if container.PipelineID != 0 { pipelineID.Int64 = int64(container.PipelineID) pipelineID.Valid = true } var resourceID sql.NullInt64 if container.ResourceID != 0 { resourceID.Int64 = int64(container.ResourceID) resourceID.Valid = true } var resourceTypeVersion string if container.ResourceTypeVersion != nil { resourceTypeVersionBytes, err := json.Marshal(container.ResourceTypeVersion) if err != nil { return SavedContainer{}, err } resourceTypeVersion = string(resourceTypeVersionBytes) } var buildID sql.NullInt64 if container.BuildID != 0 { buildID.Int64 = int64(container.BuildID) buildID.Valid = true } workerName := container.WorkerName if workerName == "" { workerName = container.WorkerName } var attempts sql.NullString if len(container.Attempts) > 0 { attemptsBlob, err := json.Marshal(container.Attempts) if err != nil { return SavedContainer{}, err } attempts.Valid = true attempts.String = string(attemptsBlob) } var imageResourceSource sql.NullString if container.ImageResourceSource != nil { marshaled, err := json.Marshal(container.ImageResourceSource) if err != nil { return SavedContainer{}, err } imageResourceSource.String = string(marshaled) imageResourceSource.Valid = true } var imageResourceType sql.NullString if container.ImageResourceType != "" { imageResourceType.String = container.ImageResourceType imageResourceType.Valid = true } _, err = tx.Exec(` INSERT INTO containers (handle, resource_id, step_name, pipeline_id, build_id, type, worker_name, expires_at, ttl, check_type, check_source, plan_id, working_directory, env_variables, attempts, stage, image_resource_type, image_resource_source, process_user, resource_type_version) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW() + $8::INTERVAL, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)`, container.Handle, resourceID, container.StepName, pipelineID, buildID, container.Type.String(), workerName, interval, ttl, container.CheckType, checkSource, string(container.PlanID), container.WorkingDirectory, envVariables, attempts, string(container.Stage), imageResourceType, imageResourceSource, user, resourceTypeVersion, ) if err != nil { return SavedContainer{}, err } newContainer, err := scanContainer(tx.QueryRow(` SELECT `+containerColumns+` FROM containers c `+containerJoins+` WHERE c.handle = $1 `, container.Handle)) if err != nil { return SavedContainer{}, err } err = tx.Commit() if err != nil { return SavedContainer{}, err } return newContainer, nil }
func (db *SQLDB) CreateContainer(container Container, ttl time.Duration) (Container, error) { if !isValidID(container.ContainerIdentifier) { return Container{}, ErrInvalidIdentifier } tx, err := db.conn.Begin() if err != nil { return Container{}, err } checkSource, err := json.Marshal(container.CheckSource) if err != nil { return Container{}, err } envVariables, err := json.Marshal(container.EnvironmentVariables) if err != nil { return Container{}, err } user := container.User interval := fmt.Sprintf("%d second", int(ttl.Seconds())) var pipelineID sql.NullInt64 if container.PipelineName != "" { pipeline, err := db.GetPipelineByTeamNameAndName(atc.DefaultTeamName, container.PipelineName) if err != nil { return Container{}, fmt.Errorf("failed to find pipeline: %s", err.Error()) } pipelineID.Int64 = int64(pipeline.ID) pipelineID.Valid = true } var resourceID sql.NullInt64 if container.ResourceID != 0 { resourceID.Int64 = int64(container.ResourceID) resourceID.Valid = true } var buildID sql.NullInt64 if container.BuildID != 0 { buildID.Int64 = int64(container.BuildID) buildID.Valid = true } workerName := container.WorkerName if workerName == "" { workerName = container.WorkerName } var attempts sql.NullString if len(container.Attempts) > 0 { attemptsBlob, err := json.Marshal(container.Attempts) if err != nil { return Container{}, err } attempts.Valid = true attempts.String = string(attemptsBlob) } var imageResourceSource sql.NullString if container.ImageResourceSource != nil { marshaled, err := json.Marshal(container.ImageResourceSource) if err != nil { return Container{}, err } imageResourceSource.String = string(marshaled) imageResourceSource.Valid = true } var imageResourceType sql.NullString if container.ImageResourceType != "" { imageResourceType.String = container.ImageResourceType imageResourceType.Valid = true } defer tx.Rollback() _, err = tx.Exec(` INSERT INTO containers (handle, resource_id, step_name, pipeline_id, build_id, type, worker_name, expires_at, check_type, check_source, plan_id, working_directory, env_variables, attempts, stage, image_resource_type, image_resource_source, process_user) VALUES ($1, $2, $3, $4, $5, $6, $7, NOW() + $8::INTERVAL, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)`, container.Handle, resourceID, container.StepName, pipelineID, buildID, container.Type.String(), workerName, interval, container.CheckType, checkSource, string(container.PlanID), container.WorkingDirectory, envVariables, attempts, string(container.Stage), imageResourceType, imageResourceSource, user, ) if err != nil { return Container{}, err } newContainer, err := scanContainer(tx.QueryRow(` SELECT `+containerColumns+` FROM containers c `+containerJoins+` WHERE c.handle = $1 `, container.Handle)) if err != nil { return Container{}, err } err = tx.Commit() if err != nil { return Container{}, err } return newContainer, nil }
func (database Database) listAllConnections() (res DbUsersWithConnections) { res = make(DbUsersWithConnections) rows, err := database.db.Query(` -- Left join because we want users without connections as well SELECT u1.id, u1.username, u2.id, u2.username FROM user AS u1 LEFT JOIN connection ON u1.id = connection.fromUser LEFT JOIN user AS u2 ON u2.id = connection.toUser ORDER BY u1.id `) checkErr(err) defer rows.Close() for rows.Next() { var fromUser User var toUsername sql.NullString var toId sql.NullInt64 err := rows.Scan(&fromUser.Id, &fromUser.Username, &toId, &toUsername) checkErr(err) if toId.Valid { // this user has at least one connection, unpack the nullable values toIdValue, _ := toId.Value() toUsernameValue, _ := toUsername.Value() res[fromUser] = append(res[fromUser], User{toIdValue.(int64), toUsernameValue.(string)}) } else { // this user doesn't have any connections res[fromUser] = []User{} } } return res }