mongo_aggregation_dsl 0.0.0.pre4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +61 -0
  3. data/.gitignore +54 -0
  4. data/.reek.yml +5 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +51 -0
  7. data/.ruby-version +1 -0
  8. data/Gemfile +10 -0
  9. data/Gemfile.lock +205 -0
  10. data/README.md +56 -0
  11. data/Rakefile +8 -0
  12. data/codecov.yml +3 -0
  13. data/config/pronto-circleci.yml +7 -0
  14. data/lib/aggregate/contracts/class_includes.rb +26 -0
  15. data/lib/aggregate/contracts/hash_max_length.rb +24 -0
  16. data/lib/aggregate/contracts/hash_min_length.rb +24 -0
  17. data/lib/aggregate/contracts/hash_value_type.rb +31 -0
  18. data/lib/aggregate/contracts/starts_with.rb +24 -0
  19. data/lib/aggregate/contracts.rb +8 -0
  20. data/lib/aggregate/pipeline.rb +41 -0
  21. data/lib/aggregate/stages/base.rb +20 -0
  22. data/lib/aggregate/stages/facet.rb +24 -0
  23. data/lib/aggregate/stages/group.rb +25 -0
  24. data/lib/aggregate/stages/hash_base.rb +13 -0
  25. data/lib/aggregate/stages/lookup.rb +26 -0
  26. data/lib/aggregate/stages/match.rb +25 -0
  27. data/lib/aggregate/stages/project.rb +17 -0
  28. data/lib/aggregate/stages/replace_root.rb +22 -0
  29. data/lib/aggregate/stages/unwind.rb +29 -0
  30. data/lib/aggregate/stages.rb +10 -0
  31. data/lib/aggregate/values/array.rb +20 -0
  32. data/lib/aggregate/values/base.rb +46 -0
  33. data/lib/aggregate/values/document_class.rb +27 -0
  34. data/lib/aggregate/values/hash.rb +43 -0
  35. data/lib/aggregate/values/nil.rb +25 -0
  36. data/lib/aggregate/values/object_id.rb +24 -0
  37. data/lib/aggregate/values/string.rb +22 -0
  38. data/lib/aggregate/values/symbol.rb +52 -0
  39. data/lib/aggregate/values.rb +8 -0
  40. data/lib/aggregate.rb +19 -0
  41. data/lib/mongo_aggregation_dsl.rb +3 -0
  42. data/mongo_aggregation_dsl.gemspec +42 -0
  43. metadata +385 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 939d254e03bcd1b34e04c7de797781863e8a9a53
