dbee 2.0.1 → 2.1.1

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: 4cccb1a5e9bf46985f887caa422c34401a0fcfd6b792b47e7a58ca1111ed6bef
4
- data.tar.gz: 9814c17b3483ebb7d5303eb95576e2f94321cae1cd4db219cb57da564316c43b
3
+ metadata.gz: b3c9c1444028bdfd5a4aa9eeb8c98055184f1b2cec2b819376e3f5344850d3b9
4
+ data.tar.gz: '059ac6adca29bae5a1eb0fc9f13247159047f1e8c82b3b31398d4492913ef595'
5
5
  SHA512:
6
- metadata.gz: fdf4aa6edf57d80e1c6ba29db2b4776f6e6acab607962b093648fd3f6fad812c17d7f15d664b0fe14becd46bcd71f785ea643ad4ffdac2d61154011feb27471d
7
- data.tar.gz: 472bfcd22ebee89c2c15f789c90f1147d2938941283fc4a29400e7316de42166ffc34497ee7d1ec447e7be4e26cc3276c2e06d7260976fb3dc38633e808b85b0
6
+ metadata.gz: f67474cd84508029e3f3ca6e91ee2a1192b3cb1f8bf36f6b2d18a9c51e75ba3af897b01ea16676c6c79b000bd8d44d1381a7785fa56a9b81b906d47332e1c687
7
+ data.tar.gz: 6d6d061db4ef0c39cc1af32368d725c8354af5fc143a562f10e3beed7c3d260f7ddc93ab2aaff6016c483f370e9ccfec5e54c72dffcb8044c723025cb40dfdb5
@@ -1,6 +1,13 @@
1
- Metrics/LineLength:
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+ NewCops: enable
4
+
5
+ Layout/LineLength:
2
6
  Max: 100
3
7
 
8
+ Metrics/AbcSize:
9
+ Max: 16
10
+
4
11
  Metrics/BlockLength:
5
12
  ExcludedMethods:
6
13
  - let
@@ -10,14 +17,8 @@ Metrics/BlockLength:
10
17
  - specify
11
18
  - define
12
19
 
13
- Metrics/MethodLength:
14
- Max: 25
15
-
16
- AllCops:
17
- TargetRubyVersion: 2.4
18
-
19
- Metrics/AbcSize:
20
- Max: 16
21
-
22
20
  Metrics/ClassLength:
23
21
  Max: 125
22
+
23
+ Metrics/MethodLength:
24
+ Max: 25
@@ -1 +1 @@
1
- 2.6.3
1
+ 2.6.6
@@ -4,9 +4,9 @@ env:
4
4
  language: ruby
5
5
  rvm:
6
6
  # Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
7
- - 2.4.6
8
- - 2.5.5
9
- - 2.6.3
7
+ - 2.5.8
8
+ - 2.6.6
9
+ - 2.7.1
10
10
  cache: bundler
11
11
  before_script:
12
12
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
@@ -1,3 +1,45 @@
1
+ # 2.1.1 (July 14th, 2020)
2
+
3
+ * Removed guard that ensured a query has at least one field to establish a more rational base-case.
4
+
5
+ # 2.1.0 (July 13th, 2020)
6
+
7
+ ### Additions:
8
+
9
+ * Added Dbee::Query::Field#aggregator (such as ave, min, max, sum, etc.)
10
+ * Added Dbee::Query::Field#filters (allows for doing select column filtering)
11
+
12
+ ### Changes:
13
+
14
+ * Bumped minimum Ruby version to 2.5
15
+
16
+ # 2.0.3 (January 7th, 2020)
17
+
18
+ ### Fixes:
19
+
20
+ * Constant resolution will now explicitly set inherit to false when calling `Object#const_defined?` and `Object#const_get`. This should equate to less false positives. For example:
21
+
22
+ ```ruby
23
+ class A; end
24
+
25
+ module B
26
+ class A; end
27
+ class C; end
28
+ end
29
+ ```
30
+
31
+ If `B::A` is the desired class, it would not be suitable to just declare an association on `A` as that would resolve explicitly to `::A`. It also means C cannot be auto-resolved without prefixing/sharing the namespace with parent association `A`.
32
+
33
+ # 2.0.2 (November 7th, 2019)
34
+
35
+ ### Additions:
36
+
37
+ * As of 2019-11-07, it is not recommended to use Ruby 2.3, but support was requested and added for Ruby 2.3.8. This is subject to being deprecated with next version.
38
+
39
+ ### Fixes:
40
+
41
+ * Constantizing during inflection will now first check Object#const_defined? and if it is missing, it will now call Object#const_missing. This should work better with auto-loaded environments where constant names may collide, since Object#const_get will traverse down the entire hierarchy and may lead to false positives.
42
+
1
43
  # 2.0.0 (September 3rd, 2019)
