trailblazer-finder 0.3.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +1 -4
- data/CHANGES.md +3 -0
- data/LICENSE.txt +1 -1
- data/README.md +0 -7
- data/lib/trailblazer/finder.rb +9 -18
- data/lib/trailblazer/finder/activity/find.rb +26 -28
- data/lib/trailblazer/finder/activity/prepare.rb +17 -14
- data/lib/trailblazer/finder/activity/prepare_adapters.rb +52 -0
- data/lib/trailblazer/finder/activity/prepare_entity.rb +25 -0
- data/lib/trailblazer/finder/activity/prepare_filters.rb +29 -0
- data/lib/trailblazer/finder/activity/prepare_paging.rb +42 -0
- data/lib/trailblazer/finder/activity/prepare_params.rb +27 -0
- data/lib/trailblazer/finder/activity/prepare_properties.rb +44 -0
- data/lib/trailblazer/finder/activity/prepare_sorting.rb +52 -0
- data/lib/trailblazer/finder/activity/process.rb +12 -8
- data/lib/trailblazer/finder/activity/process_adapters.rb +40 -0
- data/lib/trailblazer/finder/activity/process_filters.rb +21 -0
- data/lib/trailblazer/finder/activity/process_paging.rb +19 -0
- data/lib/trailblazer/finder/activity/process_predicates.rb +23 -0
- data/lib/trailblazer/finder/activity/process_sorting.rb +19 -0
- data/lib/trailblazer/finder/version.rb +1 -1
- data/lib/trailblazer/operation/finder.rb +42 -49
- data/spec/spec_helper.rb +4 -0
- data/trailblazer-finder.gemspec +6 -7
- metadata +32 -57
- data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +0 -101
- data/lib/trailblazer/finder/activity/prepare/adapters.rb +0 -66
- data/lib/trailblazer/finder/activity/prepare/entity.rb +0 -32
- data/lib/trailblazer/finder/activity/prepare/filters.rb +0 -36
- data/lib/trailblazer/finder/activity/prepare/paging.rb +0 -49
- data/lib/trailblazer/finder/activity/prepare/params.rb +0 -33
- data/lib/trailblazer/finder/activity/prepare/properties.rb +0 -47
- data/lib/trailblazer/finder/activity/prepare/sorting.rb +0 -57
- data/lib/trailblazer/finder/activity/process/adapters.rb +0 -48
- data/lib/trailblazer/finder/activity/process/filters.rb +0 -28
- data/lib/trailblazer/finder/activity/process/paging.rb +0 -26
- data/lib/trailblazer/finder/activity/process/predicates.rb +0 -30
- data/lib/trailblazer/finder/activity/process/sorting.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb1a6d3df9380459d5e21c54c7525b0848e63ef921251d9560d6e51aba373b71
|
4
|
+
data.tar.gz: 9255d7b252793df093f83e4d46a4a3b777011374e75e245c5673a4c9deccc49c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 246da8f4eb7de635a9eb692f03fdafdaae1154a4b2e2e40f647227571e83a6ce366ac4062ae88b177befc50dcdaf94de262f726d1dee9b5f2b756f94ede0097f
|
7
|
+
data.tar.gz: a63b631f720310717e83798cf891bbb8e3fd31f06e545c068942640a277486791d749c1bd47b17f73cc715bda036bf99dc86de2d23d9d5953640243db0091d3e
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGES.md
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# THIS IS MOSTLY OUT OF DATE
|
2
|
-
|
3
|
-
# NEW README AND RELEASE COMING NEXT WEEK
|
4
|
-
|
5
1
|
# Trailblazer Finder
|
6
2
|
|
7
3
|
Provides DSL for creating [Trailblazer](https://github.com/trailblazer/trailblazer) based Finder Objects. But it is designed to be used on its own as a separate gem. It was influenced by popular [Ransack](https://github.com/activerecord-hackery/ransack) gem, but in addition to [ActiveRecord](https://github.com/rails/rails/tree/master/activerecord), it can be used with [DataMapper](https://github.com/datamapper) or [Sequel](https://github.com/jeremyevans/sequel). It also integrates with [Kaminari](https://github.com/kaminari/kaminari) or [Will Paginate](https://github.com/mislav/will_paginate), as well as [FriendlyId](https://github.com/norman/friendly_id)
|
@@ -431,9 +427,6 @@ class Post::Finder < Trailblazer::Finder
|
|
431
427
|
end
|
432
428
|
```
|
433
429
|
|
434
|
-
### Utils / Helpers
|
435
|
-
Coming soon
|
436
|
-
|
437
430
|
## Contributing
|
438
431
|
1. Fork it
|
439
432
|
2. Create your feature branch
|
data/lib/trailblazer/finder.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "forwardable"
|
4
|
-
require "trailblazer
|
4
|
+
require "trailblazer"
|
5
5
|
require "dry-types"
|
6
6
|
require "ostruct"
|
7
7
|
|
@@ -21,19 +21,7 @@ require "trailblazer/finder/adapters/sequel/sorting"
|
|
21
21
|
require "trailblazer/finder/adapters/basic/predicates"
|
22
22
|
require "trailblazer/finder/adapters/basic/paging"
|
23
23
|
require "trailblazer/finder/adapters/basic/sorting"
|
24
|
-
require "trailblazer/finder/activity/prepare/entity"
|
25
|
-
require "trailblazer/finder/activity/prepare/properties"
|
26
|
-
require "trailblazer/finder/activity/prepare/filters"
|
27
|
-
require "trailblazer/finder/activity/prepare/params"
|
28
|
-
require "trailblazer/finder/activity/prepare/adapters"
|
29
|
-
require "trailblazer/finder/activity/prepare/paging"
|
30
|
-
require "trailblazer/finder/activity/prepare/sorting"
|
31
24
|
require "trailblazer/finder/activity/prepare"
|
32
|
-
require "trailblazer/finder/activity/process/adapters"
|
33
|
-
require "trailblazer/finder/activity/process/predicates"
|
34
|
-
require "trailblazer/finder/activity/process/paging"
|
35
|
-
require "trailblazer/finder/activity/process/sorting"
|
36
|
-
require "trailblazer/finder/activity/process/filters"
|
37
25
|
require "trailblazer/finder/activity/process"
|
38
26
|
require "trailblazer/finder/activity/find"
|
39
27
|
require "trailblazer/finder/helpers/basic"
|
@@ -41,15 +29,18 @@ require "trailblazer/finder/helpers/sorting"
|
|
41
29
|
require "trailblazer/finder/dsl"
|
42
30
|
require "trailblazer/finder/find"
|
43
31
|
require "trailblazer/finder/base"
|
44
|
-
|
45
|
-
# :nocov:
|
46
|
-
require "trailblazer/operation/finder" if Gem.loaded_specs.key?("trailblazer")
|
47
|
-
# :nocov:
|
32
|
+
require "trailblazer/operation/finder"
|
48
33
|
|
49
34
|
module Trailblazer
|
50
35
|
class Finder
|
36
|
+
DRY_TYPES_VERSION = Gem::Version.new(Dry::Types::VERSION)
|
37
|
+
LEGACY_DRY_TYPES = DRY_TYPES_VERSION <= Gem::Version.new('1')
|
51
38
|
module Types
|
52
|
-
|
39
|
+
if LEGACY_DRY_TYPES
|
40
|
+
include Dry::Types.module
|
41
|
+
else
|
42
|
+
include Dry.Types(default: :nominal)
|
43
|
+
end
|
53
44
|
end
|
54
45
|
|
55
46
|
include Base
|
@@ -4,33 +4,12 @@ module Trailblazer
|
|
4
4
|
class Finder
|
5
5
|
module Activity
|
6
6
|
# Find Activity
|
7
|
-
|
7
|
+
class Find < Trailblazer::Activity::Railway
|
8
8
|
PREDICATES = %w[eq not_eq blank not_blank lt lte gt gte sw not_sw ew not_ew cont not_cont].freeze
|
9
9
|
|
10
|
-
extend Trailblazer::Activity::Railway()
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
def fetch_filters(ctx, result, attribute)
|
15
|
-
filter_attribute = ctx[:filters][attribute]
|
16
|
-
result[:filter] = {}
|
17
|
-
result[:name] = attribute
|
18
|
-
result[:filter][:handler] = filter_attribute[:with] || filter_attribute[:block]
|
19
|
-
end
|
20
|
-
|
21
|
-
def fetch_properties(result, attribute, value, properties)
|
22
|
-
splitter = Utils::Splitter.new attribute, value
|
23
|
-
PREDICATES.each do |predicate|
|
24
|
-
next unless splitter.split_key predicate
|
25
|
-
next unless properties.include?(splitter.field.to_sym)
|
26
|
-
|
27
|
-
result[:name] = splitter.field
|
28
|
-
result[:predicate] = predicate
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def process_params(ctx, **)
|
33
|
-
ctx[:params].each do |attribute, value|
|
11
|
+
def process_params(ctx, params:, **)
|
12
|
+
params.each do |attribute, value|
|
34
13
|
result = {}
|
35
14
|
|
36
15
|
fetch_filters(ctx, result, attribute) || result if ctx[:filters].include?(attribute)
|
@@ -47,10 +26,29 @@ module Trailblazer
|
|
47
26
|
ctx[:finder] = Finder::Find.new(ctx[:entity], ctx[:params], ctx[:process], ctx[:paging], ctx[:sorting], ctx[:config])
|
48
27
|
end
|
49
28
|
|
50
|
-
step Subprocess(Prepare)
|
51
|
-
step
|
52
|
-
step Subprocess(Process)
|
53
|
-
step
|
29
|
+
step Subprocess(Prepare)
|
30
|
+
step :process_params
|
31
|
+
step Subprocess(Process)
|
32
|
+
step :set_finder
|
33
|
+
|
34
|
+
private
|
35
|
+
def fetch_filters(ctx, result, attribute)
|
36
|
+
filter_attribute = ctx[:filters][attribute]
|
37
|
+
result[:filter] = {}
|
38
|
+
result[:name] = attribute
|
39
|
+
result[:filter][:handler] = filter_attribute[:with] || filter_attribute[:block]
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_properties(result, attribute, value, properties)
|
43
|
+
splitter = Utils::Splitter.new attribute, value
|
44
|
+
PREDICATES.each do |predicate|
|
45
|
+
next unless splitter.split_key predicate
|
46
|
+
next unless properties.include?(splitter.field.to_sym)
|
47
|
+
|
48
|
+
result[:name] = splitter.field
|
49
|
+
result[:predicate] = predicate
|
50
|
+
end
|
51
|
+
end
|
54
52
|
end
|
55
53
|
end
|
56
54
|
end
|
@@ -1,28 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "prepare_adapters"
|
4
|
+
require_relative "prepare_entity"
|
5
|
+
require_relative "prepare_properties"
|
6
|
+
require_relative "prepare_filters"
|
7
|
+
require_relative "prepare_params"
|
8
|
+
require_relative "prepare_paging"
|
9
|
+
require_relative "prepare_sorting"
|
10
|
+
|
3
11
|
module Trailblazer
|
4
12
|
class Finder
|
5
13
|
module Activity
|
6
14
|
# Prepare Activity
|
7
|
-
|
8
|
-
extend Trailblazer::Activity::Railway()
|
9
|
-
|
10
|
-
module_function
|
11
|
-
|
15
|
+
class Prepare < Trailblazer::Activity::Railway
|
12
16
|
def clean_ctx((ctx, flow_options), **)
|
13
|
-
# ctx.delete(:config)
|
14
17
|
ctx.delete(:options)
|
15
18
|
[Trailblazer::Activity::Right, [ctx, flow_options]]
|
16
19
|
end
|
17
20
|
|
18
|
-
step Subprocess(
|
19
|
-
step Subprocess(
|
20
|
-
step Subprocess(
|
21
|
-
step Subprocess(
|
22
|
-
step Subprocess(
|
23
|
-
step Subprocess(
|
24
|
-
step Subprocess(
|
25
|
-
step
|
21
|
+
step Subprocess(PrepareAdapters)
|
22
|
+
step Subprocess(PrepareEntity)
|
23
|
+
step Subprocess(PrepareProperties)
|
24
|
+
step Subprocess(PrepareFilters)
|
25
|
+
step Subprocess(PrepareParams)
|
26
|
+
step Subprocess(PreparePaging)
|
27
|
+
step Subprocess(PrepareSorting)
|
28
|
+
step :clean_ctx
|
26
29
|
end
|
27
30
|
end
|
28
31
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
# Adapters Activity
|
7
|
+
class PrepareAdapters < Trailblazer::Activity::Railway
|
8
|
+
def check_for_adapters(ctx, **)
|
9
|
+
adapters = ctx.dig(:config, :adapters)
|
10
|
+
return true if adapters.empty?
|
11
|
+
|
12
|
+
adapters.each do |adapter|
|
13
|
+
return true if Finder::Adapters.constants.include?(adapter.to_sym)
|
14
|
+
end
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
18
|
+
## Only one ORM can be accepted
|
19
|
+
def validate_adapters(ctx, **)
|
20
|
+
adapters = ctx.dig(:config, :adapters)
|
21
|
+
return true if adapters.empty?
|
22
|
+
|
23
|
+
adapters.each do |adapter|
|
24
|
+
if ORM_ADAPTERS.include?(adapter)
|
25
|
+
return false if (adapters & (ORM_ADAPTERS - [adapter])).any?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def invalid_adapters_error((ctx, flow_options), **_circuit_options)
|
32
|
+
(ctx[:errors] ||= []) << {adapters: "One or more of the specified adapters are invalid"}
|
33
|
+
end
|
34
|
+
|
35
|
+
def multiple_orm_error((ctx, flow_options), **_circuit_options)
|
36
|
+
(ctx[:errors] ||= []) << {adapters: "More then one ORM adapter specified"}
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_adapters(ctx, **)
|
40
|
+
adapters = ctx.dig(:config, :adapters)
|
41
|
+
ctx[:adapters] = (ORM_ADAPTERS & adapters).any? ? adapters : ["Basic"] + adapters
|
42
|
+
end
|
43
|
+
|
44
|
+
step :check_for_adapters
|
45
|
+
fail :invalid_adapters_error, Output(:success) => End(:failure)
|
46
|
+
step :validate_adapters
|
47
|
+
fail :multiple_orm_error
|
48
|
+
step :set_adapters
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
class PrepareEntity < Trailblazer::Activity::Railway
|
7
|
+
def validate_entity(ctx, **)
|
8
|
+
ctx.dig(:options,:entity) || ctx.dig(:config,:entity)
|
9
|
+
end
|
10
|
+
|
11
|
+
def invalid_entity_error(ctx, **)
|
12
|
+
(ctx[:errors] ||= []) << {entity: "Invalid entity specified"}
|
13
|
+
end
|
14
|
+
|
15
|
+
def set_entity(ctx, **)
|
16
|
+
ctx[:entity] = ctx.dig(:options,:entity) || instance_eval(&ctx[:config][:entity])
|
17
|
+
end
|
18
|
+
|
19
|
+
step (:validate_entity)
|
20
|
+
fail (:invalid_entity_error)
|
21
|
+
step (:set_entity)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
class PrepareFilters < Trailblazer::Activity::Railway
|
7
|
+
def validate_filters(ctx, **)
|
8
|
+
filters = ctx.dig(:config, :filters)
|
9
|
+
filters.each do |key, _value|
|
10
|
+
return false if !filters[key][:with].nil? && !filters[key][:with].is_a?(Symbol)
|
11
|
+
end
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
def invalid_filters_error(ctx, **)
|
16
|
+
(ctx[:errors] ||= []) << {filters: "One or more filters are missing a with method definition"}
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_filters(ctx, **)
|
20
|
+
ctx[:filters] = ctx[:config][:filters]
|
21
|
+
end
|
22
|
+
|
23
|
+
step :validate_filters
|
24
|
+
fail :invalid_filters_error
|
25
|
+
step :set_filters
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
class PreparePaging < Trailblazer::Activity::Railway
|
7
|
+
def check_paging(ctx, **)
|
8
|
+
paging = ctx[:config][:paging] || nil
|
9
|
+
return false if ctx[:config][:paging].empty? || paging.nil?
|
10
|
+
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_paging(ctx, **)
|
15
|
+
ctx[:paging] = ctx.dig(:config,:paging) || {}
|
16
|
+
ctx[:paging][:current_page] = ctx.dig(:params,:page) || 1
|
17
|
+
return true unless ctx[:params][:per_page]
|
18
|
+
|
19
|
+
ctx[:paging][:per_page] = ctx[:params][:per_page].to_i || ctx[:paging][:per_page]
|
20
|
+
ctx[:paging][:per_page] = ctx[:paging][:max_per_page] if ctx[:paging][:per_page] > ctx[:paging][:max_per_page]
|
21
|
+
ctx[:paging][:per_page] = ctx[:paging][:min_per_page] if ctx[:paging][:per_page] < ctx[:paging][:min_per_page]
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear_paging(ctx, **)
|
26
|
+
ctx[:params].delete(:page) unless ctx[:params][:page].nil?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
step (:check_paging),
|
31
|
+
Output(:failure) => Track(:end_paging)
|
32
|
+
step (:set_paging),
|
33
|
+
Output(:success) => Track(:end_paging),
|
34
|
+
Output(:failure) => Track(:failure)
|
35
|
+
step (:clear_paging),
|
36
|
+
magnetic_to: :end_paging,
|
37
|
+
Output(:success) => Track(:success),
|
38
|
+
Output(:failure) => Track(:failure)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
# Params Activity
|
7
|
+
class PrepareParams < Trailblazer::Activity::Railway
|
8
|
+
def validate_params(_ctx, **)
|
9
|
+
# Should probably validate some things here at some point
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def invalid_params_error(_ctx, **)
|
14
|
+
# (ctx[:errors] ||= []) << {params: "One or more parameters are invalid"}
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_params(ctx, **)
|
18
|
+
ctx[:params] = ctx[:options][:params] || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
step (:validate_params)
|
22
|
+
fail (:invalid_params_error)
|
23
|
+
step (:set_params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Finder
|
5
|
+
module Activity
|
6
|
+
class PrepareProperties < Trailblazer::Activity::Railway
|
7
|
+
def check_property_types(ctx, **)
|
8
|
+
properties = ctx[:config][:properties] || {}
|
9
|
+
return true if properties.empty?
|
10
|
+
|
11
|
+
properties.each do |key, _value|
|
12
|
+
return !properties[key][:type].nil?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def validate_property_types(ctx, **)
|
17
|
+
properties = ctx[:config][:properties] || {}
|
18
|
+
return true if properties.empty?
|
19
|
+
|
20
|
+
properties.each do |key, _value|
|
21
|
+
if LEGACY_DRY_TYPES
|
22
|
+
return properties[key][:type].class.ancestors.include?(::Dry::Types::Definition)
|
23
|
+
else
|
24
|
+
return properties[key][:type].class.ancestors.include?(::Dry::Types::Nominal)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def invalid_properties_error(ctx, **)
|
30
|
+
(ctx[:errors] ||= []) << {properties: "One or more properties are missing a valid type"}
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_properties(ctx, **)
|
34
|
+
ctx[:properties] = ctx[:config][:properties]
|
35
|
+
end
|
36
|
+
|
37
|
+
step :check_property_types
|
38
|
+
step :validate_property_types
|
39
|
+
fail :invalid_properties_error
|
40
|
+
step :set_properties
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|