shnaider_carproj 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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +71 -0
  4. data/diagrams/add_owner.jpg +0 -0
  5. data/diagrams/delete_owner.jpg +0 -0
  6. data/diagrams/er.png +0 -0
  7. data/diagrams/owner.jpg +0 -0
  8. data/diagrams/owner.sai2 +0 -0
  9. data/diagrams/start.jpg +0 -0
  10. data/lib/car/controllers/publisher_input_form_controller_create.rb +44 -0
  11. data/lib/car/controllers/publisher_input_form_controller_edit.rb +52 -0
  12. data/lib/car/controllers/publisher_list_controller.rb +99 -0
  13. data/lib/car/tenant_db_data_source.rb +63 -0
  14. data/lib/car/ui/tenant_input_form.rb +69 -0
  15. data/lib/car/ui/tenant_list_view.rb +168 -0
  16. data/lib/controllers/tab_students_controller.rb +43 -0
  17. data/lib/data_sources/car_db_data_source.rb +43 -0
  18. data/lib/data_sources/db_client.rb +34 -0
  19. data/lib/db_config/carshering_config.yaml +5 -0
  20. data/lib/db_config/config.yaml +5 -0
  21. data/lib/db_config/migrations/create_db.sql +3 -0
  22. data/lib/db_config/migrations/create_tables.sql +29 -0
  23. data/lib/db_config/mock_data/mock_data.sql +55 -0
  24. data/lib/models/car.rb +31 -0
  25. data/lib/models/owner.rb +32 -0
  26. data/lib/models/student.rb +102 -0
  27. data/lib/models/student_base.rb +100 -0
  28. data/lib/models/student_short.rb +50 -0
  29. data/lib/models/tenant.rb +40 -0
  30. data/lib/owner/controllers/owner_input_form_controller_create.rb +44 -0
  31. data/lib/owner/controllers/owner_input_form_controller_edit.rb +53 -0
  32. data/lib/owner/controllers/owner_list_controller.rb +107 -0
  33. data/lib/owner/owner_db_data_source.rb +70 -0
  34. data/lib/owner/ui/owner_input_form.rb +69 -0
  35. data/lib/owner/ui/owner_list_view.rb +169 -0
  36. data/lib/repositories/adapters/db_source_adapter.rb +54 -0
  37. data/lib/repositories/adapters/file_source_adapter.rb +37 -0
  38. data/lib/repositories/containers/data_list.rb +74 -0
  39. data/lib/repositories/containers/data_list_student_short.rb +18 -0
  40. data/lib/repositories/containers/data_table.rb +35 -0
  41. data/lib/repositories/data_sources/db_data_source.rb +32 -0
  42. data/lib/repositories/data_sources/file_data_source.rb +75 -0
  43. data/lib/repositories/data_sources/transformers/data_transformer_base.rb +15 -0
  44. data/lib/repositories/data_sources/transformers/data_transformer_json.rb +16 -0
  45. data/lib/repositories/data_sources/transformers/data_transformer_yaml.rb +16 -0
  46. data/lib/repositories/student_repository.rb +32 -0
  47. data/lib/state_holders/list_state_notifier.rb +62 -0
  48. data/lib/tenant/controllers/tenant_input_form_controller_create.rb +44 -0
  49. data/lib/tenant/controllers/tenant_input_form_controller_edit.rb +53 -0
  50. data/lib/tenant/controllers/tenant_list_controller.rb +107 -0
  51. data/lib/tenant/tenant_db_data_source.rb +90 -0
  52. data/lib/tenant/ui/tenant_input_form.rb +69 -0
  53. data/lib/tenant/ui/tenant_list_view.rb +169 -0
  54. data/lib/views/main_window.rb +25 -0
  55. data/lib/views/tab_students.rb +148 -0
  56. data/requirements.docx +0 -0
  57. data/shnaider_carproj.gemspec +15 -0
  58. data/test/car_test.rb +33 -0
  59. data/test/logger.rb +27 -0
  60. data/test/main.rb +5 -0
  61. data/test/owner_test.rb +48 -0
  62. data/test/state_notifier_test.rb +80 -0
  63. data/test/tenant_test.rb +48 -0
  64. metadata +118 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 339fd6dfea18bd5835659ef5aa075a7fae2591cd439df33d4464c0161f7e747f
