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