daodalus-moped 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +7 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +72 -0
  5. data/LICENCE.md +9 -0
  6. data/README.md +316 -0
  7. data/Rakefile +8 -0
  8. data/daodalus-moped.gemspec +24 -0
  9. data/lib/daodalus.rb +29 -0
  10. data/lib/daodalus/connection.rb +19 -0
  11. data/lib/daodalus/dao.rb +35 -0
  12. data/lib/daodalus/dsl.rb +21 -0
  13. data/lib/daodalus/dsl/aggregation/group.rb +88 -0
  14. data/lib/daodalus/dsl/aggregation/limit.rb +23 -0
  15. data/lib/daodalus/dsl/aggregation/match.rb +35 -0
  16. data/lib/daodalus/dsl/aggregation/project.rb +79 -0
  17. data/lib/daodalus/dsl/aggregation/skip.rb +23 -0
  18. data/lib/daodalus/dsl/aggregation/sort.rb +29 -0
  19. data/lib/daodalus/dsl/aggregation/unwind.rb +23 -0
  20. data/lib/daodalus/dsl/aggregations.rb +44 -0
  21. data/lib/daodalus/dsl/clause.rb +19 -0
  22. data/lib/daodalus/dsl/matchers.rb +87 -0
  23. data/lib/daodalus/dsl/queries.rb +31 -0
  24. data/lib/daodalus/dsl/query.rb +42 -0
  25. data/lib/daodalus/dsl/select.rb +43 -0
  26. data/lib/daodalus/dsl/update.rb +86 -0
  27. data/lib/daodalus/dsl/updates.rb +71 -0
  28. data/lib/daodalus/dsl/where.rb +30 -0
  29. data/lib/daodalus/invalid_connection_error.rb +7 -0
  30. data/lib/daodalus/invalid_query_error.rb +4 -0
  31. data/spec/lib/daodalus/connection_spec.rb +22 -0
  32. data/spec/lib/daodalus/dao_spec.rb +26 -0
  33. data/spec/lib/daodalus/dsl/aggregation/group_spec.rb +92 -0
  34. data/spec/lib/daodalus/dsl/aggregation/limit_spec.rb +22 -0
  35. data/spec/lib/daodalus/dsl/aggregation/match_spec.rb +32 -0
  36. data/spec/lib/daodalus/dsl/aggregation/project_spec.rb +74 -0
  37. data/spec/lib/daodalus/dsl/aggregation/skip_spec.rb +22 -0
  38. data/spec/lib/daodalus/dsl/aggregation/sort_spec.rb +36 -0
  39. data/spec/lib/daodalus/dsl/aggregation/unwind_spec.rb +24 -0
  40. data/spec/lib/daodalus/dsl/clause_spec.rb +22 -0
  41. data/spec/lib/daodalus/dsl/query_spec.rb +35 -0
  42. data/spec/lib/daodalus/dsl/select_spec.rb +46 -0
  43. data/spec/lib/daodalus/dsl/update_spec.rb +113 -0
  44. data/spec/lib/daodalus/dsl/where_spec.rb +133 -0
  45. data/spec/lib/daodalus/dsl_spec.rb +12 -0
  46. data/spec/pointless_coverage_spec.rb +9 -0
  47. data/spec/spec_helper.rb +18 -0
  48. data/spec/support/mongo_cleaner.rb +12 -0
  49. metadata +208 -0
