eitil 1.3.5 → 1.3.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b0a89a4609655c28ab6ee41d45b0c74d34b47d31cef1f494b0d942717cdf5371
4
- data.tar.gz: 905882089b4723ee74710f4877eaecc612ac35c75b9ea954efd9edeb656d8cda
3
+ metadata.gz: 800a7394bf32ae0a35ac26f8af1f854f90161acc373a3cc346422bb71ff58652
4
+ data.tar.gz: '04928eaebb9da031a756d431a2b76893c7d69f9084c48da9066631337014510b'
5
5
  SHA512:
6
- metadata.gz: 8d395e454f20dffb4d7f4a5b9d77944fdbb4603013e5c562ad09d4768642a5df4b98fe8b2e6a10510535b0428aa6f506edab944a787954a8847cac27480df4da
7
- data.tar.gz: c117f0a635d79282a6b7d54dd72a71de77d054c209f25b3c4cd76aae7469320af507c1f35f25b6770041b7b3fbfe3198b9c193c2bec8ed51acf6115a4f75ddcf
6
+ metadata.gz: 07b716769dec7ee55df77d28a4d4fda783868f931f50f8ff44caaa28b28a614c08496ddb1b3c1f6035a4ca6a7ffe98e96547bad2d75872ae5ce3fb20d96b5fa9
7
+ data.tar.gz: 6795a24f73771f86e40a774cb0ab409288eba5b1e82b5b1e97983fd273ee186d6dda22dac75ee99701e3e321c83b855950fc0e156a877f1f1c62aaaa9b664b37
@@ -150,11 +150,20 @@ extended_resources(controller, **kwargs)
150
150
 
151
151
 
152
152
 
153
- ## EitilWrapper::Scopes
153
+ ## EitilWrapper::Records
154
154
 
155
155
  ```ruby
156
156
 
157
- require "eitil_wrapper/scopes"
157
+ # include all below EitilWrapper::Records helpers through:
158
+ require "eitil_wrapper/records"
159
+
160
+ ```
161
+
162
+ ### Scopes
163
+
164
+ ```ruby
165
+
166
+ require "eitil_wrapper/records/scopes"
158
167
 
159
168
  ```
160
169
 
@@ -175,8 +184,6 @@ Scopes are generated through the columns of your model's database table. Which s
175
184
  .{column_name}_before_date(date)
176
185
  .{column_name}_after_date(date)
177
186
  .{column_name}_between_dates(start_date, end_date)
178
- .{column_name}_oldest_first
179
- .{column_name}_newest_first
180
187
 
181
188
  # columns of datatype: date
182
189
  .{column_name}_today
@@ -186,27 +193,96 @@ Scopes are generated through the columns of your model's database table. Which s
186
193
  .{column_name}_before_date(date)
187
194
  .{column_name}_after_date(date)
188
195
  .{column_name}_between_dates(start_date, end_date)
189
- .{column_name}_oldest_first
190
- .{column_name}_newest_first
191
196
 
192
197
  # columns of datatype: integer
193
198
  .{column_name}_equal_to(number)
194
199
  .{column_name}_lower_than(number)
195
200
  .{column_name}_higher_than(number)
196
201
  .{column_name}_between(min, max)
197
- .{column_name}_ascending
198
- .{column_name}_descending
199
202
 
200
203
  # columns of datatype: float
201
204
  .{column_name}_equal_to(number)
202
205
  .{column_name}_lower_than(number)
203
206
  .{column_name}_higher_than(number)
204
207
  .{column_name}_between(min, max)
208
+ ```
209
+
210
+ ### Sorts
211
+
212
+
213
+ ```ruby
214
+
215
+ require "eitil_wrapper/records/sorts"
216
+
217
+ ```
218
+
219
+ Sorts are generated through the columns of your model's database table. Which sorts are generated depends on the datatype of a column. A sort method is defined only if it does not already responds to another method of the same name. The sorts generated are:
220
+
221
+ ```ruby
222
+ # require "eitil_wrapper/scopes/default_scopes"
223
+
224
+ # columns of datatype: datetime
225
+ .{column_name}_oldest_first
226
+ .{column_name}_newest_first
227
+
228
+ # columns of datatype: date
229
+ .{column_name}_oldest_first
230
+ .{column_name}_newest_first
231
+
232
+ # columns of datatype: integer
233
+ .{column_name}_ascending
234
+ .{column_name}_descending
235
+
236
+ # columns of datatype: float
205
237
  .{column_name}_ascending
206
238
  .{column_name}_descending
