DocUA commited on
Commit
9fe40c6
·
1 Parent(s): 21fefa5

add Employees

Browse files
Files changed (5) hide show
  1. Dockerfile +19 -6
  2. app.py +184 -13
  3. start.sh +40 -1
  4. templates/database.html +43 -0
  5. templates/index.html +71 -6
Dockerfile CHANGED
@@ -12,19 +12,32 @@ RUN mkdir -p /docker-entrypoint-initdb.d
12
  # Копіювання SQL файлу ініціалізації
13
  COPY init.sql /docker-entrypoint-initdb.d/
14
 
15
- # Встановлення необхідних пакетів для API
16
  RUN rm -f /etc/apt/sources.list.d/mysql.list && \
17
  apt-get update && \
18
- apt-get install -y python3 python3-pip && \
19
  pip3 install --no-cache-dir flask mysql-connector-python && \
20
  rm -rf /var/lib/apt/lists/*
21
 
22
- # Копіювання файлів API
23
- COPY app.py /app.py
24
- COPY static /static
 
 
 
 
 
 
 
 
 
 
 
25
  COPY templates /templates
 
 
26
 
27
- # Скрипт для запуску MySQL та API
28
  COPY start.sh /start.sh
29
  RUN chmod +x /start.sh
30
 
 
12
  # Копіювання SQL файлу ініціалізації
13
  COPY init.sql /docker-entrypoint-initdb.d/
14
 
15
+ # Встановлення Git та інших необхідних інструментів
16
  RUN rm -f /etc/apt/sources.list.d/mysql.list && \
17
  apt-get update && \
18
+ apt-get install -y git python3 python3-pip wget && \
19
  pip3 install --no-cache-dir flask mysql-connector-python && \
20
  rm -rf /var/lib/apt/lists/*
21
 
22
+ # Завантаження та розпакування бази даних Employees
23
+ RUN mkdir -p /tmp/employees && \
24
+ cd /tmp/employees && \
25
+ git clone https://github.com/datacharmer/test_db.git && \
26
+ cd test_db && \
27
+ # Копіюємо скрипти імпорту в директорію ініціалізації
28
+ cp employees.sql /docker-entrypoint-initdb.d/01-employees.sql && \
29
+ # Зберігаємо тестові дані для пізнішого використання
30
+ mkdir -p /var/lib/mysql-files && \
31
+ cp -r *.dump /var/lib/mysql-files/ && \
32
+ cd / && \
33
+ rm -rf /tmp/employees
34
+
35
+ # Копіювання файлів веб-додатку
36
  COPY templates /templates
37
+ COPY static /static
38
+ COPY app.py /app.py
39
 
40
+ # Скрипт для запуску
41
  COPY start.sh /start.sh
42
  RUN chmod +x /start.sh
43
 
app.py CHANGED
@@ -4,9 +4,9 @@ import json
4
  import os
5
  import time
6
 
7
- app = Flask(__name__)
8
 
9
- def get_db_connection():
10
  # Спробуємо підключитися кілька разів (може знадобитися, якщо MySQL ще запускається)
11
  for i in range(5):
12
  try:
@@ -14,7 +14,7 @@ def get_db_connection():
14
  host="localhost",
15
  user="test_user",
16
  password="test_password",
17
- database="test_db"
18
  )
19
  except Exception as e:
20
  if i < 4: # Якщо це не остання спроба
@@ -34,11 +34,40 @@ def get_mysql_status():
34
  except Exception as e:
35
  return {"status": "offline", "error": str(e)}
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  @app.route('/')
38
  def index():
39
  # Перевіряємо статус MySQL
40
  status = get_mysql_status()
41
 
 
 
 
42
  # Отримуємо списки баз даних і таблиць, якщо MySQL онлайн
43
  databases = []
44
  tables = []
@@ -61,21 +90,28 @@ def index():
61
  except Exception as e:
62
  print(f"Помилка: {e}")
63
 
64
- return render_template('index.html', status=status, databases=databases, tables=tables)
 
 
 
 
 
65
 
66
  @app.route('/execute', methods=['POST'])
67
  def execute_query():
68
  if request.content_type == 'application/json':
69
  data = request.json
70
  query = data.get('query', '')
 
71
  else:
72
  query = request.form.get('query', '')
 
73
 
74
  if not query:
75
  return jsonify({'error': 'Запит не може бути порожнім'}), 400
76
 
77
  try:
78
- conn = get_db_connection()
79
  cursor = conn.cursor(dictionary=True)
80
  cursor.execute(query)
81
 
@@ -85,7 +121,10 @@ def execute_query():
85
 
86
  # Якщо запит з веб-форми, повертаємо HTML
87
  if request.content_type != 'application/json':
88
- return render_template('result.html', results=result, query=query)
 
 
 
89
  else:
90
  return jsonify({'result': result})
91
  else:
@@ -96,8 +135,9 @@ def execute_query():
96
  # Якщо запит з веб-форми, повертаємо HTML
97
  if request.content_type != 'application/json':
98
  return render_template('result.html',
99
- affected_rows=affected_rows,
100
- query=query)
 
101
  else:
102
  return jsonify({'affected_rows': affected_rows})
103
 
@@ -105,14 +145,14 @@ def execute_query():
105
  error_msg = str(e)
106
  # Якщо запит з веб-форми, повертаємо HTML
107
  if request.content_type != 'application/json':
108
- return render_template('result.html', error=error_msg, query=query)
109
  else:
110
  return jsonify({'error': error_msg}), 500
111
 
112
- @app.route('/table/<table_name>')
113
- def show_table(table_name):
114
  try:
115
- conn = get_db_connection()
116
  cursor = conn.cursor(dictionary=True)
117
 
118
  # Отримуємо структуру таблиці
@@ -123,11 +163,142 @@ def show_table(table_name):
123
  cursor.execute(f"SELECT * FROM `{table_name}` LIMIT 100")
124
  data = cursor.fetchall()
125
 
 
 
 
 
126
  conn.close()
127
  return render_template('table.html',
 
128
  table_name=table_name,
129
  columns=columns,
130
- data=data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  except Exception as e:
132
  return render_template('error.html', error=str(e))
133
 
 
4
  import os
5
  import time
6
 
7
+ app = Flask(__name__, template_folder='templates', static_folder='static')
8
 
9
+ def get_db_connection(database='test_db'):
10
  # Спробуємо підключитися кілька разів (може знадобитися, якщо MySQL ще запускається)
11
  for i in range(5):
12
  try:
 
14
  host="localhost",
15
  user="test_user",
16
  password="test_password",
17
+ database=database
18
  )
19
  except Exception as e:
20
  if i < 4: # Якщо це не остання спроба
 
34
  except Exception as e:
35
  return {"status": "offline", "error": str(e)}
36
 
37
+ def check_employees_db():
38
+ try:
39
+ # Перевіряємо чи існує база даних employees
40
+ conn = get_db_connection()
41
+ cursor = conn.cursor()
42
+ cursor.execute("SHOW DATABASES LIKE 'employees'")
43
+ exists = cursor.fetchone() is not None
44
+ cursor.close()
45
+ conn.close()
46
+
47
+ if exists:
48
+ # Якщо база існує, перевіряємо наявність таблиць
49
+ conn = get_db_connection('employees')
50
+ cursor = conn.cursor()
51
+ cursor.execute("SHOW TABLES")
52
+ tables = cursor.fetchall()
53
+ table_count = len(tables)
54
+ cursor.close()
55
+ conn.close()
56
+ return exists, table_count
57
+
58
+ return exists, 0
59
+ except Exception as e:
60
+ print(f"Помилка перевірки бази employees: {e}")
61
+ return False, 0
62
+
63
  @app.route('/')
64
  def index():
65
  # Перевіряємо статус MySQL
66
  status = get_mysql_status()
67
 
68
+ # Перевіряємо наявність бази employees
69
+ employees_exists, employees_tables = check_employees_db()
70
+
71
  # Отримуємо списки баз даних і таблиць, якщо MySQL онлайн
72
  databases = []
73
  tables = []
 
90
  except Exception as e:
91
  print(f"Помилка: {e}")
92
 
93
+ return render_template('index.html',
94
+ status=status,
95
+ databases=databases,
96
+ tables=tables,
97
+ employees_exists=employees_exists,
98
+ employees_tables=employees_tables)
99
 
100
  @app.route('/execute', methods=['POST'])
101
  def execute_query():
102
  if request.content_type == 'application/json':
103
  data = request.json
104
  query = data.get('query', '')
105
+ database = data.get('database', 'test_db')
106
  else:
107
  query = request.form.get('query', '')
108
+ database = request.form.get('database', 'test_db')
109
 
110
  if not query:
111
  return jsonify({'error': 'Запит не може бути порожнім'}), 400
112
 
113
  try:
114
+ conn = get_db_connection(database)
115
  cursor = conn.cursor(dictionary=True)
116
  cursor.execute(query)
117
 
 
121
 
122
  # Якщо запит з веб-форми, повертаємо HTML
123
  if request.content_type != 'application/json':
124
+ return render_template('result.html',
125
+ results=result,
126
+ query=query,
127
+ database=database)
128
  else:
129
  return jsonify({'result': result})
130
  else:
 
135
  # Якщо запит з веб-форми, повертаємо HTML
136
  if request.content_type != 'application/json':
137
  return render_template('result.html',
138
+ affected_rows=affected_rows,
139
+ query=query,
140
+ database=database)
141
  else:
142
  return jsonify({'affected_rows': affected_rows})
143
 
 
145
  error_msg = str(e)
146
  # Якщо запит з веб-форми, повертаємо HTML
147
  if request.content_type != 'application/json':
148
+ return render_template('result.html', error=error_msg, query=query, database=database)
149
  else:
150
  return jsonify({'error': error_msg}), 500
151
 
152
+ @app.route('/table/<database>/<table_name>')
153
+ def show_table(database, table_name):
154
  try:
155
+ conn = get_db_connection(database)
156
  cursor = conn.cursor(dictionary=True)
157
 
158
  # Отримуємо структуру таблиці
 
163
  cursor.execute(f"SELECT * FROM `{table_name}` LIMIT 100")
164
  data = cursor.fetchall()
165
 
166
+ # Отримуємо загальну кількість рядків у таблиці
167
+ cursor.execute(f"SELECT COUNT(*) as count FROM `{table_name}`")
168
+ total_count = cursor.fetchone()['count']
169
+
170
  conn.close()
171
  return render_template('table.html',
172
+ database=database,
173
  table_name=table_name,
174
  columns=columns,
175
+ data=data,
176
+ total_count=total_count)
177
+ except Exception as e:
178
+ return render_template('error.html', error=str(e))
179
+
180
+ @app.route('/database/<database>')
181
+ def show_database(database):
182
+ try:
183
+ conn = get_db_connection(database)
184
+ cursor = conn.cursor()
185
+
186
+ # Отримуємо списки таблиць
187
+ cursor.execute(f"SHOW TABLES FROM `{database}`")
188
+ tables = [table[0] for table in cursor.fetchall()]
189
+
190
+ # Отримуємо розмір кожної таблиці
191
+ table_info = []
192
+ for table in tables:
193
+ cursor.execute(f"SELECT COUNT(*) FROM `{database}`.`{table}`")
194
+ count = cursor.fetchone()[0]
195
+
196
+ cursor.execute(f"""
197
+ SELECT
198
+ ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb
199
+ FROM
200
+ information_schema.TABLES
201
+ WHERE
202
+ table_schema = '{database}'
203
+ AND table_name = '{table}'
204
+ """)
205
+ size = cursor.fetchone()[0] or 0
206
+
207
+ table_info.append({
208
+ 'name': table,
209
+ 'count': count,
210
+ 'size': size
211
+ })
212
+
213
+ conn.close()
214
+ return render_template('database.html',
215
+ database=database,
216
+ tables=table_info)
217
+ except Exception as e:
218
+ return render_template('error.html', error=str(e))
219
+
220
+ @app.route('/employees')
221
+ def employees_info():
222
+ try:
223
+ # Перевіряємо чи існує база даних employees
224
+ employees_exists, table_count = check_employees_db()
225
+
226
+ if not employees_exists:
227
+ return render_template('error.html',
228
+ error="База даних 'employees' не знайдена",
229
+ suggestion="Можливо, виникли проблеми з імпортом бази даних.")
230
+
231
+ conn = get_db_connection('employees')
232
+ cursor = conn.cursor(dictionary=True)
233
+
234
+ # Отримуємо інформацію про таблиці
235
+ cursor.execute("""
236
+ SELECT
237
+ table_name,
238
+ table_rows,
239
+ ROUND(data_length / 1024 / 1024, 2) as data_size_mb,
240
+ ROUND(index_length / 1024 / 1024, 2) as index_size_mb,
241
+ ROUND((data_length + index_length) / 1024 / 1024, 2) as total_size_mb
242
+ FROM
243
+ information_schema.TABLES
244
+ WHERE
245
+ table_schema = 'employees'
246
+ """)
247
+ tables_info = cursor.fetchall()
248
+
249
+ # Отримуємо загальну кількість співробітників
250
+ cursor.execute("SELECT COUNT(*) as count FROM employees")
251
+ total_employees = cursor.fetchone()['count']
252
+
253
+ # Отримуємо кількість департаментів
254
+ cursor.execute("SELECT COUNT(*) as count FROM departments")
255
+ total_departments = cursor.fetchone()['count']
256
+
257
+ # Отримуємо діапазон дат
258
+ cursor.execute("SELECT MIN(hire_date) as min_date, MAX(hire_date) as max_date FROM employees")
259
+ date_range = cursor.fetchone()
260
+
261
+ # Отримуємо кількість чоловіків і жінок
262
+ cursor.execute("""
263
+ SELECT
264
+ gender,
265
+ COUNT(*) as count,
266
+ ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM employees), 2) as percentage
267
+ FROM
268
+ employees
269
+ GROUP BY
270
+ gender
271
+ """)
272
+ gender_stats = cursor.fetchall()
273
+
274
+ # Отримуємо топ департаментів за кількістю співробітників
275
+ cursor.execute("""
276
+ SELECT
277
+ d.dept_name,
278
+ COUNT(de.emp_no) as employee_count
279
+ FROM
280
+ departments d
281
+ JOIN
282
+ dept_emp de ON d.dept_no = de.dept_no
283
+ WHERE
284
+ de.to_date = '9999-01-01'
285
+ GROUP BY
286
+ d.dept_name
287
+ ORDER BY
288
+ employee_count DESC
289
+ LIMIT 5
290
+ """)
291
+ top_departments = cursor.fetchall()
292
+
293
+ conn.close()
294
+
295
+ return render_template('employees.html',
296
+ tables_info=tables_info,
297
+ total_employees=total_employees,
298
+ total_departments=total_departments,
299
+ date_range=date_range,
300
+ gender_stats=gender_stats,
301
+ top_departments=top_departments)
302
  except Exception as e:
303
  return render_template('error.html', error=str(e))
304
 
start.sh CHANGED
@@ -6,7 +6,7 @@ echo "Запуск MySQL..."
6
 
7
  # Чекаємо, поки MySQL запуститься
8
  echo "Очікування запуску MySQL..."
9
- sleep 15
10
 
11
  # Перевірка, чи запустився MySQL
12
  echo "Перевірка стану MySQL..."
@@ -19,6 +19,45 @@ for i in {1..10}; do
19
  sleep 3
20
  done
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  # Запуск Flask API
23
  echo "Запуск API на порту 7860..."
24
  python3 /app.py
 
6
 
7
  # Чекаємо, поки MySQL запуститься
8
  echo "Очікування запуску MySQL..."
9
+ sleep 20
10
 
11
  # Перевірка, чи запустився MySQL
12
  echo "Перевірка стану MySQL..."
 
19
  sleep 3
20
  done
21
 
22
+ # Перевіряємо чи існує база employees
23
+ echo "Перевірка наявності бази employees..."
24
+ if mysql -u root -proot_password -e "SHOW DATABASES" | grep -q "employees"; then
25
+ echo "База даних employees вже існує"
26
+ else
27
+ echo "База даних employees не знайдена, перевіряємо наявність скрипту імпорту..."
28
+
29
+ # Перевіряємо, чи вже було виконано імпорт employees.sql
30
+ if [ -f /docker-entrypoint-initdb.d/01-employees.sql ]; then
31
+ echo "Файл імпорту знайдено, але база даних не створена. Можливо, виникла помилка під час імпорту."
32
+ else
33
+ echo "Файл імпорту не знайдено. Спробуємо завантажити базу даних з GitHub..."
34
+
35
+ # Завантажуємо employees з GitHub якщо раптом не було завантажено під час збірки
36
+ mkdir -p /tmp/employees && \
37
+ cd /tmp/employees && \
38
+ git clone https://github.com/datacharmer/test_db.git && \
39
+ cd test_db && \
40
+
41
+ # Імпортуємо базу даних
42
+ echo "Імпорт бази даних employees..."
43
+ mysql -u root -proot_password < employees.sql
44
+
45
+ if [ $? -eq 0 ]; then
46
+ echo "База даних employees успішно імпортована!"
47
+ else
48
+ echo "Помилка під час імпорту бази даних employees!"
49
+ fi
50
+
51
+ cd / && \
52
+ rm -rf /tmp/employees
53
+ fi
54
+ fi
55
+
56
+ # Надаємо права користувачу test_user на базу employees
57
+ echo "Надання прав доступу до бази employees користувачу test_user..."
58
+ mysql -u root -proot_password -e "GRANT ALL PRIVILEGES ON employees.* TO 'test_user'@'%';"
59
+ mysql -u root -proot_password -e "FLUSH PRIVILEGES;"
60
+
61
  # Запуск Flask API
62
  echo "Запуск API на порту 7860..."
63
  python3 /app.py
templates/database.html ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="uk">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>База даних {{ database }}</title>
7
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">
8
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
9
+ </head>
10
+ <body>
11
+ <div class="container mt-4">
12
+ <div class="d-flex justify-content-between align-items-center mb-4">
13
+ <h1>База даних: {{ database }}</h1>
14
+ <a href="/" class="btn btn-primary">На головну</a>
15
+ </div>
16
+
17
+ <!-- Список таблиць -->
18
+ <div class="card mb-4">
19
+ <div class="card-header bg-info text-white">
20
+ <h5>Таблиці в базі даних</h5>
21
+ </div>
22
+ <div class="card-body p-0">
23
+ <div class="table-responsive">
24
+ <table class="table table-striped table-bordered mb-0">
25
+ <thead class="table-dark">
26
+ <tr>
27
+ <th>Назва таблиці</th>
28
+ <th>Кількість рядків</th>
29
+ <th>Розмір (МБ)</th>
30
+ <th>Дії</th>
31
+ </tr>
32
+ </thead>
33
+ <tbody>
34
+ {% for table in tables %}
35
+ <tr>
36
+ <td>{{ table.name }}</td>
37
+ <td>{{ table.count | int }}</td>
38
+ <td>{{ table.size }}</td>
39
+ <td>
40
+ <a href="/table/{{ database }}/{{ table.name }}" class="btn btn-sm btn-primary">Структура і дані</a>
41
+ <button class="btn btn-sm btn-success" onclick="copyToQueryConsole('SELECT * FROM {{ table.name }} LIMIT 10;')">Запит SELECT</button>
42
+ </td>
43
+ </tr>
templates/index.html CHANGED
@@ -11,6 +11,28 @@
11
  <div class="container mt-4">
12
  <h1 class="mb-4">MySQL Сервер 8.0.22 для навчальних цілей</h1>
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  <!-- Статус сервера -->
15
  <div class="card mb-4">
16
  <div class="card-header {% if status.status == 'online' %}bg-success text-white{% else %}bg-danger text-white{% endif %}">
@@ -19,6 +41,20 @@
19
  <div class="card-body">
20
  {% if status.status == 'online' %}
21
  <p><strong>Версія MySQL:</strong> {{ status.version }}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  {% else %}
23
  <p class="text-danger"><strong>Помилка:</strong> {{ status.error }}</p>
24
  {% endif %}
@@ -33,22 +69,36 @@
33
  <div class="card-body">
34
  <p>Для виконання SQL запитів надсилайте POST запити на <code>/execute</code> з JSON тілом:</p>
35
  <pre><code>{
36
- "query": "ваш SQL запит"
 
37
  }</code></pre>
38
  <p>Приклад використання з curl:</p>
39
  <pre><code>curl -X POST https://mysql-itud-docsa.hf.space/execute \
40
  -H "Content-Type: application/json" \
41
- -d '{"query":"SELECT * FROM test"}'</code></pre>
 
 
 
 
 
42
  </div>
43
  </div>
44
 
45
  <!-- SQL Консоль -->
46
- <div class="card mb-4">
47
  <div class="card-header bg-primary text-white">
48
  <h5>SQL Консоль</h5>
49
  </div>
50
  <div class="card-body">
51
  <form action="/execute" method="post">
 
 
 
 
 
 
 
 
52
  <div class="mb-3">
53
  <label for="query" class="form-label">Введіть SQL запит:</label>
54
  <textarea class="form-control" id="query" name="query" rows="6" placeholder="SELECT * FROM test"></textarea>
@@ -70,7 +120,12 @@
70
  {% if databases %}
71
  <ul class="list-group">
72
  {% for db in databases %}
73
- <li class="list-group-item">{{ db }}</li>
 
 
 
 
 
74
  {% endfor %}
75
  </ul>
76
  {% else %}
@@ -91,7 +146,7 @@
91
  <ul class="list-group">
92
  {% for table in tables %}
93
  <li class="list-group-item">
94
- <a href="/table/{{ table }}">{{ table }}</a>
95
  </li>
96
  {% endfor %}
97
  </ul>
@@ -109,7 +164,8 @@
109
  <h5>Практичне заняття №1</h5>
110
  </div>
111
  <div class="card-body">
112
- <p>Для виконання завдання 1.3 виконайте наступний SQL скрипт:</p>
 
113
  <pre><code>-- Нереформатований скрипт
114
  create table if not exists test (numbers int, words varchar (10));
115
 
@@ -119,6 +175,15 @@ CREATE TABLE IF NOT EXISTS test (
119
  words VARCHAR(10) -- Поле для текстових значень максимум 10 символів
120
  );</code></pre>
121
  <button class="btn btn-outline-primary" onclick="copyToQueryConsole('create table if not exists test (numbers int, words varchar (10));')">Копіювати до консолі</button>
 
 
 
 
 
 
 
 
 
122
  </div>
123
  </div>
124
  </div>
 
11
  <div class="container mt-4">
12
  <h1 class="mb-4">MySQL Сервер 8.0.22 для навчальних цілей</h1>
13
 
14
+ <!-- Навігація -->
15
+ <div class="card mb-4">
16
+ <div class="card-header bg-dark text-white">
17
+ <h5>Навігація</h5>
18
+ </div>
19
+ <div class="card-body">
20
+ <div class="row">
21
+ <div class="col-md-4 mb-2">
22
+ <a href="#sql-console" class="btn btn-primary w-100">SQL Консоль</a>
23
+ </div>
24
+ <div class="col-md-4 mb-2">
25
+ <a href="/database/test_db" class="btn btn-secondary w-100">База даних test_db</a>
26
+ </div>
27
+ {% if employees_exists %}
28
+ <div class="col-md-4 mb-2">
29
+ <a href="/employees" class="btn btn-success w-100">База даних employees</a>
30
+ </div>
31
+ {% endif %}
32
+ </div>
33
+ </div>
34
+ </div>
35
+
36
  <!-- Статус сервера -->
37
  <div class="card mb-4">
38
  <div class="card-header {% if status.status == 'online' %}bg-success text-white{% else %}bg-danger text-white{% endif %}">
 
41
  <div class="card-body">
42
  {% if status.status == 'online' %}
43
  <p><strong>Версія MySQL:</strong> {{ status.version }}</p>
44
+
45
+ <!-- Інформація про базу employees -->
46
+ {% if employees_exists %}
47
+ <div class="alert alert-success">
48
+ <h5>База даних "Employees" успішно імпортована!</h5>
49
+ <p>Кількість таблиць: {{ employees_tables }}</p>
50
+ <a href="/employees" class="btn btn-sm btn-outline-success">Переглянути деталі</a>
51
+ </div>
52
+ {% else %}
53
+ <div class="alert alert-warning">
54
+ <h5>База даних "Employees" не знайдена</h5>
55
+ <p>Можливо, виникли проблеми при імпорті бази даних.</p>
56
+ </div>
57
+ {% endif %}
58
  {% else %}
59
  <p class="text-danger"><strong>Помилка:</strong> {{ status.error }}</p>
60
  {% endif %}
 
69
  <div class="card-body">
70
  <p>Для виконання SQL запитів надсилайте POST запити на <code>/execute</code> з JSON тілом:</p>
71
  <pre><code>{
72
+ "query": "ваш SQL запит",
73
+ "database": "назва_бази_даних" // опціонально, за замовчуванням "test_db"
74
  }</code></pre>
75
  <p>Приклад використання з curl:</p>
76
  <pre><code>curl -X POST https://mysql-itud-docsa.hf.space/execute \
77
  -H "Content-Type: application/json" \
78
+ -d '{"query":"SELECT * FROM test", "database":"test_db"}'</code></pre>
79
+
80
+ <p>Для роботи з базою даних employees:</p>
81
+ <pre><code>curl -X POST https://mysql-itud-docsa.hf.space/execute \
82
+ -H "Content-Type: application/json" \
83
+ -d '{"query":"SELECT * FROM employees LIMIT 5", "database":"employees"}'</code></pre>
84
  </div>
85
  </div>
86
 
87
  <!-- SQL Консоль -->
88
+ <div class="card mb-4" id="sql-console">
89
  <div class="card-header bg-primary text-white">
90
  <h5>SQL Консоль</h5>
91
  </div>
92
  <div class="card-body">
93
  <form action="/execute" method="post">
94
+ <div class="mb-3">
95
+ <label for="database" class="form-label">Виберіть базу даних:</label>
96
+ <select class="form-select" id="database" name="database">
97
+ {% for db in databases %}
98
+ <option value="{{ db }}" {% if db == 'test_db' %}selected{% endif %}>{{ db }}</option>
99
+ {% endfor %}
100
+ </select>
101
+ </div>
102
  <div class="mb-3">
103
  <label for="query" class="form-label">Введіть SQL запит:</label>
104
  <textarea class="form-control" id="query" name="query" rows="6" placeholder="SELECT * FROM test"></textarea>
 
120
  {% if databases %}
121
  <ul class="list-group">
122
  {% for db in databases %}
123
+ <li class="list-group-item">
124
+ <a href="/database/{{ db }}">{{ db }}</a>
125
+ {% if db == 'employees' %}
126
+ <span class="badge bg-success">Навчальна база</span>
127
+ {% endif %}
128
+ </li>
129
  {% endfor %}
130
  </ul>
131
  {% else %}
 
146
  <ul class="list-group">
147
  {% for table in tables %}
148
  <li class="list-group-item">
149
+ <a href="/table/test_db/{{ table }}">{{ table }}</a>
150
  </li>
151
  {% endfor %}
152
  </ul>
 
164
  <h5>Практичне заняття №1</h5>
165
  </div>
166
  <div class="card-body">
167
+ <h5>Завдання 1.3</h5>
168
+ <p>Для виконання тестового завдання виконайте наступний SQL скрипт:</p>
169
  <pre><code>-- Нереформатований скрипт
170
  create table if not exists test (numbers int, words varchar (10));
171
 
 
175
  words VARCHAR(10) -- Поле для текстових значень максимум 10 символів
176
  );</code></pre>
177
  <button class="btn btn-outline-primary" onclick="copyToQueryConsole('create table if not exists test (numbers int, words varchar (10));')">Копіювати до консолі</button>
178
+
179
+ <h5 class="mt-4">Завдання із використанням - Бази даних "Employees"</h5>
180
+ <p>Завдання 1.2 виконане автоматично - базу даних "Employees" вже імпортовано в середовище MySQL.</p>
181
+ {% if employees_exists %}
182
+ <p>Ви можете переглянути структуру та дані бази за посиланням:</p>
183
+ <a href="/employees" class="btn btn-success">Переглянути базу "Employees"</a>
184
+ {% else %}
185
+ <p class="text-danger">На жаль, база даних "Employees" не була успішно імпортована.</p>
186
+ {% endif %}
187
  </div>
188
  </div>
189
  </div>