File size: 11,134 Bytes
21fefa5
 
 
 
d6e94b1
18df3b2
859af98
49da158
 
 
 
 
d6da6ee
 
49da158
 
 
21fefa5
49da158
 
 
 
21fefa5
18df3b2
 
21fefa5
18df3b2
 
 
 
 
9fe40c6
 
 
18df3b2
 
 
9fe40c6
18df3b2
 
 
9fe40c6
49da158
 
 
 
 
 
1ed277e
 
 
 
 
d6da6ee
1ed277e
 
49da158
 
 
 
 
 
1ed277e
49da158
 
1ed277e
 
 
 
 
 
d6da6ee
1ed277e
 
49da158
 
 
 
 
 
1ed277e
49da158
 
 
 
 
 
 
18df3b2
49da158
18df3b2
 
49da158
18df3b2
 
49da158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9fe40c6
49da158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6e94b1
21fefa5
 
18df3b2
21fefa5
 
 
49da158
21fefa5
 
49da158
859af98
21fefa5
 
d6e94b1
21fefa5
49da158
21fefa5
 
 
 
 
 
49da158
 
 
 
 
21fefa5
 
 
 
49da158
 
 
 
 
21fefa5
 
 
49da158
 
 
 
 
9fe40c6
49da158
 
9fe40c6
49da158
 
9fe40c6
49da158
 
1ed277e
 
 
 
 
 
 
 
9fe40c6
49da158
 
 
 
 
 
 
 
 
9fe40c6
49da158
 
 
9fe40c6
49da158
 
 
9fe40c6
49da158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21fefa5
49da158
d6e94b1
859af98
49da158
859af98
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
from flask import Flask, request, jsonify, render_template
import mysql.connector
import os
import time

app = Flask(__name__, template_folder='/templates', static_folder='/static')

# Параметри підключення до віддаленої бази даних
DB_CONFIG = {
    "host": "mysql-emploees-zabolotniua-5b91.c.aivencloud.com",
    "port": 12374,
    "user": "avnadmin",
    "password": "AVNS_rccbF_so2YPvPk3zg0z"
    # Без SSL налаштувань
}

def get_db_connection(database=None):
    try:
        config = DB_CONFIG.copy()
        if database:
            config["database"] = database
        return mysql.connector.connect(**config)
    except Exception as e:
        print(f"Error connecting to MySQL: {e}")
        raise e

@app.route('/')
def index():
    # Перевіряємо статус MySQL
    status = {"status": "offline", "version": "Unknown"}
    
    try:
        conn = get_db_connection()
        cursor = conn.cursor()
        cursor.execute("SELECT VERSION()")
        version = cursor.fetchone()[0]
        status = {"status": "online", "version": version}
        
        # Отримуємо списки баз даних
        cursor.execute("SHOW DATABASES")
        databases = [db[0] for db in cursor.fetchall()]
        
        cursor.close()
        conn.close()
        
        # Перевіряємо наявність бази даних employees
        employees_exists = "employees" in databases
        
        connection_info = {
            "host": DB_CONFIG["host"],
            "port": DB_CONFIG["port"],
            "user": DB_CONFIG["user"],
            "password": DB_CONFIG["password"],
            "ssl_mode": "REQUIRED"  # Тільки для відображення
        }
        
        return render_template('index.html', 
                              status=status, 
                              databases=databases, 
                              tables=[], 
                              employees_exists=employees_exists,
                              remote_connection=True,
                              connection_info=connection_info)
    except Exception as e:
        print(f"Error: {e}")
        
        connection_info = {
            "host": DB_CONFIG["host"],
            "port": DB_CONFIG["port"],
            "user": DB_CONFIG["user"],
            "password": DB_CONFIG["password"],
            "ssl_mode": "REQUIRED"  # Тільки для відображення
        }
        
        return render_template('index.html', 
                              status={"status": "offline", "error": str(e)}, 
                              databases=[], 
                              tables=[],
                              employees_exists=False,
                              remote_connection=True,
                              connection_info=connection_info)

@app.route('/database/<database>')
def show_database(database):
    try:
        conn = get_db_connection(database)
        cursor = conn.cursor()
        
        # Отримуємо списки таблиць
        cursor.execute(f"SHOW TABLES FROM `{database}`")
        tables = [table[0] for table in cursor.fetchall()]
        
        # Закриваємо з'єднання і створюємо нове для кожної таблиці
        cursor.close()
        conn.close()
        
        # Отримуємо інформацію про таблиці
        table_info = []
        
        for table in tables:
            try:
                conn = get_db_connection(database)
                cursor = conn.cursor()
                
                # Отримуємо кількість рядків
                cursor.execute(f"SELECT COUNT(*) FROM `{database}`.`{table}`")
                count = cursor.fetchone()[0]
                
                table_info.append({
                    'name': table,
                    'count': count,
                    'size': 'N/A'  # Розмір не можемо отримати з віддаленої бази
                })
                
                cursor.close()
                conn.close()
            except Exception as e:
                print(f"Error getting info for table {table}: {e}")
                table_info.append({
                    'name': table,
                    'count': 'Error',
                    'size': 'Error'
                })
        
        return render_template('database.html', 
                              database=database,
                              tables=table_info,
                              remote_connection=True)
    except Exception as e:
        return render_template('error.html', error=str(e))

