func TestCursor_simple(t *testing.T) { eventID := uuid.NewV4() createdAtEvent := time.Now() cursor1 := NewCursorFromSource( eventID, createdAtEvent, ) cursor2 := NewCursorEvents(cursor1.String()) assert.Equal(t, uuid.Equal(cursor2.LastEventID(), cursor1.LastEventID()), true, ) assert.Equal(t, cursor1.LastCreatedAt(), cursor2.LastCreatedAt()) // not valid cursor cursor2 = NewCursorEvents("invalid data") assert.Equal(t, uuid.Equal( cursor2.LastEventID(), uuid.Nil, ), true, ) assert.Equal( t, cursor2.LastCreatedAt(), time.Time{}) // empty cursor cursor2 = NewCursorEvents("") assert.Equal(t, uuid.Equal( cursor2.LastEventID(), uuid.Nil, ), true, ) assert.Equal( t, cursor2.LastCreatedAt(), time.Time{}) }
func PutOAuthUser(mdb *Store, u *pb.OAuthUser) (*pb.OAuthUser, error) { key, v, err := GetOAuthUser(mdb, u.Provider, u.UserId) if err != nil { return nil, err } if v != nil { if u.Uuid != "" && v.Uuid != "" { uuid1, _ := uuid.FromString(u.Uuid) uuid2, _ := uuid.FromString(v.Uuid) if !uuid.Equal(uuid1, uuid2) { return nil, fmt.Errorf("user mismatch") } } if u.Uuid == "" { u.Uuid = v.Uuid } } bytes, err := proto.Marshal(u) if err != nil { return nil, err } // refresh OAuth User info to store err = mdb.Put(key.Bytes(), bytes) if err != nil { return nil, err } return u, nil }
// Equal returns true if two WorkItemLink objects are equal; otherwise false is returned. func (l WorkItemLink) Equal(u convert.Equaler) bool { other, ok := u.(WorkItemLink) if !ok { return false } if !l.Lifecycle.Equal(other.Lifecycle) { return false } if !satoriuuid.Equal(l.ID, other.ID) { return false } if l.Version != other.Version { return false } if l.SourceID != other.SourceID { return false } if l.TargetID != other.TargetID { return false } if l.LinkTypeID != other.LinkTypeID { return false } return true }
// Equal returns true if two WorkItemLinkType objects are equal; otherwise false is returned. func (t WorkItemLinkType) Equal(u convert.Equaler) bool { other, ok := u.(WorkItemLinkType) if !ok { return false } if !t.Lifecycle.Equal(other.Lifecycle) { return false } if !satoriuuid.Equal(t.ID, other.ID) { return false } if t.Name != other.Name { return false } if t.Version != other.Version { return false } if !strPtrIsNilOrContentIsEqual(t.Description, other.Description) { return false } if t.Topology != other.Topology { return false } if t.SourceTypeName != other.SourceTypeName { return false } if t.TargetTypeName != other.TargetTypeName { return false } if t.ForwardName != other.ForwardName { return false } if t.ReverseName != other.ReverseName { return false } if !satoriuuid.Equal(t.LinkCategoryID, other.LinkCategoryID) { return false } return true }
// CheckValidForCreation returns an error if the work item link // cannot be used for the creation of a new work item link. func (l *WorkItemLink) CheckValidForCreation() error { if satoriuuid.Equal(l.LinkTypeID, satoriuuid.Nil) { return errors.NewBadParameterError("link_type_id", l.LinkTypeID) } return 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 }
func TestHey_simple_searchNodalEvents(t *testing.T) { hey := NewService( db, log.New(os.Stderr, "[test hey]", 1), ) ctx, _ := generateClientIDWithContext() user1 := uuid.NewV4() user2 := uuid.NewV4() owners := []uuid.UUID{ user1, user2, } var channelName = "my_custom_channel_name" channelID, threadID, err := hey.CreateChannelName( ctx, channelName, owners, ) assert.NoError(t, err) assert.NotEqual(t, channelID, uuid.Nil) assert.NotEqual(t, threadID, uuid.Nil) creatorID := uuid.NewV4() var threadName = "my_custom_thread_name1" branchThreadID, nodalEventID, err := hey.CreateNodalEventWithThreadNameWithData( ctx, threadName, threadID, owners, creatorID, []byte("data value"), ) assert.NoError(t, err) assert.NotEqual(t, branchThreadID, uuid.Nil) assert.NotEqual(t, nodalEventID, uuid.Nil) // check nodal events searchResult, err := hey.FindEventsByName( ctx, user1, channelName+"."+channelName, "", 100, ) assert.NoError(t, err) assert.True(t, len(searchResult.Events()) == 1) assert.True(t, uuid.Equal( searchResult.Events()[0].ThreadID(), threadID, )) assert.True(t, uuid.Equal( searchResult.Events()[0].BranchThreadID(), branchThreadID, )) assert.True(t, bytes.Equal( searchResult.Events()[0].Data(), []byte("data value"), )) }
func TestHey_simple_search(t *testing.T) { hey := NewService( db, log.New(os.Stderr, "[test hey]", 1), ) ctx, _ := generateClientIDWithContext() user1 := uuid.NewV4() user2 := uuid.NewV4() owners := []uuid.UUID{ user1, user2, } var channelName = "my_custom_channel_name" channelID, threadID, err := hey.CreateChannelName( ctx, channelName, owners, ) assert.NoError(t, err) assert.NotEqual(t, channelID, uuid.Nil) assert.NotEqual(t, threadID, uuid.Nil) creatorID := uuid.NewV4() var threadName = "my_custom_thread_name" branchThreadID, nodalEventID, err := hey.CreateNodalEventWithThreadName( ctx, threadName, threadID, owners, creatorID, ) assert.NoError(t, err) assert.NotEqual(t, branchThreadID, uuid.Nil) assert.NotEqual(t, nodalEventID, uuid.Nil) // create events totalEvents := 10 eventIDS := make([]uuid.UUID, totalEvents) for index := 0; index <= totalEvents-1; index++ { // new event newEventID, err := hey.CreateEvent( ctx, branchThreadID, creatorID, []byte("hello machine #"+strconv.Itoa(index)), ) assert.NoError(t, err) assert.NotEqual(t, newEventID, uuid.Nil) eventIDS[index] = newEventID } // reverse ids for i, j := 0, len(eventIDS)-1; i < j; i, j = i+1, j-1 { eventIDS[i], eventIDS[j] = eventIDS[j], eventIDS[i] } // ------------------------------------ // Search from thread ID // ------------------------------------ // Search var watcherID = uuid.NewV4() var perPage = 3 var searchResult _hey.SearchResult var cursor = "" var countItemsLastPage = totalEvents - (perPage * (totalEvents / perPage)) for page := 0; page <= (totalEvents / perPage); page++ { searchResult, err = hey.FindEvents( ctx, watcherID, branchThreadID, cursor, perPage, ) assert.NoError(t, err) cursor = searchResult.Cursor() // save for next query var _perPage = perPage if page+1 > totalEvents/perPage { // for last page _perPage = countItemsLastPage } // check items per page assert.Equal(t, len(searchResult.Events()), _perPage, "%d, %#v", _perPage, searchResult.Events()) for i := 0; i < _perPage; i++ { item := searchResult.Events()[i] t.Log(i, len(searchResult.Events()), page*perPage+i) expectedItemID := eventIDS[page*perPage+i] assert.Equal( t, uuid.Equal( eventIDS[page*perPage+i], item.EventID(), ), true, "expected %v, got %v", expectedItemID, item.EventID(), ) } } // ------------------------------------ // Search from thread name // ------------------------------------ // Search cursor = "" for page := 0; page <= (totalEvents / perPage); page++ { searchResult, err = hey.FindEventsByName( ctx, watcherID, channelName+"."+threadName, cursor, perPage, ) assert.NoError(t, err, "%q, %d", cursor, page) cursor = searchResult.Cursor() // save for next query // assert.NotEmpty(t, cursor) var _perPage = perPage if page+1 > totalEvents/perPage { // for last page _perPage = countItemsLastPage } // check items per page assert.Equal(t, len(searchResult.Events()), _perPage, "%d, %#v", _perPage, searchResult.Events()) for i := 0; i < _perPage; i++ { item := searchResult.Events()[i] t.Log(i, len(searchResult.Events()), page*perPage+i) expectedItemID := eventIDS[page*perPage+i] assert.Equal( t, uuid.Equal( eventIDS[page*perPage+i], item.EventID(), ), true, "expected %v, got %v", expectedItemID, item.EventID(), ) } } }