appfuel 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/appfuel.gemspec +1 -1
  4. data/lib/appfuel/application/app_container.rb +0 -1
  5. data/lib/appfuel/application/dispatcher.rb +32 -0
  6. data/lib/appfuel/application/root.rb +4 -4
  7. data/lib/appfuel/application.rb +2 -1
  8. data/lib/appfuel/domain/domain_name_parser.rb +9 -5
  9. data/lib/appfuel/domain.rb +0 -7
  10. data/lib/appfuel/handler/base.rb +8 -14
  11. data/lib/appfuel/storage/db/mapper.rb +31 -35
  12. data/lib/appfuel/storage/db/repository.rb +53 -121
  13. data/lib/appfuel/storage/repository/base.rb +246 -0
  14. data/lib/appfuel/storage/repository/criteria.rb +317 -0
  15. data/lib/appfuel/{domain → storage/repository}/expr.rb +1 -1
  16. data/lib/appfuel/storage/repository/expr_conjunction.rb +41 -0
  17. data/lib/appfuel/{domain → storage/repository}/expr_parser.rb +10 -22
  18. data/lib/appfuel/{domain → storage/repository}/expr_transform.rb +7 -7
  19. data/lib/appfuel/{repository → storage/repository}/mapper.rb +8 -3
  20. data/lib/appfuel/storage/repository/order_expr.rb +51 -0
  21. data/lib/appfuel/storage/repository/runner.rb +62 -0
  22. data/lib/appfuel/storage/repository/search_parser.rb +50 -0
  23. data/lib/appfuel/storage/repository/search_transform.rb +58 -0
  24. data/lib/appfuel/{domain/criteria_settings.rb → storage/repository/settings.rb} +20 -5
  25. data/lib/appfuel/{repository.rb → storage/repository.rb} +13 -0
  26. data/lib/appfuel/storage.rb +1 -0
  27. data/lib/appfuel/version.rb +1 -1
  28. data/lib/appfuel.rb +0 -2
  29. metadata +21 -19
  30. data/lib/appfuel/domain/base_criteria.rb +0 -171
  31. data/lib/appfuel/domain/exists_criteria.rb +0 -57
  32. data/lib/appfuel/domain/expr_conjunction.rb +0 -27
  33. data/lib/appfuel/domain/search_criteria.rb +0 -137
  34. data/lib/appfuel/repository/base.rb +0 -86
  35. data/lib/appfuel/repository_runner.rb +0 -60
  36. /data/lib/appfuel/{repository → storage/repository}/initializer.rb +0 -0
  37. /data/lib/appfuel/{repository → storage/repository}/mapping_dsl.rb +0 -0
  38. /data/lib/appfuel/{repository → storage/repository}/mapping_entry.rb +0 -0
@@ -1,7 +1,5 @@
1
- require 'parslet'
2
-
3
1
  module Appfuel
4
- module Domain
2
+ module Repository
5
3
  # A PEG (Parser Expression Grammer) transformer for our domain language.
6
4
  #
7
5
  class ExprTransform < Parslet::Transform
@@ -41,13 +39,15 @@ module Appfuel
41
39
  end
42
40
 
43
41
  def self.build_conjunction_node(data)
44
- if data.key?(:root)
42
+ if data.is_a?(Expr) || data.is_a?(ExprConjunction)
43
+ node = data
44
+ elsif data.key?(:root)
45
45
  node = data[:root]
46
46
  elsif data.key?(:domain_expr)
47
- node = data[:domain_expr]
47
+ node = data[:domain_expr]
48
48
  elsif data.key?(:and) || data.key?(:or)
49
- op = right.key?(:and) ? 'and' : 'or'
50
- node = build_conjunction(op, data)
49
+ op = data.key?(:and) ? :and : :or
50
+ node = build_conjunction(op, data[op])
51
51
  end
52
52
  node
53
53
  end
@@ -138,13 +138,14 @@ module Appfuel
138
138
  app_container[key]
139
139
  end
140
140
 
141
- def to_entity_hash(domain_name, data)
141
+ def to_entity_hash(domain_name, storage)
142
142
  entity_attrs = {}
143
+ storage_data = storage_hash(storage)
143
144
  each_entity_attr(domain_name) do |entry|
