rails-crud-tools 0.6.18 → 0.6.20

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.
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zip"
4
+ require_relative "crud_logger"
5
+ require_relative "constants"
6
+ require "fileutils"
7
+
8
+ module Rails
9
+ module Crud
10
+ module Tools
11
+ # The OperationsLogger module is responsible for logging CRUD operations in controllers and jobs.
12
+ # It provides methods to log request and job details, and to write CRUD operations to an Excel file.
13
+ module OperationsLogger
14
+ # コントローラのCRUD操作をログ出力する
15
+ def log_crud_operations
16
+ config = CrudConfig.instance.config
17
+ if config.enabled
18
+ CrudConfig.instance.load_config
19
+ log_request_details
20
+ Thread.current[:crud_request] = request
21
+ end
22
+
23
+ yield
24
+
25
+ if config.enabled
26
+ key = "#{controller_path}##{action_name}"
27
+ method = request.request_method
28
+ if CrudOperations.instance.table_operations_present?(method, key)
29
+ CrudOperations.instance.log_operations(method, key)
30
+ log_and_write_operations(method, key)
31
+ end
32
+ end
33
+ ensure
34
+ Thread.current[:crud_request] = nil
35
+ end
36
+
37
+ # ジョブのCRUD操作をログ出力する
38
+ def log_crud_operations_for_job
39
+ config = CrudConfig.instance.config
40
+ if config.enabled
41
+ CrudConfig.instance.load_config
42
+ log_job_details
43
+ key = self.class.name
44
+ Thread.current[:crud_sidekiq_job_class] = key
45
+ end
46
+
47
+ yield
48
+
49
+ if config.enabled && CrudOperations.instance.table_operations_present?(Constants::DEFAULT_METHOD, key)
50
+ CrudOperations.instance.log_operations(Constants::DEFAULT_METHOD, key)
51
+ log_and_write_operations(Constants::DEFAULT_METHOD, key)
52
+ end
53
+ ensure
54
+ Thread.current[:crud_sidekiq_job_class] = nil
55
+ end
56
+
57
+ # xlsxファイルの最終更新者を更新する
58
+ def set_last_modified_by(file_path, modifier_name)
59
+ CrudLogger.logger.debug "Starting to read/write ZIP file: #{file_path}"
60
+ CrudLogger.logger.debug "File size: #{File.size(file_path)}"
61
+
62
+ File.open(file_path, "r+") do |f|
63
+ f.flock(File::LOCK_EX)
64
+ begin
65
+ Zip::File.open(file_path) do |zip_file|
66
+ doc_props = zip_file.find_entry("docProps/core.xml")
67
+ if doc_props
68
+ content = doc_props.get_input_stream.read
69
+ updated_content = if content.include?("<cp:lastModifiedBy>")
70
+ content.sub(
71
+ %r{<cp:lastModifiedBy>.*?</cp:lastModifiedBy>},
72
+ "<cp:lastModifiedBy>#{modifier_name}</cp:lastModifiedBy>"
73
+ )
74
+ else
75
+ content.sub(
76
+ %r{</cp:coreProperties>},
77
+ "<cp:lastModifiedBy>#{modifier_name}</cp:lastModifiedBy></cp:coreProperties>"
78
+ )
79
+ end
80
+ zip_file.get_output_stream("docProps/core.xml") { |f| f.write(updated_content) }
81
+ CrudLogger.logger.info "Set the last modifier to #{modifier_name}."
82
+ else
83
+ CrudLogger.logger.warn "docProps/core.xml was not found."
84
+ end
85
+ end
86
+ ensure
87
+ f.flock(File::LOCK_UN)
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+
94
+ # リクエストの詳細をログ出力する
95
+ def log_request_details
96
+ method = request.request_method
97
+ CrudLogger.logger.info "******************** Method: #{method}, Controller: #{controller_path}, Action: #{action_name}, Key: #{controller_path}##{action_name} ********************"
98
+ end
99
+
100
+ # ジョブの詳細をログ出力する
101
+ def log_job_details
102
+ job_name = self.class.name
103
+ CrudLogger.logger.info "******************** Job: #{job_name} ********************"
104
+ end
105
+
106
+ # ExcelファイルにCRUD操作を書き込む
107
+ def log_and_write_operations(method, key)
108
+ CrudData.instance.reload_if_needed
109
+ sheet = CrudData.instance.crud_sheet
110
+
111
+ # フラグを初期化
112
+ contents_changed = false
113
+
114
+ CrudOperations.instance.table_operations[method][key].each_key do |table_name|
115
+ row = CrudData.instance.crud_rows[method][key]
116
+ col = CrudData.instance.crud_cols[table_name]
117
+
118
+ # colまたはrowが存在しない場合にログ出力してスキップ
119
+ unless row && col
120
+ CrudLogger.logger.warn "Row or Column not found for table: #{table_name}, method: #{method}, key: #{key}, row: #{row}, col: #{col}"
121
+ next
122
+ end
123
+
124
+ # sheet[row][col]がnilの場合に警告文を出力し、空文字列として処理を進める
125
+ cell = sheet[row][col]
126
+ if cell.nil?
127
+ cell = sheet.add_cell(row, col, "")
128
+ CrudLogger.logger.warn "Cell not found at row: #{row}, col: #{col} for table: #{table_name}, method: #{method}, key: #{key}. Adding new cell."
129
+ existing_value = ""
130
+ else
131
+ existing_value = cell.value || ""
132
+ end
133
+
134
+ # 新しい値と既存の値を結合し、重複を排除
135
+ new_value = CrudOperations.instance.table_operations[method][key][table_name].join
136
+ merged_value = (existing_value.chars + new_value.chars).uniq
137
+
138
+ # CRUDの順序に並び替え
139
+ crud_order = %w[C R U D]
140
+ sorted_value = merged_value.sort_by { |char| crud_order.index(char) }.join
141
+
142
+ # 値が変化した場合のみ change_contents を実行
143
+ if cell.value != sorted_value
144
+ cell.change_contents(sorted_value)
145
+ contents_changed = true
146
+ end
147
+ end
148
+
149
+ return unless contents_changed
150
+
151
+ Thread.new do
152
+ update_crud_file
153
+ rescue StandardError => e
154
+ CrudLogger.logger.error "Failed to update #{CrudConfig.instance.config.crud_file_path}: #{e.message}\n#{e.backtrace.join("\n")}"
155
+ end
156
+ end
157
+
158
+ def update_crud_file
159
+ # バックアップを作成
160
+ if File.size(CrudConfig.instance.config.crud_file_path).positive?
161
+ backup_path = "#{CrudConfig.instance.config.crud_file_path}.bak"
162
+ FileUtils.cp(CrudConfig.instance.config.crud_file_path, backup_path)
163
+ end
164
+
165
+ File.open(CrudConfig.instance.config.crud_file_path, "r+") do |crud_file|
166
+ crud_file.flock(File::LOCK_EX)
167
+ begin
168
+ # Excelファイルを書き込む
169
+ CrudData.instance.workbook.write(crud_file)
170
+ timestamp = File.mtime(crud_file)
171
+ # タイムスタンプを更新する
172
+ CrudData.instance.last_loaded_time = timestamp
173
+ CrudLogger.logger.info "Updated timestamp: #{timestamp}"
174
+ ensure
175
+ crud_file.flock(File::LOCK_UN)
176
+ end
177
+ end
178
+
179
+ # 最終更新者を設定
180
+ set_last_modified_by(CrudConfig.instance.config.crud_file_path, CrudData.instance.process_id)
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/railtie"
4
+ require_relative "crud_operations_logger"
5
+
6
+ module Rails
7
+ module Crud
8
+ module Tools
9
+ # The Railtie class is responsible for adding custom initialization code to a Rails application.
10
+ # It includes filters for logging CRUD operations in controllers and jobs.
11
+ class Railtie < ::Rails::Railtie
12
+ initializer "rails-crud.add_after_action" do
13
+ ActiveSupport.on_load(:action_controller) do
14
+ include Rails::Crud::Tools::OperationsLogger
15
+
16
+ # 全てのコントローラにafter_actionフィルタを追加
17
+ ActionController::Base.class_eval do
18
+ around_action :log_crud_operations
19
+ end
20
+
21
+ # APIモードの場合はActionController::APIにも追加
22
+ ActionController::API.class_eval do
23
+ around_action :log_crud_operations
24
+ end
25
+ end
26
+
27
+ # ActiveJobにもフィルタを追加
28
+ ActiveSupport.on_load(:active_job) do
29
+ include Rails::Crud::Tools::OperationsLogger
30
+
31
+ # 全てのジョブにaround_performフィルタを追加
32
+ ActiveJob::Base.class_eval do
33
+ around_perform :log_crud_operations_for_job
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Crud
5
+ module Tools
6
+ VERSION = "0.6.20"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubyXL"
4
+ require "rubyXL/convenience_methods/cell"
5
+ require "rubyXL/convenience_methods/color"
6
+ require "rubyXL/convenience_methods/font"
7
+ require "rubyXL/convenience_methods/workbook"
8
+ require "rubyXL/convenience_methods/worksheet"
9
+ require_relative "tools/crud_operations"
10
+ require_relative "tools/crud_config"
11
+ require_relative "tools/crud_notifications"
12
+ require_relative "tools/railtie"
13
+ require_relative "tools/crud_data"
14
+
15
+ module Rails
16
+ module Crud
17
+ # The Tools module provides utility methods for setting up notifications and processing SQL queries.
18
+ # It includes methods to subscribe to ActiveSupport notifications and handle different types of SQL operations.
19
+ module Tools
20
+ def self.setup
21
+ unless File.exist?(CrudConfig.config_path)
22
+ puts "The .crudconfig.yml file is required. Please run `bundle exec crud init`."
23
+ return
24
+ end
25
+
26
+ unless File.exist?(CrudConfig.instance.config.crud_file_path)
27
+ puts "The CRUD file is required. Please run `bundle exec crud gen crud`."
28
+ return
29
+ end
30
+
31
+ CrudData.instance.process_id = "rails-crud-tools-#{Time.now.strftime("%Y%m%d%H%M%S")}"
32
+ CrudData.instance.load_crud_data
33
+ setup_notifications
34
+ end
35
+
36
+ setup unless ENV["SKIP_CRUD_SETUP"] == "true"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,6 @@
1
+ module Rails
2
+ module Crud
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-crud-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.18
4
+ version: 0.6.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - yhijikata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-30 00:00:00.000000000 Z
11
+ date: 2025-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -55,17 +55,49 @@ dependencies:
55
55
  description: This gem provides CRUD functionality for Rails applications.
