Completed
Push — main ( 19662a...9f7f07 )
by Yume
14s queued 11s
created

app/queries/queries.go   B

Size/Duplication

Total Lines 289
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 43
eloc 184
dl 0
loc 289
rs 8.96
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A queries.PostMem 0 25 4
A queries.FetchMem 0 8 2
A queries.FetchTrainingCards 0 27 4
A queries.FetchNextCard 0 24 4
A queries.PopulateMemDate 0 15 3
A queries.GenerateCreatorAccess 0 22 3
B queries.GenerateAccess 0 30 6
A queries.GetSubUsers 0 12 2
A queries.CheckAccess 0 17 3
A queries.GenerateMCQ 0 15 4
A queries.FetchNextTodayCard 0 16 2
A queries.FillResponseDeck 0 21 3
A queries.GenerateMemDate 0 17 3
1
package queries
2
3
import (
4
	"errors"
5
	"gorm.io/gorm"
6
	"math/rand"
7
	"memnixrest/app/models"
8
	"memnixrest/pkg/core"
9
	"memnixrest/pkg/database"
10
	"memnixrest/pkg/utils"
11
	"time"
12
)
13
14
func FillResponseDeck(deck *models.Deck, permission models.AccessPermission) models.ResponseDeck {
15
	db := database.DBConn
16
17
	deckResponse := new(models.ResponseDeck)
18
19
	deckResponse.Deck = *deck
20
	deckResponse.DeckID = deck.ID
21
	deckResponse.Permission = permission
22
23
	if owner := deck.GetOwner(); owner.ID != 0 {
24
		deckResponse.Owner = owner
25
		deckResponse.OwnerId = owner.ID
26
	}
27
28
	var count int64
29
	if err := db.Table("cards").Where("cards.deck_id = ?", deck.ID).Count(&count).Error; err != nil {
30
		deckResponse.CardCount = 0
31
	} else {
32
		deckResponse.CardCount = count
33
	}
34
	return *deckResponse
35
}
36
37
// GenerateCreatorAccess function
38
func GenerateCreatorAccess(user *models.User, deck *models.Deck) *models.ResponseHTTP {
39
	db := database.DBConn
40
41
	access := new(models.Access)
42
	res := new(models.ResponseHTTP)
43
44
	if err := db.Joins("User").Joins("Deck").Where("accesses.user_id = ? AND accesses.deck_id =?", user.ID, deck.ID).Find(&access).Error; err != nil {
45
		if errors.Is(err, gorm.ErrRecordNotFound) {
46
			access.Fill(user.ID, deck.ID, models.AccessOwner)
47
			db.Create(access)
48
		}
49
	} else {
50
		res.GenerateError(utils.ErrorForbidden)
51
		return res
52
	}
53
54
	log := CreateLog(models.LogSubscribe, user.Username+" subscribed to "+deck.DeckName)
55
	_ = CreateUserLog(user.ID, log)
56
	_ = CreateDeckLog(deck.ID, log)
57
58
	res.GenerateSuccess("Success register a creator access !", *access, 1)
59
	return res
60
}
61
62
// GenerateAccess function
63
func GenerateAccess(user *models.User, deck *models.Deck) *models.ResponseHTTP {
64
	db := database.DBConn
65
	res := new(models.ResponseHTTP)
66
67
	if deck.Status != models.DeckPublic && user.Permissions != models.PermAdmin {
68
		res.GenerateError(utils.ErrorForbidden)
69
		return res
70
	}
71
72
	access := new(models.Access)
73
74
	if err := db.Joins("User").Joins("Deck").Where("accesses.user_id = ? AND accesses.deck_id =?", user.ID, deck.ID).Find(&access).Error; err != nil {
75
		if errors.Is(err, gorm.ErrRecordNotFound) {
76
			access.Fill(user.ID, deck.ID, models.AccessStudent)
77
			db.Preload("User").Preload("Deck").Create(access)
78
		}
79
80
	} else {
81
		if access.Permission >= models.AccessStudent {
82
			res.GenerateError(utils.ErrorAlreadySub)
83
			return res
84
85
		} else {
86
			access.Fill(user.ID, deck.ID, models.AccessStudent)
87
			db.Preload("User").Preload("Deck").Save(access)
88
		}
89
	}
90
91
	res.GenerateSuccess("Success register an access", *access, 1)
92
	return res
93
}
94
95
func CheckAccess(userID, deckID uint, perm models.AccessPermission) *models.ResponseHTTP {
96
	db := database.DBConn // DB Conn
97
98
	access := new(models.Access)
99
	res := new(models.ResponseHTTP)
100
101
	if err := db.Joins("User").Joins("Deck").Where("accesses.user_id = ? AND accesses.deck_id = ?", userID, deckID).First(&access).Error; err != nil {
102
		access.Permission = models.AccessNone
103
	}
104
105
	if access.Permission < perm {
106
		res.GenerateError(utils.ErrorForbidden)
107
		return res
108
	}
109
110
	res.GenerateSuccess("Success checking access permissions", *access, 1)
111
	return res
112
}
113
114
func PostMem(user *models.User, card *models.Card, validation *models.CardResponseValidation, training bool) *models.ResponseHTTP {
115
	db := database.DBConn // DB Conn
116
	res := new(models.ResponseHTTP)
117
118
	memDate := new(models.MemDate)
119
120
	if err := db.Joins("Card").Joins("User").Joins("Deck").Where("mem_dates.user_id = ? AND mem_dates.card_id = ?",
121
		user.ID, card.ID).First(&memDate).Error; err != nil {
122
		res.GenerateError(utils.ErrorRequestFailed) // MemDate not found
123
		// TODO: Create a default MemDate
124
		return res
125
	}
126
127
	exMem := FetchMem(memDate.CardID, user.ID)
128
	if exMem.Efactor == 0 {
129
		exMem.FillDefaultValues(user.ID, card.ID)
130
	}
131
132
	if training {
133
		core.UpdateMemTraining(&exMem, validation.Validate)
134
	} else {
135
		core.UpdateMem(&exMem, validation.Validate)
136
	}
137
	res.GenerateSuccess("Success Post Mem", nil, 0)
138
	return res
139
}
140
141
func PopulateMemDate(user *models.User, deck *models.Deck) *models.ResponseHTTP {
142
	db := database.DBConn // DB Conn
143
	var cards []models.Card
144
	res := new(models.ResponseHTTP)
145
146
	if err := db.Joins("Deck").Where("cards.deck_id = ?", deck.ID).Find(&cards).Error; err != nil {
147
		res.GenerateError(err.Error()) // MemDate not found
148
		return res
149
	}
150
151
	for _, s := range cards {
152
		_ = GenerateMemDate(user.ID, s.ID, s.DeckID)
153
	}
154
	res.GenerateSuccess("Success generated mem_date", nil, 0)
155
	return res
156
}
157
158
func GetSubUsers(deckID uint) *models.ResponseHTTP {
159
	res := new(models.ResponseHTTP)
160
161
	db := database.DBConn // DB Conn
162
	var users []models.User
163
164
	if err := db.Joins("left join accesses ON users.id = accesses.user_id AND accesses.deck_id = ?", deckID).Where("accesses.permission > ?", models.AccessNone).Find(&users).Error; err != nil {
165
		res.GenerateError(err.Error())
166
		return res
167
	}
168
	res.GenerateSuccess("Success getting sub users", users, len(users))
169
	return res
170
}
171
172
func GenerateMemDate(userID, cardID, deckID uint) *models.ResponseHTTP {
173
	db := database.DBConn // DB Conn
174
	res := new(models.ResponseHTTP)
175
176
	memDate := new(models.MemDate)
177
178
	if err := db.Joins("User").Joins("Card").Where("mem_dates.user_id = ? AND mem_dates.card_id = ?", userID, cardID).First(&memDate).Error; err != nil {
179
		if errors.Is(err, gorm.ErrRecordNotFound) {
180
			memDate.Generate(userID, cardID, deckID)
181
			db.Create(memDate)
182
		} else {
183
			res.GenerateError(err.Error())
184
			return res
185
		}
186
	}
187
	res.GenerateSuccess("Success generate MemDate", memDate, 1)
188
	return res
189
}
190
191
func FetchMem(cardID, userID uint) models.Mem {
192
	db := database.DBConn // DB Conn
193
194
	mem := new(models.Mem)
195
	if err := db.Joins("Card").Where("mems.card_id = ? AND mems.user_id = ?", cardID, userID).Order("id desc").First(&mem).Error; err != nil {
196
		mem.Efactor = 0
197
	}
198
	return *mem
199
}
200
201
func GenerateMCQ(memDate *models.MemDate, userID uint) []string {
202
203
	mem := FetchMem(memDate.CardID, userID)
204
205
	var answersList []string
206
	if mem.IsMCQ() || memDate.Card.Type == models.CardMCQ {
207
208
		answersList = memDate.Card.GetMCQAnswers()
209
		if len(answersList) == 4 {
210
			memDate.Card.Type = 2 // MCQ
211
		}
212
		return answersList
213
	}
214
215
	return answersList
216
}
217
218
func FetchTrainingCards(userID, deckID uint) *models.ResponseHTTP {
219
	res := new(models.ResponseHTTP)
220
	db := database.DBConn // DB Conn
221
	var result []models.ResponseCard
222
223
	var memDates []models.MemDate
224
225
	if err := db.Joins("Deck").Joins("Card").Where("mem_dates.deck_id = ? AND mem_dates.user_id = ?", deckID, userID).Find(&memDates).Error; err != nil {
226
		res.GenerateError(err.Error())
227
		return res
228
	}
229
	responseCard := new(models.ResponseCard)
230
	var answersList []string
231
232
	for i := range memDates {
233
234
		answersList = GenerateMCQ(&memDates[i], userID)
235
		responseCard.Generate(memDates[i].Card, answersList)
236
237
		result = append(result, *responseCard)
238
	}
239
240
	rand.Seed(time.Now().UnixNano())
241
	rand.Shuffle(len(result), func(i, j int) { result[i], result[j] = result[j], result[i] })
242
243
	res.GenerateSuccess("Success getting next card", result, len(result))
244
	return res
245
246
}
247
248
func FetchNextTodayCard(userID uint) *models.ResponseHTTP {
249
	res := new(models.ResponseHTTP)
250
	responseCard := new(models.ResponseCard)
251
	memDate := new(models.MemDate)
252
	var answersList []string
253
254
	if result := memDate.GetNextToday(userID); !result.Success {
255
		res.GenerateError("Next card not found")
256
		return res
257
	}
258
	answersList = GenerateMCQ(memDate, userID)
259
260
	responseCard.Generate(memDate.Card, answersList)
261
262
	res.GenerateSuccess("Success getting next card", responseCard, 1)
263
	return res
264
}
265
266
func FetchNextCard(userID, deckID uint) *models.ResponseHTTP {
267
	res := new(models.ResponseHTTP)
268
	responseCard := new(models.ResponseCard)
269
	memDate := new(models.MemDate)
270
	var answersList []string
271
272
	if deckID != 0 {
273
		if result := memDate.GetNextByDeck(userID, deckID); !result.Success {
274
			res.GenerateError("Next card not found")
275
			return res
276
		}
277
	} else {
278
		if result := memDate.GetNext(userID); !result.Success {
279
			res.GenerateError("Next card not found")
280
			return res
281
		}
282
283
	}
284
285
	answersList = GenerateMCQ(memDate, userID)
286
	responseCard.Generate(memDate.Card, answersList)
287
288
	res.GenerateSuccess("Success getting next card", responseCard, 1)
289
	return res
290
}
291