func (t *testSyncerSuite) TestMysqlGTIDSync(c *C) { t.setupTest(c, mysql.MySQLFlavor) r, err := t.c.Execute("SELECT @@gtid_mode") c.Assert(err, IsNil) modeOn, _ := r.GetString(0, 0) if modeOn != "ON" { c.Skip("GTID mode is not ON") } r, err = t.c.Execute("SHOW GLOBAL VARIABLES LIKE 'SERVER_UUID'") c.Assert(err, IsNil) var masterUuid uuid.UUID if s, _ := r.GetString(0, 1); len(s) > 0 && s != "NONE" { masterUuid, err = uuid.FromString(s) c.Assert(err, IsNil) } set, _ := mysql.ParseMysqlGTIDSet(fmt.Sprintf("%s:%d-%d", masterUuid.String(), 1, 2)) s, err := t.b.StartSyncGTID(set) c.Assert(err, IsNil) t.testSync(c, s) }
// Delete deletes the space with the given id // returns NotFoundError or InternalError func (r *GormRepository) Delete(ctx context.Context, ID satoriuuid.UUID) error { if ID == satoriuuid.Nil { log.Error(ctx, map[string]interface{}{ "spaceID": ID.String(), }, "unable to find the space by ID") return errors.NewNotFoundError("space", ID.String()) } space := Space{ID: ID} tx := r.db.Delete(space) if err := tx.Error; err != nil { log.Error(ctx, map[string]interface{}{ "spaceID": ID.String(), }, "unable to delete the space") return errors.NewInternalError(err.Error()) } if tx.RowsAffected == 0 { log.Error(ctx, map[string]interface{}{ "spaceID": ID.String(), }, "none row was affected by the deletion operation") return errors.NewNotFoundError("space", ID.String()) } return nil }
func findUser(id uuid.UUID, users []*app.IdentityData) *app.IdentityData { for _, user := range users { if *user.ID == id.String() { return user } } return nil }
func findIdent(id uuid.UUID, idents []*app.IdentityData) *app.IdentityData { for _, ident := range idents { if *ident.ID == id.String() { return ident } } return nil }
// /a/comment func (s *Server) CommentHandler(c *gin.Context) { c.Request.ParseForm() id := c.Request.Form.Get("id") entryId := c.Request.Form.Get("entry") rawBody := c.Request.Form.Get("body") if entryId == "" || rawBody == "" { c.JSON(http.StatusBadRequest, gin.H{"status": "bad request"}) return } body := util.DefaultSanitize(rawBody) body = util.EntityToLink(body) profile, _ := s.CurrentUser(c) from := &pb.Feed{ Id: profile.Id, Name: profile.Name, Type: profile.Type, } comment := &pb.Comment{ Body: body, RawBody: rawBody, From: from, } var err error var uuid1 uuid.UUID if id != "" { uuid1, err = uuid.FromString(id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"status": "bad request"}) return } } else { comment.Date = time.Now().UTC().Format(time.RFC3339) name := entryId + profile.Uuid + comment.Date uuid1 = uuid.NewV5(uuid.NamespaceURL, name) } comment.Id = uuid1.String() req := &pb.CommentRequest{ Entry: entryId, Comment: comment, } ctx, cancel := DefaultTimeoutContext() defer cancel() _, err = s.client.CommentEntry(ctx, req) if RequestError(c, err) { return } comment.Commands = []string{"edit", "delete"} c.JSON(200, comment) }
// Encode encodes uuid.UUID into a string using the least significant bits // (LSB) first according to the alphabet. if the most significant bits (MSB) // are 0, the string might be shorter. func (su *ShortUUID) Encode(u uuid.UUID) string { var num big.Int num.SetString(strings.Replace(u.String(), "-", "", 4), 16) // Calculate encoded length. factor := math.Log(float64(25)) / math.Log(float64(su.alphabet.Length())) length := math.Ceil(factor * float64(len(u.Bytes()))) return su.numToString(&num, int(length)) }
func NewCursorFromSource(eventID uuid.UUID, createdAt time.Time) CursorEvents { res := make([]byte, lengthCursor) copy(res, eventID.Bytes()) b2, err := createdAt.MarshalBinary() if err != nil { println("[WARNING] marshal time", err.Error()) } copy(res[16:], b2) return CursorEvents(Base64(res)) }
// Delete a single comment func (m *GormCommentRepository) Delete(ctx context.Context, id uuid.UUID) error { if id == uuid.Nil { return errors.NewNotFoundError("comment", id.String()) } tx := m.db.Delete(&Comment{ID: id}) if tx.RowsAffected == 0 { return errors.NewNotFoundError("comment", id.String()) } if err := tx.Error; err != nil { return errors.NewInternalError(err.Error()) } return nil }
// Load a single Area regardless of parent func (m *GormAreaRepository) Load(ctx context.Context, id uuid.UUID) (*Area, error) { defer goa.MeasureSince([]string{"goa", "db", "Area", "get"}, time.Now()) var obj Area tx := m.db.Where("id = ?", id).First(&obj) if tx.RecordNotFound() { return nil, errors.NewNotFoundError("Area", id.String()) } if tx.Error != nil { return nil, errors.NewInternalError(tx.Error.Error()) } return &obj, nil }
// Load returns the space for the given id // returns NotFoundError or InternalError func (r *GormRepository) Load(ctx context.Context, ID satoriuuid.UUID) (*Space, error) { res := Space{} tx := r.db.Where("id=?", ID).First(&res) if tx.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "spaceID": ID.String(), }, "state or known referer was empty") return nil, errors.NewNotFoundError("space", ID.String()) } if tx.Error != nil { return nil, errors.NewInternalError(tx.Error.Error()) } return &res, nil }
// CreateNodalEvent create new nodal event // waiting ChannelID from context func (s *Service) CreateNodalEvent( ctx context.Context, threadID uuid.UUID, owners []uuid.UUID, creatorID uuid.UUID, ) (uuid.UUID, uuid.UUID, error) { return s.createNodalEvent( ctx, threadID.String(), threadID, owners, creatorID, []byte{}, ) }
func TestUUIDKey(t *testing.T) { Convey("Giving prefix, convert to bytes", t, func() { uuid1 := new(uuid.UUID) So(uuid1.String(), ShouldEqual, "00000000-0000-0000-0000-000000000000") id, err := uuid.FromString("c6f8dca8-54f0-11dd-b489-003048343a40") So(err, ShouldBeNil) So(hex.EncodeToString(id.Bytes()), ShouldEqual, hex.EncodeToString(id[:16][:])) prefix := NewUUIDKey(TableFeed, id) So(prefix.Len(), ShouldEqual, 20) uid := "c6f8dca854f011ddb489003048343a40" So(prefix.String(), ShouldEqual, "00000001"+uid) So(hex.EncodeToString(prefix.Bytes()), ShouldEqual, "00000001"+uid) }) }
func (rest *TestSpaceIterationREST) TestListIterationsBySpace() { t := rest.T() resource.Require(t, resource.Database) var spaceID uuid.UUID application.Transactional(rest.db, func(app application.Application) error { repo := app.Iterations() newSpace := space.Space{ Name: "Test 1", } p, err := app.Spaces().Create(context.Background(), &newSpace) if err != nil { t.Error(err) } spaceID = p.ID for i := 0; i < 3; i++ { start := time.Now() end := start.Add(time.Hour * (24 * 8 * 3)) name := "Sprint #2" + strconv.Itoa(i) i := iteration.Iteration{ Name: name, SpaceID: spaceID, StartAt: &start, EndAt: &end, } repo.Create(context.Background(), &i) } return nil }) svc, ctrl := rest.UnSecuredController() _, cs := test.ListSpaceIterationsOK(t, svc.Context, svc, ctrl, spaceID.String()) assert.Len(t, cs.Data, 3) for _, iterationItem := range cs.Data { subString := fmt.Sprintf("?filter[iteration]=%s", iterationItem.ID.String()) require.Contains(t, *iterationItem.Relationships.Workitems.Links.Related, subString) assert.Equal(t, 0, iterationItem.Relationships.Workitems.Meta["total"]) assert.Equal(t, 0, iterationItem.Relationships.Workitems.Meta["closed"]) } }
// CreateThread create new thread // waiting in the context of the client ID, linked event and thread IDs func (r *ThreadRepository) CreateThread( tx *pg.Tx, clientID, threadID, channelID, relatedEventID, parentThreadID uuid.UUID, owners []uuid.UUID, ) error { _, err := tx.Exec(`INSERT INTO threads ( thread_id, client_id, channel_id, ext_id, owners, related_event_id, parent_thread_id, created_at, updated_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`, threadID, clientID, channelID, utils.HashText(threadID.String()), (&utils.UUIDS{}).FromArray(owners), relatedEventID, parentThreadID, time.Now(), time.Now(), ) return err }
// LoadTypeFromDB return work item link type for the given ID func (r *GormWorkItemLinkTypeRepository) LoadTypeFromDBByID(ctx context.Context, ID satoriuuid.UUID) (*WorkItemLinkType, error) { log.Info(ctx, map[string]interface{}{ "pkg": "link", "wiltID": ID.String(), }, "Loading work item link type with ID ", ID) res := WorkItemLinkType{} db := r.db.Model(&res).Where("ID=?", ID.String()).First(&res) if db.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "wiltID": ID.String(), }, "work item link type not found") return nil, errors.NewNotFoundError("work item link type", ID.String()) } if db.Error != nil { return nil, errors.NewInternalError(db.Error.Error()) } return &res, nil }
// Load a single Iteration regardless of parent func (m *GormIterationRepository) Load(ctx context.Context, id uuid.UUID) (*Iteration, error) { defer goa.MeasureSince([]string{"goa", "db", "iteration", "get"}, time.Now()) var obj Iteration tx := m.db.Where("id = ?", id).First(&obj) if tx.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "iterationID": id.String(), }, "iteration cannot be found") return nil, errors.NewNotFoundError("Iteration", id.String()) } if tx.Error != nil { log.Error(ctx, map[string]interface{}{ "iterationID": id.String(), "err": tx.Error, }, "unable to load the iteration") return nil, errors.NewInternalError(tx.Error.Error()) } return &obj, nil }
// LoadTypeFromDB return work item link type for the given name in the correct link category // NOTE: Two link types can coexist with different categoryIDs. func (r *GormWorkItemLinkTypeRepository) LoadTypeFromDBByNameAndCategory(ctx context.Context, name string, categoryId satoriuuid.UUID) (*WorkItemLinkType, error) { log.Info(ctx, map[string]interface{}{ "pkg": "link", "wiltName": name, "categoryId": categoryId, }, "Loading work item link type %s with category ID %s", name, categoryId.String()) res := WorkItemLinkType{} db := r.db.Model(&res).Where("name=? AND link_category_id=?", name, categoryId.String()).First(&res) if db.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "wiltName": name, "categoryId": categoryId.String(), }, "work item link type not found") return nil, errors.NewNotFoundError("work item link type", name) } if db.Error != nil { return nil, errors.NewInternalError(db.Error.Error()) } return &res, nil }
// Load a single comment regardless of parent func (m *GormCommentRepository) Load(ctx context.Context, id uuid.UUID) (*Comment, error) { defer goa.MeasureSince([]string{"goa", "db", "comment", "get"}, time.Now()) var obj Comment tx := m.db.Where("id=?", id).First(&obj) if tx.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "commentID": id.String(), }, "comment search operation failed!") return nil, errors.NewNotFoundError("comment", id.String()) } if tx.Error != nil { log.Error(ctx, map[string]interface{}{ "commentID": id.String(), "err": tx.Error, }, "unable to load the comment") return nil, errors.NewInternalError(tx.Error.Error()) } return &obj, nil }
func (r *EventRepository) findEvents( clientID, watcherID, threadID uuid.UUID, cursorStr string, perPage int, ) ([]hey.Event, string, error) { cursor := utils.NewCursorEvents(cursorStr) lastEventID := cursor.LastEventID() lastEventCreatedAt := cursor.LastCreatedAt() cursor = utils.EmptyCursorEvents // reset cursor if perPage <= 0 || perPage > PerPageMax { perPage = PerPageDefault } var events = make([]hey.Event, perPage) // var events []hey.Event // find // args for first page var args = []interface{}{ clientID, threadID, perPage, } sqlFirstPage := `SELECT t.event_id, t.created_at FROM threadline as t WHERE t.client_id = $1 AND t.thread_id = $2 ORDER BY t.created_at DESC, t.event_id ASC LIMIT $3` sqlNextPages := `SELECT t.event_id, t.created_at FROM threadline as t WHERE t.client_id = $1 AND t.thread_id = $2 AND (t.created_at, t.event_id) < ($3, $4) ORDER BY t.created_at DESC, t.event_id ASC LIMIT $5` sql := sqlFirstPage if !uuid.Equal(lastEventID, uuid.Nil) { sql = sqlNextPages args = []interface{}{ clientID, threadID, lastEventCreatedAt, lastEventID, perPage, } } rows, err := r.db.Query(sql, args...) if err != nil { return events, "", err } var _event hey.Event var _eventID uuid.UUID var _createdAt time.Time var i = 0 for rows.Next() { if err = rows.Scan( &_eventID, &_createdAt, ); err != nil { println("[ERR] error scan row", err.Error()) continue } _event, err = r.FindEvent( clientID, _eventID, ) if err != nil { println( "[ERR] error find event by ID", _eventID.String(), err.Error()) continue } events[i] = _event i++ } if _event != nil { cursor = utils.NewCursorFromSource( _event.EventID(), _event.CreatedAt(), ) } if i < perPage-1 { // обрезать хвост у массива событий, если кол-во найденных меньше // чем ожидаемое кол-во events = events[:i] } return events, cursor.String(), err }