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.
- checksums.yaml +7 -0
- data/README.md +35 -0
- data/Rakefile +4 -0
- data/doc/Add_student_presenter.html +238 -0
- data/doc/App_logger.html +386 -0
- data/doc/Base_presenter.html +265 -0
- data/doc/Binary_tree.html +300 -0
- data/doc/Binary_tree_iterator.html +217 -0
- data/doc/Contact_sort_decorator.html +219 -0
- data/doc/DB_client.html +252 -0
- data/doc/Data_list.html +625 -0
- data/doc/Data_list_student_short.html +148 -0
- data/doc/Data_storage_strategy.html +178 -0
- data/doc/Data_table.html +264 -0
- data/doc/Deep_dup.html +152 -0
- data/doc/Edit_contacts_presenter.html +199 -0
- data/doc/Edit_git_presenter.html +192 -0
- data/doc/Edit_student_presenter.html +464 -0
- data/doc/Field_filter_decorator.html +219 -0
- data/doc/Filter.html +148 -0
- data/doc/Filter_decorator.html +209 -0
- data/doc/Full_name_filter_decorator.html +211 -0
- data/doc/Full_name_sort_decorator.html +217 -0
- data/doc/Gemfile.html +98 -0
- data/doc/Git_sort_decorator.html +220 -0
- data/doc/Has_not_field_filter_decorator.html +209 -0
- data/doc/JSON_storage_strategy.html +183 -0
- data/doc/Person.html +511 -0
- data/doc/README_md.html +147 -0
- data/doc/Rakefile.html +94 -0
- data/doc/Replace_student_presenter.html +204 -0
- data/doc/Sort_decorator.html +214 -0
- data/doc/Student.html +755 -0
- data/doc/StudentMvp/Error.html +105 -0
- data/doc/StudentMvp.html +111 -0
- data/doc/Student_list_presenter.html +667 -0
- data/doc/Student_short.html +398 -0
- data/doc/Students_list.html +341 -0
- data/doc/Students_list_DB.html +361 -0
- data/doc/Students_list_file.html +460 -0
- data/doc/Students_list_file_adapter.html +341 -0
- data/doc/Students_list_interface.html +298 -0
- data/doc/YAML_storage_strategy.html +183 -0
- data/doc/bin/setup.html +96 -0
- data/doc/created.rid +44 -0
- data/doc/css/fonts.css +167 -0
- data/doc/css/rdoc.css +662 -0
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +174 -0
- data/doc/js/darkfish.js +114 -0
- data/doc/js/navigation.js +105 -0
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search.js +110 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +229 -0
- data/doc/js/searcher.js.gz +0 -0
- data/doc/table_of_contents.html +1047 -0
- data/lib/data_access/DB_client/DB_client.rb +26 -0
- data/lib/deep_dup/deep_dup.rb +14 -0
- data/lib/logger/logger.rb +64 -0
- data/lib/models/binary_tree/binary_tree.rb +163 -0
- data/lib/models/binary_tree/binary_tree_iterator.rb +36 -0
- data/lib/models/data_list/data_list.rb +97 -0
- data/lib/models/data_list/data_list_student_short.rb +16 -0
- data/lib/models/data_storage_strategy/JSON_storage_strategy.rb +20 -0
- data/lib/models/data_storage_strategy/YAML_storage_strategy.rb +20 -0
- data/lib/models/data_storage_strategy/data_storage_strategy.rb +11 -0
- data/lib/models/data_table/data_table.rb +52 -0
- data/lib/models/filter/filter.rb +5 -0
- data/lib/models/filter/filter_decorator.rb +14 -0
- data/lib/models/filter/sort_decorator.rb +15 -0
- data/lib/models/filter/student_filters/contact_sort_decorator.rb +50 -0
- data/lib/models/filter/student_filters/field_filter_decorator.rb +34 -0
- data/lib/models/filter/student_filters/full_name_filter_decorator.rb +26 -0
- data/lib/models/filter/student_filters/full_name_sort_decorator.rb +32 -0
- data/lib/models/filter/student_filters/git_sort_decorator.rb +35 -0
- data/lib/models/filter/student_filters/has_not_field_filter_decorator.rb +24 -0
- data/lib/models/person/person.rb +72 -0
- data/lib/models/student/student.rb +204 -0
- data/lib/models/student_short/student_short.rb +98 -0
- data/lib/models/students_list/students_list.rb +32 -0
- data/lib/models/students_list/students_list_DB.rb +95 -0
- data/lib/models/students_list/students_list_file.rb +134 -0
- data/lib/models/students_list/students_list_file_adapter.rb +45 -0
- data/lib/models/students_list/students_list_interface.rb +25 -0
- data/lib/presenters/base_presenters/base_presenter.rb +26 -0
- data/lib/presenters/base_presenters/student_list_presenter.rb +273 -0
- data/lib/presenters/edit_student/add_student_presenter.rb +46 -0
- data/lib/presenters/edit_student/edit_contacts_presenter.rb +36 -0
- data/lib/presenters/edit_student/edit_git_presenter.rb +28 -0
- data/lib/presenters/edit_student/edit_student_presenter.rb +109 -0
- data/lib/presenters/edit_student/replace_student_presenter.rb +37 -0
- data/lib/student_mvp/version.rb +5 -0
- data/lib/student_mvp.rb +8 -0
- data/sig/student_mvp.rbs +4 -0
- 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
|