4
+ data.tar.gz: d91bb52fd5bc15ef8a198715484f29ea1d3e887f
5
+ SHA512:
6
+ metadata.gz: ced780b0b600bcf8b069445de552314d49fbcf4b22db1502f25b30ffe29a4d196ffba9b3da6f7aa9ad19685c49969dfd5c494957874cca3199749082cba8efb3
7
+ data.tar.gz: 58c41fc7f244b76fc54d6ee77cdb0e445ad24d17fcd82f4ce54ef6a6d7e9a31235207b928b2d60e67e80d5251f9556b9747061347694c90ae78a0974cf1cd8c7
@@ -0,0 +1,61 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.3.4-node-browsers
11
+ environment:
12
+
13
+ working_directory: ~/repo
14
+
15
+ steps:
16
+ - checkout
17
+
18
+ # Download and cache dependencies
19
+ - restore_cache:
20
+ keys:
21
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
22
+ # fallback to using the latest cache if no exact match is found
23
+ - v1-dependencies-
24
+
25
+ - run:
26
+ name: Install system dependencies
27
+ command: |
28
+ sudo apt-get update
29
+ sudo apt-get install cmake
30
+
31
+ - run:
32
+ name: install dependencies
33
+ command: |
34
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
35
+
36
+ - save_cache:
37
+ paths:
38
+ - ./venv
39
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
40
+
41
+ - run:
42
+ name: pronto
43
+ command: echo ${PRONTO_GITHUB_ACCESS_TOKEN} && bundle exec pronto-circleci
44
+
45
+ # run tests!
46
+ - run:
47
+ name: run tests
48
+ command: |
49
+ mkdir /tmp/test-results
50
+
51
+ bundle exec rspec --format progress \
52
+ --format RspecJunitFormatter \
53
+ --out /tmp/test-results/rspec.xml \
54
+ --format progress
55
+
56
+ # collect reports
57
+ - store_test_results:
58
+ path: /tmp/test-results
59
+ - store_artifacts:
60
+ path: /tmp/test-results
61
+ destination: test-results
data/.gitignore ADDED
@@ -0,0 +1,54 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
51
+
52
+ .idea/
53
+ .rspec_status
54
+ cornucopia_report/
data/.reek.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ detectors:
3
+ # TooManyStatements is covered by RuboCop.
4
+ TooManyStatements:
5
+ enabled: false
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,51 @@
1
+ # https://github.com/bbatsov/rubocop/blob/master/config/default.yml
2
+
3
+ Documentation:
4
+ Enabled: false
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 2.3
8
+ Exclude:
9
+ - "bin/**/*"
10
+
11
+ LineLength:
12
+ Max: 150
13
+
14
+ ## Multi-line method chaining should be done with leading dots.
15
+ Layout/DotPosition:
16
+ EnforcedStyle: trailing
17
+
18
+ Layout/MultilineMethodCallIndentation:
19
+ Enabled: false
20
+
21
+ Layout/MultilineOperationIndentation:
22
+ Enabled: false
23
+
24
+ Metrics/MethodLength:
25
+ Max: 15
26
+
27
+ StringLiterals:
28
+ EnforcedStyle: double_quotes
29
+
30
+ IndentHash:
31
+ EnforcedStyle: consistent
32
+
33
+ # Indentation of `when`.
34
+ Layout/CaseIndentation:
35
+ EnforcedStyle: case
36
+ SupportedStyles:
37
+ - case
38
+ - end
39
+ IndentOneStep: true
40
+ # By default, the indentation width from Style/IndentationWidth is used
41
+ # But it can be overridden by setting this parameter
42
+ # This only matters if IndentOneStep is true
43
+ IndentationWidth: ~
44
+
45
+ Metrics/ClassLength:
46
+ Max: 150
47
+
48
+ Metrics/BlockLength:
49
+ Exclude:
50
+ - "spec/**/*"
51
+ - "*.gemspec"
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.1
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in acts-as-taggable-on-mongoid.gemspec
8
+ gemspec
9
+
10
+ gem "gem-release"
data/Gemfile.lock ADDED
@@ -0,0 +1,205 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mongo_aggregation_dsl (0.0.0.pre4)
5
+ autoloaded (~> 2)
6
+ contracts-lite
7
+ mongo (~> 2.6.2)
8
+ mongoid (~> 5.2.0)
9
+ origin (~> 2.3.1)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ activemodel (4.2.10)
15
+ activesupport (= 4.2.10)
16
+ builder (~> 3.1)
17
+ activesupport (4.2.10)
18
+ i18n (~> 0.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.3, >= 0.3.4)
21
+ tzinfo (~> 1.1)
22
+ addressable (2.5.2)
23
+ public_suffix (>= 2.0.2, < 4.0)
24
+ ast (2.4.0)
25
+ autoloaded (2.2.1)
26
+ axiom-types (0.1.1)
27
+ descendants_tracker (~> 0.0.4)
28
+ ice_nine (~> 0.11.0)
29
+ thread_safe (~> 0.3, >= 0.3.1)
30
+ brakeman (4.3.1)
31
+ bson (4.3.0)
32
+ builder (3.2.3)
33
+ code_analyzer (0.4.8)
34
+ sexp_processor
35
+ codeclimate-engine-rb (0.4.1)
36
+ virtus (~> 1.0)
37
+ codecov (0.1.10)
38
+ json
39
+ simplecov
40
+ url
41
+ coercible (1.0.0)
42
+ descendants_tracker (~> 0.0.1)
43
+ colorize (0.8.1)
44
+ concurrent-ruby (1.0.5)
45
+ contracts-lite (0.15.0)
46
+ database_cleaner (1.7.0)
47
+ descendants_tracker (0.0.4)
48
+ thread_safe (~> 0.3, >= 0.3.1)
49
+ diff-lcs (1.3)
50
+ docile (1.3.1)
51
+ equalizer (0.0.11)
52
+ erubis (2.7.0)
53
+ faraday (0.15.2)
54
+ multipart-post (>= 1.2, < 3)
55
+ fasterer (0.4.1)
56
+ colorize (~> 0.7)
57
+ ruby_parser (~> 3.11.0)
58
+ gem-release (2.0.1)
59
+ gitlab (4.5.0)
60
+ httparty (>= 0.14.0)
61
+ terminal-table (>= 1.5.1)
62
+ httparty (0.16.2)
63
+ multi_xml (>= 0.5.2)
64
+ i18n (0.9.5)
65
+ concurrent-ruby (~> 1.0)
66
+ ice_nine (0.11.2)
67
+ jaro_winkler (1.5.1)
68
+ json (2.1.0)
69
+ kwalify (0.7.2)
70
+ minitest (5.11.3)
71
+ mongo (2.6.2)
72
+ bson (>= 4.3.0, < 5.0.0)
73
+ mongoid (5.2.1)
74
+ activemodel (~> 4.0)
75
+ mongo (>= 2.4.1, < 3.0.0)
76
+ origin (~> 2.3)
77
+ tzinfo (>= 0.3.37)
78
+ multi_xml (0.6.0)
79
+ multipart-post (2.0.0)
80
+ octokit (4.11.0)
81
+ sawyer (~> 0.8.0, >= 0.5.3)
82
+ origin (2.3.1)
83
+ parallel (1.12.1)
84
+ parser (2.5.1.2)
85
+ ast (~> 2.4.0)
86
+ powerpack (0.1.2)
87
+ pronto (0.9.5)
88
+ gitlab (~> 4.0, >= 4.0.0)
89
+ httparty (>= 0.13.7)
90
+ octokit (~> 4.7, >= 4.7.0)
91
+ rainbow (~> 2.1)
92
+ rugged (~> 0.24, >= 0.23.0)
93
+ thor (~> 0.19.0)
94
+ pronto-brakeman (0.9.1)
95
+ brakeman (>= 3.2.0)
96
+ pronto (~> 0.9.0)
97
+ pronto-circleci (1.0.1)
98
+ pronto (~> 0.9)
99
+ pronto-fasterer (0.9.0)
100
+ fasterer (~> 0.3, >= 0.3.0)
101
+ pronto (~> 0.9.0)
102
+ pronto-rails_best_practices (0.9.0)
103
+ pronto (~> 0.9.0)
104
+ rails_best_practices (~> 1.16, >= 1.15.0)
105
+ pronto-reek (0.9.1)
106
+ pronto (~> 0.9.0)
107
+ reek (>= 4.2, < 6.0)
108
+ pronto-rubocop (0.9.1)
109
+ pronto (~> 0.9.0)
110
+ rubocop (~> 0.50, >= 0.49.1)
111
+ public_suffix (3.0.3)
112
+ rails_best_practices (1.19.3)
113
+ activesupport
114
+ code_analyzer (>= 0.4.8)
115
+ erubis
116
+ i18n
117
+ json
118
+ require_all (~> 2.0)
119
+ ruby-progressbar
120
+ rainbow (2.2.2)
121
+ rake
122
+ rake (10.5.0)
123
+ reek (5.0.2)
124
+ codeclimate-engine-rb (~> 0.4.0)
125
+ kwalify (~> 0.7.0)
126
+ parser (>= 2.5.0.0, < 2.6, != 2.5.1.1)
127
+ rainbow (>= 2.0, < 4.0)
128
+ require_all (2.0.0)
129
+ rspec (3.8.0)
130
+ rspec-core (~> 3.8.0)
131
+ rspec-expectations (~> 3.8.0)
132
+ rspec-mocks (~> 3.8.0)
133
+ rspec-core (3.8.0)
134
+ rspec-support (~> 3.8.0)
135
+ rspec-expectations (3.8.1)
136
+ diff-lcs (>= 1.2.0, < 2.0)
137
+ rspec-support (~> 3.8.0)
138
+ rspec-mocks (3.8.0)
139
+ diff-lcs (>= 1.2.0, < 2.0)
140
+ rspec-support (~> 3.8.0)
141
+ rspec-support (3.8.0)
142
+ rspec_junit_formatter (0.3.0)
143
+ rspec-core (>= 2, < 4, != 2.12.0)
144
+ rubocop (0.59.0)
145
+ jaro_winkler (~> 1.5.1)
146
+ parallel (~> 1.10)
147
+ parser (>= 2.5, != 2.5.1.1)
148
+ powerpack (~> 0.1)
149
+ rainbow (>= 2.2.2, < 4.0)
150
+ ruby-progressbar (~> 1.7)
151
+ unicode-display_width (~> 1.0, >= 1.0.1)
152
+ ruby-progressbar (1.10.0)
153
+ ruby_parser (3.11.0)
154
+ sexp_processor (~> 4.9)
155
+ rugged (0.27.4)
156
+ sawyer (0.8.1)
157
+ addressable (>= 2.3.5, < 2.6)
158
+ faraday (~> 0.8, < 1.0)
159
+ sexp_processor (4.11.0)
160
+ simplecov (0.16.1)
161
+ docile (~> 1.1)
162
+ json (>= 1.8, < 3)
163
+ simplecov-html (~> 0.10.0)
164
+ simplecov-html (0.10.2)
165
+ simplecov-rcov (0.2.3)
166
+ simplecov (>= 0.4.1)
167
+ terminal-table (1.8.0)
168
+ unicode-display_width (~> 1.1, >= 1.1.1)
169
+ thor (0.19.4)
170
+ thread_safe (0.3.6)
171
+ tzinfo (1.2.5)
172
+ thread_safe (~> 0.1)
173
+ unicode-display_width (1.4.0)
174
+ url (0.3.2)
175
+ virtus (1.0.5)
176
+ axiom-types (~> 0.1)
177
+ coercible (~> 1.0)
178
+ descendants_tracker (~> 0.0, >= 0.0.3)
179
+ equalizer (~> 0.0, >= 0.0.9)
180
+
181
+ PLATFORMS
182
+ ruby
183
+
184
+ DEPENDENCIES
185
+ bundler (~> 1.16)
186
+ codecov (~> 0.1.0, ~> 0.1)
187
+ database_cleaner
188
+ gem-release
189
+ mongo_aggregation_dsl!
190
+ pronto
191
+ pronto-brakeman
192
+ pronto-circleci
193
+ pronto-fasterer
194
+ pronto-rails_best_practices
195
+ pronto-reek
196
+ pronto-rubocop
197
+ rake (~> 10.0)
198
+ rspec (~> 3.0)
199
+ rspec_junit_formatter (~> 0.3.0)
200
+ rubocop
201
+ simplecov
202
+ simplecov-rcov
203
+
204
+ BUNDLED WITH
205
+ 1.16.4
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # mongo_aggregation_dsl
2
+
3
+ This gem provides a basic implementation of a mongo aggregation dsl. It is by no means complete.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mongo_aggregation_dsl'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mongo_aggregation_dsl
20
+
21
+ ## Usage
22
+
23
+ Example returns an array containing the resulting document json
24
+ ```ruby
25
+ Aggregate::Pipeline.new(User).
26
+ match(account_id: BSON::ObjectId("111111111111111")).
27
+ project(id: 1).
28
+ lookup(
29
+ from: EndUser,
30
+ let: { user_id: :"$_id" },
31
+ as: "my_record",
32
+ pipeline: Aggregate::Pipeline.new.
33
+ match(
34
+ :expr.and => [
35
+ { eq: %w[$user_id $$user_id] },
36
+ { eq: ["$status_code", 1] }
37
+ ]
38
+ ).
39
+ project(id: 1)
40
+ ).execute
41
+ ```
42
+
43
+ ## Development
44
+
45
+ After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
46
+
47
+ To release a new version, update the version number in `mongo_aggregation_dsl.gemspec`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/CardTapp/mongo_aggregation_dsl. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
56
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/codecov.yml ADDED
@@ -0,0 +1,3 @@
1
+ codecov:
2
+ ci:
3
+ - CircleCI
@@ -0,0 +1,7 @@
1
+ github:
2
+ org: "CardTapp"
3
+ repo: "mongo_aggregation_dsl"
4
+ pronto:
5
+ comments_on_diff: true
6
+ reviews_on_diff: true
7
+ report_status: true
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Contracts
5
+ # Validates that a class includes a given module
6
+ class ClassIncludes < ::Contracts::Builtin::CallableClass
7
+ def initialize(klasses)
8
+ @klasses = [klasses].flatten(1)
9
+ end
10
+
11
+ # :reek:FeatureEnvy
12
+ # :reek:ManualDispatch
13
+ def valid?(object)
14
+ @klasses.all? { |klass| object.respond_to?(:included_modules) && object.included_modules.include?(klass) }
15
+ end
16
+
17
+ def to_s
18
+ "Expected to include #{@klasses}"
19
+ end
20
+
21
+ def inspect
22
+ to_s
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Contracts
5
+ # Validates a hash length does not exceed the max given value
6
+ class HashMaxLength < ::Contracts::Builtin::CallableClass
7
+ def initialize(*vals)
8
+ @length = vals[0]
9
+ end
10
+
11
+ def valid?(hash)
12
+ hash.length <= @length
13
+ end
14
+
15
+ def to_s
16
+ "Hash length to be less than than or equal to #{@length}"
17
+ end
18
+
19
+ def inspect
20
+ to_s
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Contracts
5
+ # Validates a hash length is less than the min given value
6
+ class HashMinLength < ::Contracts::Builtin::CallableClass
7
+ def initialize(*vals)
8
+ @length = vals[0]
9
+ end
10
+
11
+ def valid?(hash)
12
+ hash.length >= @length
13
+ end
14
+
15
+ def to_s
16
+ "Hash length to be greater than or equal to #{@length}"
17
+ end
18
+
19
+ def inspect
20
+ to_s
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Contracts
5
+ # Validates the value types in a given range are of a given type
6
+ class HashValueType < ::Contracts::Builtin::CallableClass
7
+ def initialize(*vals)
8
+ @range = vals[0]
9
+ @type = vals[1]
10
+ @error = nil
11
+ end
12
+
13
+ def valid?(hash)
14
+ values = hash.values[@range]
15
+ if values.is_a? Array
16
+ values.all? { |value| value.is_a? @type }
17
+ else
18
+ values.is_a?(@type)
19
+ end
20
+ end
21
+
22
+ def to_s
23
+ "Hash values #{@range} to be of type #{@type}"
24
+ end
25
+
26
+ def inspect
27
+ to_s
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Contracts
5
+ # Validates an object in string format begins with the given value
6
+ class StartsWith < ::Contracts::Builtin::CallableClass
7
+ def initialize(*args)
8
+ @start = args[0]
9
+ end
10
+
11
+ def valid?(object)
12
+ object.to_s.start_with?(@start)
13
+ end
14
+
15
+ def to_s
16
+ "Expected to start with #{@start}"
17
+ end
18
+
19
+ def inspect
20
+ to_s
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ # Contracts are used in stages to apply validation of the options passed into a stage
5
+ module Contracts
6
+ Autoloaded.module {}
7
+ end
8
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ # Represents an aggregation pipeline and is the main entry point to the DSL
5
+ # Example: Aggregate::Pipeline.new().match().project().execute()
6
+ class Pipeline
7
+ attr_reader :stages
8
+
9
+ def initialize(klass = nil)
10
+ @klass = klass
11
+ @stages = []
12
+ end
13
+
14
+ def to_s
15
+ inspect
16
+ end
17
+
18
+ def inspect
19
+ @stages.to_s
20
+ end
21
+
22
+ # :reek:NilCheck
23
+ def execute
24
+ raise "Pipeline initializer must specify a class in order to be executable" if @klass.nil?
25
+
26
+ db = Mongoid.default_client.database
27
+ command = "function(){return db.#{@klass.collection_name}.aggregate(#{self}).toArray()}"
28
+
29
+ # https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/operation/result.rb
30
+ result = db.command("$eval": command, nolock: true, await_data: true)
31
+ result.documents
32
+ end
33
+
34
+ Aggregate::Stages.constants.each do |klass|
35
+ define_method(klass.to_s.underscore) do |options|
36
+ @stages << "Aggregate::Stages::#{klass}".constantize.new(options)
37
+ self
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aggregate
4
+ module Stages
5
+ # derived stages are required to implement the following contract
6
+ # def to_s
7
+ # # return a properly formatted stage
8
+ # end
9
+ class Base < Aggregate::Values::Base
10
+ include ::Contracts::Core
11
+ include ::Contracts::Builtin
12
+ attr_reader :options
13
+ # :reek:NilCheck
14
+ def initialize(options)
15
+ value_handler = self.class.value_handlers.detect { |handler| handler.handles?(options) }
16
+ @options = value_handler.nil? ? options : value_handler.new(options, false)
17
+ end
18
+ end
19
+ end
20
+ end