|
СисПрог Курсова (2). Міністерство освіти, науки, молоді І спорту україни одеський національний політехнічний університет
Завдання:
1) в СКБД PostgreSQL створити таблицю:
структура таблиці дозволить зберігати записи із файлу у відповідності з варіантами у таблиці 1.1.2; врахувати наявність додаткової колонки первинного ключа; назву таблиці визначити у відповідності зі змістом даних; команду створення таблиці типу CREATE TABLE IF NOT EXISTS назва_таблиці ... внести у скрипт; назва скрипту: create + ваше прізвище транслітерацією + .sql, наприклад: create_ivanov.sql;
2) розробити програму на мові C#, яка:
читає файл із рядками у відповідності з варіантами у таблиці 1.1.2; створює новий файл-скрипт із SQL-командами типу INSERT INTO назва_таблиці .... назва скрипту: insert + ваше прізвище транслітерацією + .sql,
наприклад: insert_ivanov.sql
3) створити та заповнити таблицю БД,використовуючи утиліту psql, яка через перенаправлення виводу даних внесе рядки в БД:
psql БД < create_ivanov.sql
psql БД < insert_ivanov.sql Виконання:
Набираємо код в терміналі
d_gergel@dell:$ echo "CREATE TABLE IF NOT EXISTS Activities
(id int primary key, name varchar(90));" > create_gergel.sql
Вміст файлу create_gergel.sql
CREATE TABLE IF NOT EXISTS Activities
(id int primary key, name varchar(90));
Створюємо файл 1.cs, який містить код для створення файлу insert_gergel.sql
using System;
using System.IO; class InsertInDB
{
static void Main()
{
//Зчитуємо всі рядки з файлу в масив 'values'
string[] values = File.ReadAllLines("activities");
//Створюємо файл "insert_gergel.sql" та починаємо записувати в нього sql-команди
using (StreamWriter sw = new StreamWriter(File.Create("insert_gergel.sql")))
{
//Записуємо початок sql-команди вставлення
sw.WriteLine("INSERT INTO Activities(id, name) VALUES");
//Запускаємо цикл, який проходить по масиву 'values'
for(int i = 0; i < values.Length; i++)
{
//Записуємо значення елементу масиву, яке треба вставити в таблицю
sw.Write($"('{i+1}', '{values[i]}')");
if(i != values.Length - 1)
sw.WriteLine(",");
}
//Записуємо символ завершення sql-команди
sw.WriteLine(";");
Console.WriteLine("Файл 'insert_gergel.sql' успіщно створено.");
}}}
Скомпілюємо й запустимо код
Отримуємо файл із таким вмістом:
insert_gergel.sql
INSERT INTO Activities(id, name) VALUES
('1', 'Сільське, лісове та рибне господарство'),
('2', 'сільське господарство, мисливство та надання повязаних із ними послуг'),
('3', 'лісове господарство та лісозаготівлі'),
('4', 'рибне господарство'),
('5', 'Промисловість'),
('6', 'Будівництво'),
('7', 'Оптова та роздрібна торгівля; ремонт автотранспортних засобів і мотоциклів'),
('8', 'оптова та роздрібна торгівля автотранспортними засобами та мотоциклами, їх ремонт'),
('9', 'оптова торгівля, крім торгівлі автотранспортними засобами та мотоциклами'),
('10', 'роздрібна торгівля, крім торгівлі автотранспортними засобами та мотоциклами'),
('11', 'Транспорт, складське господарство, поштова та курєрська діяльність'),
('12', 'наземний і трубопровідний транспорт'),
('13', 'водний транспорт'),
('14', 'авіаційний транспорт'),
('15', 'складське господарство та допоміжна діяльність у сфері транспорту'),
('16', 'поштова та курєрська діяльність'),
('17', 'Тимчасове розміщування й організація харчування'),
('18', 'тимчасове розміщування'),
('19', 'діяльність із забезпечення стравами та напоями'),
('20', 'Інформація та телекомунікації');
Виконуємо записані в попередніх файлах команди
d_gergel@dell:/sp_cwork$ sudo -u postgres psql postgres < create_gergel.sql
CREATE TABLE
d_gergel@dell:/sp_cwork$ sudo -u postgres psql postgres < insert_gergel.sql
INSERT 0 20 Перевіримо вміст нашої створеної таблиці
d_gergel@dell:/sp_cwork$ echo "SELECT * FROM Activities" | sudo -u postgres psql postgres
id | name
----+-----------------------------------------------------------------------------------
1 | Сільське, лісове та рибне господарство
2 | сільське господарство, мисливство та надання повязаних із ними послуг
3 | лісове господарство та лісозаготівлі
4 | рибне господарство
5 | Промисловість
.............
(20 rows)
Етап 2.2. Автоматичний запуск процесів-транзакцій
Завдання:
розробити програму на мові C#, яка: - запускає декілька потоків; - кожний поток виконує транзакцію, яка містить чотири операції: SET ISOLATION LEVEL рівень; SELECT * FROM таблиця WHERE колонка_первинний_ключ = значення1 UPDATE таблиця SET колонка_з_назвами = значення1 WHERE колонка_первинний_ключ = значення1 COMMIT; рівень ізоляції транзакції визначається у відповідності з варіантом таблиці 2.2.1. кількість потоків визначається параметром командного рядку майбутнього запуску програми
Таблиця 2.2.1
Виконання:
Створюємо кодовий файл 2.cs
using System;
using System.IO;
using System.Diagnostics; class RunTransactions
{
static void Main(string[] args)
{
uint n = 0; //кількість потоків //Перевіряємо, чи було передано параметр
if(args.Length == 0)
{
Console.Write("Кількість потоків: ");
//уводимо кількість потоків
n = Convert.ToUInt32(Console.ReadLine());
}
//отримуємо кількість потоків із переданого параметру
else n = Convert.ToUInt32(args[0]);
//видаляємо папку 'logs', щоб очистити старі дані
if(Directory.Exists("logs"))
Directory.Delete("logs", true);
//створюємо папку для зберігання проміжних файлів
Directory.CreateDirectory("logs");
using(StreamWriter sw = new
StreamWriter(File.Create($"logs/trans.sql")))
{
//Записуємо команду початку транзакції
sw.WriteLine("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE
READ;"); //Вписуємо команду SELECT, обираємо 5-й рядок
sw.WriteLine("SELECT * FROM Activities WHERE id = '5';"); //Вписуємо команду зміни значення поля 'name' в 5-му рядку //на 'TRANSACTED'
sw.WriteLine("UPDATE Activities SET name = 'TRANSACTED'
WHERE id = 5;");
//Вписуємо команду, яка завершує транзакцію
sw.WriteLine("COMMIT;");
}
//Починаємо запуск транзакцій
Process[] processes = new Process[n];
for(uint i = 1; i <= n; i++)
{
Console.WriteLine($"Запуск транзакції {i}...");
//Команда запуску psql
string run_psql_command
= $"sudo -u postgres psql postgres < logs/trans.sql";
//Запускаємо транзакцію в psql через Bash та //перенаправляємо виведення в log-файл
processes[i-1]
= Process.Start("/bin/bash", $"-c \"{run_psql_command} 2> logs/err_{i}.log 1> logs/{i}.log\"");
}
Console.WriteLine("\nЗапуск транзакцій завершено.");
//Затримуємо вихід з програми, допоки не виконаються
//всі запущені процеси
while (true)
{
bool all_exited = true;
foreach(Process p in processes)
{
if(!p.HasExited)
{
all_exited = false;
break;
}
}
if(all_exited)
break;
};
Console.WriteLine("\nТранзакції завершили роботу.");
}
}
Компілюємо та запускаємо код
Етап 2.3. Підключення скриптів з 1-го та 2-го етапів до псевдографічного діалогового інтерфейу користувача
Додати скрипти до псевдографічного діалогового інтерфейсу користувача утиліти Linux dialog або whiptail для програм створених на етапах 2.1 та 2.2; назви пунктів меню нових підключення нових скриптів визначити самостійно;
Створимо скриптовий файл 3_2.sh
#!/bin/bash
#Створює sql-файли
create_files(){
#Перевірка наявності файлу create_gergel.sql
if [[ -f "create_gergel.sql" ]]; then
dialog --title "Попередження" --msgbox "Файл \"create_gergel.sql\" вже існує. \nЙого вміст буде перезаписано." 10 40
fi #Перевірка наявності файлу create_gergel.sql
if [[ -f "insert_gergel.sql" ]]; then
dialog --title "Попередження" --msgbox
"Файл \"insert_gergel.sql\" вже існує.
Його вміст буде перезаписано." 10 40
fi #Створюємо файл create_gergel.sql
file1_created=1
echo "CREATE TABLE IF NOT EXISTS Activities
(id int PRIMARY KEY, name VARCHAR(90));" > create_gergel.sql
if [[ ! $? -eq 0 ]]; then
file1_created=0
fi #Створюємо файл create_gergel.sql
file2_created=1
mono 1.exe #запускаємо скомпільований C#-код
if [[ ! $? -eq 0 ]]; then
file2_created=0
fi #Будуємо кінцеве повідомлення
create_status=('невдача' 'успіх')
message="Результати створення файлів:
create_gergel.sql: ${create_status[file1_created]}
insert_gergel.sql: ${create_status[file2_created]}"
dialog --title "Створення sql-файлів" --msgbox "$message" 10 40
} #Переглядає вказаний через аргумент файл
view_file(){
content=$(cat "$1")
dialog --title "$1" --msgbox "$content" 15 65
} #Запускає sql-файл
run_sql_file(){
#Запускаємо команду та записуємо її помилки в 'errors'
sudo -u postgres psql postgres < "$1" 2> errors #Зчитуємо "файл помилок"
err_output=$(cat errors)
if [[ ${#err_output} -eq 0 ]]; then #якщо файл 'errors' порожній
dialog --title "Виконання \"$1\""
--msgbox "Файл \"$1\" успішно виконано." 15 65 else #якщо файл 'errors' НЕ порожній
dialog --msgbox "Виникла помилка в PostgreSQL: \n$err_output" 0 0
fi
rm errors #вилучаємо "файл помилок"
} view_table(){
#Запускаємо команду та записуємо її помилки в 'errors'
echo "SELECT * FROM Activities;" | sudo -u postgres psql postgres
2> errors 1> output
#Зчитуємо "файл помилок"
err=$(cat errors)
if [[ ${#err} -eq 0 ]]; then #якщо файл 'errors' порожній
outp=$(cat output)
dialog --title "Вміст таблиці 'Activities'" --msgbox "$outp" 0 0 else #якщо файл 'errors' НЕ порожній
dialog --msgbox "Виникла помилка в PostgreSQL: \n$err" 15 65
fi
rm errors output
} #Видаляє таблтцю з БД
delete_table(){
#Запускаємо команду та записуємо її помилки в 'errors'
echo "DROP TABLE Activities;" | sudo -u postgres psql postgres
2> errors #Зчитуємо "файл помилок"
err=$(cat errors)
if [[ ${#err} -eq 0 ]]; then #якщо файл 'errors' порожній
dialog --title "Видалення таблиці"
--msgbox"Таблицю 'Activities' успішно вилучено з бази даних." 0 0 else #якщо файл 'errors' НЕ порожній
dialog --msgbox "Виникла помилка в PostgreSQL: \n$err" 15 65
fi
rm errors
} #Очищає таблицю в БД
clear_table(){
#Запускаємо команду та записуємо її помилки в 'errors'
echo "DELETE FROM Activities;" | sudo -u postgres psql postgres
2> errors
#Зчитуємо "файл помилок"
err=$(cat errors)
if [[ ${#err} -eq 0 ]]; then #якщо файл 'errors' порожній
dialog --title "Очищення таблиці"
--msgbox "Таблицю 'Activities' успішно очищено." 15 65 else #якщо файл 'errors' НЕ порожній
dialog --msgbox "Виникла помилка в PostgreSQL: \n$err" 15 65
fi
rm errors
}
#Запускає транзакції
run_transactions(){
t_count=$(dialog --stdout --title "Кількість потоків"
--inputbox "Уведіть кількість потоків:" 10 60 "5")
mono 2.exe $t_count 1> output 2> errors
message="Результати виконання транзакцій: \n"
for (( i = 1; i <= t_count; i++ )); do
err=$(cat "logs/err_$i.log")
if [[ ${#err} -eq 0 ]]; then
message+="Т$i - ОК \n"
else
message+="Т$i - $err \n"
fi
done dialog --msgbox "$message" 0 0
} #Головна функція скрипту
main(){
#Нескінченний цикл
while true; do
#Створюємо меню для перегляду характеристик
sel_idx=$(dialog --stdout --menu "Оберіть дію:" 0 0 10 \
1 "Створити sql-файли" \
2 "Переглянути файл create_gergel.sql" \
3 "Переглянути файл insert_gergel.sql" \
4 "Виконати файл create_gergel.sql" \
5 "Виконати файл insert_gergel.sql" \
6 "Переглянути вміст таблиці 'Activities'" \
7 "Очистити таблицю 'Activities'" \
8 "Видалити таблицю 'Activities'" \
9 "Виконати транзакції для таблиці 'Activities'" \
10 "Вихід")
case $sel_idx in
1)
create_files;;
2)
view_file 'create_gergel.sql';;
3)
view_file 'insert_gergel.sql';;
4)
run_sql_file 'create_gergel.sql';;
5)
run_sql_file 'insert_gergel.sql';;
6)
view_table;;
7)
clear_table;;
8)
delete_table;;
9)
run_transactions;;
10)
break;;
esac
done; clear
} #Виклик головної функції
main
Головне меню скрипта
Обираємо пункт 1
Обираємо пункт 2
Обираємо пункт 3
Обираємо пункт 4
Обираємо пункт 5
Обираємо пункт 6
Обираємо пункт 7
Переглянемо таблицю ‘Activities’ ще раз
Обираємо пункт 8
Обираємо пункт 9
ВИСНОВКИ
Було виконано курсову роботу з навчальної дисципліни «Системне програмування» в ході якої було розроблено скрипти мовами Bash і C#.
Скрипти мали виконувати такі операції:
Автоматичне створення каталогів, які мають назви, попередньо визначені в текстовому файлі Перегляд характеристик операційної системи Автоматичне створення sql-скриптів, що створюють та заповнюють таблицю в БД Автоматичний запуск процесів-транзакцій
Для взаємодії зі скриптами було використано псевдографічний інтерфейс, який забезпечується за допомогою утиліти dialog.
Результатом виконання даної роботи є набуття навичок скриптового програмування мовами Bash і C# та автоматизації виконання рутинних операцій. |
|
|