Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-27 07:41:43

0001 """
0002 PanDA Database browsing views.
0003 
0004 This module provides views for browsing the external PanDA database
0005 following the same patterns as the existing SWF database browser.
0006 """
0007 
0008 from django.shortcuts import render
0009 from django.contrib.auth.decorators import login_required
0010 from django.http import Http404, JsonResponse
0011 from django.db import connections
0012 from datetime import datetime, date
0013 
0014 
0015 @login_required
0016 def panda_database_tables_list(request):
0017     """
0018     PanDA database tables list view using server-side DataTables.
0019     Shows all tables in the PanDA database with counts and last insert times.
0020     """
0021     from django.urls import reverse
0022     
0023     # Column definitions for DataTables
0024     columns = [
0025         {'name': 'name', 'title': 'Table Name', 'orderable': True},
0026         {'name': 'count', 'title': 'Row Count', 'orderable': True},
0027         {'name': 'last_insert', 'title': 'Last Insert', 'orderable': True},
0028     ]
0029     
0030     context = {
0031         'table_title': 'PanDA Database Overview',
0032         'table_description': 'Server-side processing view of all tables in the PanDA database with row counts and last insert times.',
0033         'ajax_url': reverse('monitor_app:panda_database_tables_datatable_ajax'),
0034         'columns': columns,
0035     }
0036     return render(request, 'monitor_app/database_tables_server.html', context)
0037 
0038 
0039 @login_required
0040 def panda_database_tables_datatable_ajax(request):
0041     """
0042     AJAX endpoint for server-side DataTables processing of PanDA database tables.
0043     """
0044     from ..utils import DataTablesProcessor, format_datetime
0045     
0046     # Initialize DataTables processor
0047     columns = ['name', 'count', 'last_insert']
0048     dt = DataTablesProcessor(request, columns, default_order_column=0, default_order_direction='asc')
0049     
0050     # Get PanDA database connection
0051     panda_connection = connections['panda']
0052     
0053     # Build table metadata
0054     table_records = []
0055     try:
0056         with panda_connection.cursor() as cursor:
0057             # Get list of all tables in the PanDA database
0058             # PanDA uses the doma_panda schema, not public
0059             cursor.execute("""
0060                 SELECT table_name 
0061                 FROM information_schema.tables 
0062                 WHERE table_schema = 'doma_panda' 
0063                 AND table_type = 'BASE TABLE'
0064                 ORDER BY table_name
0065             """)
0066             tables = [row[0] for row in cursor.fetchall()]
0067             
0068             for table_name in tables:
0069                 record = {
0070                     'name': table_name,
0071                     'count': 0,
0072                     'last_insert': None
0073                 }
0074                 
0075                 try:
0076                     # Get row count - use schema-qualified table name
0077                     cursor.execute(f'SELECT COUNT(*) FROM "doma_panda"."{table_name}"')
0078                     record['count'] = cursor.fetchone()[0]
0079                     
0080                     # Try to find a timestamp column for last insert
0081                     cursor.execute("""
0082                         SELECT column_name 
0083                         FROM information_schema.columns 
0084                         WHERE table_schema = 'doma_panda'
0085                         AND table_name = %s 
0086                         AND data_type IN ('timestamp', 'timestamp with time zone', 'timestamp without time zone')
0087                         ORDER BY ordinal_position
0088                         LIMIT 1
0089                     """, [table_name])
0090                     
0091                     timestamp_col = cursor.fetchone()
0092                     if timestamp_col:
0093                         cursor.execute(f'SELECT MAX("{timestamp_col[0]}") FROM "doma_panda"."{table_name}"')
0094                         result = cursor.fetchone()
0095                         if result and result[0]:
0096                             record['last_insert'] = result[0]
0097                             
0098                 except Exception:
0099                     pass  # Skip tables we can't access
0100                 
0101                 table_records.append(record)
0102                 
0103     except Exception as e:
0104         # If we can't connect to PanDA database, return empty result
0105         table_records = []
0106     
0107     # Get total counts
0108     records_total = len(table_records)
0109     
0110     # Apply search filtering
0111     if dt.search_value:
0112         search_term = dt.search_value.lower()
0113         table_records = [r for r in table_records if search_term in r['name'].lower()]
0114     
0115     records_filtered = len(table_records)
0116     
0117     # Apply ordering
0118     table_records.sort(key=lambda r: (r[dt.order_column] is None, r[dt.order_column]), reverse=(dt.order_direction == 'desc'))
0119     
0120     # Apply pagination
0121     start = dt.start
0122     length = dt.length if dt.length > 0 else len(table_records)
0123     paginated_records = table_records[start:start + length]
0124     
0125     # Format data for DataTables
0126     data = []
0127     for record in paginated_records:
0128         from django.urls import reverse
0129         table_url = reverse('monitor_app:panda_database_table_list', args=[record['name']])
0130         table_link = f'<a href="{table_url}">{record["name"]}</a>'
0131         count_str = str(record['count'])
0132         last_insert_str = format_datetime(record['last_insert'])
0133         
0134         data.append([table_link, count_str, last_insert_str])
0135     
0136     return dt.create_response(data, records_total, records_filtered)
0137 
0138 
0139 @login_required
0140 def panda_database_table_list(request, table_name):
0141     """
0142     PanDA database individual table view (excluding problematic TEXT columns).
0143     """
0144     from django.urls import reverse
0145     
0146     # Get PanDA database connection
0147     panda_connection = connections['panda']
0148     
0149     # Get column information (exclude problematic TEXT columns)
0150     columns = []
0151     try:
0152         with panda_connection.cursor() as cursor:
0153             # Get first 20 columns only
0154             cursor.execute("""
0155                 SELECT column_name 
0156                 FROM information_schema.columns 
0157                 WHERE table_schema = 'doma_panda' 
0158                 AND table_name = %s 
0159                 ORDER BY ordinal_position
0160                 LIMIT 20
0161             """, [table_name])
0162             columns = [row[0] for row in cursor.fetchall()]
0163             if not columns:
0164                 raise Http404()
0165     except Exception:
0166         raise Http404()
0167     
0168     # Convert columns for DataTables format
0169     datatable_columns = [{'name': col, 'title': col.replace('_', ' ').title(), 'orderable': True} for col in columns]
0170     
0171     context = {
0172         'table_title': f'PanDA Table: {table_name}',
0173         'table_description': f'PanDA database table contents for {table_name} (first 20 columns only). Search, sorting, and pagination available.',
0174         'ajax_url': reverse('monitor_app:panda_database_table_datatable_ajax', kwargs={'table_name': table_name}),
0175         'columns': datatable_columns,
0176         'table_name': table_name,
0177     }
0178     return render(request, 'monitor_app/database_table_list.html', context)
0179 
0180 
0181 @login_required
0182 def panda_database_table_datatable_ajax(request, table_name):
0183     """
0184     AJAX endpoint for server-side DataTables processing of individual PanDA database table.
0185     """
0186     from ..utils import DataTablesProcessor, format_datetime
0187     
0188     # Get PanDA database connection
0189     panda_connection = connections['panda']
0190     
0191     # Get column information (exclude problematic TEXT columns)
0192     columns = []
0193     try:
0194         with panda_connection.cursor() as cursor:
0195             # Get first 20 columns only
0196             cursor.execute("""
0197                 SELECT column_name 
0198                 FROM information_schema.columns 
0199                 WHERE table_schema = 'doma_panda' 
0200                 AND table_name = %s 
0201                 ORDER BY ordinal_position
0202                 LIMIT 20
0203             """, [table_name])
0204             columns = [row[0] for row in cursor.fetchall()]
0205             if not columns:
0206                 raise Http404()
0207     except Exception:
0208         raise Http404()
0209     
0210     # Initialize DataTables processor
0211     dt = DataTablesProcessor(request, columns, default_order_column=0, default_order_direction='asc')
0212     
0213     # Build base query - select columns excluding large TEXT fields
0214     column_list = ', '.join([f'"{col}"' for col in columns])
0215     query = f'SELECT {column_list} FROM "doma_panda"."{table_name}"'
0216     count_query = f'SELECT COUNT(*) FROM "doma_panda"."{table_name}"'
0217     params = []
0218     
0219     try:
0220         with panda_connection.cursor() as cursor:
0221             # Get total count
0222             cursor.execute(count_query)
0223             records_total = cursor.fetchone()[0]
0224             
0225             # Apply search filtering
0226             where_conditions = []
0227             if dt.search_value:
0228                 search_conditions = []
0229                 for column in columns:
0230                     search_conditions.append(f'CAST("{column}" AS TEXT) ILIKE %s')
0231                     params.append(f'%{dt.search_value}%')
0232                 where_conditions.append(f"({' OR '.join(search_conditions)})")
0233             
0234             # Build filtered query
0235             filtered_query = query
0236             filtered_count_query = count_query
0237             if where_conditions:
0238                 where_clause = ' WHERE ' + ' AND '.join(where_conditions)
0239                 filtered_query += where_clause
0240                 filtered_count_query += where_clause
0241             
0242             # Get filtered count
0243             cursor.execute(filtered_count_query, params)
0244             records_filtered = cursor.fetchone()[0]
0245             
0246             # Apply ordering
0247             if dt.order_column:
0248                 order_direction = 'ASC' if dt.order_direction == 'asc' else 'DESC'
0249                 filtered_query += f' ORDER BY "{dt.order_column}" {order_direction}'
0250             
0251             # Apply pagination
0252             filtered_query += f' LIMIT {dt.length} OFFSET {dt.start}'
0253             
0254             # Execute main query
0255             cursor.execute(filtered_query, params)
0256             rows = cursor.fetchall()
0257             
0258             # Format data for DataTables
0259             data = []
0260             for row in rows:
0261                 formatted_row = []
0262                 for i, value in enumerate(row):
0263                     if i == 0:  # First column should be a link to detail page
0264                         from django.urls import reverse
0265                         detail_url = reverse('monitor_app:panda_database_table_row_detail', args=[table_name, str(value)])
0266                         formatted_row.append(f'<a href="{detail_url}">{str(value) if value is not None else ""}</a>')
0267                     elif value is None:
0268                         formatted_row.append('')
0269                     elif isinstance(value, (datetime, date)):
0270                         formatted_row.append(format_datetime(value))
0271                     else:
0272                         formatted_row.append(str(value))
0273                 data.append(formatted_row)
0274             
0275     except Exception as e:
0276         # Return empty result on error
0277         data = []
0278         records_total = 0
0279         records_filtered = 0
0280     
0281     return dt.create_response(data, records_total, records_filtered)
0282 
0283 
0284 @login_required
0285 def panda_database_table_row_detail(request, table_name, row_id):
0286     """
0287     PanDA database individual row detail view.
0288     Shows all column values for a specific row.
0289     """
0290     # Get PanDA database connection
0291     panda_connection = connections['panda']
0292     
0293     # Get all columns for this table (all columns for detail view)
0294     columns = []
0295     try:
0296         with panda_connection.cursor() as cursor:
0297             cursor.execute("""
0298                 SELECT column_name 
0299                 FROM information_schema.columns 
0300                 WHERE table_schema = 'doma_panda' 
0301                 AND table_name = %s 
0302                 ORDER BY ordinal_position
0303             """, [table_name])
0304             columns = [row[0] for row in cursor.fetchall()]
0305             if not columns:
0306                 raise Http404("Table not found")
0307     except Exception:
0308         raise Http404("Table not found")
0309     
0310     # Get the row data using the first column as identifier
0311     row_data = {}
0312     try:
0313         with panda_connection.cursor() as cursor:
0314             # Build query to get the specific row
0315             column_list = ', '.join([f'"{col}"' for col in columns])
0316             query = f'SELECT {column_list} FROM "doma_panda"."{table_name}" WHERE "{columns[0]}" = %s LIMIT 1'
0317             
0318             cursor.execute(query, [row_id])
0319             row = cursor.fetchone()
0320             
0321             if not row:
0322                 raise Http404("Row not found")
0323                 
0324             # Create list of (column, value) pairs
0325             row_data = []
0326             for i, column in enumerate(columns):
0327                 value = row[i]
0328                 if value is None:
0329                     formatted_value = None
0330                 elif isinstance(value, (datetime, date)):
0331                     from ..utils import format_datetime
0332                     formatted_value = format_datetime(value)
0333                 else:
0334                     formatted_value = str(value)
0335                 row_data.append((column, formatted_value))
0336                     
0337     except Exception:
0338         raise Http404("Row not found")
0339     
0340     context = {
0341         'table_name': table_name,
0342         'row_id': row_id,
0343         'row_data': row_data,
0344     }
0345     return render(request, 'monitor_app/panda_table_row_detail.html', context)
0346 
0347