144
145
  attr_name = entry.storage_attr
145
146
  domain_attr = entry.domain_attr
146
- next unless data.key?(attr_name)
147
- update_entity_hash(domain_attr, data[attr_name], entity_attrs)
147
+ next unless storage_data.key?(attr_name)
148
+ update_entity_hash(domain_attr, storage_data[attr_name], entity_attrs)
148
149
  end
149
150
 
150
151
  entity_attrs
@@ -221,6 +222,10 @@ module Appfuel
221
222
  target
222
223
  end
223
224
 
225
+ def expr_conjunction?(value)
226
+ value.instance_of?(ExprConjunction)
227
+ end
228
+
224
229
  private
225
230
  def validate_domain(entity_name)
226
231
  unless entity?(entity_name)
@@ -0,0 +1,51 @@
1
+ module Appfuel
2
+ module Repository
3
+ class OrderExpr < Expr
4
+
5
+ def self.build(data)
6
+ return [data] if data.instance_of?(self)
7
+ data = [data] if data.is_a?(String)
8
+ unless data.respond_to?(:each)
9
+ fail "order must be a string or implement :each"
10
+ end
11
+
12
+ results = []
13
+ data.each do |item|
14
+ item = parse_order_string(item) if item.is_a?(String)
15
+ if item.instance_of?(self)
16
+ results << item
17
+ next
18
+ end
19
+
20
+ if !item.is_a?(Hash)
21
+ fail "order array must be a list of strings or hashes"
22
+ end
23
+ domain_attr, dir = item.first
24
+ results << self.new(domain_attr, dir)
25
+ end
26
+ results
27
+ end
28
+
29
+ def initialize(domain_attr, op = nil)
30
+ op ||= 'asc'
31
+
32
+ super(domain_attr, op, nil)
33
+ @op = @op.downcase
34
+ unless ['asc', 'desc'].include?(@op)
35
+ fail "order direction must be either asc or desc"
36
+ end
37
+ end
38
+
39
+ def to_s
40
+ "#{attr_list.join('.')} #{op}"
41
+ end
42
+
43
+ private
44
+ def self.parse_order_string(str)
45
+ str, dir = str.split(' ')
46
+ dir = 'asc' if dir.nil?
47
+ {str => dir.downcase}
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,62 @@
1
+ module Appfuel
2
+ # Used in the validation system by custom predicates to ask the question if
3
+ # an entity exists in the database
4
+ module Repository
5
+ class Runner
6
+ attr_reader :repo_namespace, :criteria_class
7
+
8
+ # The call relies on the fact that we can build a criteria find the
9
+ # correct repo and call the exists? interface on that repo. The identity
10
+ # of any given repo requires its namespace + its class name.
11
+ #
12
+ # @param namespace [String] fully qualified namespace string fro repos
13
+ # @param criteria_class [Class] class used to represent the criteria
14
+ # @returns [ExistsInDbRunner]
15
+ def initialize(namespace, criteria_class)
16
+ @repo_namespace = namespace
17
+ @criteria_class = criteria_class
18
+ end
19
+
20
+ def create_criteria(entity_key, opts = {})
21
+ criteria_class.new(entity_key, opts)
22
+ end
23
+
24
+ def query(criteria)
25
+ load_repo(criteria).query(criteria)
26
+ end
27
+
28
+ # @param entity_key [String] the type identifier for an entity
29
+ # @param opts [Hash] one attr => value pair is required
30
+ # repo => name is optional
31
+ #
32
+ # @return [Bool]
33
+ def exists?(entity_key, opts = {})
34
+ fail "opts must be a hash" unless opts.is_a?(Hash)
35
+
36
+ criteria_opts = {}
37
+ if opts.key?(:repo)
38
+ criteria_opts[:repo] = opts.delete(:repo)
39
+ end
40
+ fail "opts hash must have one attr => value pair" if opts.empty?
41
+
42
+ property, value = opts.first
43
+ criteria = create_criteria(entity_key, criteria_opts)
44
+ criteria.exists(property, value)
45
+
46
+ load_repo(criteria).exists?(criteria)
47
+ end
48
+
49
+
50
+ private
51
+
52
+ def load_repo(criteria)
53
+ klass = "#{repo_namespace}::#{criteria.repo_name}"
54
+ unless Kernel.const_defined?(klass)
55
+ fail "RepositoryRunner: failed - repo #{klass} not defined"
56
+ end
57
+
58
+ Kernel.const_get(klass).new
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,50 @@
1
+ module Appfuel
2
+ module Repository
3
+ class SearchParser < ExprParser
4
+ rule(:filter_identifier) { stri('filter') }
5
+ rule(:order_identifier) { stri('order') }
6
+ rule(:limit_identifier) { stri('limit') }
7
+
8
+ rule(:order_dir) do
9
+ (stri('asc') | stri('desc')).as(:order_dir)
10
+ end
11
+
12
+ rule(:domain_name) do
13
+ attr_label.as(:feature) >> str('.') >> attr_label.as(:basename)
14
+ end
15
+
16
+ rule(:limit_expr) do
17
+ (
18
+ limit_identifier >> space >> space? >> integer.as(:value)
19
+ ).as(:limit)
20
+ end
21
+
22
+ rule(:order_expr) do
23
+ (
24
+ (domain_attr >> space >> order_dir) | domain_attr
25
+ ).as(:order_expr)
26
+ end
27
+
28
+ # order id
29
+ # order id asc
30
+ # order foo.id asc
31
+ # order foo.id, code desc, foo.bar.id asc
32
+ rule(:order_by) do
33
+ (
34
+ order_identifier >> space >> space? >>
35
+ (order_expr >> (comma >> order_expr).repeat).maybe
36
+ ).as(:order)
37
+ end
38
+
39
+ rule(:search) do
40
+ (
41
+ domain_name.as(:domain) >> space >> space? >>
42
+ filter_identifier >> space >> space? >>
43
+ or_operation.as(:filters) >> order_by.maybe >> space? >> limit_expr.maybe
44
+ ).as(:search)
45
+ end
46
+
47
+ root(:search)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,58 @@
1
+ module Appfuel
2
+ module Repository
3
+ class SearchTransform < ExprTransform
4
+
5
+
6
+ rule(order_dir: simple(:n)) {
7
+ value = n.to_s.downcase
8
+ value == 'desc' ? 'desc' : 'asc'
9
+ }
10
+
11
+ rule(order_expr: subtree(:expr)) do |dict|
12
+ expr = dict[:expr]
13
+ domain_attr = expr[:domain_attr]
14
+ order_dir = expr[:order_dir] || 'asc'
15
+ OrderExpr.new(domain_attr, order_dir)
16
+ end
17
+
18
+ rule(attr_label: simple(:n)) { n.to_s }
19
+
20
+ rule(domain_attr: simple(:n)) {
21
+ list = n.is_a?(Array) ? n : [n]
22
+ {domain_attr: list}
23
+ }
24
+
25
+ rule(domain_expr: subtree(:domain_expr)) do |dict|
26
+ data = dict[:domain_expr]
27
+ domain_attr = data[:domain_attr]
28
+ op = data[:op]
29
+ value = data[:value]
30
+ Expr.new(domain_attr, op, value)
31
+ end
32
+
33
+ rule(search: subtree(:search)) do |dict|
34
+ search = dict[:search]
35
+ domain = search[:domain]
36
+ filters = search[:filters]
37
+ orders = search[:order]
38
+ limit = search[:limit]
39
+
40
+ if filters.is_a?(Hash) && filters.key?(:root)
41
+ filters = filters[:root]
42
+ end
43
+ result = {}
44
+ result[:domain] = "#{domain[:feature]}.#{domain[:basename]}"
45
+ result[:filters] = filters
46
+ unless limit.nil?
47
+ result[:limit] = limit[:value]
48
+ end
49
+
50
+ unless orders.nil?
51
+ orders = orders.is_a?(Array) ? orders : [orders]
52
+ result[:order] = orders
53
+ end
54
+ {search: Criteria.build(result)}
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,6 +1,5 @@
1
1
  module Appfuel
