src/api/crud.go (view raw)
1package api
2
3import (
4 "encoding/json"
5 "errors"
6 "net/http"
7
8 "github.com/birabittoh/go-lift/src/database"
9 "gorm.io/gorm"
10)
11
12// Routines handlers
13func getRoutinesHandler(db *gorm.DB) http.HandlerFunc {
14 return func(w http.ResponseWriter, r *http.Request) {
15 var routines []database.Routine
16 result := db.Preload("Exercises").Preload("Supersets").Preload("Supersets.Sets").Find(&routines)
17 if result.Error != nil {
18 jsonError(w, http.StatusInternalServerError, "Failed to fetch routines: "+result.Error.Error())
19 return
20 }
21 jsonResponse(w, http.StatusOK, routines)
22 }
23}
24
25func getRoutineHandler(db *gorm.DB) http.HandlerFunc {
26 return func(w http.ResponseWriter, r *http.Request) {
27 id := r.PathValue("id")
28 var routine database.Routine
29 result := db.Preload("Exercises").Preload("Supersets").Preload("Supersets.Sets").First(&routine, id)
30 if result.Error != nil {
31 if errors.Is(result.Error, gorm.ErrRecordNotFound) {
32 jsonError(w, http.StatusNotFound, "Routine not found")
33 return
34 }
35 jsonError(w, http.StatusInternalServerError, "Failed to fetch routine: "+result.Error.Error())
36 return
37 }
38 jsonResponse(w, http.StatusOK, routine)
39 }
40}
41
42func createRoutineHandler(db *gorm.DB) http.HandlerFunc {
43 return func(w http.ResponseWriter, r *http.Request) {
44 var routine database.Routine
45 if err := json.NewDecoder(r.Body).Decode(&routine); err != nil {
46 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
47 return
48 }
49
50 if err := db.Create(&routine).Error; err != nil {
51 jsonError(w, http.StatusInternalServerError, "Failed to create routine: "+err.Error())
52 return
53 }
54
55 // Reload with associations
56 db.Preload("Exercises").Preload("Supersets").Preload("Supersets.Sets").First(&routine, routine.ID)
57
58 jsonResponse(w, http.StatusCreated, routine)
59 }
60}
61
62func updateRoutineHandler(db *gorm.DB) http.HandlerFunc {
63 return func(w http.ResponseWriter, r *http.Request) {
64 id := r.PathValue("id")
65 var routine database.Routine
66
67 // Check if exists
68 if err := db.First(&routine, id).Error; err != nil {
69 if errors.Is(err, gorm.ErrRecordNotFound) {
70 jsonError(w, http.StatusNotFound, "Routine not found")
71 return
72 }
73 jsonError(w, http.StatusInternalServerError, "Database error: "+err.Error())
74 return
75 }
76
77 // Parse update data
78 if err := json.NewDecoder(r.Body).Decode(&routine); err != nil {
79 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
80 return
81 }
82
83 // Save with associations
84 if err := db.Session(&gorm.Session{FullSaveAssociations: true}).Save(&routine).Error; err != nil {
85 jsonError(w, http.StatusInternalServerError, "Failed to update routine: "+err.Error())
86 return
87 }
88
89 // Reload complete data
90 db.Preload("Exercises").Preload("Supersets").Preload("Supersets.Sets").First(&routine, id)
91 jsonResponse(w, http.StatusOK, routine)
92 }
93}
94
95func deleteRoutineHandler(db *gorm.DB) http.HandlerFunc {
96 return func(w http.ResponseWriter, r *http.Request) {
97 id := r.PathValue("id")
98 if err := db.Delete(&database.Routine{}, id).Error; err != nil {
99 jsonError(w, http.StatusInternalServerError, "Failed to delete routine: "+err.Error())
100 return
101 }
102 jsonResponse(w, http.StatusOK, map[string]string{"message": "Routine deleted successfully"})
103 }
104}
105
106// Exercises handlers
107func getExercisesHandler(db *gorm.DB) http.HandlerFunc {
108 return func(w http.ResponseWriter, r *http.Request) {
109 var exercises []database.Exercise
110 if err := db.Find(&exercises).Error; err != nil {
111 jsonError(w, http.StatusInternalServerError, "Failed to fetch exercises: "+err.Error())
112 return
113 }
114 jsonResponse(w, http.StatusOK, exercises)
115 }
116}
117
118func getExerciseHandler(db *gorm.DB) http.HandlerFunc {
119 return func(w http.ResponseWriter, r *http.Request) {
120 id := r.PathValue("id")
121 var exercise database.Exercise
122 if err := db.First(&exercise, id).Error; err != nil {
123 if errors.Is(err, gorm.ErrRecordNotFound) {
124 jsonError(w, http.StatusNotFound, "Exercise not found")
125 return
126 }
127 jsonError(w, http.StatusInternalServerError, "Failed to fetch exercise: "+err.Error())
128 return
129 }
130 jsonResponse(w, http.StatusOK, exercise)
131 }
132}
133
134func createExerciseHandler(db *gorm.DB) http.HandlerFunc {
135 return func(w http.ResponseWriter, r *http.Request) {
136 var exercise database.Exercise
137 if err := json.NewDecoder(r.Body).Decode(&exercise); err != nil {
138 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
139 return
140 }
141
142 if err := db.Create(&exercise).Error; err != nil {
143 jsonError(w, http.StatusInternalServerError, "Failed to create exercise: "+err.Error())
144 return
145 }
146
147 jsonResponse(w, http.StatusCreated, exercise)
148 }
149}
150
151func updateExerciseHandler(db *gorm.DB) http.HandlerFunc {
152 return func(w http.ResponseWriter, r *http.Request) {
153 id := r.PathValue("id")
154
155 // Verify exercise exists
156 var exercise database.Exercise
157 if err := db.First(&exercise, id).Error; err != nil {
158 if errors.Is(err, gorm.ErrRecordNotFound) {
159 jsonError(w, http.StatusNotFound, "Exercise not found")
160 return
161 }
162 jsonError(w, http.StatusInternalServerError, "Database error: "+err.Error())
163 return
164 }
165
166 // Parse update data
167 if err := json.NewDecoder(r.Body).Decode(&exercise); err != nil {
168 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
169 return
170 }
171
172 if err := db.Save(&exercise).Error; err != nil {
173 jsonError(w, http.StatusInternalServerError, "Failed to update exercise: "+err.Error())
174 return
175 }
176
177 jsonResponse(w, http.StatusOK, exercise)
178 }
179}
180
181func deleteExerciseHandler(db *gorm.DB) http.HandlerFunc {
182 return func(w http.ResponseWriter, r *http.Request) {
183 id := r.PathValue("id")
184 if err := db.Delete(&database.Exercise{}, id).Error; err != nil {
185 jsonError(w, http.StatusInternalServerError, "Failed to delete exercise: "+err.Error())
186 return
187 }
188 jsonResponse(w, http.StatusOK, map[string]string{"message": "Exercise deleted successfully"})
189 }
190}
191
192// RecordRoutines handlers
193func getRecordRoutinesHandler(db *gorm.DB) http.HandlerFunc {
194 return func(w http.ResponseWriter, r *http.Request) {
195 var records []database.RecordRoutine
196 result := db.Preload("RecordExercises").Preload("Routine.Exercises").Preload("Routine.Supersets").Find(&records)
197 if result.Error != nil {
198 jsonError(w, http.StatusInternalServerError, "Failed to fetch record routines: "+result.Error.Error())
199 return
200 }
201 jsonResponse(w, http.StatusOK, records)
202 }
203}
204
205func getRecordRoutineHandler(db *gorm.DB) http.HandlerFunc {
206 return func(w http.ResponseWriter, r *http.Request) {
207 id := r.PathValue("id")
208 var record database.RecordRoutine
209 result := db.Preload("Routine").Preload("Routine.Exercises").Preload("Routine.Supersets").First(&record, id)
210 if result.Error != nil {
211 if errors.Is(result.Error, gorm.ErrRecordNotFound) {
212 jsonError(w, http.StatusNotFound, "Record routine not found")
213 return
214 }
215 jsonError(w, http.StatusInternalServerError, "Failed to fetch record routine: "+result.Error.Error())
216 return
217 }
218 jsonResponse(w, http.StatusOK, record)
219 }
220}
221
222func createRecordRoutineHandler(db *gorm.DB) http.HandlerFunc {
223 return func(w http.ResponseWriter, r *http.Request) {
224 var record database.RecordRoutine
225 if err := json.NewDecoder(r.Body).Decode(&record); err != nil {
226 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
227 return
228 }
229
230 if err := db.Create(&record).Error; err != nil {
231 jsonError(w, http.StatusInternalServerError, "Failed to create record routine: "+err.Error())
232 return
233 }
234
235 // Reload with associations
236 db.Preload("Routine").Preload("Routine.Exercises").Preload("Routine.Supersets").First(&record, record.ID)
237
238 jsonResponse(w, http.StatusCreated, record)
239 }
240}
241
242func updateRecordRoutineHandler(db *gorm.DB) http.HandlerFunc {
243 return func(w http.ResponseWriter, r *http.Request) {
244 id := r.PathValue("id")
245 var record database.RecordRoutine
246
247 // Check if exists
248 if err := db.First(&record, id).Error; err != nil {
249 if errors.Is(err, gorm.ErrRecordNotFound) {
250 jsonError(w, http.StatusNotFound, "Record routine not found")
251 return
252 }
253 jsonError(w, http.StatusInternalServerError, "Database error: "+err.Error())
254 return
255 }
256
257 // Parse update data
258 if err := json.NewDecoder(r.Body).Decode(&record); err != nil {
259 jsonError(w, http.StatusBadRequest, "Invalid request body: "+err.Error())
260 return
261 }
262
263 // Save with associations
264 if err := db.Session(&gorm.Session{FullSaveAssociations: true}).Save(&record).Error; err != nil {
265 jsonError(w, http.StatusInternalServerError, "Failed to update record routine: "+err.Error())
266 return
267 }
268
269 // Reload complete data
270 db.Preload("Routine").Preload("Routine.Exercises").Preload("Routine.Supersets").First(&record, id)
271 jsonResponse(w, http.StatusOK, record)
272 }
273}
274
275func deleteRecordRoutineHandler(db *gorm.DB) http.HandlerFunc {
276 return func(w http.ResponseWriter, r *http.Request) {
277 id := r.PathValue("id")
278 if err := db.Delete(&database.RecordRoutine{}, id).Error; err != nil {
279 jsonError(w, http.StatusInternalServerError, "Failed to delete record routine: "+err.Error())
280 return
281 }
282 jsonResponse(w, http.StatusOK, map[string]string{"message": "Record routine deleted successfully"})
283 }
284}