eventsModel.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package repository
  2. import (
  3. "database/sql"
  4. "fmt"
  5. )
  6. type Collaborator struct {
  7. ID int64 `json:"id"`
  8. Name string `json:"name"`
  9. }
  10. type Event struct {
  11. ID int
  12. Name string
  13. Date string
  14. PassageValue string
  15. HotelValue string
  16. GiftValue string
  17. TeamValue string
  18. SponsorValue string
  19. TotalValue string
  20. CollaboratorIDs []int64 `json:"-"`
  21. Collaborators []Collaborator
  22. }
  23. type EventRepository struct {
  24. DB *sql.DB
  25. }
  26. func NewEventRepository(db *sql.DB) EventRepository {
  27. return EventRepository{DB: db}
  28. }
  29. func (r EventRepository) GetEvents() ([]Event, error) {
  30. rows, err := r.DB.Query(`
  31. SELECT
  32. e.event_id,
  33. e.event_name,
  34. e.event_date,
  35. e.event_passage_value,
  36. e.event_hotel_value,
  37. e.event_gift_value,
  38. e.event_team_value,
  39. e.event_sponsor_value,
  40. e.event_total_value,
  41. c.collaborator_id,
  42. c.collaborator_name
  43. FROM events e
  44. NATURAL JOIN event_collaborators
  45. NATURAL JOIN collaborator c
  46. `)
  47. if err != nil {
  48. return nil, err
  49. }
  50. defer rows.Close()
  51. eventsMap := make(map[int]Event)
  52. for rows.Next() {
  53. var id int
  54. var name, date, passage, hotel, gift, team, sponsor, total string
  55. var collID int64
  56. var collName string
  57. if err := rows.Scan(&id, &name, &date, &passage, &hotel, &gift, &team, &sponsor, &total, &collID, &collName); err != nil {
  58. return nil, err
  59. }
  60. e, exists := eventsMap[id]
  61. if !exists {
  62. e = Event{
  63. ID: id,
  64. Name: name,
  65. Date: date,
  66. PassageValue: passage,
  67. HotelValue: hotel,
  68. GiftValue: gift,
  69. TeamValue: team,
  70. SponsorValue: sponsor,
  71. TotalValue: total,
  72. CollaboratorIDs: []int64{},
  73. Collaborators: []Collaborator{},
  74. }
  75. }
  76. e.Collaborators = append(e.Collaborators, Collaborator{ID: collID, Name: collName})
  77. eventsMap[id] = e
  78. }
  79. events := make([]Event, 0, len(eventsMap))
  80. for _, e := range eventsMap {
  81. events = append(events, e)
  82. }
  83. return events, rows.Err()
  84. }
  85. func (r EventRepository) CreateEvent(event *Event) (int64, error) {
  86. tx, err := r.DB.Begin()
  87. if err != nil {
  88. return 0, fmt.Errorf("failed to begin transaction: %w", err)
  89. }
  90. var eventID int64
  91. err = tx.QueryRow(`
  92. INSERT INTO events (
  93. event_name,
  94. event_date,
  95. event_passage_value,
  96. event_hotel_value,
  97. event_gift_value,
  98. event_team_value,
  99. event_sponsor_value,
  100. event_total_value
  101. ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
  102. RETURNING event_id
  103. `,
  104. event.Name,
  105. event.Date,
  106. event.PassageValue,
  107. event.HotelValue,
  108. event.GiftValue,
  109. event.TeamValue,
  110. event.SponsorValue,
  111. event.TotalValue,
  112. ).Scan(&eventID)
  113. if err != nil {
  114. tx.Rollback()
  115. return 0, fmt.Errorf("failed to insert event: %w", err)
  116. }
  117. for _, collabID := range event.CollaboratorIDs {
  118. if collabID <= 0 {
  119. continue
  120. }
  121. var exists bool
  122. err = tx.QueryRow(
  123. "SELECT EXISTS(SELECT 1 FROM collaborator WHERE collaborator_id = ?)",
  124. collabID,
  125. ).Scan(&exists)
  126. if err != nil {
  127. tx.Rollback()
  128. return 0, fmt.Errorf("failed to verify collaborator: %w", err)
  129. }
  130. if !exists {
  131. tx.Rollback()
  132. return 0, fmt.Errorf("collaborator with ID %d does not exist", collabID)
  133. }
  134. _, err = tx.Exec(
  135. "INSERT INTO event_collaborators (event_id, collaborator_id) VALUES (?, ?)",
  136. eventID,
  137. collabID,
  138. )
  139. if err != nil {
  140. tx.Rollback()
  141. return 0, fmt.Errorf("failed to associate collaborator %d with event: %w", collabID, err)
  142. }
  143. }
  144. if err := tx.Commit(); err != nil {
  145. return 0, fmt.Errorf("failed to commit transaction: %w", err)
  146. }
  147. return eventID, nil
  148. }
  149. func (r EventRepository) DeleteEvent(eventID int) (int64, error) {
  150. result, err := r.DB.Exec("DELETE FROM events WHERE event_id = ?", eventID)
  151. if err != nil {
  152. return 0, err
  153. }
  154. return result.RowsAffected()
  155. }
  156. func (r EventRepository) EditEvent(event *Event) error {
  157. tx, err := r.DB.Begin()
  158. if err != nil {
  159. return fmt.Errorf("failed to begin transaction: %w", err)
  160. }
  161. res, err := tx.Exec(`
  162. UPDATE events
  163. SET
  164. event_name = ?,
  165. event_date = ?,
  166. event_passage_value = ?,
  167. event_hotel_value = ?,
  168. event_gift_value = ?,
  169. event_team_value = ?,
  170. event_sponsor_value = ?,
  171. event_total_value = ?
  172. WHERE event_id = ?
  173. `,
  174. event.Name,
  175. event.Date,
  176. event.PassageValue,
  177. event.HotelValue,
  178. event.GiftValue,
  179. event.TeamValue,
  180. event.SponsorValue,
  181. event.TotalValue,
  182. event.ID,
  183. )
  184. if err != nil {
  185. tx.Rollback()
  186. return fmt.Errorf("failed to update event: %w", err)
  187. }
  188. affected, err := res.RowsAffected()
  189. if err != nil {
  190. tx.Rollback()
  191. return fmt.Errorf("failed to get rows affected: %w", err)
  192. }
  193. if affected == 0 {
  194. tx.Rollback()
  195. return sql.ErrNoRows
  196. }
  197. // Replace collaborator associations
  198. if _, err := tx.Exec("DELETE FROM event_collaborators WHERE event_id = ?", event.ID); err != nil {
  199. tx.Rollback()
  200. return fmt.Errorf("failed to clear collaborator associations: %w", err)
  201. }
  202. for _, collabID := range event.CollaboratorIDs {
  203. if collabID <= 0 {
  204. continue
  205. }
  206. var exists bool
  207. if err := tx.QueryRow(
  208. "SELECT EXISTS(SELECT 1 FROM collaborator WHERE collaborator_id = ?)",
  209. collabID,
  210. ).Scan(&exists); err != nil {
  211. tx.Rollback()
  212. return fmt.Errorf("failed to verify collaborator: %w", err)
  213. }
  214. if !exists {
  215. tx.Rollback()
  216. return fmt.Errorf("collaborator with ID %d does not exist", collabID)
  217. }
  218. if _, err := tx.Exec(
  219. "INSERT INTO event_collaborators (event_id, collaborator_id) VALUES (?, ?)",
  220. event.ID,
  221. collabID,
  222. ); err != nil {
  223. tx.Rollback()
  224. return fmt.Errorf("failed to associate collaborator %d with event: %w", collabID, err)
  225. }
  226. }
  227. if err := tx.Commit(); err != nil {
  228. return fmt.Errorf("failed to commit transaction: %w", err)
  229. }
  230. return nil
  231. }