2
- module Domain
3
-
2
+ module Repository
4
3
  # The Criteria represents the interface between the repositories and actions
5
4
  # or commands. The allow you to find entities in the application storage (
6
5
  # a database) without knowledge of that storage system. The criteria will
@@ -19,7 +18,7 @@ module Appfuel
19
18
  # transform
20
19
  # search_name
21
20
  #
22
- class CriteriaSettings
21
+ class Settings
23
22
  DEFAULT_PAGE = 1
24
23
  DEFAULT_PER_PAGE = 20
25
24
 
@@ -29,8 +28,8 @@ module Appfuel
29
28
  # @param opts [Hash] options for initializing criteria
30
29
  # @return [Criteria]
31
30
  def initialize(settings = {})
32
- @parser = settings[:expr_parser] || ExprParser.new
33
- @transform = settings[:expr_transform] || ExprTransform.new
31
+ @parser = settings[:parser] || SearchParser.new
32
+ @transform = settings[:transform] || SearchTransform.new
34
33
 
35
34
 
36
35
  empty_dataset_is_valid!
@@ -55,10 +54,22 @@ module Appfuel
55
54
  all
56
55
  end
57
56
 
57
+ manual_query(settings[:manual_query]) if settings.key?(:manual_query)
58
+
58
59
  page(settings[:page] || DEFAULT_PAGE)
