Count responses in store
This commit is contained in:
		@@ -91,10 +91,25 @@ const schema = `
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	CREATE TABLE response_time (
 | 
						CREATE TABLE response_time (
 | 
				
			||||||
		response_id INTEGER PRIMARY KEY,
 | 
							response_id INTEGER PRIMARY KEY,
 | 
				
			||||||
 | 
							date DATE NOT NULL,
 | 
				
			||||||
		time INTEGER NOT NULL,
 | 
							time INTEGER NOT NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CHECK (0 <= time < 24)
 | 
							CHECK (0 <= time < 24),
 | 
				
			||||||
	);`
 | 
							UNIQUE (response_id, date, time)
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						CREATE TRIGGER enforce_valid_response_dates
 | 
				
			||||||
 | 
						BEFORE INSERT ON response_time
 | 
				
			||||||
 | 
						BEGIN
 | 
				
			||||||
 | 
							SELECT
 | 
				
			||||||
 | 
								CASE
 | 
				
			||||||
 | 
									WHEN NEW.date BETWEEN event.earliest_date AND event.latest_date
 | 
				
			||||||
 | 
										THEN RAISE(ABORT, 'response date is out of range')
 | 
				
			||||||
 | 
								END
 | 
				
			||||||
 | 
							FROM response
 | 
				
			||||||
 | 
							JOIN event ON response.event_id = event.id
 | 
				
			||||||
 | 
							WHERE response.id = NEW.response_id;
 | 
				
			||||||
 | 
						END;`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *Store) createSchema() error {
 | 
					func (s *Store) createSchema() error {
 | 
				
			||||||
	conn := s.pool.Get(context.Background())
 | 
						conn := s.pool.Get(context.Background())
 | 
				
			||||||
@@ -224,3 +239,41 @@ func (s *Store) GetEventResponses(ctx context.Context, query GetEventResponsesQu
 | 
				
			|||||||
	// TODO return an error if the event does not exist?
 | 
						// TODO return an error if the event does not exist?
 | 
				
			||||||
	return result, err
 | 
						return result, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreateEventResponseCommand struct {
 | 
				
			||||||
 | 
						EventAlphaID string
 | 
				
			||||||
 | 
						DateHours    map[time.Time]int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CreateEventResponseResult struct {
 | 
				
			||||||
 | 
						ResponseAlphaID string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *Store) CreateEventResponse(ctx context.Context, cmd CreateEventResponseCommand) (result CreateEventResponseResult, err error) {
 | 
				
			||||||
 | 
						const responseAlphaIDLength = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conn := s.pool.Get(ctx)
 | 
				
			||||||
 | 
						defer s.pool.Put(conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer sqlitex.Save(conn)(&err)
 | 
				
			||||||
 | 
						responseAlphaID, err := s.genString(responseAlphaIDLength)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return CreateEventResponseResult{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Create response
 | 
				
			||||||
 | 
						const responseQuery = `
 | 
				
			||||||
 | 
							INSERT INTO response(event_id, alpha_id)
 | 
				
			||||||
 | 
								SELECT event.id AS event_id, ? AS alpha_id
 | 
				
			||||||
 | 
								FROM event
 | 
				
			||||||
 | 
								WHERE event.alpha_id = ?;`
 | 
				
			||||||
 | 
						err = sqlitex.Exec(conn, responseQuery, nil, responseAlphaID, cmd.EventAlphaID)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return CreateEventResponseResult{}, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// TODO Create response times
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return CreateEventResponseResult{
 | 
				
			||||||
 | 
							ResponseAlphaID: responseAlphaID,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,3 +44,58 @@ func TestCreateEvent(t *testing.T) {
 | 
				
			|||||||
	is.True(metadataResult.EarliestDate.Equal(earliest))
 | 
						is.True(metadataResult.EarliestDate.Equal(earliest))
 | 
				
			||||||
	is.True(metadataResult.LatestDate.Equal(latest))
 | 
						is.True(metadataResult.LatestDate.Equal(latest))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGetEventResponses(t *testing.T) {
 | 
				
			||||||
 | 
						store, err := back.NewMemoryStore(back.SecureGenString)
 | 
				
			||||||
 | 
						is.New(t).NoErr(err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createEvent := func(is *is.I) (eventID string) {
 | 
				
			||||||
 | 
							event, err := store.CreateEvent(context.Background(), back.CreateEventCommand{
 | 
				
			||||||
 | 
								Name: "blah",
 | 
				
			||||||
 | 
								Description: "stuff happening",
 | 
				
			||||||
 | 
								EarliestDate: time.Now(),
 | 
				
			||||||
 | 
								LatestDate: time.Now().AddDate(0,0,1),
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							is.NoErr(err)
 | 
				
			||||||
 | 
							return event.AlphaID
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						getTotalResponses := func(is *is.I, eventID string) int {
 | 
				
			||||||
 | 
							responses, err := store.GetEventResponses(context.Background(), back.GetEventResponsesQuery{
 | 
				
			||||||
 | 
								AlphaID: eventID,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							is.NoErr(err)
 | 
				
			||||||
 | 
							return responses.TotalResponses
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createEmptyResponse := func(is *is.I, eventID string) {
 | 
				
			||||||
 | 
							_, err = store.CreateEventResponse(context.Background(), back.CreateEventResponseCommand{
 | 
				
			||||||
 | 
								EventAlphaID: eventID,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							is.NoErr(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Run("TotalResponses counts the number of responses created", func(t *testing.T) {
 | 
				
			||||||
 | 
							is := is.New(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							eventID := createEvent(is)
 | 
				
			||||||
 | 
							is.Equal(getTotalResponses(is, eventID), 0)
 | 
				
			||||||
 | 
							const respondTimes = 5
 | 
				
			||||||
 | 
							for i := 1; i <= respondTimes; i++ {
 | 
				
			||||||
 | 
								createEmptyResponse(is, eventID)
 | 
				
			||||||
 | 
								is.Equal(getTotalResponses(is, eventID), i)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Run("TotalResponses does not count responses to other events", func(t *testing.T) {
 | 
				
			||||||
 | 
							is := is.New(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							eventID := createEvent(is)
 | 
				
			||||||
 | 
							createEmptyResponse(is, eventID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Create a response to another event
 | 
				
			||||||
 | 
							createEmptyResponse(is, createEvent(is))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							is.Equal(getTotalResponses(is, eventID), 1)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user