@app.route('/table/<database>/<table_name>')
def show_table(database, table_name):
    try:
        conn = get_db_connection(database)
        cursor = conn.cursor(dictionary=True)
        
        # Отримуємо структуру таблиці
        cursor.execute(f"DESCRIBE `{table_name}`")
        columns = cursor.fetchall()
        
        # Отримуємо дані таблиці
        cursor.execute(f"SELECT * FROM `{table_name}` LIMIT 100")
        data = cursor.fetchall()
        
        # Отримуємо загальну кількість рядків у таблиці
        cursor.execute(f"SELECT COUNT(*) as count FROM `{table_name}`")
        total_count = cursor.fetchone()['count']
        
        conn.close()
        return render_template('table.html', 
                              database=database,
                              table_name=table_name, 
                              columns=columns, 
                              data=data,
                              total_count=total_count,
                              remote_connection=True)
    except Exception as e:
        return render_template('error.html', error=str(e))

@app.route('/execute', methods=['POST'])
def execute_query():
    # Отримуємо дані з форми або JSON
    if request.content_type == 'application/json':
        data = request.json
        query = data.get('query', '')
        database = data.get('database', 'employees')
    else:
        query = request.form.get('query', '')
        database = request.form.get('database', 'employees')
    
    if not query:
        return jsonify({'error': 'Запит не може бути порожнім'}), 400
    
    try:
        conn = get_db_connection(database)
        cursor = conn.cursor(dictionary=True)
        cursor.execute(query)
        
        if query.lower().strip().startswith('select'):
            result = cursor.fetchall()
            conn.close()
            return render_template('result.html', 
                                 results=result, 
                                 query=query,
                                 database=database,
                                 remote_connection=True)
        else:
            conn.commit()
            affected_rows = cursor.rowcount
            conn.close()
            return render_template('result.html', 
                                 affected_rows=affected_rows, 
                                 query=query,
                                 database=database,
                                 remote_connection=True)
            
    except Exception as e:
        error_msg = str(e)
        return render_template('result.html', 
                              error=error_msg, 
                              query=query, 
                              database=database,
                              remote_connection=True)

@app.route('/employees')
def employees_info():
    try:
        conn = get_db_connection('employees')
        cursor = conn.cursor(dictionary=True)
        
        # Отримуємо інформацію про таблиці
        cursor.execute("SHOW TABLES FROM employees")
        tables_result = cursor.fetchall()
        tables = []
        
        # Знаходимо ім'я стовпця з назвою таблиці
        table_column_name = list(tables_result[0].keys())[0] if tables_result else None
        
        if table_column_name:
            tables = [table[table_column_name] for table in tables_result]
        
        tables_info = []
        for table in tables:
            cursor.execute(f"SELECT COUNT(*) as count FROM employees.{table}")
            count = cursor.fetchone()['count']
            tables_info.append({
                'table_name': table,
                'employee_count': count,
                'total_size_mb': 'N/A'  # Не можемо отримати розмір з віддаленої бази
            })
        
        # Отримуємо загальну кількість співробітників
        cursor.execute("SELECT COUNT(*) as count FROM employees")
        total_employees = cursor.fetchone()['count']
        
        # Отримуємо кількість департаментів
        cursor.execute("SELECT COUNT(*) as count FROM departments")
        total_departments = cursor.fetchone()['count']
        
        # Отримуємо діапазон дат
        cursor.execute("SELECT MIN(hire_date) as min_date, MAX(hire_date) as max_date FROM employees")
        date_range = cursor.fetchone()
        
        # Отримуємо кількість чоловіків і жінок
        cursor.execute("""
            SELECT 
                gender, 
                COUNT(*) as count,
                ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM employees), 2) as percentage
            FROM 
                employees 
            GROUP BY 
                gender
        """)
        gender_stats = cursor.fetchall()
        
        # Отримуємо топ департаментів за кількістю співробітників
        cursor.execute("""
            SELECT 
                d.dept_name,
                COUNT(de.emp_no) as employee_count
            FROM 
                departments d
            JOIN 
                dept_emp de ON d.dept_no = de.dept_no
            WHERE 
                de.to_date = '9999-01-01'
            GROUP BY 
                d.dept_name
            ORDER BY 
                employee_count DESC
            LIMIT 5
        """)
        top_departments = cursor.fetchall()
        
        conn.close()
        
        return render_template('employees.html',
                               tables_info=tables_info,
                               total_employees=total_employees,
                               total_departments=total_departments,
                               date_range=date_range,
                               gender_stats=gender_stats,
                               top_departments=top_departments,
                               remote_connection=True)
    except Exception as e:
        return render_template('error.html', error=str(e))

if __name__ == '__main__':
    # Запуск веб-сервера
    app.run(host='0.0.0.0', port=7860)