59
60
  per_page(settings[:per_page] || DEFAULT_PER_PAGE)
60
61
  end
61
62
 
63
+ def manual_query?
64
+ !manual_query.nil?
65
+ end
66
+
67
+ def manual_query(value = nil)
68
+ return @manual_query if value.nil?
69
+ @manual_query = value
70
+ self
71
+ end
72
+
62
73
  def disable_pagination?
63
74
  @disable_pagination
64
75
  end
@@ -85,6 +96,10 @@ module Appfuel
85
96
  self
86
97
  end
87
98
 
99
+ def single?
100
+ first? || last?
101
+ end
102
+
88
103
  def all?
89
104
  @all
90
105
  end
@@ -1,8 +1,21 @@
1
+ require 'parslet'
2
+ require 'parslet/convenience'
3
+
1
4
  require_relative 'repository/base'
2
5
  require_relative 'repository/mapping_entry'
3
6
  require_relative 'repository/mapping_dsl'
4
7
  require_relative 'repository/mapper'
5
8
  require_relative 'repository/initializer'
9
+ require_relative 'repository/runner'
10
+ require_relative 'repository/expr'
11
+ require_relative 'repository/expr_conjunction'
12
+ require_relative 'repository/order_expr'
13
+ require_relative 'repository/criteria'
14
+ require_relative 'repository/expr_parser'
15
+ require_relative 'repository/search_parser'
16
+ require_relative 'repository/expr_transform'
17
+ require_relative 'repository/search_transform'
18
+ require_relative 'repository/settings'
6
19
 
7
20
  module Appfuel
8
21
  module Repository
@@ -1,3 +1,4 @@
1
+ require_relative 'storage/repository'
1
2
  require_relative 'storage/file'
2
3
  require_relative 'storage/memory'
3
4
  require_relative 'storage/db'
@@ -1,3 +1,3 @@
1
1
  module Appfuel
2
- VERSION = "0.2.5"
2
+ VERSION = "0.2.6"
3
3
  end
data/lib/appfuel.rb CHANGED
@@ -197,8 +197,6 @@ end
197
197
  # Domain Entities
198
198
  require "appfuel/domain"
199
199
  require "appfuel/presenter"
200
- require "appfuel/repository"
201
- require "appfuel/repository_runner"
202
200
  require "appfuel/storage"
203
201
  require "appfuel/handler"
204
202
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appfuel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Scott-Buccleuch
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-25 00:00:00.000000000 Z
11
+ date: 2017-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.2
19
+ version: 5.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.2
26
+ version: 5.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dry-types
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -259,6 +259,7 @@ files:
259
259
  - lib/appfuel/application.rb
260
260
  - lib/appfuel/application/app_container.rb
261
261
  - lib/appfuel/application/container_class_registration.rb
262
+ - lib/appfuel/application/dispatcher.rb
262
263
  - lib/appfuel/application/root.rb
263
264
  - lib/appfuel/cli_msg_request.rb
264
265
  - lib/appfuel/configuration.rb
@@ -267,19 +268,11 @@ files:
267
268
  - lib/appfuel/configuration/populate.rb
268
269
  - lib/appfuel/configuration/search.rb