4
+ data.tar.gz: 9c3c5b97d97868b31c5bd45ce6f5ce1e8f4ad2e1107d4b3d6a6554f9faa52b11
5
+ SHA512:
6
+ metadata.gz: ad32d0f6da08e7ecd1c91035a1eb1aae6ddcba905ccea56c40f25394c01f1d412a02984bcd7f09e7533e1059b8a5e38fb15b01385e5c7201a2d1d31a92da5556
7
+ data.tar.gz: d36c46679bd8d2ae3e57ee147685de2471201d5b278076215c3329e617ced17ec854d4285c667458e3908c6c488f3439d4df38ef85418aa9d0dacf5bf9e996ba
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mysql2"
6
+ gem "glimmer-dsl-libui", "~> 0.7.4"
7
+ gem 'win32api'
8
+ gem "minitest"
9
+ gem "logger"
10
+ gem 'rubocop', group: 'development'
data/Gemfile.lock ADDED
@@ -0,0 +1,71 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ array_include_methods (1.4.0)
5
+ ast (2.4.2)
6
+ chunky_png (1.4.0)
7
+ color (1.8)
8
+ equalizer (0.0.11)
9
+ facets (3.1.0)
10
+ glimmer (2.7.3)
11
+ array_include_methods (~> 1.4.0)
12
+ facets (>= 3.1.0, < 4.0.0)
13
+ glimmer-dsl-libui (0.7.4)
14
+ chunky_png (~> 1.4.0)
15
+ color (~> 1.8)
16
+ equalizer (= 0.0.11)
17
+ glimmer (~> 2.7.3)
18
+ libui (~> 0.1.2.pre)
19
+ os (>= 1.0.0, < 2.0.0)
20
+ perfect-shape (~> 1.0.7)
21
+ rouge (>= 3.26.0, < 4.0.0)
22
+ super_module (~> 1.4.1)
23
+ json (2.6.3)
24
+ libui (0.1.2.pre-x64-mingw)
25
+ logger (1.5.3)
26
+ matrix (0.4.2)
27
+ method_source (1.0.0)
28
+ minitest (5.16.3)
29
+ mysql2 (0.5.5)
30
+ os (1.1.4)
31
+ parallel (1.22.1)
32
+ parser (3.2.2.0)
33
+ ast (~> 2.4.1)
34
+ perfect-shape (1.0.7)
35
+ equalizer (>= 0.0.11, < 1.1.0)
36
+ matrix (>= 0.4.2, < 1.1.0)
37
+ rainbow (3.1.1)
38
+ regexp_parser (2.7.0)
39
+ rexml (3.2.5)
40
+ rouge (3.30.0)
41
+ rubocop (1.50.1)
42
+ json (~> 2.3)
43
+ parallel (~> 1.10)
44
+ parser (>= 3.2.0.0)
45
+ rainbow (>= 2.2.2, < 4.0)
46
+ regexp_parser (>= 1.8, < 3.0)
47
+ rexml (>= 3.2.5, < 4.0)
48
+ rubocop-ast (>= 1.28.0, < 2.0)
49
+ ruby-progressbar (~> 1.7)
50
+ unicode-display_width (>= 2.4.0, < 3.0)
51
+ rubocop-ast (1.28.0)
52
+ parser (>= 3.2.1.0)
53
+ ruby-progressbar (1.13.0)
54
+ super_module (1.4.1)
55
+ method_source (>= 0.8.2, < 1.1.0)
56
+ unicode-display_width (2.4.2)
57
+ win32api (0.1.0)
58
+
59
+ PLATFORMS
60
+ x64-mingw-ucrt
61
+
62
+ DEPENDENCIES
63
+ glimmer-dsl-libui (~> 0.7.4)
64
+ logger
65
+ minitest
66
+ mysql2
67
+ rubocop
68
+ win32api
69
+
70
+ BUNDLED WITH
71
+ 2.4.10
Binary file
Binary file
data/diagrams/er.png ADDED
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'win32api'
4
+
5
+ class OwnerInputFormControllerCreate
6
+ def initialize(parent_controller)
7
+ @parent_controller = parent_controller
8
+ @publisher_rep = OwnerDbDataSource.new
9
+ end
10
+
11
+ def set_view(view)
12
+ @view = view
13
+ end
14
+
15
+ def on_view_created
16
+ # begin
17
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
18
+ # rescue Mysql2::Error::ConnectionError
19
+ # on_db_conn_error
20
+ # end
21
+ end
22
+
23
+ def process_fields(fields)
24
+ begin
25
+ puts fields
26
+ item = Tenant.new(-1, *fields.values)
27
+ puts item
28
+ item = @publisher_rep.add(item)
29
+ @parent_controller.state_notifier.add(item)
30
+ @view.close
31
+ rescue ArgumentError => e
32
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
33
+ api.call(0, e.message, 'Error', 0)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def on_db_conn_error
40
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
41
+ api.call(0, "No connection to DB", "Error", 0)
42
+ @view.close
43
+ end
44
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'win32api'
4
+
5
+ class OwnerInputFormControllerEdit
6
+ def initialize(parent_controller, item)
7
+ @parent_controller = parent_controller
8
+ @item = item
9
+ @publisher_rep = OwnerDbDataSource.new
10
+ end
11
+
12
+ def set_view(view)
13
+ @view = view
14
+ end
15
+
16
+ def on_view_created
17
+ # begin
18
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
19
+ # rescue Mysql2::Error::ConnectionError
20
+ # on_db_conn_error
21
+ # end
22
+
23
+ # @item = @author_rep.get(@item_id)
24
+ # @view.make_readonly(:git, :telegram, :email, :phone)
25
+ populate_fields(@item)
26
+ end
27
+
28
+ def populate_fields(item)
29
+ @view.set_value(:name, item.name)
30
+ @view.set_value(:email, item.email)
31
+ end
32
+
33
+ def process_fields(fields)
34
+ begin
35
+ item = Tenant.new(@item.publisher_id, *fields.values)
36
+ item = @publisher_rep.change(item)
37
+ @parent_controller.state_notifier.replace(@item, item)
38
+ @view.close
39
+ rescue ArgumentError => e
40
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
41
+ api.call(0, e.message, 'Error', 0)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def on_db_conn_error
48
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
49
+ api.call(0, "No connection to DB", "Error", 0)
50
+ @view.close
51
+ end
52
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/state_holders/list_state_notifier'
4
+ require_relative '../ui/tenant_input_form'
5
+ require_relative 'publisher_input_form_controller_create.rb'
6
+ require_relative 'publisher_input_form_controller_edit'
7
+ require_relative '../tenant_db_data_source'
8
+ require 'win32api'
9
+
10
+ class OwnerListController
11
+
12
+ attr_reader :state_notifier
13
+ def initialize(view)
14
+ @view = view
15
+ @state_notifier = ListStateNotifier.new
16
+ @state_notifier.add_listener(@view)
17
+ @publisher_rep = OwnerDbDataSource.new
18
+
19
+ @sort_columns = %w[PublisherID Name Email]
20
+ @sort_by = @sort_columns.first
21
+
22
+ @email_filter_columns = [nil, true, false]
23
+ @email_filter = @email_filter_columns.first
24
+ end
25
+
26
+
27
+
28
+ def on_view_created
29
+ # begin
30
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
31
+ # rescue Mysql2::Error::ConnectionError
32
+ # on_db_conn_error
33
+ # end
34
+ end
35
+
36
+ def show_view
37
+ @view.create.show
38
+ end
39
+
40
+ def show_modal_add
41
+ controller = OwnerInputFormControllerCreate.new(self)
42
+ view = OwnerInputForm.new(controller)
43
+ controller.set_view(view)
44
+ view.create.show
45
+ end
46
+
47
+ def show_modal_edit(current_page, per_page, selected_row)
48
+ # item_num = (current_page - 1) * per_page + selected_row
49
+
50
+ item = @state_notifier.get(selected_row)
51
+
52
+ controller = OwnerInputFormControllerEdit.new(self, item)
53
+ view = OwnerInputForm.new(controller)
54
+ controller.set_view(view)
55
+ view.create.show
56
+ end
57
+
58
+ def delete_selected(current_page, per_page, selected_row)
59
+ begin
60
+ item = @state_notifier.get(selected_row)
61
+ @publisher_rep.delete(item.publisher_id)
62
+ @state_notifier.delete(item)
63
+ rescue
64
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
65
+ api.call(0, "You cannot delete the author because he is associated with some book", "Error", 0)
66
+ end
67
+ end
68
+
69
+ def refresh_data(page, per_page)
70
+ # begin
71
+ # @data_list = @student_rep.paginated_short_students(page, per_page, @data_list)
72
+ # @view.update_student_count(@student_rep.student_count)
73
+ # rescue
74
+ # on_db_conn_error
75
+ # end
76
+ items = @publisher_rep.get_list(per_page, page, @sort_by, 'ASC', @email_filter)
77
+ @state_notifier.set_all(items)
78
+ @view.update_count(@publisher_rep.count)
79
+ end
80
+
81
+ def sort(page, per_page, sort_index)
82
+ @sort_by = @sort_columns[sort_index]
83
+ refresh_data(page, per_page)
84
+ end
85
+
86
+ def filter_email(page, per_page, filter_index)
87
+ @email_filter = @email_filter_columns[filter_index]
88
+ refresh_data(page, per_page)
89
+ end
90
+
91
+
92
+ private
93
+
94
+ def on_db_conn_error
95
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
96
+ api.call(0, "No connection to DB", "Error", 0)
97
+ exit(false)
98
+ end
99
+ end
@@ -0,0 +1,63 @@
1
+ require 'mysql2'
2
+ require_relative '../data_sources/db_client'
3
+ require_relative '../models/ls/car'
4
+
5
+ class CarDbDataSource
6
+ def initialize
7
+ @client = DBClient.instance
8
+ end
9
+
10
+ def add(car)
11
+ query = "INSERT INTO car (Model, OwnerID, TenantID) VALUES ('#{car.model}', #{car.owner_id}', '#{car.tenant_id}')"
12
+ @client.query(query)
13
+ car_id = @client.last_id
14
+ get(car_id)
15
+ end
16
+
17
+ def change(tenant)
18
+ query = "UPDATE car SET Model='#{tenant.name}', Email=#{tenant.email.nil? ? 'NULL' : "'#{tenant.email}'"} WHERE PublisherID=#{tenant.tenant_id}"
19
+ @client.query(query)
20
+ get(tenant.tenant_id)
21
+ end
22
+
23
+ def delete(id)
24
+ query = "DELETE FROM Tenant WHERE TenantID=#{id}"
25
+ @client.query(query)
26
+ end
27
+
28
+ def get(id)
29
+ query = "SELECT * FROM Tenant WHERE TenantID=#{id}"
30
+ result = @client.query(query).first
31
+ if result
32
+ Tenant.new(result[:'TenantID'], result[:'Name'], result[:'Email'])
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ def get_list(page_size, page_num, sort_field, sort_direction, has_email = nil)
39
+ offset = (page_num - 1) * page_size
40
+ query = "SELECT * FROM Tenant"
41
+
42
+ if has_email == true
43
+ query += " WHERE Email IS NOT NULL"
44
+ elsif has_email == false
45
+ query += " WHERE Email IS NULL"
46
+ end
47
+
48
+ query += " ORDER BY #{sort_field} #{sort_direction} LIMIT #{page_size} OFFSET #{offset}"
49
+
50
+ results = @client.query(query)
51
+ tenants = []
52
+ results.each do |result|
53
+ tenants << Tenant.new(result[:'TenantID'], result[:'Name'], result[:'Email'])
54
+ end
55
+ tenants
56
+ end
57
+
58
+ def count
59
+ query = "SELECT COUNT(*) FROM Tenant"
60
+ result = @client.query(query).first
61
+ result[:'COUNT(*)']
62
+ end
63
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require_relative '../controllers/publisher_input_form_controller_create.rb'
5
+ require './lib/models/author'
6
+ require 'win32api'
7
+
8
+ class OwnerInputForm
9
+ include Glimmer
10
+
11
+ def initialize(controller, existing_student = nil)
12
+ @item = existing_student.to_hash unless existing_student.nil?
13
+ @controller = controller
14
+ @entries = {}
15
+ end
16
+
17
+ def on_create
18
+ @controller.on_view_created
19
+ end
20
+
21
+ def create
22
+ @root_container = window('Издатель', 300, 70) {
23
+ resizable false
24
+
25
+ vertical_box {
26
+ @student_form = form {
27
+ stretchy false
28
+
29
+ fields = [[:name, 'Название'], [:email, 'Почта']]
30
+
31
+ fields.each do |field|
32
+ @entries[field[0]] = entry {
33
+ label field[1]
34
+ }
35
+ end
36
+ }
37
+
38
+ button('Сохранить') {
39
+ stretchy false
40
+
41
+ on_clicked {
42
+ values = @entries.transform_values { |v| v.text.force_encoding("utf-8").strip }
43
+ values.transform_values! { |v| v.empty? ? nil : v}
44
+
45
+ @controller.process_fields(values)
46
+ }
47
+ }
48
+ }
49
+ }
50
+ on_create
51
+ @root_container
52
+ end
53
+
54
+ def set_value(field, value)
55
+ return unless @entries.include?(field)
56
+
57
+ @entries[field].text = value
58
+ end
59
+
60
+ def make_readonly(*fields)
61
+ fields.each do |field|
62
+ @entries[field].read_only = true
63
+ end
64
+ end
65
+
66
+ def close
67
+ @root_container.destroy
68
+ end
69
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require_relative '../controllers/tenant_list_controller'
5
+ require_relative 'tenant_input_form'
6
+
7
+ class TenantListView
8
+ include Glimmer
9
+
10
+ PAGE_SIZE = 20
11
+
12
+ def initialize
13
+ @controller = TenantListController.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(tenants)
33
+ @items = []
34
+
35
+ i = 0
36
+ item_num = 0
37
+ tenants.each do |tenant|
38
+ i += 1
39
+ item_num = ((@current_page - 1) * PAGE_SIZE) + i
40
+ @items << Struct.new(:№, :id, :название, :почта).new(item_num, publisher.publisher_id, publisher.name, publisher.email)
41
+ end
42
+
43
+ @table.model_array = @items
44
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
45
+ end
46
+
47
+ def update_count(new_cnt)
48
+ @total_count = new_cnt
49
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
50
+ end
51
+
52
+ def create
53
+
54
+ root_container = horizontal_box {
55
+ # Секция 1
56
+ vertical_box {
57
+ stretchy false
58
+
59
+ vertical_box {
60
+ stretchy false
61
+
62
+ label {
63
+ text 'Почта'
64
+ }
65
+ combobox { |c|
66
+ items ['Не важно','Есть','Нет']
67
+ selected 0
68
+ on_selected do
69
+ @controller.filter_email(@current_page, PAGE_SIZE, c.selected)
70
+ end
71
+ }
72
+
73
+ label {
74
+ text 'Сортировка'
75
+ }
76
+ combobox { |c|
77
+ items ['ID','Название','Почта']
78
+ selected 0
79
+ on_selected do
80
+ @controller.sort(@current_page, PAGE_SIZE, c.selected)
81
+ end
82
+ }
83
+ }
84
+
85
+
86
+ }
87
+
88
+ # Секция 2
89
+ vertical_box {
90
+ @table = refined_table(
91
+ table_editable: false,
92
+ filter: lambda do |row_hash, query|
93
+ utf8_query = query.force_encoding("utf-8")
94
+ row_hash['Имя автора'].include?(utf8_query)
95
+ end,
96
+ table_columns: {
97
+ '№' => :text,
98
+ 'ID' => :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,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './views/main_window'
4
+ require './repositories/student_repository'
5
+ require './repositories/adapters/db_source_adapter'
6
+ require './repositories/containers/data_list_student_short'
7
+ require 'win32api'
8
+
9
+ class TabStudentsController
10
+ def initialize(view)
11
+ @view = view
12
+ @data_list = DataListStudentShort.new([])
13
+ @data_list.add_listener(@view)
14
+ end
15
+
16
+ def on_view_created
17
+ begin
18
+ @student_rep = StudentRepository.new(DBSourceAdapter.new)
19
+ rescue Mysql2::Error::ConnectionError
20
+ on_db_conn_error
21
+ end
22
+ end
23
+
24
+ def show_view
25
+ @view.create.show
26
+ end
27
+
28
+ def refresh_data(page, per_page)
29
+ begin
30
+ @data_list = @student_rep.paginated_short_students(page, per_page, @data_list)
31
+ @view.update_count(@student_rep.student_count)
32
+ rescue
33
+ on_db_conn_error
34
+ end
35
+ end
36
+
37
+ def on_db_conn_error
38
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
39
+ api.call(0, "No connection to DB", "Error", 0)
40
+ # TODO: Возможность переключения на JSON помимо exit
41
+ exit(false)
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ require 'mysql2'
2
+ require_relative 'db_client'
3
+ class CarDbDataSource
4
+ def initialize
5
+ @client = DBClient.instance
6
+ end
7
+
8
+ def add(car)
9
+ query = "INSERT INTO Car (CarID, Model, OwnerID, TenantID) VALUES (#{car.id}, '#{car.title}', #{car.owner_id}, #{car.tenant_id})"
10
+ @client.query(query)
11
+ end
12
+
13
+ def change(car)
14
+ query = "UPDATE Car SET Title='#{car.title}', OwnerID=#{car.owner_id}, TenantID=#{car.tenant_id} WHERE CarID=#{car.id}"
15
+ @client.query(query)
16
+ end
17
+
18
+ def delete(id)
19
+ query = "DELETE FROM Car WHERE CarID=#{id}"
20
+ @client.query(query)
21
+ end
22
+
23
+ def get(id)
24
+ query = "SELECT * FROM Car WHERE CarID=#{id}"
25
+ result = @client.query(query).first
26
+ if result
27
+ Car.new(result['CarID'], result['Model'], result['OwnerID'], result['TenantID'])
28
+ else
29
+ nil
30
+ end
31
+ end
32
+
33
+ def get_list(page_size, page_num, sort_field, sort_direction)
34
+ offset = (page_num - 1) * page_size
35
+ query = "SELECT * FROM Car ORDER BY #{sort_field} #{sort_direction} LIMIT #{page_size} OFFSET #{offset}"
36
+ results = @client.query(query)
37
+ cars = []
38
+ results.each do |result|
39
+ cars << Car.new(result['CarID'], result['Model'], result['OwnerID'], result['TenantID'])
40
+ end
41
+ cars
42
+ end
43
+ end