AIdeaText commited on
Commit
bf76c5a
·
verified ·
1 Parent(s): ac4bde9

Update modules/database/sql_db.py

Browse files
Files changed (1) hide show
  1. modules/database/sql_db.py +43 -180
modules/database/sql_db.py CHANGED
@@ -1,5 +1,4 @@
1
  #modules/database/sql_db.py
2
-
3
  from .database_init import get_container
4
  from datetime import datetime, timezone
5
  import logging
@@ -8,26 +7,25 @@ import uuid
8
 
9
  logger = logging.getLogger(__name__)
10
 
11
- ###########################################
12
-
13
  def get_user(username, role=None):
14
  container = get_container("users")
15
  try:
16
- query = f"SELECT * FROM c WHERE c.id = '{username}'"
17
- if role:
18
- query += f" AND c.role = '{role}'"
19
  items = list(container.query_items(
20
- query=query,
21
- enable_cross_partition_query=True # Añadimos esta línea
 
22
  ))
 
 
 
 
 
23
  return items[0] if items else None
24
  except Exception as e:
25
  logger.error(f"Error al obtener usuario {username}: {str(e)}")
26
  return None
27
 
28
- ###########################################
29
-
30
-
31
  def get_admin_user(username):
32
  return get_user(username, role='Administrador')
33
 
@@ -37,10 +35,6 @@ def get_student_user(username):
37
  def get_teacher_user(username):
38
  return get_user(username, role='Profesor')
39
 
40
-
41
-
42
- ###################################################
43
-
44
  def create_user(username, password, role, additional_info=None):
45
  """Crea un nuevo usuario"""
46
  container = get_container("users")
@@ -50,17 +44,17 @@ def create_user(username, password, role, additional_info=None):
50
 
51
  try:
52
  user_data = {
53
- 'id': username,
54
  'password': password,
55
  'role': role,
56
  'timestamp': datetime.now(timezone.utc).isoformat(),
57
- 'additional_info': additional_info or {},
58
- 'partitionKey': username # Añadimos esta línea
59
  }
60
 
 
61
  container.create_item(
62
  body=user_data,
63
- enable_cross_partition_query=True # Añadimos esta línea
64
  )
65
  logger.info(f"Usuario {role} creado: {username}")
66
  return True
@@ -69,8 +63,6 @@ def create_user(username, password, role, additional_info=None):
69
  logger.error(f"Error al crear usuario {role}: {str(e)}")
70
  return False
71
 
72
-
73
- #######################################################
74
  def create_student_user(username, password, additional_info=None):
75
  return create_user(username, password, 'Estudiante', additional_info)
76
 
@@ -80,10 +72,6 @@ def create_teacher_user(username, password, additional_info=None):
80
  def create_admin_user(username, password, additional_info=None):
81
  return create_user(username, password, 'Administrador', additional_info)
82
 
83
- ############-- Funciones de control del tiempo de sesión ##################
84
-
85
- ###########################################################
86
-
87
  def record_login(username):
88
  """Registra el inicio de sesión de un usuario"""
89
  try:
@@ -98,12 +86,12 @@ def record_login(username):
98
  "type": "session",
99
  "username": username,
100
  "loginTime": datetime.now(timezone.utc).isoformat(),
101
- "additional_info": {},
102
- "partitionKey": username
103
  }
104
 
105
  result = container.create_item(
106
- body=session_doc # Solo el body
 
107
  )
108
  logger.info(f"Sesión {session_id} registrada para {username}")
109
  return session_id
@@ -111,8 +99,6 @@ def record_login(username):
111
  logger.error(f"Error registrando login: {str(e)}")
112
  return None
113
 
114
- ###########################################################
115
-
116
  def record_logout(username, session_id):
117
  """Registra el cierre de sesión y calcula la duración"""
118
  try:
@@ -121,15 +107,13 @@ def record_logout(username, session_id):
121
  logger.error("No se pudo obtener el contenedor users_sessions")
122
  return False
123
 
124
- query = "SELECT * FROM c WHERE c.id = @id AND c.username = @username"
125
- params = [
126
- {"name": "@id", "value": session_id},
127
- {"name": "@username", "value": username}
128
- ]
129
-
130
  items = list(container.query_items(
131
- query=query,
132
- parameters=params # Removido enable_cross_partition_query
 
 
 
 
133
  ))