269
270
  - lib/appfuel/domain.rb
270
- - lib/appfuel/domain/base_criteria.rb
271
271
  - lib/appfuel/domain/criteria_builder.rb
272
- - lib/appfuel/domain/criteria_settings.rb
273
272
  - lib/appfuel/domain/domain_name_parser.rb
274
273
  - lib/appfuel/domain/dsl.rb
275
274
  - lib/appfuel/domain/entity.rb
276
275
  - lib/appfuel/domain/entity_collection.rb
277
- - lib/appfuel/domain/exists_criteria.rb
278
- - lib/appfuel/domain/expr.rb
279
- - lib/appfuel/domain/expr_conjunction.rb
280
- - lib/appfuel/domain/expr_parser.rb
281
- - lib/appfuel/domain/expr_transform.rb
282
- - lib/appfuel/domain/search_criteria.rb
283
276
  - lib/appfuel/domain/value_object.rb
284
277
  - lib/appfuel/errors.rb
285
278
  - lib/appfuel/feature.rb
@@ -297,13 +290,6 @@ files:
297
290
  - lib/appfuel/predicates.rb
298
291
  - lib/appfuel/presenter.rb
299
292
  - lib/appfuel/presenter/base.rb
300
- - lib/appfuel/repository.rb
301
- - lib/appfuel/repository/base.rb
302
- - lib/appfuel/repository/initializer.rb
303
- - lib/appfuel/repository/mapper.rb
304
- - lib/appfuel/repository/mapping_dsl.rb
305
- - lib/appfuel/repository/mapping_entry.rb
306
- - lib/appfuel/repository_runner.rb
307
293
  - lib/appfuel/request.rb
308
294
  - lib/appfuel/response.rb
309
295
  - lib/appfuel/response_handler.rb
@@ -323,6 +309,22 @@ files:
323
309
  - lib/appfuel/storage/memory.rb
324
310
  - lib/appfuel/storage/memory/mapper.rb
325
311
  - lib/appfuel/storage/memory/repository.rb
312
+ - lib/appfuel/storage/repository.rb
313
+ - lib/appfuel/storage/repository/base.rb
314
+ - lib/appfuel/storage/repository/criteria.rb
315
+ - lib/appfuel/storage/repository/expr.rb
316
+ - lib/appfuel/storage/repository/expr_conjunction.rb
317
+ - lib/appfuel/storage/repository/expr_parser.rb
318
+ - lib/appfuel/storage/repository/expr_transform.rb
319
+ - lib/appfuel/storage/repository/initializer.rb
320
+ - lib/appfuel/storage/repository/mapper.rb
321
+ - lib/appfuel/storage/repository/mapping_dsl.rb
322
+ - lib/appfuel/storage/repository/mapping_entry.rb
323
+ - lib/appfuel/storage/repository/order_expr.rb
324
+ - lib/appfuel/storage/repository/runner.rb
325
+ - lib/appfuel/storage/repository/search_parser.rb
326
+ - lib/appfuel/storage/repository/search_transform.rb
327
+ - lib/appfuel/storage/repository/settings.rb
326
328
  - lib/appfuel/types.rb
327
329
  - lib/appfuel/validation.rb
328
330
  - lib/appfuel/validation/validator.rb
