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)
}
Exemple #2
0
// 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
}
Exemple #5
0
// /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)
}
Exemple #6
0
// 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))
}
Exemple #7
0
// 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
}
Exemple #8
0
// 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
}
Exemple #9
0
// 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
}
Exemple #10
0
// 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{},
	)
}
Exemple #11
0
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"])
	}
}
Exemple #13
0
// 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
}
Exemple #15
0
// 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
}
Exemple #17
0
// 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
}
Exemple #18
0
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
}