parent
7896de3c3e
commit
da53a9c4ae
@ -0,0 +1,20 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: mysql_container
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: rootpassword
|
||||
MYSQL_DATABASE: project_db
|
||||
MYSQL_USER: project_user
|
||||
MYSQL_PASSWORD: project_password
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./db/migrations:/docker-entrypoint-initdb.d # Автоматическая инициализация базы (скрипты миграций)
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
@ -0,0 +1,11 @@
|
||||
CREATE TABLE IF NOT EXISTS student (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
git VARCHAR(255) NOT NULL,
|
||||
surname VARCHAR(100) NOT NULL,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
patronymic VARCHAR(100) NOT NULL,
|
||||
birth_date DATE NOT NULL,
|
||||
phone VARCHAR(20),
|
||||
telegram VARCHAR(50),
|
||||
email VARCHAR(100)
|
||||
);
|
@ -0,0 +1,4 @@
|
||||
INSERT INTO student (git, surname, name, patronymic, birth_date, phone, telegram, email)
|
||||
VALUES
|
||||
('https://github.com/example', 'Иванов', 'Иван', 'Иванович', '2000-01-01', '+123456789', '@telegram', 'email@example.com'),
|
||||
('https://github.com/example2', 'Петров', 'Петр', 'Петрович', '1999-05-15', '+987654321', '@petrov', 'petrov@example.com');
|
@ -0,0 +1,23 @@
|
||||
require 'mysql2'
|
||||
require 'singleton'
|
||||
|
||||
class DatabaseConnection
|
||||
include Singleton
|
||||
|
||||
def initialize
|
||||
@client = Mysql2::Client.new(
|
||||
host: 'localhost',
|
||||
username: 'project_user',
|
||||
password: 'project_password',
|
||||
database: 'project_db'
|
||||
)
|
||||
end
|
||||
|
||||
def client
|
||||
@client
|
||||
end
|
||||
|
||||
def query(sql)
|
||||
@client.query(sql)
|
||||
end
|
||||
end
|
@ -0,0 +1,101 @@
|
||||
require_relative '../db_connection'
|
||||
require_relative '../student'
|
||||
require_relative '../student_short'
|
||||
require_relative '../data_list_student_short'
|
||||
require 'date'
|
||||
|
||||
class StudentsListDB
|
||||
def initialize
|
||||
@db = DatabaseConnection.instance
|
||||
end
|
||||
|
||||
# Получить объект Student по ID.
|
||||
def get_student_by_id(id)
|
||||
result = @db.query("SELECT * FROM student WHERE id = #{id} LIMIT 1")
|
||||
row = result.first
|
||||
row ? row_to_student(row) : nil
|
||||
end
|
||||
|
||||
# Получить список из k студентов (страница n) в виде объекта DataList.
|
||||
def get_k_n_student_short_list(k, n)
|
||||
offset = (n - 1) * k
|
||||
results = @db.query("SELECT * FROM student ORDER BY surname, name, patronymic LIMIT #{k} OFFSET #{offset}")
|
||||
student_shorts = results.map { |row| StudentShort.from_student(row_to_student(row)) }
|
||||
DataListStudentShort.new(student_shorts)
|
||||
end
|
||||
|
||||
# Добавить объект Student в БД (ID формируется автоматически).
|
||||
def add_student(student)
|
||||
sql = <<~SQL
|
||||
INSERT INTO student (git, surname, name, patronymic, birth_date, phone, telegram, email)
|
||||
VALUES (
|
||||
'#{escape(student.git)}',
|
||||
'#{escape(student.surname)}',
|
||||
'#{escape(student.name)}',
|
||||
'#{escape(student.patronymic)}',
|
||||
'#{student.birth_date}',
|
||||
#{student.phone ? "'#{escape(student.phone)}'" : "NULL"},
|
||||
#{student.telegram ? "'#{escape(student.telegram)}'" : "NULL"},
|
||||
#{student.email ? "'#{escape(student.email)}'" : "NULL"}
|
||||
)
|
||||
SQL
|
||||
|
||||
@db.query(sql)
|
||||
new_id = @db.query("SELECT LAST_INSERT_ID() as id").first['id']
|
||||
student.id = new_id.to_s
|
||||
student
|
||||
end
|
||||
|
||||
# Обновить студента по ID.
|
||||
def update_student_by_id(id, new_student)
|
||||
sql = <<~SQL
|
||||
UPDATE student SET
|
||||
git = '#{escape(new_student.git)}',
|
||||
surname = '#{escape(new_student.surname)}',
|
||||
name = '#{escape(new_student.name)}',
|
||||
patronymic = '#{escape(new_student.patronymic)}',
|
||||
birth_date = '#{new_student.birth_date}',
|
||||
phone = #{new_student.phone ? "'#{escape(new_student.phone)}'" : "NULL"},
|
||||
telegram = #{new_student.telegram ? "'#{escape(new_student.telegram)}'" : "NULL"},
|
||||
email = #{new_student.email ? "'#{escape(new_student.email)}'" : "NULL"}
|
||||
WHERE id = #{id}
|
||||
SQL
|
||||
|
||||
@db.query(sql)
|
||||
@db.client.affected_rows > 0
|
||||
end
|
||||
|
||||
# Удалить студента по ID.
|
||||
def delete_student_by_id(id)
|
||||
@db.query("DELETE FROM student WHERE id = #{id}")
|
||||
@db.client.affected_rows > 0
|
||||
end
|
||||
|
||||
# Получить количество студентов.
|
||||
def get_student_short_count
|
||||
result = @db.query("SELECT COUNT(*) as count FROM student")
|
||||
result.first['count']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Преобразование строки результата в объект Student.
|
||||
def row_to_student(row)
|
||||
Student.new(
|
||||
id: row['id'].to_s,
|
||||
git: row['git'],
|
||||
surname: row['surname'],
|
||||
name: row['name'],
|
||||
patronymic: row['patronymic'],
|
||||
birth_date: Date.parse(row['birth_date'].to_s),
|
||||
phone: row['phone'],
|
||||
telegram: row['telegram'],
|
||||
email: row['email']
|
||||
)
|
||||
end
|
||||
|
||||
# Простой метод для экранирования строк (на практике лучше использовать подготовленные выражения).
|
||||
def escape(value)
|
||||
@db.client.escape(value.to_s)
|
||||
end
|
||||
end
|
Loading…
Reference in new issue