56
56
  email:
57
57
  - yhijikata@systemlancer.com
58
- executables: []
58
+ executables:
59
+ - console
60
+ - crud
61
+ - setup
59
62
  extensions: []
60
63
  extra_rdoc_files: []
61
- files: []
62
- homepage: https://github.com/YamabikoLab
64
+ files:
65
+ - ".devcontainer/devcontainer.json"
66
+ - ".devcontainer/docker-compose.yml"
67
+ - ".rspec"
68
+ - ".rubocop.yml"
69
+ - CHANGELOG.md
70
+ - Dockerfile
71
+ - Gemfile
72
+ - LICENSE
73
+ - LICENSE.txt
74
+ - README.md
75
+ - Rakefile
76
+ - docker-compose.yml
77
+ - exe/console
78
+ - exe/crud
79
+ - exe/setup
80
+ - lib/rails/crud/tools.rb
81
+ - lib/rails/crud/tools/cli.rb
82
+ - lib/rails/crud/tools/constants.rb
83
+ - lib/rails/crud/tools/crud_config.rb
84
+ - lib/rails/crud/tools/crud_data.rb
85
+ - lib/rails/crud/tools/crud_logger.rb
86
+ - lib/rails/crud/tools/crud_notifications.rb
87
+ - lib/rails/crud/tools/crud_operations.rb
88
+ - lib/rails/crud/tools/crud_operations_logger.rb
89
+ - lib/rails/crud/tools/railtie.rb
90
+ - lib/rails/crud/tools/version.rb
91
+ - sig/rails/crud.rbs
92
+ - tools/crud_macro.xlsm
93
+ homepage: https://github.com/YamabikoLab/rails-crud-tools
63
94
  licenses:
64
95
  - MIT
65
96
  metadata:
66
- homepage_uri: https://github.com/YamabikoLab
97
+ homepage_uri: https://github.com/YamabikoLab/rails-crud-tools
67
98
  source_code_uri: https://github.com/YamabikoLab/rails-crud-tools
68
99
  changelog_uri: https://github.com/YamabikoLab/rails-crud-tools/blob/main/CHANGELOG.md
100
+ rubygems_mfa_required: 'true'
69
101
  post_install_message:
70
102
  rdoc_options: []
71
103
  require_paths:
@@ -74,7 +106,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
74
106
  requirements:
75
107
  - - ">="
76
108
  - !ruby/object:Gem::Version
77
- version: 2.7.0
109
+ version: '3.1'
78
110
  required_rubygems_version: !ruby/object:Gem::Requirement
79
111
  requirements:
80
112
  - - ">="