|
|
@ -58,29 +58,34 @@ func (s *Store) Close() error {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (s *Store) Claim(ctx context.Context, userId, player, province string, claimType ClaimType) (int, error) {
|
|
|
|
func (s *Store) Claim(ctx context.Context, userId, player, province string, claimType ClaimType) (int, error) {
|
|
|
|
defer s.Audit(&AuditableEvent{
|
|
|
|
audit := &AuditableEvent{
|
|
|
|
userId: userId,
|
|
|
|
userId: userId,
|
|
|
|
eventType: EventClaim,
|
|
|
|
eventType: EventClaim,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
defer s.Audit(audit)
|
|
|
|
|
|
|
|
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
tx, err := s.db.Begin()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to begin transaction: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to begin transaction: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
defer tx.Commit() //nolint:errcheck
|
|
|
|
defer tx.Commit() //nolint:errcheck
|
|
|
|
|
|
|
|
|
|
|
|
conflicts, err := s.FindConflicts(ctx, userId, province, claimType)
|
|
|
|
conflicts, err := s.FindConflicts(ctx, userId, province, claimType)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to run conflicts check: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to run conflicts check: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if len(conflicts) > 0 {
|
|
|
|
if len(conflicts) > 0 {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, ErrConflict{Conflicts: conflicts}
|
|
|
|
return 0, ErrConflict{Conflicts: conflicts}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// check that provided name matches the claim type
|
|
|
|
// check that provided name matches the claim type
|
|
|
|
stmt, err := s.db.PrepareContext(ctx, fmt.Sprintf(`SELECT COUNT(1) FROM provinces WHERE LOWER(provinces.%s) = ?`, claimTypeToColumn[claimType]))
|
|
|
|
stmt, err := s.db.PrepareContext(ctx, fmt.Sprintf(`SELECT COUNT(1) FROM provinces WHERE LOWER(provinces.%s) = ?`, claimTypeToColumn[claimType]))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to prepare count query: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to prepare count query: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -88,25 +93,30 @@ func (s *Store) Claim(ctx context.Context, userId, player, province string, clai
|
|
|
|
var count int
|
|
|
|
var count int
|
|
|
|
err = row.Scan(&count)
|
|
|
|
err = row.Scan(&count)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to scan: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to scan: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if count == 0 {
|
|
|
|
if count == 0 {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("found no provinces for %s named %s", claimType, province)
|
|
|
|
return 0, fmt.Errorf("found no provinces for %s named %s", claimType, province)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stmt, err = s.db.PrepareContext(ctx, "INSERT INTO claims (player, claim_type, val, userid) VALUES (?, ?, ?, ?)")
|
|
|
|
stmt, err = s.db.PrepareContext(ctx, "INSERT INTO claims (player, claim_type, val, userid) VALUES (?, ?, ?, ?)")
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to prepare claim query: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to prepare claim query: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res, err := stmt.ExecContext(ctx, player, claimType, province, userId)
|
|
|
|
res, err := stmt.ExecContext(ctx, player, claimType, province, userId)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to insert claim: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to insert claim: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
id, err := res.LastInsertId()
|
|
|
|
id, err := res.LastInsertId()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return 0, fmt.Errorf("failed to get last ID: %w", err)
|
|
|
|
return 0, fmt.Errorf("failed to get last ID: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -242,26 +252,31 @@ func (s *Store) DescribeClaim(ctx context.Context, ID int) (ClaimDetail, error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (s *Store) DeleteClaim(ctx context.Context, ID int, userId string) error {
|
|
|
|
func (s *Store) DeleteClaim(ctx context.Context, ID int, userId string) error {
|
|
|
|
defer s.Audit(&AuditableEvent{
|
|
|
|
audit := &AuditableEvent{
|
|
|
|
userId: userId,
|
|
|
|
userId: userId,
|
|
|
|
eventType: EventUnclaim,
|
|
|
|
eventType: EventUnclaim,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
defer s.Audit(audit)
|
|
|
|
|
|
|
|
|
|
|
|
stmt, err := s.db.PrepareContext(ctx, "DELETE FROM claims WHERE id = ? AND userid = ?")
|
|
|
|
stmt, err := s.db.PrepareContext(ctx, "DELETE FROM claims WHERE id = ? AND userid = ?")
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return fmt.Errorf("failed to prepare query: %w", err)
|
|
|
|
return fmt.Errorf("failed to prepare query: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res, err := stmt.ExecContext(ctx, ID, userId)
|
|
|
|
res, err := stmt.ExecContext(ctx, ID, userId)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return fmt.Errorf("failed to delete claim ID %d: %w", ID, err)
|
|
|
|
return fmt.Errorf("failed to delete claim ID %d: %w", ID, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rows, err := res.RowsAffected()
|
|
|
|
rows, err := res.RowsAffected()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return fmt.Errorf("failed to get affected rows: %w", err)
|
|
|
|
return fmt.Errorf("failed to get affected rows: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if rows == 0 {
|
|
|
|
if rows == 0 {
|
|
|
|
|
|
|
|
audit.err = ErrNoSuchClaim
|
|
|
|
return ErrNoSuchClaim
|
|
|
|
return ErrNoSuchClaim
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
@ -283,13 +298,15 @@ func (s *Store) CountClaims(ctx context.Context) (total, uniquePlayers int, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (s *Store) Flush(ctx context.Context, userId string) error {
|
|
|
|
func (s *Store) Flush(ctx context.Context, userId string) error {
|
|
|
|
defer s.Audit(&AuditableEvent{
|
|
|
|
audit := &AuditableEvent{
|
|
|
|
userId: userId,
|
|
|
|
userId: userId,
|
|
|
|
eventType: EventFlush,
|
|
|
|
eventType: EventFlush,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
defer s.Audit(audit)
|
|
|
|
|
|
|
|
|
|
|
|
_, err := s.db.ExecContext(ctx, "DELETE FROM claims;")
|
|
|
|
_, err := s.db.ExecContext(ctx, "DELETE FROM claims;")
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
audit.err = err
|
|
|
|
return fmt.Errorf("failed to execute delete query: %w", err)
|
|
|
|
return fmt.Errorf("failed to execute delete query: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|