207
239
  ```
208
240
 
209
241
 
242
+ ### Calculators
243
+
244
+
245
+ ```ruby
246
+
247
+ require "eitil_wrapper/records/calculators"
248
+
249
+ ```
250
+
251
+ Calculators are generated through the columns of your model's database table. Which calculators are generated depends on the datatype of a column. A calculator method is defined only if it does not already responds to another method of the same name. The calculators generated are:
252
+
253
+ ```ruby
254
+ # require "eitil_wrapper/scopes/default_scopes"
255
+
256
+ # columns of datatype: array (serialized)
257
+ .{column_name}_sum # returns all uniq elements in a new, single array
258
+ .{column_name}_sum_i # sum and map to integer
259
+ .{column_name}_sum_f # sum and map to float
260
+ .{column_name}_sum_d # sum and map to decimal
261
+
262
+ # columns of datatype: integer
263
+ .{column_name}_max
264
+ .{column_name}_min
265
+ .{column_name}_sum
266
+ .{column_name}_avg
267
+
268
+ # columns of datatype: float
269
+ .{column_name}_max
270
+ .{column_name}_min
271
+ .{column_name}_sum
272
+ .{column_name}_avg
273
+
274
+ # columns of datatype: decimal
275
+ .{column_name}_max
276
+ .{column_name}_min
277
+ .{column_name}_sum
278
+ .{column_name}_avg
279
+
280
+ # columns of datatype: bigint
281
+ .{column_name}_max
282
+ .{column_name}_min
283
+ .{column_name}_sum
284
+ .{column_name}_avg
285
+ ```
210
286
 
211
287
 
212
288
 
@@ -7,9 +7,16 @@ module EitilWrapper
7
7
 
8
8
  initializer "my_railtie.configure_rails_initialization", options: :after do |app|
9
9
 
10
+ if Object.const_defined?('EitilWrapper::Records::DefaultCalculators')
11
+ ::ApplicationRecord.send(:extend, EitilWrapper::Records::DefaultCalculators)
12
+ end
13
+
14
+ if Object.const_defined?('EitilWrapper::Records::DefaultScopes')
15
+ ::ApplicationRecord.send(:extend, EitilWrapper::Records::DefaultScopes)
16
+ end
10
17
 
11
- if Object.const_defined?('EitilWrapper::Scopes::DefaultScopes')
12
- ::ApplicationRecord.send(:extend, EitilWrapper::Scopes::DefaultScopes)
18
+ if Object.const_defined?('EitilWrapper::Records::DefaultSorts')
19
+ ::ApplicationRecord.send(:extend, EitilWrapper::Records::DefaultSorts)
13
20
  end
14
21
 
15
22
  if Object.const_defined?('EitilWrapper::Callbacks::HelperMethods')
@@ -0,0 +1,104 @@
1
+
2
+ # require "eitil_wrapper/records/default_calculators"
3
+
4
+ # require "eitil_wrapper/railtie" to run the dynamic dispatch as an init hook during boot
5
+ require "eitil_wrapper/railtie"
6
+
7
+ module EitilWrapper
8
+ module Records
9
+ module DefaultCalculators
10
+
11
+ Eitil::ApplicationRecordModules << self
12
+
13
+ SharableNumberCalculators = -> (_class, column) {
14
+ _class.eitil_calculator :"#{column}_max", -> { _class.maximum(column) }
15
+ _class.eitil_calculator :"#{column}_min", -> { _class.minimum(column) }
16
+ _class.eitil_calculator :"#{column}_sum", -> { _class.sum(column) }
17
+ _class.eitil_calculator :"#{column}_avg", -> { _class.average(column) }
18
+ }
19
+
20
+ SharableIterableCalculators = -> (_class, column) {
21
+ _class.eitil_calculator :"#{column}_sum", -> { _class.pluck(column).flatten!.uniq! }
22
+ _class.eitil_calculator :"#{column}_sum_i", -> { _class.pluck(column).flatten!.uniq!.map(&:to_i) }
23
+ _class.eitil_calculator :"#{column}_sum_f", -> { _class.pluck(column).flatten!.uniq!.map(&:to_f) }
24
+ _class.eitil_calculator :"#{column}_sum_d", -> { _class.pluck(column).flatten!.uniq!.map(&:to_d) }
25
+ }
26
+
27
+ def inherited(subclass)
28
+ super
29
+ return if Eitil.skip_default_calculators_for_models.include?(subclass.to_s.to_sym)
30
+
31
+ # Set the proper table_names for namespaced models. Without setting this,
32
+ # Rails run into problems due to the fact that the first call to the model's
33
+ # constant triggers this initializer first, and only thereafter the model file
34
+ # which sets the correct table_name through a macro.
35
+
36
+ namespaced_class = subclass.to_s.include?('::')
37
+ subclass.table_name = subclass.to_s.gsub('::', '_').downcase.pluralize if namespaced_class
38
+
39
+ subclass.use_eitil_calculators
40
+
41
+ rescue => e
42
+ puts "default calculators failed for class '#{subclass}' with expected table '#{subclass.table_name}' because of #{e.class} and '#{e.to_s.split(' ').first}'"
43
+ end
44
+
45
+ def use_eitil_calculators
46
+ return if abstract_class?
47
+
48
+ # text[] is postgresql's datatype for serialized arrays
49
+ # numeric is postgresql's datatype for decimals
50
+ # double precision is postgresql's datatype for floats
51
+
52
+
53
+ %w[integer bigint double\ precision numeric].each do |_type|
54
+ send :"create_eitil_#{_type.gsub(' ','_')}_calculators"
55
+ end
56
+
57
+ create_array_calculators
58
+ end
59
+
60
+ def eitil_calculator(_name, _proc)
61
+ # skip calculator methods for primary and foreign key columns
62
+ return if _name.to_s =~ /^id_[a-z]{1,}$/ || _name.to_s =~ /_id_[a-z]{1,}$/
63
+
64
+ define_singleton_method(_name) { _proc.call } unless respond_to? _name
65
+ end
66
+
67
+ def calculator_columns_of_type(data_type)
68
+ columns_hash.select { |column,v| v.sql_type == data_type }
69
+ end
70
+
71
+ def create_eitil_integer_calculators
72
+ calculator_columns_of_type("integer")&.map do |column, object|
73
+ SharableNumberCalculators.call self, column
74
+ end
75
+ end
76
+
77
+ def create_eitil_bigint_calculators
78
+ calculator_columns_of_type("bigint")&.map do |column, object|
79
+ SharableNumberCalculators.call self, column
80
+ end
81
+ end
82
+
83
+ def create_eitil_double_precision_calculators
84
+ calculator_columns_of_type("double\ precision")&.map do |column, object|
85
+ SharableNumberCalculators.call self, column
86
+ end
87
+ end
88
+
89
+ def create_eitil_numeric_calculators
90
+ calculator_columns_of_type("numeric")&.map do |column, object|
91
+ SharableNumberCalculators.call self, column
92
+ end
93
+ end
94
+
95
+ def create_array_calculators
96
+ columns = columns_hash.select { |column,v| v.sql_type == "text" && v.default == "{}" }
97
+ columns&.map do |column, object|
98
+ SharableIterableCalculators.call self, column
99
+ end
100
+ end
101
+
102
+ end
103
+ end
104
+ end
@@ -1,11 +1,11 @@
1
1
 
2
- # require "eitil_wrapper/scopes/default_scopes"
2
+ # require "eitil_wrapper/records/default_scopes"
3
3
 
4
4
  # require "eitil_wrapper/railtie" to run the dynamic dispatch as an init hook during boot
5
5
  require "eitil_wrapper/railtie"
6
6
 
7
7
  module EitilWrapper
8
- module Scopes
8
+ module Records
9
9
  module DefaultScopes
10
10
 
11
11
  Eitil::ApplicationRecordModules << self
@@ -19,9 +19,6 @@ module EitilWrapper
19
19
  _class.eitil_scope :"#{column}_before_date", -> (date) { where("#{column} = ?", date) }
20
20
  _class.eitil_scope :"#{column}_after_date", -> (date) { where("#{column} = ?", date) }
21
21
  _class.eitil_scope :"#{column}_between_dates", -> (from, till) { where("#{column} >= ? and #{column} <= ?", from, till) }
22
-
23
- _class.eitil_scope :"#{column}_oldest_first", -> { order("#{column} ASC") }
24
- _class.eitil_scope :"#{column}_newest_first", -> { order("#{column} DESC") }
25
22
  }
26
23
 
27
24
  SharableNumScopes = -> (_class, column) {
@@ -29,9 +26,6 @@ module EitilWrapper
29
26
  _class.eitil_scope :"#{column}_lower_than", -> (number) { where("#{column} = <", number) }
30
27
  _class.eitil_scope :"#{column}_higher_than", -> (number) { where("#{column} = >", number) }
31
28
  _class.eitil_scope :"#{column}_between", -> (min, max) { where("#{column} >= ? and #{column} <= ?", min, max) }
32
-
33
- _class.eitil_scope :"#{column}_ascending", -> { order("#{column} ASC") }
34
- _class.eitil_scope :"#{column}_descending", -> { order("#{column} DESC") }
35
29
  }
36
30
 
37
31
  def inherited(subclass)
@@ -42,13 +36,14 @@ module EitilWrapper
42
36
  # Rails run into problems due to the fact that the first call to the model's
43
37
  # constant triggers this initializer first, and only thereafter the model file
44
38
  # which sets the correct table_name through a macro.
39
+
45
40
  namespaced_class = subclass.to_s.include?('::')
46
41
  subclass.table_name = subclass.to_s.gsub('::', '_').downcase.pluralize if namespaced_class
47
42
 
48
43
  subclass.use_eitil_scopes
49
44
 
50
45
  rescue => e
51
- puts "default scopes failed for #{subclass} because of #{e.class} and '#{e.to_s.split(' ').first}'"
46
+ puts "default scopes failed for class '#{subclass}' with expected table '#{subclass.table_name}' because of #{e.class} and '#{e.to_s.split(' ').first}'"
52
47
  end
53
48
 
54
49
  def use_eitil_scopes
@@ -97,4 +92,4 @@ module EitilWrapper
97
92
 
98
93
  end
99
94
  end
100
- end
95
+ end
@@ -0,0 +1,81 @@
1
+
2
+ # require "eitil_wrapper/records/default_sorts"
3
+
4
+ # require "eitil_wrapper/railtie" to run the dynamic dispatch as an init hook during boot
5
+ require "eitil_wrapper/railtie"
6
+
7
+
8
+ module EitilWrapper
9
+ module Records
10
+ module DefaultSorts
11
+
12
+ Eitil::ApplicationRecordModules << self
13
+
14
+ SharableDateSorts = -> (_class, column) {
15
+ _class.eitil_sort :"#{column}_oldest_first", -> { _class.order("#{column} ASC") }
16
+ _class.eitil_sort :"#{column}_newest_first", -> { _class.order("#{column} DESC") }
17
+ }
18
+
19
+ SharableNumSorts = -> (_class, column) {
20
+ _class.eitil_sort :"#{column}_ascending", -> { _class.order("#{column} ASC") }
21
+ _class.eitil_sort :"#{column}_descending", -> { _class.order("#{column} DESC") }
22
+ }
23
+
24
+ def inherited(subclass)
25
+ super
26
+ return if Eitil.skip_default_sorts_for_models.include?(subclass.to_s.to_sym)
27
+
28
+ # Set the proper table_names for namespaced models. Without setting this,
29
+ # Rails run into problems due to the fact that the first call to the model's
30
+ # constant triggers this initializer first, and only thereafter the model file
31
+ # which sets the correct table_name through a macro.
32
+
33
+ namespaced_class = subclass.to_s.include?('::')
34
+ subclass.table_name = subclass.to_s.gsub('::', '_').downcase.pluralize if namespaced_class
35
+
36
+ subclass.use_eitil_sorts
37
+
38
+ rescue => e
39
+ puts "default sorts failed for class '#{subclass}' with expected table '#{subclass.table_name}' because of #{e.class} and '#{e.to_s.split(' ').first}'"
40
+ end
41
+
42
+ def use_eitil_sorts
43
+ return if abstract_class?
44
+ %i[datetime date integer float].each { |_type| send :"create_eitil_#{_type}_sorts" }
45
+ end
46
+
47
+ def eitil_sort(_name, _proc)
48
+ define_singleton_method(_name) { _proc.call } unless respond_to? _name
49
+ end
50
+
51
+ def sort_columns_of_type(data_type)
52
+ columns_hash.select { |column,v| v.sql_type_metadata.type == data_type }
53
+ end
54
+
55
+ def create_eitil_datetime_sorts
56
+ columns_of_type(:datetime)&.map do |column, object|
57
+ SharableDateSorts.call self, column
58
+ end
59
+ end
60
+
61
+ def create_eitil_date_sorts
62
+ columns_of_type(:date)&.map do |column, object|
63
+ SharableDateSorts.call self, column
64
+ end
65
+ end
66
+
67
+ def create_eitil_integer_sorts
68
+ columns_of_type(:integer)&.map do |column, object|
69
+ SharableNumSorts.call self, column
70
+ end
71
+ end
72
+
73
+ def create_eitil_float_sorts
74
+ columns_of_type(:float)&.map do |column, object|
75
+ SharableNumSorts.call self, column
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,4 @@
1
+
2
+ require "eitil_wrapper/records/default_scopes"
3
+ require "eitil_wrapper/records/default_calculators"
4
+ require "eitil_wrapper/records/default_sorts"
@@ -2,7 +2,7 @@
2
2
  require "eitil_wrapper"
3
3
 
4
4
  require "eitil_wrapper/jobs"
5
- require "eitil_wrapper/scopes"
5
+ require "eitil_wrapper/records"
6
6
  require "eitil_wrapper/routes"
7
7
  require "eitil_wrapper/callbacks"
8
8
  require "eitil_wrapper/decorators"
data/lib/eitil/railtie.rb CHANGED
@@ -31,10 +31,14 @@ module Eitil
31
31
 
32
32
  Eitil.mattr_accessor :controller_ivars,
33
33
  :skip_default_scopes_for_models,
34
+ :skip_default_calculators_for_models,
35
+ :skip_default_sorts_for_models,
34
36
  :skip_callback_helper_methods_for_models
35
37
 
36
- Eitil.controller_ivars ||= []
37
- Eitil.skip_default_scopes_for_models ||= []
38
+ Eitil.controller_ivars ||= []
39
+ Eitil.skip_default_scopes_for_models ||= []
40
+ Eitil.skip_default_calculators_for_models ||= []
41
+ Eitil.skip_default_sorts_for_models ||= []
38
42
  Eitil.skip_callback_helper_methods_for_models ||= []
39
43
 
40
44
  def Eitil.set_config(&block)
data/lib/eitil/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Eitil
2
2
 
3
- VERSION = '1.3.5'
3
+ VERSION = '1.3.9'
4
4
 
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eitil
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jurriaan Schrofer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-20 00:00:00.000000000 Z
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -207,7 +207,6 @@ files:
207
207
  - eitil_core/lib/eitil_core/hash/auto_dig.rb
208
208
  - eitil_core/lib/eitil_core/hash/transform_string_values.rb
209
209
  - eitil_core/lib/eitil_core/kernel.rb
210
- - eitil_core/lib/eitil_core/kernel/always_require_relative.rb
211
210
  - eitil_core/lib/eitil_core/kernel/loadquire.rb
212
211
  - eitil_core/lib/eitil_core/kernel/loadquire_bang.rb
213
212
  - eitil_core/lib/eitil_core/lookups.rb
@@ -284,13 +283,15 @@ files:
284
283
  - eitil_wrapper/lib/eitil_wrapper/jobs/new_job_now.rb
285
284
  - eitil_wrapper/lib/eitil_wrapper/jobs/single_method_job.rb
286
285
  - eitil_wrapper/lib/eitil_wrapper/railtie.rb
286
+ - eitil_wrapper/lib/eitil_wrapper/records.rb
287
+ - eitil_wrapper/lib/eitil_wrapper/records/default_calculators.rb
288
+ - eitil_wrapper/lib/eitil_wrapper/records/default_scopes.rb
289
+ - eitil_wrapper/lib/eitil_wrapper/records/default_sorts.rb
287
290
  - eitil_wrapper/lib/eitil_wrapper/request_logger.rb
288
291
  - eitil_wrapper/lib/eitil_wrapper/request_logger/controller_mixin.rb
289
292
  - eitil_wrapper/lib/eitil_wrapper/request_logger/logger_job.rb
290
293
  - eitil_wrapper/lib/eitil_wrapper/routes.rb
291
294
  - eitil_wrapper/lib/eitil_wrapper/routes/extended_resources.rb
292
- - eitil_wrapper/lib/eitil_wrapper/scopes.rb
293
- - eitil_wrapper/lib/eitil_wrapper/scopes/default_scopes.rb
294
295
  - lib/eitil.rb
295
296
  - lib/eitil/all.rb
296
297
  - lib/eitil/railtie.rb
@@ -470,7 +471,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
470
471
  - !ruby/object:Gem::Version
471
472
  version: '0'
472
473
  requirements: []
473
- rubygems_version: 3.1.2
474
+ rubygems_version: 3.0.9
474
475
  signing_key:
475
476
  specification_version: 4
476
477
  summary: Eitil (eitje utility) never stops increasing your life's efficacy and productivity,
@@ -1,21 +0,0 @@
1
-
2
- # require "eitil_core/kernel/always_require_relative"
3
-
4
- Kernel.module_eval do
5
-
6
- def always_require_relative(current_path, relative_path, extension = '.rb')
7
-
8
- unless Object.const_defined?('Rails')
9
- return require_relative(path)
10
- end
11
-
12
- absolute_path = File.expand_path(relative_path, current_path).concat(extension)
13
-
14
- if Rails.env.development?
15
- load(absolute_path)
16
- else
17
- require(absolute_path)
18
- end
19
- end
20
-
21
- end
@@ -1,2 +0,0 @@
1
-
2
- require "eitil_wrapper/scopes/default_scopes"