2
44
 
3
45
  ### Additions:
data/README.md CHANGED
@@ -363,6 +363,22 @@ You execute a Query against a Data Model, using a Provider. The sample provider
363
363
 
364
364
  Here are some sample executions based off the preceding examples:
365
365
 
366
+ ##### Base Case
367
+
368
+ If a query has no fields then it is implied you would like all fields on the root table. For example:
369
+
370
+ ````ruby
371
+ require 'dbee/providers/active_record_provider'
372
+
373
+ class Practice < Dbee::Base; end
374
+
375
+ provider = Dbee::Providers::ActiveRecordProvider.new
376
+ query = {}
377
+ sql = Dbee.sql(Practice, query, provider)
378
+ ````
379
+
380
+ It equivalent to saying: `SELECT practices.* FROM practices`. This helps to establish a deterministic base-case: it returns the same implicit columns that is independent of sql joins (sorters and/or filters may require sql joins.)
381
+
366
382
  ##### Code-First Execution
367
383
 
368
384
  ````ruby
@@ -407,6 +423,129 @@ sql = Dbee.sql(model, query, provider)
407
423
 
408
424
  The above examples showed how to use a plugin provider, see the plugin provider's documentation for more information about its options and use.
409
425
 
426
+ #### Aggregation
427
+
428
+ Fields can be configured to use aggregation by setting its `aggregator` attribute. For example, say we wanted to count the number of patients per practice:
429
+
430
+ **Data Model**:
431
+
432
+ ````yaml
433
+ name: practice
434
+ models:
435
+ - name: patients
436
+ constraints:
437
+ - type: reference
438
+ name: practice_id
439
+ parent: id
440
+ ````
441
+
442
+ **Query**:
443
+
444
+ ````ruby
445
+ query = {
446
+ fields: [
447
+ {
448
+ key_path: 'id',
449
+ display: 'Practice ID #',
450
+ },
451
+ {
452
+ key_path: 'name',
453
+ display: 'Practice Name',
454
+ },
455
+ {
456
+ key_path: 'patients.id',
457
+ display: 'Total Patients',
458
+ aggregator: :count
459
+ },
460
+ ]
461
+ ````
462
+
463
+ An example of a materialized result would be something akin to:
464
+
465
+ Practice ID # | Practice Name | Total Patients
466
+ ------------- | --------------- | --------------
467
+ 1 | Families Choice | 293
468
+ 2 | Awesome Choice | 2305
469
+ 3 | Best Value | 1200
470
+
471
+ A complete list of aggregator values can be found by inspecting the `Dbee::Query::Field::Aggregator` constant.
472
+
473
+ #### Field/Column Level Filtering & Pivoting
474
+
475
+ Fields can also have filters which provide post-filtering (on the select-level instead of at query-level.) This can be used in conjunction with aggregate functions to provide pivoting. For example:
476
+
477
+ **Data/Schema Example**:
478
+
479
+ patients:
480
+
481
+ id | first | last
482
+ -- | ----- | -----
483
+ 1 | frank | rizzo
484
+
485
+ patient_fields:
486
+
487
+ id | patient_id | key | value
488
+ -- | ---------- | --------------- | -----
489
+ 1 | 1 | dob | 1900-01-01
490
+ 2 | 1 | drivers_license | ABC123
491
+
492
+ **Model Configuration**:
493
+
494
+ ````yaml
495
+ name: patients
496
+ models:
497
+ - name: patient_fields
498
+ constraints:
499
+ - type: reference
500
+ parent: id
501
+ name: patient_id
502
+ ````
503
+
504
+ **Query**:
505
+
506
+ ````ruby
507
+ query = {
508
+ fields: [
509
+ {
510
+ key_path: 'id',
511
+ display: 'ID #'
512
+ },
513
+ {
514
+ key_path: 'first',
515
+ display: 'First Name'
516
+ },
517
+ {
518
+ aggregator: :max,
519
+ key_path: 'patient_fields.value',
520
+ display: 'Date of Birth',
521
+ filters: [
522
+ {
523
+ key_path: 'patient_fields.key',
524
+ value: 'dob'
525
+ }
526
+ ]
527
+ },
528
+ {
529
+ aggregator: :max,
530
+ key_path: 'patient_fields.value',
531
+ display: 'Drivers License #',
532
+ filters: [
533
+ {
534
+ key_path: 'patient_fields.key',
535
+ value: 'drivers_license'
536
+ }
537
+ ]
538
+ }
539
+ }
540
+ }
541
+ ````
542
+
543
+ Executing the query above against the data and model would yield:
544
+
545
+ ID # | First Name | Date of Birth | Drivers License #
546
+ -- | ---------- | ------------- | -----------------
547
+ 1 | frank | 1900-01-01 | ABC123
548
+
410
549
 
411
550
  ## Contributing
412
551
 
@@ -15,20 +15,28 @@ Gem::Specification.new do |s|
15
15
  s.email = ['mruggio@bluemarblepayroll.com']
16
16
  s.files = `git ls-files`.split("\n")
17
17
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
18
+ s.bindir = 'exe'
19
+ s.executables = []
19
20
  s.homepage = 'https://github.com/bluemarblepayroll/dbee'
20
21
  s.license = 'MIT'
22
+ s.metadata = {
23
+ 'bug_tracker_uri' => 'https://github.com/bluemarblepayroll/dbee/issues',
24
+ 'changelog_uri' => 'https://github.com/bluemarblepayroll/dbee/blob/master/CHANGELOG.md',
25
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/dbee',
26
+ 'homepage_uri' => s.homepage,
27
+ 'source_code_uri' => s.homepage
28
+ }
21
29
 
22
- s.required_ruby_version = '>= 2.4.6'
30
+ s.required_ruby_version = '>= 2.5'
23
31
 
24
- s.add_dependency('acts_as_hashable', '~>1', '>=1.1.0')
32
+ s.add_dependency('acts_as_hashable', '~>1', '>=1.2.0')
25
33
  s.add_dependency('dry-inflector', '~>0')
26
34
 
27
35
  s.add_development_dependency('guard-rspec', '~>4.7')
28
36
  s.add_development_dependency('pry', '~>0')
29
37
  s.add_development_dependency('rake', '~> 13')
30
38
  s.add_development_dependency('rspec')
31
- s.add_development_dependency('rubocop', '~>0.75.1')
32
- s.add_development_dependency('simplecov', '~>0.17.0')
33
- s.add_development_dependency('simplecov-console', '~>0.5.0')
39
+ s.add_development_dependency('rubocop', '~>0.88.0')
40
+ s.add_development_dependency('simplecov', '~>0.18.5')
41
+ s.add_development_dependency('simplecov-console', '~>0.7.0')
34
42
  end
File without changes
@@ -12,6 +12,7 @@ require 'dry/inflector'
12
12
  require 'forwardable'
13
13
 
14
14
  require_relative 'dbee/base'
15
+ require_relative 'dbee/constant_resolver'
15
16
  require_relative 'dbee/key_chain'
16
17
  require_relative 'dbee/key_path'
17
18
  require_relative 'dbee/model'
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ module Dbee
11
+ # This class is responsible for turning strings and symbols into constants.
12
+ # It does not deal with inflection, simply just constant resolution.
13
+ class ConstantResolver
14
+ # Only use Module constant resolution if a string or symbol was passed in.
15
+ # Any other type is defined as an acceptable constant and is simply returned.
16
+ def constantize(value)
17
+ value.is_a?(String) || value.is_a?(Symbol) ? object_constant(value) : value
18
+ end
19
+
20
+ private
21
+
22
+ # If the constant has been loaded, we can safely use it through const_get.
23
+ # If the constant has not been loaded, we need to defer to const_missing to resolve it.
24
+ # If we blindly call const_get, it may return false positives for namespaced constants
25
+ # or anything nested.
26
+ def object_constant(value)
27
+ if Object.const_defined?(value, false)
28
+ Object.const_get(value, false)
29
+ else
30
+ Object.const_missing(value)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -19,16 +19,17 @@ module Dbee
19
19
  raise ArgumentError, 'inflector is required' unless inflector
20
20
  raise ArgumentError, 'name is required' if name.to_s.empty?
21
21
 
22
- @on_class_name = on_class_name
23
- @inflector = inflector
24
- @name = name.to_s
25
- @opts = opts || {}
22
+ @on_class_name = on_class_name
23
+ @inflector = inflector
24
+ @name = name.to_s
25
+ @opts = opts || {}
26
+ @constant_resolver = ConstantResolver.new
26
27
 
27
28
  freeze
28
29
  end
29
30
 
30
31
  def model_constant
31
- constantize(class_name)
32
+ constant_resolver.constantize(class_name)
32
33
  end
33
34
 
34
35
  def constraints
@@ -37,17 +38,18 @@ module Dbee
37
38
 
38
39
  private
39
40
 
41
+ attr_reader :constant_resolver
42
+
40
43
  def class_name
41
44
  opts[:model] || relative_class_name
42
45
  end
43
46
 
47
+ # This will automatically prefix the name of the module within the current classes
48
+ # hierarchy. If the class does not happen to be in the same namespace then it needs
49
+ # to be explicitly set in the association using 'model' option.
44
50
  def relative_class_name
45
51
  (on_class_name.split('::')[0...-1] + [inflector.classify(name)]).join('::')
46
52
  end
47
-
48
- def constantize(value)
49
- value.is_a?(String) || value.is_a?(Symbol) ? Object.const_get(value) : value
50
- end
51
53
  end
52
54
  end
53
55
  end
@@ -21,37 +21,35 @@ module Dbee
21
21
  extend Forwardable
22
22
  acts_as_hashable
23
23
 
24
- class NoFieldsError < StandardError; end
25
-
26
- attr_reader :fields, :filters, :limit, :sorters
27
-
28
- def_delegator :fields, :sort, :sorted_fields
29
-
30
- def_delegator :filters, :sort, :sorted_filters
31
-
32
- def_delegator :sorters, :sort, :sorted_sorters
33
-
34
- def initialize(fields:, filters: [], limit: nil, sorters: [])
35
- @fields = Field.array(fields)
36
-
37
- # If no fields were passed into a query then we will have no data to return.
38
- # Let's raise a hard error here and let the consumer deal with it since this may
39
- # have implications in downstream SQL generators.
40
- raise NoFieldsError if @fields.empty?
41
-
42
- @filters = Filters.array(filters).uniq
43
- @limit = limit.to_s.empty? ? nil : limit.to_i
44
- @sorters = Sorters.array(sorters).uniq
24
+ attr_reader :fields,
25
+ :filters,
26
+ :limit,
27
+ :sorters
28
+
29
+ def_delegator :fields, :sort, :sorted_fields
30
+ def_delegator :filters, :sort, :sorted_filters
31
+ def_delegator :sorters, :sort, :sorted_sorters
32
+
33
+ def initialize(
34
+ fields: [],
35
+ filters: [],
36
+ limit: nil,
37
+ sorters: []
38
+ )
39
+ @fields = Field.array(fields)
40
+ @filters = Filters.array(filters).uniq
41
+ @limit = limit.to_s.empty? ? nil : limit.to_i
42
+ @sorters = Sorters.array(sorters).uniq
45
43
 
46
44
  freeze
47
45
  end
48
46
 
49
47
  def ==(other)
50
48
  other.instance_of?(self.class) &&
49
+ other.limit == limit &&
51
50
  other.sorted_fields == sorted_fields &&
52
51
  other.sorted_filters == sorted_filters &&
53
- other.sorted_sorters == sorted_sorters &&
54
- other.limit == limit
52
+ other.sorted_sorters == sorted_sorters
55
53
  end
56
54
  alias eql? ==
57
55
 
@@ -62,7 +60,11 @@ module Dbee
62
60
  private
63
61
 
64
62
  def key_paths
65
- (fields.map(&:key_path) + filters.map(&:key_path) + sorters.map(&:key_path))
63
+ (
64
+ fields.flat_map(&:key_paths) +
65
+ filters.map(&:key_path) +
66
+ sorters.map(&:key_path)
67
+ )
66
68
  end
67
69
  end
68
70
  end
@@ -15,24 +15,55 @@ module Dbee
15
15
  class Field
16
16
  acts_as_hashable
17
17
 
18
- attr_reader :key_path, :display
18
+ module Aggregator
19
+ AVE = :ave
20
+ COUNT = :count
21
+ MAX = :max
22
+ MIN = :min
23
+ SUM = :sum
24
+ end
25
+ include Aggregator
26
+
27
+ attr_reader :aggregator, :display, :filters, :key_path
19
28
 
20
- def initialize(key_path:, display: nil)
29
+ def initialize(
30
+ aggregator: nil,
31
+ display: nil,
32
+ filters: [],
33
+ key_path:
34
+ )
21
35
  raise ArgumentError, 'key_path is required' if key_path.to_s.empty?
22
36
 
23
- @key_path = KeyPath.get(key_path)
24
- @display = (display.to_s.empty? ? key_path : display).to_s
37
+ @aggregator = aggregator ? Aggregator.const_get(aggregator.to_s.upcase.to_sym) : nil
38
+ @display = (display.to_s.empty? ? key_path : display).to_s
39
+ @filters = Filters.array(filters).uniq
40
+ @key_path = KeyPath.get(key_path)
25
41
 
26
42
  freeze
27
43
  end
28
44
 
45
+ def filters?
46
+ filters.any?
47
+ end
48
+
49
+ def aggregator?
50
+ !aggregator.nil?
51
+ end
52
+
29
53
  def hash
30
- "#{key_path}#{display}".hash
54
+ [
55
+ aggregator,
56
+ display,
57
+ filters,
58
+ key_path
59
+ ].hash
31
60
  end
32
61
 
33
62
  def ==(other)
34
63
  other.instance_of?(self.class) &&
64
+ other.aggregator == aggregator &&
35
65
  other.key_path == key_path &&
66
+ other.filters == filters &&
36
67
  other.display == display
37
68
  end
38
69
  alias eql? ==
@@ -40,6 +71,10 @@ module Dbee
40
71
  def <=>(other)
41
72
  "#{key_path}#{display}" <=> "#{other.key_path}#{other.display}"
42
73
  end
74
+
75
+ def key_paths
76
+ [key_path] + filters.map(&:key_path)
77
+ end
43
78
  end
44
79
  end
45
80
  end
@@ -8,5 +8,5 @@
8
8
  #
9
9
 
10
10
  module Dbee
11
- VERSION = '2.0.1'
11
+ VERSION = '2.1.1'
12
12
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright (c) 2019-present, Blue Marble Payroll, LLC
5
+ #
6
+ # This source code is licensed under the MIT license found in the
7
+ # LICENSE file in the root directory of this source tree.
8
+ #
9
+
10
+ require 'spec_helper'
11
+
12
+ describe Dbee::ConstantResolver do
13
+ module A
14
+ class B; end
15
+ class E; end
16
+ end
17
+
18
+ class B; end
19
+
20
+ module C
21
+ class D; end
22
+ class E; end
23
+
24
+ module F
25
+ class G; end
26
+ end
27
+ end
28
+
29
+ it 'resolves nested constant with the same as an ancestor constants sibling' do
30
+ expect(subject.constantize('A::B')).to eq(::A::B)
31
+ end
32
+
33
+ it 'resolves root constant' do
34
+ expect(subject.constantize('B')).to eq(::B)
35
+ end
36
+
37
+ it 'does not resolve constant in a different parent module' do
38
+ expect { subject.constantize('C::B') }.to raise_error(NameError)
39
+ end
40
+
41
+ it 'does not resolve constant in a different parent module' do
42
+ expect { subject.constantize('D') }.to raise_error(NameError)
43
+ end
44
+
45
+ it 'resolves same leaf constants specific to their parents' do
46
+ expect(subject.constantize('A::E')).to eq(::A::E)
47
+ expect(subject.constantize('C::E')).to eq(::C::E)
48
+ end
49
+
50
+ it 'does not resolve constant without its parent' do
51
+ expect { subject.constantize('F') }.to raise_error(NameError)
52
+ end
53
+ end
@@ -10,6 +10,31 @@
10
10
  require 'spec_helper'
11
11
 
12
12
  describe Dbee::Query::Field do
13
+ let(:config) do
14
+ {
15
+ display: 'd',
16
+ key_path: 'a.b.c'
17
+ }
18
+ end
19
+
20
+ let(:config_with_aggregation_and_filters) do
21
+ config.merge(
22
+ aggregator: :ave,
23
+ filters: [
24
+ {
25
+ key_path: 'a.b',
26
+ value: 'something'
27
+ }
28
+ ]
29
+ )
30
+ end
31
+
32
+ subject { described_class.new(config_with_aggregation_and_filters) }
33
+
34
+ let(:subject_without_aggregation_and_filters) do
35
+ described_class.new(config)
36
+ end
37
+
13
38
  it 'should act as hashable' do
14
39
  expect(described_class).to respond_to(:make)
15
40
  expect(described_class).to respond_to(:array)
@@ -24,16 +49,19 @@ describe Dbee::Query::Field do
24
49
  end
25
50
 
26
51
  context 'equality' do
27
- let(:config) { { key_path: 'a.b.c', display: 'd' } }
52
+ specify '#hash produces same output as [aggregator, key_path, and display]' do
53
+ expected = [
54
+ subject.aggregator,
55
+ subject.display,
56
+ subject.filters,
57
+ subject.key_path
58
+ ].hash
28
59
 
29
- subject { described_class.new(config) }
30
-
31
- specify '#hash produces same output as concatenated string hash of key_path and display' do
32
- expect(subject.hash).to eq("#{config[:key_path]}#{config[:display]}".hash)
60
+ expect(subject.hash).to eq(expected)
33
61
  end
34
62
 
35
63
  specify '#== and #eql? compare attributes' do
36
- object2 = described_class.new(config)
64
+ object2 = described_class.new(config_with_aggregation_and_filters)
37
65
 
38
66
  expect(subject).to eq(object2)
39
67
  expect(subject).to eql(object2)
@@ -44,4 +72,24 @@ describe Dbee::Query::Field do
44
72
  expect(subject).not_to eq(nil)
45
73
  end
46
74
  end
75
+
76
+ describe '#aggregator?' do
77
+ it 'returns true if not nil' do
78
+ expect(subject.aggregator?).to be true
79
+ end
80
+
81
+ it 'returns false if nil' do
82
+ expect(subject_without_aggregation_and_filters.aggregator?).to be false
83
+ end
84
+ end
85
+
86
+ describe '#filters?' do
87
+ it 'returns true if at least one filter' do
88
+ expect(subject.filters?).to be true
89
+ end
90
+
91
+ it 'returns false if nil' do
92
+ expect(subject_without_aggregation_and_filters.filters?).to be false
93
+ end
94
+ end
47
95
  end
@@ -36,14 +36,6 @@ describe Dbee::Query do
36
36
  end
37
37
 
38
38
  describe '#initialize' do
39
- it 'should raise an ArgumentError if fields keyword is missing' do
40
- expect { described_class.new }.to raise_error(ArgumentError)
41
- end
42
-
43
- it 'should raise a NoFieldsError if no fields were passed in' do
44
- expect { described_class.new(fields: []) }.to raise_error(Dbee::Query::NoFieldsError)
45
- end
46
-
47
39
  it 'should remove duplicate filters (keep first instance)' do
48
40
  query_hash = {
49
41
  fields: [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbee
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Ruggio
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-15 00:00:00.000000000 Z
11
+ date: 2020-07-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: acts_as_hashable
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '1'
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 1.1.0
22
+ version: 1.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: '1'
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: 1.1.0
32
+ version: 1.2.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: dry-inflector
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -106,50 +106,49 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 0.75.1
109
+ version: 0.88.0
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 0.75.1
116
+ version: 0.88.0
117
117
  - !ruby/object:Gem::Dependency
118
118
  name: simplecov
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
122
122
  - !ruby/object:Gem::Version
123
- version: 0.17.0
123
+ version: 0.18.5
124
124
  type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: 0.17.0
130
+ version: 0.18.5
131
131
  - !ruby/object:Gem::Dependency
132
132
  name: simplecov-console
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: 0.5.0
137
+ version: 0.7.0
138
138
  type: :development
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: 0.5.0
144
+ version: 0.7.0
145
145
  description: " Dbee provides a simple-to-use data modeling and query API. The
146
146
  query API can produce SQL using other ORMs, such as Arel/ActiveRecord. The targeted
147
147
  use-case for Dbee is ad-hoc reporting, so the total SQL feature-set that Dbee supports
148
148
  is rather limited.\n"
149
149
  email:
150
150
  - mruggio@bluemarblepayroll.com
151
- executables:
152
- - console
151
+ executables: []
153
152
  extensions: []
154
153
  extra_rdoc_files: []
155
154
  files:
@@ -167,8 +166,10 @@ files:
167
166
  - Rakefile
168
167
  - bin/console
169
168
  - dbee.gemspec
169
+ - exe/.gitkeep
170
170
  - lib/dbee.rb
171
171
  - lib/dbee/base.rb
172
+ - lib/dbee/constant_resolver.rb
172
173
  - lib/dbee/dsl/association.rb
173
174
  - lib/dbee/dsl/association_builder.rb
174
175
  - lib/dbee/dsl/methods.rb
@@ -203,6 +204,7 @@ files:
203
204
  - lib/dbee/query/sorters/descending.rb
204
205
  - lib/dbee/version.rb
205
206
  - spec/dbee/base_spec.rb
207
+ - spec/dbee/constant_resolver_spec.rb
206
208
  - spec/dbee/key_chain_spec.rb
207
209
  - spec/dbee/key_path_spec.rb
208
210
  - spec/dbee/model/constraints/base_spec.rb
@@ -225,7 +227,12 @@ files:
225
227
  homepage: https://github.com/bluemarblepayroll/dbee
226
228
  licenses:
227
229
  - MIT
228
- metadata: {}
230
+ metadata:
231
+ bug_tracker_uri: https://github.com/bluemarblepayroll/dbee/issues
232
+ changelog_uri: https://github.com/bluemarblepayroll/dbee/blob/master/CHANGELOG.md
233
+ documentation_uri: https://www.rubydoc.info/gems/dbee
234
+ homepage_uri: https://github.com/bluemarblepayroll/dbee
235
+ source_code_uri: https://github.com/bluemarblepayroll/dbee
229
236
  post_install_message:
230
237
  rdoc_options: []
231
238
  require_paths:
@@ -234,7 +241,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
234
241
  requirements:
235
242
  - - ">="
236
243
  - !ruby/object:Gem::Version
237
- version: 2.4.6
244
+ version: '2.5'
238
245
  required_rubygems_version: !ruby/object:Gem::Requirement
239
246
  requirements:
240
247
  - - ">="
@@ -247,6 +254,7 @@ specification_version: 4
247
254
  summary: Adhoc Reporting SQL Generator
248
255
  test_files:
249
256
  - spec/dbee/base_spec.rb
257
+ - spec/dbee/constant_resolver_spec.rb
250
258
  - spec/dbee/key_chain_spec.rb
251
259
  - spec/dbee/key_path_spec.rb
252
260
  - spec/dbee/model/constraints/base_spec.rb