@@ -1,171 +0,0 @@
1
- module Appfuel
2
- module Domain
3
-
4
- # The Criteria represents the interface between the repositories and actions
5
- # or commands. The allow you to find entities in the application storage (
6
- # a database) without knowledge of that storage system. The criteria will
7
- # always refer to its queries in the domain language for which the repo is
8
- # responsible for mapping that query to its persistence layer.
9
- #
10
- # global.user
11
- # memberships.user
12
- #
13
- # exist: 'foo.bar exists id = 6'
14
- # search: 'foo.bar filter id = 6 and bar = "foo" order id asc limit 6'
15
- #
16
- # search:
17
- # domain: 'foo.bar',
18
- #
19
- # filters: 'id = 6 or id = 8 and id = 9'
20
- # filters: [
21
- # 'id = 6',
22
- # {or: 'id = 8'}
23
- # {and: id = 9'}
24
- # ]
25
- #
26
- # order: 'foo.bar.id asc'
27
- # order: 'foo.bar.id'
28
- # order: [
29
- # 'foo.bar.id',
30
- # {desc: 'foo.bar.id'},
31
- # {asc: 'foo.bar.id'}
32
- # ]
33
- # limit: 1
34
- #
35
- # settings:
36
- # page: 1
37
- # per_page: 2
38
- # disable_pagination
39
- # first
40
- # all
41
- # last
42
- # error_on_empty
43
- # parser
44
- # transform
45
- #
46
- # exists:
47
- # domain:
48
- # expr:
49
- #
50
- #
51
- class BaseCriteria
52
- include DomainNameParser
53
-
54
-
55
- attr_reader :domain_basename, :domain_name, :feature, :settings, :filters
56
-
57
- # Parse out the domain into feature, domain, determine the name of the
58
- # repo this criteria is for and initailize basic settings.
59
- # global.user
60
- #
61
- # membership.user
62
- # foo.id filter name like "foo" order foo.bar.id asc limit 2
63
- # foo.id exists foo.id = 5
64
- #
65
- # @example
66
- # SpCore::Domain::Criteria('foo', single: true)
67
- # Types.Criteria('foo.bar', single: true)
68
- #
69
- # === Options
70
- # error_on_empty: will cause the repo to fail when query returns an
71
- # an empty dataset. The failure will have the message
72
- # with key as domain and text is "<domain> not found"
73
- #
74
- # single: will cause the repo to return only one, the first,
75
- # entity in the dataset
76
- #
77
- # @param domain [String] fully qualified domain name
78
- # @param opts [Hash] options for initializing criteria
79
- # @return [Criteria]
80
- def initialize(domain_name, data = {})
81
- @feature, @domain_basename, @domain_name = parse_domain_name(domain_name)
82
- @settings = data[:settings] || CriteriaSettings.new(data)
83
- @filters = nil
84
- @params = {}
85
- end
86
-
87
- def clear_filters
88
- @filters = nil
89
- end
90
-
91
- def filters?
92
- !filters.nil?
93
- end
94
-
95
- def global?
96
- !feature?
97
- end
98
-
99
- def feature?
100
- @feature != 'global'
101
- end
102
-
103
- # @example
104
- # criteria.add_param('foo', 100)
105
- #
106
- # @param key [Symbol, String] The key name where we want to keep the value
107
- # @param value [String, Integer] The value that belongs to the key param
108
- # @return [String, Integer] The saved value
109
- def add_param(key, value)
110
- fail 'key should not be nil' if key.nil?
111
-
112
- @params[key.to_sym] = value
113
- end
114
-
115
- # @param key [String, Symbol]
116
- # @return [String, Integer, Boolean] the found value
117
- def param(key)
118
- @params[key.to_sym]
119
- end
120
-
121
- # @param key [String, Symbol]
122
- # @return [Boolean]
123
- def param?(key)
124
- @params.key?(key.to_sym)
125
- end
126
-
127
- # @return [Boolean] if the @params variable has values
128
- def params?
129
- !@params.empty?
130
- end
131
-
132
- private
133
- def parse_expr(str)
134
- if !(settings.parser && settings.parser.respond_to?(:parse))
135
- fail "expression parser must implement to :parse"
136
- end
137
-
138
- if !(settings.transform && settings.transform.respond_to?(:apply))
139
- fail "expression transform must implement :apply"
140
- end
141
-
142
- begin
143
- tree = settings.parser.parse(str)
144
- rescue Parslet::ParseFailed => e
145
- msg = "The expression (#{str}) failed to parse"
146
- err = RuntimeError.new(msg)
147
- err.set_backtrace(e.backtrace)
148
- raise err
149
- end
150
-
151
- result = settings.transform.apply(tree)
152
- result = result[:domain_expr] || result[:root]
153
- unless result
154
- fail "unable to parse (#{str}) correctly"
155
- end
156
- result
157
- end
158
-
159
- def qualify_expr(domain_expr)
160
- return domain_expr if domain_expr.qualified?
161
- if global?
162
- domain_expr.qualify_global(domain_basename)
163
- return domain_expr
164
- end
165
-
166
- domain_expr.qualify_feature(feature, domain_basename)
167
- domain_expr
168
- end
169
- end
170
- end
171
- end