student_mvp 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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +35 -0
  3. data/Rakefile +4 -0
  4. data/doc/Add_student_presenter.html +238 -0
  5. data/doc/App_logger.html +386 -0
  6. data/doc/Base_presenter.html +265 -0
  7. data/doc/Binary_tree.html +300 -0
  8. data/doc/Binary_tree_iterator.html +217 -0
  9. data/doc/Contact_sort_decorator.html +219 -0
  10. data/doc/DB_client.html +252 -0
  11. data/doc/Data_list.html +625 -0
  12. data/doc/Data_list_student_short.html +148 -0
  13. data/doc/Data_storage_strategy.html +178 -0
  14. data/doc/Data_table.html +264 -0
  15. data/doc/Deep_dup.html +152 -0
  16. data/doc/Edit_contacts_presenter.html +199 -0
  17. data/doc/Edit_git_presenter.html +192 -0
  18. data/doc/Edit_student_presenter.html +464 -0
  19. data/doc/Field_filter_decorator.html +219 -0
  20. data/doc/Filter.html +148 -0
  21. data/doc/Filter_decorator.html +209 -0
  22. data/doc/Full_name_filter_decorator.html +211 -0
  23. data/doc/Full_name_sort_decorator.html +217 -0
  24. data/doc/Gemfile.html +98 -0
  25. data/doc/Git_sort_decorator.html +220 -0
  26. data/doc/Has_not_field_filter_decorator.html +209 -0
  27. data/doc/JSON_storage_strategy.html +183 -0
  28. data/doc/Person.html +511 -0
  29. data/doc/README_md.html +147 -0
  30. data/doc/Rakefile.html +94 -0
  31. data/doc/Replace_student_presenter.html +204 -0
  32. data/doc/Sort_decorator.html +214 -0
  33. data/doc/Student.html +755 -0
  34. data/doc/StudentMvp/Error.html +105 -0
  35. data/doc/StudentMvp.html +111 -0
  36. data/doc/Student_list_presenter.html +667 -0
  37. data/doc/Student_short.html +398 -0
  38. data/doc/Students_list.html +341 -0
  39. data/doc/Students_list_DB.html +361 -0
  40. data/doc/Students_list_file.html +460 -0
  41. data/doc/Students_list_file_adapter.html +341 -0
  42. data/doc/Students_list_interface.html +298 -0
  43. data/doc/YAML_storage_strategy.html +183 -0
  44. data/doc/bin/setup.html +96 -0
  45. data/doc/created.rid +44 -0
  46. data/doc/css/fonts.css +167 -0
  47. data/doc/css/rdoc.css +662 -0
  48. data/doc/fonts/Lato-Light.ttf +0 -0
  49. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  50. data/doc/fonts/Lato-Regular.ttf +0 -0
  51. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  52. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  53. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  54. data/doc/images/add.png +0 -0
  55. data/doc/images/arrow_up.png +0 -0
  56. data/doc/images/brick.png +0 -0
  57. data/doc/images/brick_link.png +0 -0
  58. data/doc/images/bug.png +0 -0
  59. data/doc/images/bullet_black.png +0 -0
  60. data/doc/images/bullet_toggle_minus.png +0 -0
  61. data/doc/images/bullet_toggle_plus.png +0 -0
  62. data/doc/images/date.png +0 -0
  63. data/doc/images/delete.png +0 -0
  64. data/doc/images/find.png +0 -0
  65. data/doc/images/loadingAnimation.gif +0 -0
  66. data/doc/images/macFFBgHack.png +0 -0
  67. data/doc/images/package.png +0 -0
  68. data/doc/images/page_green.png +0 -0
  69. data/doc/images/page_white_text.png +0 -0
  70. data/doc/images/page_white_width.png +0 -0
  71. data/doc/images/plugin.png +0 -0
  72. data/doc/images/ruby.png +0 -0
  73. data/doc/images/tag_blue.png +0 -0
  74. data/doc/images/tag_green.png +0 -0
  75. data/doc/images/transparent.png +0 -0
  76. data/doc/images/wrench.png +0 -0
  77. data/doc/images/wrench_orange.png +0 -0
  78. data/doc/images/zoom.png +0 -0
  79. data/doc/index.html +174 -0
  80. data/doc/js/darkfish.js +114 -0
  81. data/doc/js/navigation.js +105 -0
  82. data/doc/js/navigation.js.gz +0 -0
  83. data/doc/js/search.js +110 -0
  84. data/doc/js/search_index.js +1 -0
  85. data/doc/js/search_index.js.gz +0 -0
  86. data/doc/js/searcher.js +229 -0
  87. data/doc/js/searcher.js.gz +0 -0
  88. data/doc/table_of_contents.html +1047 -0
  89. data/lib/data_access/DB_client/DB_client.rb +26 -0
  90. data/lib/deep_dup/deep_dup.rb +14 -0
  91. data/lib/logger/logger.rb +64 -0
  92. data/lib/models/binary_tree/binary_tree.rb +163 -0
  93. data/lib/models/binary_tree/binary_tree_iterator.rb +36 -0
  94. data/lib/models/data_list/data_list.rb +97 -0
  95. data/lib/models/data_list/data_list_student_short.rb +16 -0
  96. data/lib/models/data_storage_strategy/JSON_storage_strategy.rb +20 -0
  97. data/lib/models/data_storage_strategy/YAML_storage_strategy.rb +20 -0
  98. data/lib/models/data_storage_strategy/data_storage_strategy.rb +11 -0
  99. data/lib/models/data_table/data_table.rb +52 -0
  100. data/lib/models/filter/filter.rb +5 -0
  101. data/lib/models/filter/filter_decorator.rb +14 -0
  102. data/lib/models/filter/sort_decorator.rb +15 -0
  103. data/lib/models/filter/student_filters/contact_sort_decorator.rb +50 -0
  104. data/lib/models/filter/student_filters/field_filter_decorator.rb +34 -0
  105. data/lib/models/filter/student_filters/full_name_filter_decorator.rb +26 -0
  106. data/lib/models/filter/student_filters/full_name_sort_decorator.rb +32 -0
  107. data/lib/models/filter/student_filters/git_sort_decorator.rb +35 -0
  108. data/lib/models/filter/student_filters/has_not_field_filter_decorator.rb +24 -0
  109. data/lib/models/person/person.rb +72 -0
  110. data/lib/models/student/student.rb +204 -0
  111. data/lib/models/student_short/student_short.rb +98 -0
  112. data/lib/models/students_list/students_list.rb +32 -0
  113. data/lib/models/students_list/students_list_DB.rb +95 -0
  114. data/lib/models/students_list/students_list_file.rb +134 -0
  115. data/lib/models/students_list/students_list_file_adapter.rb +45 -0
  116. data/lib/models/students_list/students_list_interface.rb +25 -0
  117. data/lib/presenters/base_presenters/base_presenter.rb +26 -0
  118. data/lib/presenters/base_presenters/student_list_presenter.rb +273 -0
  119. data/lib/presenters/edit_student/add_student_presenter.rb +46 -0
  120. data/lib/presenters/edit_student/edit_contacts_presenter.rb +36 -0
  121. data/lib/presenters/edit_student/edit_git_presenter.rb +28 -0
  122. data/lib/presenters/edit_student/edit_student_presenter.rb +109 -0
  123. data/lib/presenters/edit_student/replace_student_presenter.rb +37 -0
  124. data/lib/student_mvp/version.rb +5 -0
  125. data/lib/student_mvp.rb +8 -0
  126. data/sig/student_mvp.rbs +4 -0
  127. metadata +253 -0
