papaSquidLib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +69 -0
  4. data/lib/controllers/tab_students_controller.rb +43 -0
  5. data/lib/data_sources/db_client.rb +35 -0
  6. data/lib/db_config/config.yaml +5 -0
  7. data/lib/db_config/library_config.yaml +5 -0
  8. data/lib/db_config/migrations/create_db.sql +3 -0
  9. data/lib/db_config/migrations/create_tables.sql +29 -0
  10. data/lib/db_config/mock_data/mock_data.sql +72 -0
  11. data/lib/logger.rb +27 -0
  12. data/lib/main.rb +6 -0
  13. data/lib/manager/controllers/manager_input_form_controller_create.rb +44 -0
  14. data/lib/manager/controllers/manager_input_form_controller_edit.rb +54 -0
  15. data/lib/manager/controllers/manager_list_controller.rb +99 -0
  16. data/lib/manager/manager_db_data_source.rb +63 -0
  17. data/lib/manager/ui/manager_input_form.rb +69 -0
  18. data/lib/manager/ui/manager_list_view.rb +168 -0
  19. data/lib/models/manager.rb +41 -0
  20. data/lib/models/student.rb +102 -0
  21. data/lib/models/student_base.rb +100 -0
  22. data/lib/models/student_short.rb +50 -0
  23. data/lib/models/task.rb +49 -0
  24. data/lib/models/user.rb +32 -0
  25. data/lib/papaSquidLib/version.rb +5 -0
  26. data/lib/papa_squid_lib.rb +6 -0
  27. data/lib/repositories/adapters/db_source_adapter.rb +54 -0
  28. data/lib/repositories/adapters/file_source_adapter.rb +37 -0
  29. data/lib/repositories/containers/data_list.rb +74 -0
  30. data/lib/repositories/containers/data_list_student_short.rb +18 -0
  31. data/lib/repositories/containers/data_table.rb +35 -0
  32. data/lib/repositories/data_sources/db_data_source.rb +32 -0
  33. data/lib/repositories/data_sources/file_data_source.rb +75 -0
  34. data/lib/repositories/data_sources/transformers/data_transformer_base.rb +15 -0
  35. data/lib/repositories/data_sources/transformers/data_transformer_json.rb +16 -0
  36. data/lib/repositories/data_sources/transformers/data_transformer_yaml.rb +16 -0
  37. data/lib/repositories/student_repository.rb +32 -0
  38. data/lib/state_holders/list_state_notifier.rb +60 -0
  39. data/lib/task/controllers/task_input_form_controller_create.rb +43 -0
  40. data/lib/task/controllers/task_input_form_controller_edit.rb +57 -0
  41. data/lib/task/controllers/task_list_controller.rb +93 -0
  42. data/lib/task/task_db_data_source.rb +85 -0
  43. data/lib/task/ui/task_input_form.rb +67 -0
  44. data/lib/task/ui/task_input_form_factory.rb +26 -0
  45. data/lib/task/ui/task_list_view.rb +163 -0
  46. data/lib/user/controllers/user_input_form_controller_create.rb +42 -0
  47. data/lib/user/controllers/user_input_form_controller_edit.rb +53 -0
  48. data/lib/user/controllers/user_list_controller.rb +99 -0
  49. data/lib/user/ui/user_input_form.rb +69 -0
  50. data/lib/user/ui/user_list_view.rb +170 -0
  51. data/lib/user/user_db_data_source.rb +71 -0
  52. data/lib/views/main_window.rb +32 -0
  53. data/lib/views/tab_students.rb +148 -0
  54. data/papaSquidLib.gemspec +15 -0
  55. data/test/manager_test.rb +27 -0
  56. data/test/state_notifier_test.rb +82 -0
  57. data/test/task_test.rb +51 -0
  58. data/test/user_test.rb +39 -0
  59. metadata +113 -0
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require_relative '../controllers/manager_list_controller'
5
+ require_relative 'manager_input_form'
6
+
7
+ class ManagerListView
8
+ include Glimmer
9
+
10
+ PAGE_SIZE = 20
11
+
12
+ def initialize
13
+ @controller = ManagerListController.new(self)
14
+ @current_page = 1
15
+ @total_count = 0
16
+ end
17
+
18
+ def on_create
19
+ @controller.on_view_created
20
+ @controller.refresh_data(@current_page, PAGE_SIZE)
21
+ end
22
+
23
+ # Метод наблюдателя datalist
24
+ # def on_datalist_changed(new_table)
25
+ # arr = new_table.to_2d_array
26
+ # arr.map do |row|
27
+ # row[3] = [row[3][:value], contact_color(row[3][:type])] unless row[3].nil?
28
+ # end
29
+ # @table.model_array = arr
30
+ # end
31
+
32
+ def update(managers)
33
+ @items = []
34
+ i = 0
35
+ item_num = 0
36
+ managers.each do |manager|
37
+ i += 1
38
+ item_num = ((@current_page - 1) * PAGE_SIZE) + i
39
+ @items << Struct.new(:№, :id, :имя, :почта, :телефон).new(item_num, manager.id, manager.name, manager.email, manager.phone)
40
+ end
41
+
42
+ @table.model_array = @items
43
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
44
+ end
45
+
46
+ def update_student_count(new_cnt)
47
+ @total_count = new_cnt
48
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
49
+ end
50
+
51
+ def create
52
+
53
+ root_container = horizontal_box {
54
+ # Секция 1
55
+ vertical_box {
56
+ stretchy false
57
+
58
+ vertical_box {
59
+ stretchy false
60
+
61
+ label {
62
+ text 'Почта'
63
+ }
64
+ combobox { |c|
65
+ items ['Не важно','Есть','Нет']
66
+ selected 0
67
+ on_selected do
68
+ @controller.filter_email(@current_page, PAGE_SIZE, c.selected)
69
+ end
70
+ }
71
+
72
+ label {
73
+ text 'Сортировка'
74
+ }
75
+ combobox { |c|
76
+ items ['ID','Название','Почта','Телефон']
77
+ selected 0
78
+ on_selected do
79
+ @controller.sort(@current_page, PAGE_SIZE, c.selected)
80
+ end
81
+ }
82
+ }
83
+
84
+
85
+ }
86
+
87
+ # Секция 2
88
+ vertical_box {
89
+ @table = refined_table(
90
+ table_editable: false,
91
+ filter: lambda do |row_hash, query|
92
+ utf8_query = query.force_encoding("utf-8")
93
+ row_hash['Имя пользователя'].include?(utf8_query)
94
+ end,
95
+ table_columns: {
96
+ '№' => :text,
97
+ 'ID' => :text,
98
+ 'Имя' => :text,
99
+ 'Почта' => :text,
100
+ 'Телефон' => :text,
101
+ },
102
+ per_page: PAGE_SIZE,
103
+
104
+ )
105
+
106
+ @pages = horizontal_box {
107
+ stretchy false
108
+
109
+ button("<") {
110
+ stretchy true
111
+
112
+ on_clicked do
113
+ @current_page = [@current_page - 1, 1].max
114
+ @controller.refresh_data(@current_page, PAGE_SIZE)
115
+ end
116
+
117
+ }
118
+ @page_label = label("...") { stretchy false }
119
+ button(">") {
120
+ stretchy true
121
+
122
+ on_clicked do
123
+ @current_page = [@current_page + 1, (@total_count / PAGE_SIZE.to_f).ceil].min
124
+ @controller.refresh_data(@current_page, PAGE_SIZE)
125
+ end
126
+ }
127
+ }
128
+ }
129
+
130
+ # Секция 3
131
+ vertical_box {
132
+ stretchy false
133
+
134
+ button('Добавить') {
135
+ stretchy false
136
+
137
+ on_clicked {
138
+ @controller.show_modal_add
139
+ }
140
+ }
141
+ button('Изменить') {
142
+ stretchy false
143
+
144
+ on_clicked {
145
+ @controller.show_modal_edit(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
146
+ }
147
+ }
148
+ button('Удалить') {
149
+ stretchy false
150
+
151
+ on_clicked {
152
+ @controller.delete_selected(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
153
+ @controller.refresh_data(@current_page, PAGE_SIZE)
154
+ }
155
+ }
156
+ button('Обновить') {
157
+ stretchy false
158
+
159
+ on_clicked {
160
+ @controller.refresh_data(@current_page, PAGE_SIZE)
161
+ }
162
+ }
163
+ }
164
+ }
165
+ on_create
166
+ root_container
167
+ end
168
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Manager
4
+ attr_accessor :id, :name, :email, :phone
5
+
6
+ def initialize(id, name, email, phone)
7
+ validate_null("name", name)
8
+ validate_null("email", email)
9
+ validate_null("phone", phone)
10
+
11
+ @id = id
12
+ @name = name
13
+ @email = email
14
+ @phone = phone
15
+
16
+ unless valid_email?
17
+ raise ArgumentError, "Invalid email format"
18
+ end
19
+
20
+ unless valid_phone?
21
+ raise ArgumentError, "Invalid phone number format"
22
+ end
23
+ end
24
+
25
+ def validate_null(name, value)
26
+ if value.nil?
27
+ raise ArgumentError, "Argument '#{name}' cannot be null"
28
+ end
29
+ end
30
+
31
+ def valid_email?
32
+ email_regex = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
33
+ !!(email =~ email_regex)
34
+ end
35
+
36
+ def valid_phone?
37
+ phone_regex = /\A(\+7|8)\s?\(?\d{3}\)?\s?\d{3}[\s-]?\d{2}[\s-]?\d{2}\z/
38
+ !!(phone =~ phone_regex)
39
+ end
40
+ end
41
+
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require_relative 'student_base'
5
+
6
+ class Student < StudentBase
7
+ # Делаем new предка публичным
8
+ public_class_method :new
9
+
10
+ def self.from_hash(hash)
11
+ raise ArgumentError, 'Fields required: fist_name, last_name, father_name' unless hash.key?(:first_name) && hash.key?(:last_name) && hash.key?(:father_name)
12
+
13
+ first_name = hash.delete(:first_name)
14
+ last_name = hash.delete(:last_name)
15
+ father_name = hash.delete(:father_name)
16
+
17
+ Student.new(last_name, first_name, father_name, **hash)
18
+ end
19
+
20
+ # Конструктор из JSON строки
21
+ def self.from_json_str(str)
22
+ params = JSON.parse(str, { symbolize_names: true })
23
+ from_hash(params)
24
+ end
25
+
26
+ # Делаем публичными геттеры и сеттеры базового класса
27
+ public :phone, :telegram, :email, 'id=', 'phone=', 'telegram=', 'email=', 'git='
28
+
29
+ # Стандартные геттеры для полей
30
+ attr_reader :last_name, :first_name, :father_name
31
+
32
+ # Стандартный конструктор
33
+ def initialize(last_name, first_name, father_name, **options)
34
+ self.last_name = last_name
35
+ self.first_name = first_name
36
+ self.father_name = father_name
37
+ super(**options)
38
+ end
39
+
40
+ # Сеттеры с валидацией перед присваиванием
41
+ def last_name=(new_last_name)
42
+ raise ArgumentError, "Invalid argument: last_name=#{new_last_name}" unless Student.valid_name?(new_last_name)
43
+
44
+ @last_name = new_last_name
45
+ end
46
+
47
+ def first_name=(new_first_name)
48
+ raise ArgumentError, "Invalid argument: first_name=#{new_first_name}" unless Student.valid_name?(new_first_name)
49
+
50
+ @first_name = new_first_name
51
+ end
52
+
53
+ def father_name=(new_father_name)
54
+ raise ArgumentError, "Invalid argument: father_name=#{new_father_name}" unless Student.valid_name?(new_father_name)
55
+
56
+ @father_name = new_father_name
57
+ end
58
+
59
+ # Отдельный сеттер для массовой установки контактов
60
+ def set_contacts(phone: nil, telegram: nil, email: nil)
61
+ self.phone = phone if phone
62
+ self.telegram = telegram if telegram
63
+ self.email = email if email
64
+ end
65
+
66
+ # Имя пользователя в формате Фамилия И. О.
67
+ def last_name_and_initials
68
+ "#{last_name} #{first_name[0]}. #{father_name[0]}."
69
+ end
70
+
71
+ # Краткая информация о пользователе
72
+ def short_info
73
+ info = {}
74
+ info[:last_name_and_initials] = last_name_and_initials
75
+ info[:contact] = short_contact
76
+ info[:git] = git
77
+ JSON.generate(info)
78
+ end
79
+
80
+ # Методы приведения объекта к строке
81
+ def to_s
82
+ result = "#{last_name} #{first_name} #{father_name}"
83
+ %i[id phone telegram email git].each do |attr|
84
+ attr_val = send(attr)
85
+ result += ", #{attr}=#{attr_val}" unless attr_val.nil?
86
+ end
87
+ result
88
+ end
89
+
90
+ def to_hash
91
+ attrs = {}
92
+ %i[last_name first_name father_name id phone telegram email git].each do |attr|
93
+ attr_val = send(attr)
94
+ attrs[attr] = attr_val unless attr_val.nil?
95
+ end
96
+ attrs
97
+ end
98
+
99
+ def to_json_str
100
+ JSON.generate(to_hash)
101
+ end
102
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ class StudentBase
4
+ # Запрещаем создание базового класса (он "абстрактный")
5
+ private_class_method :new
6
+
7
+ # Валидаторы для полей
8
+ def self.valid_name?(name)
9
+ name.match(/(^[А-Я][а-я]+$)|(^[A-Z][a-z]+$)/)
10
+ end
11
+
12
+ def self.valid_phone?(phone)
13
+ phone.match(/^\+?[78] ?[(-]?\d{3} ?[)-]?[ -]?\d{3}[ -]?\d{2}[ -]?\d{2}$/)
14
+ end
15
+
16
+ def self.valid_profile_name?(profile_name)
17
+ profile_name.match(/^[a-zA-Z0-9_.]+$/)
18
+ end
19
+
20
+ def self.valid_email?(email)
21
+ email.match(/^(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/)
22
+ end
23
+
24
+ # Стандартные геттеры и сеттеры для полей
25
+
26
+ protected
27
+
28
+ attr_writer :id
29
+ attr_reader :phone, :telegram, :email
30
+
31
+ public
32
+
33
+ attr_reader :id, :git
34
+
35
+ # Стандартный конструктор
36
+ def initialize(id: nil, phone: nil, telegram: nil, email: nil, git: nil)
37
+ self.id = id
38
+ self.phone = phone
39
+ self.telegram = telegram
40
+ self.email = email
41
+ self.git = git
42
+ end
43
+
44
+ # Краткая информация о первом доступном контакте пользователя
45
+ def short_contact
46
+ contact = {}
47
+ %i[telegram email phone].each do |attr|
48
+ attr_val = send(attr)
49
+ next if attr_val.nil?
50
+
51
+ contact[:type] = attr
52
+ contact[:value] = attr_val
53
+ return contact
54
+ end
55
+
56
+ nil
57
+ end
58
+
59
+ protected
60
+
61
+ # Сеттеры с валидацией перед присваиванием
62
+ def phone=(new_phone)
63
+ raise ArgumentError, "Invalid argument: phone=#{new_phone}" unless new_phone.nil? || StudentBase.valid_phone?(new_phone)
64
+
65
+ @phone = new_phone
66
+ end
67
+
68
+ def telegram=(new_telegram)
69
+ raise ArgumentError, "Invalid argument: telegram=#{new_telegram}" unless new_telegram.nil? || StudentBase.valid_profile_name?(new_telegram)
70
+
71
+ @telegram = new_telegram
72
+ end
73
+
74
+ def git=(new_git)
75
+ raise ArgumentError, "Invalid argument: git=#{new_git}" unless new_git.nil? || StudentBase.valid_profile_name?(new_git)
76
+
77
+ @git = new_git
78
+ end
79
+
80
+ def email=(new_email)
81
+ raise ArgumentError, "Invalid argument: email=#{new_email}" unless new_email.nil? || StudentBase.valid_email?(new_email)
82
+
83
+ @email = new_email
84
+ end
85
+
86
+ public
87
+
88
+ # Валидаторы объекта
89
+ def has_contacts?
90
+ !phone.nil? || !telegram.nil? || !email.nil?
91
+ end
92
+
93
+ def has_git?
94
+ !git.nil?
95
+ end
96
+
97
+ def valid?
98
+ has_contacts? && has_git?
99
+ end
100
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class StudentShort < StudentBase
4
+ # Делаем new предка публичным
5
+ public_class_method :new
6
+
7
+ # Стандартные геттеры и сеттеры
8
+
9
+ private
10
+
11
+ attr_writer :last_name_and_initials, :contact
12
+
13
+ public
14
+
15
+ attr_reader :last_name_and_initials, :contact
16
+
17
+ # Конструктор из Student
18
+ def self.from_student(student)
19
+ raise ArgumentError, 'Student ID is required' if student.id.nil?
20
+
21
+ StudentShort.new(student.id, student.short_info)
22
+ end
23
+
24
+ # Стандартный конструктор
25
+ def initialize(id, info_str)
26
+ params = JSON.parse(info_str, { symbolize_names: true })
27
+ raise ArgumentError, 'Fields required: last_name_and_initials' if !params.key?(:last_name_and_initials) || params[:last_name_and_initials].nil?
28
+
29
+ self.id = id
30
+ self.last_name_and_initials = params[:last_name_and_initials]
31
+ self.contact = params[:contact]
32
+ self.git = params[:git]
33
+
34
+ options = {}
35
+ options[:id] = id
36
+ options[:git] = git
37
+ options[contact[:type].to_sym] = contact[:value] if contact
38
+ super(**options)
39
+ end
40
+
41
+ # Методы приведения объекта к строке
42
+ def to_s
43
+ result = last_name_and_initials
44
+ %i[id contact git].each do |attr|
45
+ attr_val = send(attr)
46
+ result += ", #{attr}=#{attr_val}" unless attr_val.nil?
47
+ end
48
+ result
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ class Task
2
+ attr_reader :task_id, :completed, :user_id, :date, :description, :manager_id
3
+
4
+ def initialize(task_id, user_id, manager_id, date = set_system_date, description = nil, completed = 'Undone')
5
+ validate_null('task_id', task_id)
6
+ validate_null('user_id', user_id)
7
+ validate_null('manager_id', manager_id)
8
+
9
+ validate_completed(completed)
10
+
11
+ @task_id = task_id
12
+ @user_id = user_id
13
+ @manager_id = manager_id
14
+ @date = date
15
+ @description = description
16
+ @completed = completed
17
+
18
+ end
19
+
20
+ def to_hash
21
+ {
22
+ task_id: task_id,
23
+ user_id: user_id,
24
+ manager_id: manager_id,
25
+ date: date,
26
+ description: description,
27
+ completed: completed
28
+ }
29
+ end
30
+
31
+ private
32
+
33
+ def validate_null(name, value)
34
+ if value.nil?
35
+ raise ArgumentError, "Argument '#{name}' cannot be null"
36
+ end
37
+ end
38
+
39
+ def set_system_date
40
+ Time.now.strftime("%Y-%m-%d")
41
+ end
42
+
43
+ def validate_completed(completed)
44
+ unless completed == 'Done' || completed == 'Undone' || completed == 'Process'
45
+ raise ArgumentError, "Argument '#{completed}' can only be Done, Undone or Process"
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,32 @@
1
+ class User
2
+ attr_reader :user_id, :first_name, :last_name, :father_name
3
+
4
+ def initialize(user_id, first_name, last_name, father_name = nil)
5
+ validate_null('user_id', user_id)
6
+ validate_null('first_name', first_name)
7
+ validate_null('last_name', last_name)
8
+
9
+ validate_name_length(first_name, last_name, father_name)
10
+
11
+ @user_id = user_id
12
+ @first_name = first_name
13
+ @last_name = last_name
14
+ @father_name = father_name
15
+ end
16
+
17
+ private
18
+
19
+ def validate_null(name, value)
20
+ if value.nil?
21
+ raise ArgumentError, "Argument '#{name}' cannot be null"
22
+ end
23
+ end
24
+
25
+ def validate_name_length(first_name, last_name, father_name)
26
+ [first_name, last_name, father_name].each do |name|
27
+ if name && name.length > 50
28
+ raise ArgumentError, "Name exceeds 50 characters limit: #{name}"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PapaSquidLib
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ require 'papaSquidLib/version'
3
+
4
+ module PapaSquidLib
5
+
6
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/repositories/data_sources/db_data_source'
4
+ require './lib/models/student'
5
+ require './lib/models/student_short'
6
+ require './lib/repositories/containers/data_list_student_short'
7
+
8
+ class DBSourceAdapter
9
+ def initialize
10
+ @db = DBDataSource.instance
11
+ end
12
+
13
+ def student_by_id(student_id)
14
+ hash = @db.prepare_exec('SELECT * FROM student WHERE id = ?', student_id).first
15
+ return nil if hash.nil?
16
+
17
+ Student.from_hash(hash)
18
+ end
19
+
20
+ def paginated_short_students(page, count, existing_data_list = nil)
21
+ offset = (page - 1) * count
22
+ students = @db.prepare_exec('SELECT * FROM student LIMIT ?, ?', offset, count)
23
+ slice = students.map { |h| StudentShort.from_student(Student.from_hash(h)) }
24
+ return DataListStudentShort.new(slice) if existing_data_list.nil?
25
+
26
+ existing_data_list.replace_objects(slice)
27
+ existing_data_list
28
+ end
29
+
30
+ def add_student(student)
31
+ template = 'INSERT INTO student(last_name, first_name, father_name, phone, telegram, email, git) VALUES (?, ?, ?, ?, ?, ?, ?)'
32
+ @db.prepare_exec(template, *student_fields(student))
33
+ @db.query('SELECT LAST_INSERT_ID()').first.first[1]
34
+ end
35
+
36
+ def replace_student(student_id, student)
37
+ template = 'UPDATE student SET last_name=?, first_name=?, father_name=?, phone=?, telegram=?, email=?, git=? WHERE id=?'
38
+ @db.prepare_exec(template, *student_fields(student), student_id)
39
+ end
40
+
41
+ def remove_student(student_id)
42
+ @db.prepare_exec('DELETE FROM student WHERE id = ?', student_id)
43
+ end
44
+
45
+ def student_count
46
+ @db.query('SELECT COUNT(id) FROM student').first.first[1]
47
+ end
48
+
49
+ private
50
+
51
+ def student_fields(student)
52
+ [student.last_name, student.first_name, student.father_name, student.phone, student.telegram, student.email, student.git]
53
+ end
54
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FileSourceAdapter
4
+ def initialize(data_transformer, file_path)
5
+ @file_path = file_path
6
+ @file_source = FileDataSource.new(data_transformer)
7
+ @file_source.load_from_file(file_path)
8
+ end
9
+
10
+ def student_by_id(student_id)
11
+ @file_source.student_by_id(student_id)
12
+ end
13
+
14
+ def paginated_short_students(page, count, existing_data_list = nil)
15
+ @file_source.paginated_short_students(page, count, existing_data_list)
16
+ end
17
+
18
+ def add_student(student)
19
+ added_id = @file_source.add_student(student)
20
+ @file_source.save_to_file(@file_path)
21
+ added_id
22
+ end
23
+
24
+ def replace_student(student_id, student)
25
+ @file_source.replace_student(student_id, student)
26
+ @file_source.save_to_file(@file_path)
27
+ end
28
+
29
+ def remove_student(student_id)
30
+ @file_source.remove_student(student_id)
31
+ @file_source.save_to_file(@file_path)
32
+ end
33
+
34
+ def student_count
35
+ @file_source.student_count
36
+ end
37
+ end