134
 
135
  if not items:
@@ -143,12 +127,12 @@ def record_logout(username, session_id):
143
 
144
  session.update({
145
  "logoutTime": logout_time.isoformat(),
146
- "sessionDuration": duration,
147
- "partitionKey": username # Asegurar que partitionKey esté presente
148
  })
149
 
150
  container.upsert_item(
151
- body=session # Solo el body
 
152
  )
153
  logger.info(f"Sesión {session_id} cerrada para {username}, duración: {duration}s")
154
  return True
@@ -156,9 +140,6 @@ def record_logout(username, session_id):
156
  logger.error(f"Error registrando logout: {str(e)}")
157
  return False
158
 
159
-
160
- ###########################################################
161
-
162
  def get_recent_sessions(limit=10):
163
  """Obtiene las sesiones más recientes"""
164
  try:
@@ -167,17 +148,16 @@ def get_recent_sessions(limit=10):
167
  logger.error("No se pudo obtener el contenedor users_sessions")
168
  return []
169
 
170
- query = """
171
- SELECT c.username, c.loginTime, c.logoutTime, c.sessionDuration
172
- FROM c
173
- WHERE c.type = 'session'
174
- ORDER BY c.loginTime DESC
175
- OFFSET 0 LIMIT @limit
176
- """
177
-
178
  sessions = list(container.query_items(
179
- query=query,
180
- parameters=[{"name": "@limit", "value": limit}] # Removido enable_cross_partition_query
 
 
 
 
 
 
 
181
  ))
182
 
183
  clean_sessions = []
@@ -198,10 +178,6 @@ def get_recent_sessions(limit=10):
198
  logger.error(f"Error obteniendo sesiones recientes: {str(e)}")
199
  return []
200
 
201
-
202
-
203
- ###########################################################
204
-
205
  def get_user_total_time(username):
206
  """Obtiene el tiempo total que un usuario ha pasado en la plataforma"""
207
  try:
@@ -209,132 +185,19 @@ def get_user_total_time(username):
209
  if not container:
210
  return None
211
 
212
- query = """
213
- SELECT VALUE SUM(c.sessionDuration)
214
- FROM c
215
- WHERE c.type = 'session'
216
- AND c.username = @username
217
- AND IS_DEFINED(c.sessionDuration)
218
- """
219
-
220
  result = list(container.query_items(
221
- query=query,
222
- parameters=[{"name": "@username", "value": username}] # Removido enable_cross_partition_query
 
 
 
 
 
 
 
223
  ))
224
 
225
  return result[0] if result and result[0] is not None else 0
226
  except Exception as e:
227
  logger.error(f"Error obteniendo tiempo total: {str(e)}")
228
  return 0