@@ -0,0 +1,29 @@
1
+ require 'moped'
2
+ require 'optional'
3
+
4
+ require 'daodalus/connection'
5
+ require 'daodalus/invalid_connection_error'
6
+ require 'daodalus/invalid_query_error'
7
+
8
+ require 'daodalus/dsl/query'
9
+ require 'daodalus/dsl/clause'
10
+ require 'daodalus/dsl/matchers'
11
+
12
+ require 'daodalus/dsl/queries'
13
+ require 'daodalus/dsl/updates'
14
+
15
+ require 'daodalus/dsl/where'
16
+ require 'daodalus/dsl/select'
17
+ require 'daodalus/dsl/update'
18
+
19
+ require 'daodalus/dsl/aggregations'
20
+ require 'daodalus/dsl/aggregation/match'
21
+ require 'daodalus/dsl/aggregation/group'
22
+ require 'daodalus/dsl/aggregation/project'
23
+ require 'daodalus/dsl/aggregation/limit'
24
+ require 'daodalus/dsl/aggregation/skip'
25
+ require 'daodalus/dsl/aggregation/sort'
26
+ require 'daodalus/dsl/aggregation/unwind'
27
+
28
+ require 'daodalus/dsl'
29
+ require 'daodalus/dao'
@@ -0,0 +1,19 @@
1
+ module Daodalus
2
+
3
+ module Connection
4
+ extend self
5
+
6
+ def register(connection, name='default')
7
+ connections[name.to_s] = connection
8
+ end
9
+
10
+ def fetch(name='default')
11
+ connections.fetch(name.to_s) { raise InvalidConnectionError.new(name) }
12
+ end
13
+
14
+ def connections
15
+ @connections ||= {}
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ require 'delegate'
2
+
3
+ module Daodalus
4
+ class DAO
5
+ include DSL
6
+ extend Forwardable
7
+
8
+ def initialize(db, collection, connection=:default)
9
+ @db = db
10
+ @collection = collection
11
+ @connection = connection
12
+ end
13
+
14
+ def coll
15
+ @coll ||= Daodalus::Connection.fetch(connection).tap do |conn|
16
+ conn.use(db.to_s)
17
+ end[collection.to_s]
18
+ end
19
+
20
+ delegate [
21
+ :find,
22
+ :find_and_modify,
23
+ :insert,
24
+ :save,
25
+ :count,
26
+ :aggregate,
27
+ :update
28
+ ] => :coll
29
+
30
+ private
31
+
32
+ attr_reader :db, :collection, :connection
33
+
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ module Daodalus
2
+ module DSL
3
+ include Clause
4
+ include Queries
5
+ include Updates
6
+ include Aggregations
7
+
8
+ def query
9
+ Query.new
10
+ end
11
+
12
+ def pipeline
13
+ []
14
+ end
15
+
16
+ def dao
17
+ self
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,88 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Group
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, id, values)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @id = id
11
+ @values = values
12
+ end
13
+
14
+ def to_aggregation
15
+ { '$group' => values.merge('_id' => id) }
16
+ end
17
+
18
+ def sum(field)
19
+ aliased '$sum' => field
20
+ end
21
+ alias_method :total, :sum
22
+
23
+ def add_to_set(field)
24
+ aliased '$addToSet' => field
25
+ end
26
+ alias_method :distinct, :add_to_set
27
+
28
+ def push(field)
29
+ aliased '$push' => field
30
+ end
31
+ alias_method :collect, :push
32
+
33
+ def first(field)
34
+ aliased '$first' => field
35
+ end
36
+
37
+ def last(field)
38
+ aliased '$last' => field
39
+ end
40
+
41
+ def max(field)
42
+ aliased '$max' => field
43
+ end
44
+
45
+ def min(field)
46
+ aliased '$min' => field
47
+ end
48
+
49
+ def avg(field)
50
+ aliased '$avg' => field
51
+ end
52
+ alias_method :average, :avg
53
+
54
+ private
55
+
56
+ def id
57
+ case @id
58
+ when Symbol then @id.to_s
59
+ when Hash then @id.reduce({}) {|acc, (a,b)| acc.merge(a.to_s => b.to_s) }
60
+ else @id
61
+ end
62
+ end
63
+
64
+ def aliased clause
65
+ Alias.new do |aka|
66
+ Group.new(dao, aggregations, id, values.merge(aka => clause))
67
+ end
68
+ end
69
+
70
+ attr_reader :dao, :aggregations, :values
71
+
72
+ class Alias
73
+ def initialize(&block)
74
+ @block = block
75
+ end
76
+
77
+ def as(aka)
78
+ block.call(aka)
79
+ end
80
+
81
+ private
82
+
83
+ attr_reader :block
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,23 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Limit
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, limit)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @limit = limit
11
+ end
12
+
13
+ def to_aggregation
14
+ { '$limit' => limit }
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :dao, :aggregations, :limit
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Match
5
+ include Matchers
6
+ include Aggregations
7
+
8
+ def initialize(dao, aggregations, query, field)
9
+ @dao = dao
10
+ @aggregations = aggregations
11
+ @query = query
12
+ @field = field
13
+ end
14
+
15
+ alias_method :and, :match
16
+
17
+ def to_aggregation
18
+ { '$match' => query.wheres }
19
+ end
20
+
21
+ private
22
+
23
+ def add_clause clause
24
+ Match.new(dao, aggregations, query.where(field.to_s => clause), field)
25
+ end
26
+
27
+ def add_logical_clause clause
28
+ Match.new(dao, aggregations, query.where(clause), field)
29
+ end
30
+
31
+ attr_reader :dao, :aggregations, :query, :field
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,79 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Project
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, projection = {}, keys)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @projection = projection
11
+ @keys = keys
12
+ end
13
+
14
+ def to_aggregation
15
+ { '$project' => { '_id' => 0 }.merge(projection) }
16
+ end
17
+
18
+ def project(*keys)
19
+ Project.new(dao, aggregations, projection, keys)
20
+ end
21
+ alias_method :and, :project
22
+
23
+ def as(aka)
24
+ Project.new(dao, aggregations, @projection, [aka => keys.first])
25
+ end
26
+
27
+ def eq(*others)
28
+ Project.new(dao, aggregations, @projection, ['$eq' => keys + others])
29
+ end
30
+
31
+ def add(*others)
32
+ Project.new(dao, aggregations, @projection, ['$add' => keys + others])
33
+ end
34
+ alias_method :plus, :add
35
+
36
+ def divide(other)
37
+ Project.new(dao, aggregations, @projection, ['$divide' => keys + [other]])
38
+ end
39
+ alias_method :divided_by, :divide
40
+
41
+ def multiply(other)
42
+ Project.new(dao, aggregations, @projection, ['$multiply' => keys + [other]])
43
+ end
44
+ alias_method :multiplied_by, :multiply
45
+
46
+ def subtract(other)
47
+ Project.new(dao, aggregations, @projection, ['$subtract' => keys + [other]])
48
+ end
49
+ alias_method :minus, :subtract
50
+
51
+ def mod(other)
52
+ Project.new(dao, aggregations, @projection, ['$mod' => keys + [other]])
53
+ end
54
+
55
+ protected
56
+
57
+ def projection
58
+ keys.reduce(@projection) do |acc, k|
59
+ case k
60
+ when Hash then acc.merge(hashify k)
61
+ else acc.merge(k.to_s => 1)
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def hashify(key)
69
+ case key
70
+ when Hash then key.reduce({}) { |acc, (k,v)| acc.merge(k => hashify(v)) }
71
+ when Project then hashify key.projection
72
+ else key
73
+ end
74
+ end
75
+ attr_reader :dao, :aggregations, :keys
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,23 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Skip
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, skip)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @skip = skip
11
+ end
12
+
13
+ def to_aggregation
14
+ { '$skip' => skip }
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :dao, :aggregations, :skip
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Sort
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, keys)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @keys = keys
11
+ end
12
+
13
+ def to_aggregation
14
+ { '$sort' => keys }
15
+ end
16
+
17
+ private
18
+
19
+ def keys
20
+ @keys.reduce({}) do |acc, (k,v)|
21
+ acc.merge(k => ([-1, :desc, 'desc'].include?(v) ? -1 : 1))
22
+ end
23
+ end
24
+
25
+ attr_reader :dao, :aggregations
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregation
4
+ class Unwind
5
+ include Aggregations
6
+
7
+ def initialize(dao, aggregations, field)
8
+ @dao = dao
9
+ @aggregations = aggregations
10
+ @field = field
11
+ end
12
+
13
+ def to_aggregation
14
+ { '$unwind' => "$#{field}" }
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :dao, :aggregations, :field
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+ module Daodalus
2
+ module DSL
3
+ module Aggregations
4
+
5
+ def aggregate
6
+ dao.aggregate(pipeline)
7
+ end
8
+
9
+ def match(field=nil)
10
+ Aggregation::Match.new(dao, pipeline, Query.new, field)
11
+ end
12
+
13
+ def group(keys)
14
+ Aggregation::Group.new(dao, pipeline, keys, {})
15
+ end
16
+ alias_method :group_by, :group
17
+
18
+ def project(*keys)
19
+ Aggregation::Project.new(dao, pipeline, keys)
20
+ end
21
+
22
+ def limit(limit)
23
+ Aggregation::Limit.new(dao, pipeline, limit)
24
+ end
25
+
26
+ def skip(skip)
27
+ Aggregation::Skip.new(dao, pipeline, skip)
28
+ end
29
+
30
+ def sort(sort)
31
+ Aggregation::Sort.new(dao, pipeline, sort)
32
+ end
33
+
34
+ def unwind(field)
35
+ Aggregation::Unwind.new(dao, pipeline, field)
36
+ end
37
+
38
+ def pipeline
39
+ aggregations + [to_aggregation]
40
+ end
41
+
42
+ end
43
+ end
44
+ end