@@ -0,0 +1,32 @@
1
+ require_relative '../filter_decorator.rb'
2
+
3
+ class Full_name_sort_decorator < Filter_decorator
4
+ def initialize(filter, order)
5
+ super(filter)
6
+ self.order = order
7
+ end
8
+
9
+ def apply(filtering_obj)
10
+ if filtering_obj.is_a?(Array)
11
+ filtered_students = super(filtering_obj)
12
+
13
+ if filtered_students.nil?
14
+ return []
15
+ end
16
+
17
+ sorted_students = filtered_students.sort_by do |student|
18
+ "#{student.first_name} #{student.name} #{student.patronymic}".downcase
19
+ end
20
+
21
+ sorted_students.reverse! if self.order == :desc
22
+
23
+ return sorted_students
24
+ else
25
+ query = super(filtering_obj)
26
+ "#{query} ORDER BY CONCAT(first_name, ' ', name, ' ', patronymic) #{self.order == :asc ? 'ASC' : 'DESC'}"
27
+ end
28
+ end
29
+
30
+ private
31
+ attr_accessor :order
32
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../filter_decorator.rb'
2
+
3
+ class Git_sort_decorator < Filter_decorator
4
+ def initialize(filter, order)
5
+ super(filter)
6
+ self.order = order
7
+ end
8
+
9
+ def apply(filtering_obj)
10
+ if filtering_obj.is_a?(Array)
11
+ filtered_students = super(filtering_obj)
12
+ if filtered_students.nil?
13
+ return []
14
+ end
15
+
16
+ sorted_students = filtered_students.sort_by do |student|
17
+ value = student.git
18
+ String(value.nil? || value.empty? ? Float::INFINITY : value.downcase)
19
+ end
20
+ sorted_students.reverse! if self.order == :desc
21
+ sorted_students
22
+ else
23
+ query = super(filtering_obj)
24
+ "#{query} ORDER BY
25
+ CASE
26
+ WHEN git IS NULL OR git = '' THEN 1
27
+ ELSE 0
28
+ END,
29
+ git #{self.order == :asc ? 'ASC' : 'DESC' }"
30
+ end
31
+ end
32
+
33
+ private
34
+ attr_accessor :order
35
+ end
@@ -0,0 +1,24 @@
1
+ require_relative '../filter_decorator.rb'
2
+
3
+ class Has_not_field_filter_decorator < Filter_decorator
4
+ def initialize(filter, field)
5
+ super(filter)
6
+ self.field = field
7
+ end
8
+
9
+ def apply(filtering_obj)
10
+ if filtering_obj.is_a?(Array)
11
+ super(filtering_obj).select do |student|
12
+ student_value = student.send(self.field).to_s
13
+ student_value.nil? || student_value.empty?
14
+ end
15
+ else
16
+ query = super(filtering_obj)
17
+ condition = query.include?("WHERE") ? "AND" : "WHERE"
18
+ "#{query} #{condition} (#{field} = '' OR #{field} IS NULL)"
19
+ end
20
+ end
21
+
22
+ private
23
+ attr_accessor :field
24
+ end
@@ -0,0 +1,72 @@
1
+ class Person
2
+ attr_reader :id, :git
3
+
4
+ # checking for git availability
5
+ def validate_git?
6
+ !self.git.nil?
7
+ end
8
+
9
+ # validate git
10
+ def validate?
11
+ self.validate_git?
12
+ end
13
+
14
+ protected
15
+
16
+ # phone number validation
17
+ def self.valid_phone_number?(phone_number)
18
+ phone_number.nil? || phone_number == "" || phone_number =~ /^(?:\+7|8)[\s-]?(?:\(?\d{3}\)?[\s-]?)\d{3}[\s-]?\d{2}[\s-]?\d{2}$/
19
+ end
20
+
21
+ # telegram validation
22
+ def self.valid_telegram?(telegram)
23
+ telegram.nil? || telegram == "" || telegram =~ /@[a-zA-Z0-9_]{5,}$/
24
+ end
25
+
26
+ # git link validation
27
+ def self.valid_git?(git)
28
+ git.nil? || git == "" || git =~ %r{^https?://github\.com/[a-zA-Z0-9_\-]+$}
29
+ end
30
+
31
+ # email validation
32
+ def self.valid_email?(email)
33
+ email.nil? || email == "" || email =~ /^[\w+_.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
34
+ end
35
+
36
+ # names validation
37
+ def self.valid_name?(name)
38
+ name =~ /^[А-ЯЁ][а-яё]{1,}(-[А-ЯЁ][а-яё]{1,})?$/
39
+ end
40
+
41
+ # git setter
42
+ def git=(git)
43
+ unless self.class.valid_git?(git)
44
+ raise ArgumentError, "Wrong git link format"
45
+ end
46
+ @git = git
47
+ end
48
+
49
+ # returning hash
50
+ def self.parse_string(string)
51
+ data = string.split(',')
52
+ hash = {}
53
+
54
+ data.each do |x|
55
+ pair = x.strip.split(':')
56
+ if pair[0] && !pair[0].strip.empty? && pair[1] then
57
+ hash[pair[0].strip] = pair[1].strip + (pair[2] ? ":#{pair[2].strip}" : '')
58
+ else
59
+ raise ArgumentError, "Wrong string format"
60
+ end
61
+ end
62
+
63
+ hash
64
+ end
65
+
66
+ def get_any_contact
67
+ end
68
+
69
+ def set_contacts
70
+ end
71
+
72
+ end
@@ -0,0 +1,204 @@
1
+ require_relative '../person/person.rb'
2
+ require 'date'
3
+
4
+ class Student < Person
5
+ include Comparable
6
+ attr_reader :first_name, :name, :patronymic, :telegram, :email, :phone_number, :birthdate
7
+ attr_writer :id
8
+ attr_accessor :key_type
9
+
10
+ # constructor
11
+ def initialize(first_name:, name:, patronymic:, birthdate:, id: nil, telegram: nil, phone_number: nil, email: nil, git: nil, key_type: :birthdate)
12
+ self.id = id
13
+ self.first_name = first_name
14
+ self.name = name
15
+ self.patronymic = patronymic
16
+ self.git = git
17
+ self.set_contacts(email: email, telegram: telegram, phone_number: phone_number)
18
+ self.birthdate = birthdate
19
+ self.key_type = key_type
20
+ end
21
+
22
+ # constructor_from_string
23
+ def self.new_from_string(string)
24
+ hash = self.parse_string(string)
25
+
26
+ self.new(
27
+ id: hash['id'].to_i,
28
+ first_name: hash['first_name'],
29
+ name: hash['name'],
30
+ patronymic: hash['patronymic'],
31
+ telegram: hash['telegram'],
32
+ email: hash['email'],
33
+ phone_number: hash['phone_number'],
34
+ git: hash['git'],
35
+ birthdate: hash['birthdate']
36
+ )
37
+ end
38
+
39
+ # constructor_from_hash
40
+ def self.new_from_hash(hash)
41
+ self.new(**hash.transform_keys(&:to_sym))
42
+ end
43
+
44
+ # to string
45
+ def to_s
46
+ "#{"-------------------\nID: #{self.id}\n" unless self.id.nil?}First Name: #{ self.first_name }\nName: #{ self.name }\nPatronymic: #{ self.patronymic }\nBithdate: #{ self.birthdate }\n#{"Phone Number: #{ self.phone_number }\n" unless self.phone_number.nil?}#{"Telegram: #{ self.phone_number }\n" unless self.telegram}#{"Email: #{ self.email }\n" unless self.email.nil?}#{"Git: #{ self.git }\n" unless self.git.nil?}-------------------"
47
+ end
48
+
49
+ # to hash
50
+ def to_h
51
+ { id: self.id, first_name: self.first_name, name: self.name, patronymic: self.patronymic,
52
+ birthdate: self.birthdate, telegram: self.telegram, email: self.email, phone_number: self.phone_number, git: self.git }
53
+ end
54
+
55
+ # get short info in string
56
+ def get_info
57
+ "#{get_full_name}, git: #{self.git}, #{get_any_contact}"
58
+ end
59
+
60
+ # get full name in string
61
+ def get_full_name
62
+ "full_name: #{self.first_name} #{self.name[0]}.#{self.patronymic[0]}."
63
+ end
64
+
65
+ # get any contact in string
66
+ def get_any_contact
67
+ if telegram then
68
+ "telegram: #{self.telegram}"
69
+ elsif email
70
+ "email: #{self.email}"
71
+ elsif phone_number
72
+ "phone_number: #{self.phone_number}"
73
+ else
74
+ "no contact provided"
75
+ end
76
+ end
77
+
78
+ # to string
79
+ def to_line_s
80
+ data = []
81
+ data << "first_name: #{self.first_name}"
82
+ data << "name: #{self.name}"
83
+ data << "patronymic: #{self.patronymic}"
84
+ data << "git: #{self.git}"
85
+ if self.id then
86
+ data << "id: #{self.id}"
87
+ end
88
+ if self.telegram then
89
+ data << "telegram: #{self.telegram}"
90
+ end
91
+ if self.email then
92
+ data << "email: #{self.email}"
93
+ end
94
+ if self.phone_number then
95
+ data << "phone_number: #{phone_number}"
96
+ end
97
+ data.join(', ')
98
+ end
99
+
100
+ # checking for contacts availability
101
+ def validate_contacts?
102
+ !self.telegram.nil? || !self.email.nil? || !self.phone_number.nil?
103
+ end
104
+
105
+ # validate git and contacts
106
+ def validate?
107
+ super && self.validate_contacts?
108
+ end
109
+
110
+ # key for binary tree
111
+ def key
112
+ case self.key_type
113
+ when :birthdate
114
+ self.birthdate
115
+ when :id
116
+ self.id
117
+ when :full_name
118
+ self.get_full_name
119
+ when :contacts
120
+ self.get_any_contact
121
+ when :git
122
+ self.git
123
+ when :email
124
+ self.email
125
+ when :phone_number
126
+ self.phone_number
127
+ when :telegram
128
+ self.telegram
129
+ else
130
+ raise ArgumentError, "Unknown key_type"
131
+ end
132
+ end
133
+
134
+ def <=>(other)
135
+ if self.key.nil? && other.key.nil?
136
+ 0
137
+ elsif self.key.nil?
138
+ 1
139
+ elsif other.key.nil?
140
+ -1
141
+ else
142
+ self.key <=> other.key
143
+ end
144
+ end
145
+
146
+ def self.valid_birthdate?(birthdate)
147
+ valid = (birthdate =~ /^\d{2}\.\d{2}\.\d{4}$/)
148
+ begin
149
+ Date.parse(birthdate)
150
+ rescue
151
+ false
152
+ end
153
+ valid
154
+ end
155
+
156
+ private
157
+
158
+ # birthdate setter
159
+ def birthdate=(birthdate)
160
+ @birthdate = birthdate.is_a?(String) ? Date.parse(birthdate) : birthdate
161
+ end
162
+
163
+ # first name setter
164
+ def first_name=(first_name)
165
+ unless self.class.valid_name?(first_name)
166
+ raise ArgumentError, "Wrong first name format"
167
+ end
168
+ @first_name = first_name
169
+ end
170
+
171
+ #name setter
172
+ def name=(name)
173
+ unless self.class.valid_name?(name)
174
+ raise ArgumentError, "Wrong name format"
175
+ end
176
+ @name = name
177
+ end
178
+
179
+ # patronymic setter
180
+ def patronymic=(patronymic)
181
+ unless self.class.valid_name?(patronymic)
182
+ raise ArgumentError, "Wrong patronymic format"
183
+ end
184
+ @patronymic = patronymic
185
+ end
186
+
187
+ # contacts setter
188
+ def set_contacts(contacts)
189
+ unless self.class.valid_phone_number?(contacts[:phone_number])
190
+ raise ArgumentError, "Wrong phone number format"
191
+ end
192
+ @phone_number = contacts[:phone_number]
193
+
194
+ unless self.class.valid_telegram?(contacts[:telegram])
195
+ raise ArgumentError, "Wrong telegram format"
196
+ end
197
+ @telegram = contacts[:telegram]
198
+
199
+ unless self.class.valid_email?(contacts[:email])
200
+ raise ArgumentError, "Wrong Email format"
201
+ end
202
+ @email = contacts[:email]
203
+ end
204
+ end
@@ -0,0 +1,98 @@
1
+ require_relative '../person/person.rb'
2
+
3
+ class Student_short < Person
4
+ attr_reader :id, :full_name
5
+ private_class_method :new
6
+
7
+ def initialize(full_name:, git:, contact:, id: nil)
8
+ self.id = id
9
+ self.full_name = full_name
10
+ self.git = git
11
+ self.set_contacts(contact)
12
+ end
13
+
14
+ # constructor from Student object
15
+ def self.new_from_student_obj(student)
16
+ self.new(
17
+ id: student.id.to_i,
18
+ full_name: student.get_full_name.slice(11..-1),
19
+ git: student.git,
20
+ contact: student.get_any_contact
21
+ )
22
+ end
23
+
24
+ # constructor from string
25
+ def self.new_from_string(id, string)
26
+ hash = self.parse_string(string)
27
+ contact = ''
28
+ if hash['telegram'] then
29
+ contact = "telegram: #{hash['telegram']}"
30
+ elsif hash['email']
31
+ contact = "email: #{hash['email']}"
32
+ else
33
+ contact = "phone_number #{hash['phone_number']}"
34
+ end
35
+
36
+ self.new(
37
+ id: id.to_i,
38
+ full_name: hash['full_name'],
39
+ git: hash['git'],
40
+ contact: contact
41
+ )
42
+ end
43
+
44
+ # checking for contacts availability
45
+ def validate_contacts?
46
+ !(self.get_any_contact.nil? || self.get_any_contact == "")
47
+ end
48
+
49
+ # validate git and contacts
50
+ def validate?
51
+ super && self.validate_contacts?
52
+ end
53
+
54
+ def get_any_contact
55
+ @contact
56
+ end
57
+
58
+ private
59
+ attr_writer :id
60
+
61
+ def set_contacts(contact)
62
+ if contact == 'no contact provided'
63
+ @contact = nil
64
+ return
65
+ end
66
+ if contact.start_with?('telegram:') then
67
+ telegram = contact.slice(9..-1).strip
68
+ unless self.class.valid_telegram?(telegram)
69
+ raise ArgumentError, "Wrong telegram format"
70
+ end
71
+ elsif contact.start_with?('email:')
72
+ email = contact.slice(6..-1).strip
73
+ unless self.class.valid_email?(email)
74
+ raise ArgumentError, "Wrong email format"
75
+ end
76
+ elsif contact.start_with?('phone_number:')
77
+ phone_number = contact.slice(13..-1).strip
78
+ unless self.class.valid_phone_number?(phone_number)
79
+ raise ArgumentError, "Wrong phone number format"
80
+ end
81
+ else
82
+ raise ArgumentError, "Wrong contact format"
83
+ end
84
+ @contact = contact
85
+ end
86
+
87
+ def full_name=(full_name)
88
+ unless self.class.valid_name?(full_name)
89
+ raise ArgumentError, "Wrong name format"
90
+ end
91
+ @full_name = full_name
92
+ end
93
+
94
+ # full name validation
95
+ def self.valid_name?(name)
96
+ name =~ /^[А-ЯЁ][а-яё]{1,}(-[А-ЯЁ][а-яё]{1,})?\s[А-ЯЁ].\s?[А-ЯЁ].$/
97
+ end
98
+ end
@@ -0,0 +1,32 @@
1
+ class Students_list
2
+ def initialize(adapter)
3
+ self.adapter = adapter
4
+ end
5
+
6
+ def get_student_by_id(id)
7
+ self.adapter.get_student_by_id(id)
8
+ end
9
+
10
+ def get_k_n_student_short_list(k, n, filter = nil, data_list = nil)
11
+ self.adapter.get_k_n_student_short_list(k, n, filter, data_list)
12
+ end
13
+
14
+ def add_student(student)
15
+ self.adapter.add_student(student)
16
+ end
17
+
18
+ def replace_student(id, new_student)
19
+ self.adapter.replace_student(id, new_student)
20
+ end
21
+
22
+ def delete_student(id)
23
+ self.adapter.delete_student(id)
24
+ end
25
+
26
+ def get_student_short_count(filter = nil)
27
+ self.adapter.get_student_short_count(filter)
28
+ end
29
+
30
+ private
31
+ attr_accessor :adapter
32
+ end
@@ -0,0 +1,95 @@
1
+ require 'mysql2'
2
+ require_relative '../student/student.rb'
3
+ require_relative '../student_short/student_short.rb'
4
+ require_relative '../data_list/data_list_student_short.rb'
5
+ require_relative '../../data_access/DB_client/DB_client.rb'
6
+ require_relative './students_list_interface.rb'
7
+
8
+ class Students_list_DB < Students_list_interface
9
+ def get_student_by_id(id)
10
+ result = DB_client.instance.query("SELECT * FROM student WHERE id = ?", [id])
11
+ row = result.first
12
+ return nil unless row
13
+
14
+ Student.new_from_hash(row)
15
+ end
16
+
17
+ def get_k_n_student_short_list(k, n, filter = nil, data_list = nil)
18
+ base_query = "SELECT * FROM student"
19
+ filter_query = filter ? filter.apply(base_query) : base_query
20
+ start = (k - 1) * n
21
+
22
+ result = DB_client.instance.query(filter_query + " LIMIT ? OFFSET ?", [n, start])
23
+ students_short = result.map { |row| Student_short.new_from_student_obj(Student.new_from_hash(row)) }
24
+ data_list ||= Data_list_student_short.new(students_short)
25
+ data_list.index = start + 1
26
+ data_list.data = students_short
27
+ data_list
28
+ end
29
+
30
+ def add_student(student)
31
+ query = <<-SQL
32
+ INSERT INTO student (first_name, name, patronymic, birthdate, telegram, email, phone_number, git)
33
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
34
+ SQL
35
+
36
+ begin
37
+ DB_client.instance.query(query, [
38
+ student.first_name,
39
+ student.name,
40
+ student.patronymic,
41
+ student.birthdate,
42
+ student.telegram,
43
+ student.email,
44
+ student.phone_number,
45
+ student.git
46
+ ])
47
+ rescue Mysql2::Error => e
48
+ if e.message.include?('Duplicate entry')
49
+ raise "Student with this unique value already exists - #{e.message}"
50
+ else
51
+ raise e
52
+ end
53
+ end
54
+ end
55
+
56
+ def replace_student(id, new_student)
57
+ query = <<-SQL
58
+ UPDATE student
59
+ SET first_name = ?, name = ?, patronymic = ?, birthdate = ?, telegram = ?, email = ?, phone_number = ?, git = ?
60
+ WHERE id = ?
61
+ SQL
62
+ begin
63
+ DB_client.instance.query(query, [
64
+ new_student.first_name,
65
+ new_student.name,
66
+ new_student.patronymic,
67
+ new_student.birthdate,
68
+ new_student.telegram,
69
+ new_student.email,
70
+ new_student.phone_number,
71
+ new_student.git,
72
+ id
73
+ ])
74
+ rescue Mysql2::Error => e
75
+ if e.message.include?('Duplicate entry')
76
+ raise "Error: Student with this unique value already exists - #{e.message}"
77
+ else
78
+ raise e
79
+ end
80
+ end
81
+ end
82
+
83
+ def delete_student(id)
84
+ query = "DELETE FROM student WHERE id = ?"
85
+ DB_client.instance.query(query, [id])
86
+ end
87
+
88
+ def get_student_short_count(filter = nil)
89
+ base_query = "SELECT COUNT(*) AS count FROM student"
90
+ filter_query = filter ? filter.apply(base_query) : base_query
91
+
92
+ result = DB_client.instance.query(filter_query)
93
+ result.first['count']
94
+ end
95
+ end