229
-
230
- ###########################################################
231
- def update_student_user(username, new_info):
232
- user_container, _, _ = get_sql_containers()
233
- try:
234
- user = get_student_user(username)
235
- if user:
236
- user['additional_info'].update(new_info)
237
- user_container.upsert_item(body=user)
238
- logger.info(f"Información del estudiante actualizada: {username}")
239
- return True
240
- else:
241
- logger.warning(f"Intento de actualizar estudiante no existente: {username}")
242
- return False
243
- except Exception as e:
244
- logger.error(f"Error al actualizar información del estudiante {username}: {str(e)}")
245
- return False
246
-
247
-
248
- #########################################################
249
- def delete_student_user(username):
250
- user_container, _, _ = get_sql_containers()
251
- try:
252
- user = get_student_user(username)
253
- if user:
254
- user_container.delete_item(item=user['id'], partition_key=username)
255
- logger.info(f"Estudiante eliminado: {username}")
256
- return True
257
- else:
258
- logger.warning(f"Intento de eliminar estudiante no existente: {username}")
259
- return False
260
- except Exception as e:
261
- logger.error(f"Error al eliminar estudiante {username}: {str(e)}")
262
- return False
263
-
264
-
265
-
266
- #########################################################
267
-
268
- def store_application_request(name, lastname, email, institution, current_role, desired_role, reason):
269
- """Almacena una solicitud de aplicación"""
270
- try:
271
- # Obtener el contenedor usando get_container() que sí funciona
272
- container = get_container("application_requests")
273
- if not container:
274
- logger.error("No se pudo obtener el contenedor de solicitudes")
275
- return False
276
-
277
- # Crear documento con la solicitud
278
- # Nótese que incluimos email como partition key en el cuerpo del documento
279
- application_request = {
280
- "id": str(uuid.uuid4()),
281
- "name": name,
282
- "lastname": lastname,
283
- "email": email,
284
- "institution": institution,
285
- "current_role": current_role,
286
- "desired_role": desired_role,
287
- "reason": reason,
288
- "requestDate": datetime.utcnow().isoformat(),
289
- # El campo para partition key debe estar en el documento
290
- "partitionKey": email
291
- }
292
-
293
- # Crear el item en el contenedor - sin el parámetro enable_cross_partition_query
294
- container.create_item(
295
- body=application_request # Solo pasamos el body
296
- )
297
- logger.info(f"Solicitud de aplicación almacenada para: {email}")
298
- return True
299
-
300
- except Exception as e:
301
- logger.error(f"Error al almacenar la solicitud de aplicación: {str(e)}")
302
- logger.error(f"Detalles del error: {str(e)}")
303
- return False
304
-
305
- ############################################################
306
- def store_student_feedback(username, name, email, feedback):
307
- """Almacena el feedback de un estudiante"""
308
- try:
309
- # Obtener el contenedor - verificar disponibilidad
310
- logger.info(f"Intentando obtener contenedor user_feedback para usuario: {username}")
311
- container = get_container("user_feedback")
312
- if not container:
313
- logger.error("No se pudo obtener el contenedor user_feedback")
314
- return False
315
-
316
- # Crear documento de feedback - asegurar que el username esté como partition key
317
- feedback_item = {
318
- "id": str(uuid.uuid4()),
319
- "username": username, # Campo regular
320
- "name": name,
321
- "email": email,
322
- "feedback": feedback,
323
- "role": "Estudiante",
324
- "timestamp": datetime.now(timezone.utc).isoformat(),
325
- "partitionKey": username # Campo de partición
326
- }
327
-
328
- # Crear el item - sin el parámetro enable_cross_partition_query
329
- logger.info(f"Intentando almacenar feedback para usuario: {username}")
330
- result = container.create_item(
331
- body=feedback_item # Solo el body, no parámetros adicionales
332
- )
333
-
334
- logger.info(f"Feedback almacenado exitosamente para el usuario: {username}")
335
- return True
336
-
337
- except Exception as e:
338
- logger.error(f"Error al almacenar el feedback del estudiante {username}")
339
- logger.error(f"Detalles del error: {str(e)}")
340
- return False
 
1
  #modules/database/sql_db.py
 
2
  from .database_init import get_container
3
  from datetime import datetime, timezone
4
  import logging
 
7
 
8
  logger = logging.getLogger(__name__)
9
 
 
 
10
  def get_user(username, role=None):
11
  container = get_container("users")
12
  try:
13
+ # Consulta básica por ID que es el partition key
 
 
14
  items = list(container.query_items(
15
+ query=f"SELECT * FROM c WHERE c.id = @username",
16
+ parameters=[{"name": "@username", "value": username}],
17
+ partition_key=username
18
  ))
19
+
20
+ # Si se especifica rol, filtrar por rol
21
+ if role and items:
22
+ items = [item for item in items if item['role'] == role]
23
+
24
  return items[0] if items else None
25
  except Exception as e:
26
  logger.error(f"Error al obtener usuario {username}: {str(e)}")
27
  return None
28
 
 
 
 
29
  def get_admin_user(username):
30
  return get_user(username, role='Administrador')
31
 
 
35
  def get_teacher_user(username):
36
  return get_user(username, role='Profesor')
37
 
 
 
 
 
38
  def create_user(username, password, role, additional_info=None):
39
  """Crea un nuevo usuario"""
40
  container = get_container("users")
 
44
 
45
  try:
46
  user_data = {
47
+ 'id': username, # Este campo es el partition key
48
  'password': password,
49
  'role': role,
50
  'timestamp': datetime.now(timezone.utc).isoformat(),
51
+ 'additional_info': additional_info or {}
 
52
  }
53
 
54
+ # Usar el id como partition key
55
  container.create_item(
56
  body=user_data,
57
+ partition_key=username
58
  )
59
  logger.info(f"Usuario {role} creado: {username}")
60
  return True
 
63
  logger.error(f"Error al crear usuario {role}: {str(e)}")
64
  return False
65
 
 
 
66
  def create_student_user(username, password, additional_info=None):
67
  return create_user(username, password, 'Estudiante', additional_info)
68
 
 
72
  def create_admin_user(username, password, additional_info=None):
73
  return create_user(username, password, 'Administrador', additional_info)
74
 
 
 
 
 
75
  def record_login(username):
76
  """Registra el inicio de sesión de un usuario"""
77
  try:
 
86
  "type": "session",
87
  "username": username,
88
  "loginTime": datetime.now(timezone.utc).isoformat(),
89
+ "additional_info": {}
 
90
  }
91
 
92
  result = container.create_item(
93
+ body=session_doc,
94
+ enable_cross_partition_query=True
95
  )
96
  logger.info(f"Sesión {session_id} registrada para {username}")
97
  return session_id
 
99
  logger.error(f"Error registrando login: {str(e)}")
100
  return None
101
 
 
 
102
  def record_logout(username, session_id):
103
  """Registra el cierre de sesión y calcula la duración"""
104
  try:
 
107
  logger.error("No se pudo obtener el contenedor users_sessions")
108
  return False
109
 
 
 
 
 
 
 
110
  items = list(container.query_items(
111
+ query="SELECT * FROM c WHERE c.id = @id AND c.username = @username",
112
+ parameters=[
113
+ {"name": "@id", "value": session_id},
114
+ {"name": "@username", "value": username}
115
+ ],
116
+ enable_cross_partition_query=True
117
  ))
118
 
119
  if not items:
 
127
 
128
  session.update({
129
  "logoutTime": logout_time.isoformat(),
130
+ "sessionDuration": duration
 
131
  })
132
 
133
  container.upsert_item(
134
+ body=session,
135
+ enable_cross_partition_query=True
136
  )
137
  logger.info(f"Sesión {session_id} cerrada para {username}, duración: {duration}s")
138
  return True
 
140
  logger.error(f"Error registrando logout: {str(e)}")
141
  return False
142
 
 
 
 
143
  def get_recent_sessions(limit=10):
144
  """Obtiene las sesiones más recientes"""
145
  try:
 
148
  logger.error("No se pudo obtener el contenedor users_sessions")
149
  return []
150
 
 
 
 
 
 
 
 
 
151
  sessions = list(container.query_items(
152
+ query="""
153
+ SELECT c.username, c.loginTime, c.logoutTime, c.sessionDuration
154
+ FROM c
155
+ WHERE c.type = 'session'
156
+ ORDER BY c.loginTime DESC
157
+ OFFSET 0 LIMIT @limit
158
+ """,
159
+ parameters=[{"name": "@limit", "value": limit}],
160
+ enable_cross_partition_query=True
161
  ))
162
 
163
  clean_sessions = []
 
178
  logger.error(f"Error obteniendo sesiones recientes: {str(e)}")
179
  return []
180
 
 
 
 
 
181
  def get_user_total_time(username):
182
  """Obtiene el tiempo total que un usuario ha pasado en la plataforma"""
183
  try:
 
185
  if not container:
186
  return None
187
 
 
 
 
 
 
 
 
 
188
  result = list(container.query_items(
189
+ query="""
190
+ SELECT VALUE SUM(c.sessionDuration)
191
+ FROM c
192
+ WHERE c.type = 'session'
193
+ AND c.username = @username
194
+ AND IS_DEFINED(c.sessionDuration)
195
+ """,
196
+ parameters=[{"name": "@username", "value": username}],
197
+ enable_cross_partition_query=True
198
  ))
199
 
200
  return result[0] if result and result[0] is not None else 0
201
  except Exception as e:
202
  logger.error(f"Error obteniendo tiempo total: {str(e)}")
203
  return 0