active_house 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -0
  3. data/active_house.gemspec +1 -0
  4. data/lib/active_house.rb +1 -1
  5. data/lib/active_house/connection.rb +3 -3
  6. data/lib/active_house/exceptions.rb +9 -0
  7. data/lib/active_house/{logger.rb → logging.rb} +1 -1
  8. data/lib/active_house/model.rb +14 -12
  9. data/lib/active_house/modeling/attributes.rb +102 -0
  10. data/lib/active_house/modeling/connection.rb +38 -0
  11. data/lib/active_house/modeling/query.rb +29 -0
  12. data/lib/active_house/modeling/scope.rb +42 -0
  13. data/lib/active_house/prepared_statement.rb +34 -2
  14. data/lib/active_house/query_builder.rb +38 -0
  15. data/lib/active_house/querying/array_join.rb +42 -0
  16. data/lib/active_house/querying/collect.rb +80 -0
  17. data/lib/active_house/querying/from.rb +30 -0
  18. data/lib/active_house/querying/group_by.rb +30 -0
  19. data/lib/active_house/querying/having.rb +41 -0
  20. data/lib/active_house/querying/limit.rb +35 -0
  21. data/lib/active_house/querying/order_by.rb +58 -0
  22. data/lib/active_house/querying/scope.rb +45 -0
  23. data/lib/active_house/querying/select.rb +35 -0
  24. data/lib/active_house/querying/union.rb +67 -0
  25. data/lib/active_house/querying/where.rb +50 -0
  26. data/lib/active_house/version.rb +1 -1
  27. metadata +34 -22
  28. data/lib/active_house/array_joinable.rb +0 -31
  29. data/lib/active_house/chainable.rb +0 -151
  30. data/lib/active_house/collectable.rb +0 -44
  31. data/lib/active_house/connecting.rb +0 -36
  32. data/lib/active_house/connection_error.rb +0 -6
  33. data/lib/active_house/error.rb +0 -4
  34. data/lib/active_house/fromable.rb +0 -29
  35. data/lib/active_house/groupable.rb +0 -23
  36. data/lib/active_house/havingable.rb +0 -50
  37. data/lib/active_house/limitable.rb +0 -27
  38. data/lib/active_house/modeling.rb +0 -100
  39. data/lib/active_house/orderable.rb +0 -45
  40. data/lib/active_house/query.rb +0 -22
  41. data/lib/active_house/querying.rb +0 -21
  42. data/lib/active_house/scopeable.rb +0 -42
  43. data/lib/active_house/scoping.rb +0 -37
  44. data/lib/active_house/selectable.rb +0 -35
  45. data/lib/active_house/unionable.rb +0 -43
  46. data/lib/active_house/whereable.rb +0 -57
@@ -1,3 +1,3 @@
1
1
  module ActiveHouse
2
- VERSION = '0.4.0'.freeze
2
+ VERSION = '0.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_house
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Talakevich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-02 00:00:00.000000000 Z
11
+ date: 2019-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.10
55
+ - !ruby/object:Gem::Dependency
56
+ name: plain_model
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.2'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -113,31 +127,29 @@ files:
113
127
  - bin/console
114
128
  - bin/setup
115
129
  - lib/active_house.rb
116
- - lib/active_house/array_joinable.rb
117
- - lib/active_house/chainable.rb
118
- - lib/active_house/collectable.rb
119
130
  - lib/active_house/configuration.rb
120
- - lib/active_house/connecting.rb
121
131
  - lib/active_house/connection.rb
122
- - lib/active_house/connection_error.rb
123
- - lib/active_house/error.rb
124
- - lib/active_house/fromable.rb
125
- - lib/active_house/groupable.rb
126
- - lib/active_house/havingable.rb
127
- - lib/active_house/limitable.rb
128
- - lib/active_house/logger.rb
132
+ - lib/active_house/exceptions.rb
133
+ - lib/active_house/logging.rb
129
134
  - lib/active_house/model.rb
130
- - lib/active_house/modeling.rb
131
- - lib/active_house/orderable.rb
135
+ - lib/active_house/modeling/attributes.rb
136
+ - lib/active_house/modeling/connection.rb
137
+ - lib/active_house/modeling/query.rb
138
+ - lib/active_house/modeling/scope.rb
132
139
  - lib/active_house/prepared_statement.rb
133
- - lib/active_house/query.rb
134
- - lib/active_house/querying.rb
135
- - lib/active_house/scopeable.rb
136
- - lib/active_house/scoping.rb
137
- - lib/active_house/selectable.rb
138
- - lib/active_house/unionable.rb
140
+ - lib/active_house/query_builder.rb
141
+ - lib/active_house/querying/array_join.rb
142
+ - lib/active_house/querying/collect.rb
143
+ - lib/active_house/querying/from.rb
144
+ - lib/active_house/querying/group_by.rb
145
+ - lib/active_house/querying/having.rb
146
+ - lib/active_house/querying/limit.rb
147
+ - lib/active_house/querying/order_by.rb
148
+ - lib/active_house/querying/scope.rb
149
+ - lib/active_house/querying/select.rb
150
+ - lib/active_house/querying/union.rb
151
+ - lib/active_house/querying/where.rb
139
152
  - lib/active_house/version.rb
140
- - lib/active_house/whereable.rb
141
153
  homepage: https://github.com/senid231/active_house
142
154
  licenses:
143
155
  - MIT
@@ -1,31 +0,0 @@
1
- module ActiveHouse
2
- module ArrayJoinable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- private
7
-
8
- def build_array_join_query_part
9
- "ARRAY JOIN #{@array_joins.join(', ')}" unless @array_joins.empty?
10
- end
11
- end
12
-
13
- def initialize(*)
14
- @array_joins = []
15
- super
16
- end
17
-
18
- def array_join(*fields)
19
- raise ArgumentError, 'wrong number of arguments' if fields.empty?
20
- formatted_fields = fields.map do |field|
21
- if field.is_a?(Symbol) && model_class._attribute_opts.key?(field)
22
- opts = model_class._attribute_opts.fetch(field)
23
- opts.key?(:select) ? "#{opts[:select]} AS #{field}" : field.to_s
24
- else
25
- field.to_s
26
- end
27
- end
28
- chain_query array_joins: (@array_joins + formatted_fields).uniq
29
- end
30
- end
31
- end
@@ -1,151 +0,0 @@
1
- require_relative 'selectable'
2
- require_relative 'fromable'
3
- require_relative 'whereable'
4
- require_relative 'orderable'
5
- require_relative 'groupable'
6
- require_relative 'limitable'
7
- require_relative 'havingable'
8
- require_relative 'unionable'
9
- require_relative 'array_joinable'
10
- require 'active_support/concern'
11
-
12
- module ActiveHouse
13
- module Chainable
14
- extend ActiveSupport::Concern
15
-
16
- include ActiveHouse::Selectable
17
- include ActiveHouse::Fromable
18
- include ActiveHouse::Whereable
19
- include ActiveHouse::Orderable
20
- include ActiveHouse::Groupable
21
- include ActiveHouse::Havingable
22
- include ActiveHouse::Limitable
23
- include ActiveHouse::Unionable
24
- include ActiveHouse::ArrayJoinable
25
-
26
- included do
27
- protected
28
-
29
- def data
30
- chain_methods.values.map { |var| [var, instance_variable_get(:"@#{var}")] }.to_h
31
- end
32
-
33
- def data=(other_data)
34
- chain_methods.values.each do |var|
35
- value = other_data.fetch(var)
36
- instance_variable_set(:"@#{var}", value.nil? ? nil : value.dup)
37
- end
38
- end
39
-
40
- def query_parts
41
- [
42
- build_select_query_part,
43
- build_from_query_part,
44
- build_array_join_query_part,
45
- build_where_query_part,
46
- build_group_by_query_part,
47
- build_having_query_part,
48
- build_order_by_query_part,
49
- build_limit_query_part,
50
- build_union_query_part
51
- ]
52
- end
53
-
54
- def build_query
55
- query_parts.reject(&:nil?).join("\n")
56
- end
57
-
58
- private
59
-
60
- # By default each chain method (select, where, group_by) returns new instance of query
61
- # but in some cases we need to modify and return existing query object
62
- # (for example when we apply default_scope on query initialize).
63
- # For this you need just to wrap code that appends chain methods with #with_current_query.
64
- # Example:
65
- #
66
- # scope1 = SomeModel.all # object id #1
67
- # scope2 = scope1.where(id: 3) # object id #2
68
- # scope3 = scope2.send(:with_current_query) { scope2.where(success: true) } # object id #2
69
- #
70
- def with_current_query
71
- @_with_current_query = true
72
- yield
73
- ensure
74
- @_with_current_query = false
75
- end
76
-
77
- def chain_query(options = {})
78
- options.assert_valid_keys(*chain_methods.values)
79
- if @_with_current_query
80
- self.data = data.merge(options)
81
- self
82
- else
83
- new_instance = self.class.new(model_class)
84
- new_instance.data = data.merge(options)
85
- new_instance
86
- end
87
- end
88
- end
89
-
90
- def initialize(*)
91
- @_with_current_query = false
92
- super
93
- end
94
-
95
- # key - chain method name
96
- # value - instance variable name that which store values
97
- def chain_methods
98
- {
99
- select: :fields,
100
- where: :conditions,
101
- group_by: :grouping,
102
- order_by: :ordering,
103
- limit: :limit,
104
- having: :having,
105
- union: :unions,
106
- from: :subquery,
107
- array_join: :array_joins
108
- }
109
- end
110
-
111
- # key - instance variable name that which store values
112
- # value - default value for the variable
113
- def chain_defaults
114
- {
115
- fields: [],
116
- conditions: [],
117
- grouping: [],
118
- ordering: [],
119
- limit: { offset: nil, limit: nil },
120
- having: [],
121
- union: {},
122
- subquery: nil,
123
- array_joins: []
124
- }
125
- end
126
-
127
- def except(*values)
128
- raise ArgumentError, 'wrong number of arguments' if values.empty?
129
- not_allowed = values - chain_methods.keys
130
- unless not_allowed.empty?
131
- raise ArgumentError, "Values #{not_allowed} are not allowed, allowed only #{chain_methods.keys}."
132
- end
133
-
134
- new_data = {}
135
- chain_methods.each do |meth, var|
136
- new_data[var] = chain_defaults[var].dup if values.include?(meth)
137
- end
138
- chain_query(new_data)
139
- end
140
-
141
- def to_query
142
- build_query
143
- end
144
-
145
- def dup
146
- chain_query
147
- end
148
-
149
- alias clone dup
150
- end
151
- end
@@ -1,44 +0,0 @@
1
- require 'active_support/concern'
2
- require 'active_support/core_ext/string/filters'
3
- require 'active_support/core_ext/module/delegation'
4
-
5
- module ActiveHouse
6
- module Collectable
7
- extend ActiveSupport::Concern
8
-
9
- def initialize(*)
10
- @collection = nil
11
- super
12
- end
13
-
14
- def to_a
15
- collection
16
- end
17
-
18
- def reset
19
- @collection = nil
20
- end
21
-
22
- def loaded?
23
- !@collection.nil?
24
- end
25
-
26
- def to_hashes
27
- connection.select_rows(to_query.squish)
28
- end
29
-
30
- def collection
31
- @collection ||= fetch_collection
32
- end
33
-
34
- def fetch_collection
35
- to_hashes.map { |row| model_class.load!(row) }
36
- end
37
-
38
- included do
39
- private :collection, :fetch_collection
40
- delegate :each, :size, :count, :map, :collect, :detect, :filter, :reject, :inject, :reduce, :all?, :any?,
41
- to: :to_a
42
- end
43
- end
44
- end
@@ -1,36 +0,0 @@
1
- require_relative 'connection'
2
- require_relative 'configuration'
3
- require 'active_support/core_ext/class/attribute'
4
- require 'active_support/concern'
5
-
6
- module ActiveHouse
7
- module Connecting
8
- extend ActiveSupport::Concern
9
-
10
- included do
11
- class_attribute :_connection_class, instance_accessor: false
12
- class_attribute :_connection, instance_accessor: false
13
- self._connection_class = ActiveHouse::Connection
14
- end
15
-
16
- class_methods do
17
- def ensure_connection
18
- establish_connection if _connection.nil?
19
- end
20
-
21
- def establish_connection(name_or_config = nil)
22
- config = if name_or_config.is_a?(Hash)
23
- name_or_config.symbolize_keys
24
- else
25
- ActiveHouse.configuration.connection_config_for(name_or_config)
26
- end
27
- self._connection = _connection_class.new(config)
28
- end
29
-
30
- def connection
31
- ensure_connection
32
- _connection
33
- end
34
- end
35
- end
36
- end
@@ -1,6 +0,0 @@
1
- require_relative 'error'
2
-
3
- module ActiveHouse
4
- class ConnectionError < Error
5
- end
6
- end
@@ -1,4 +0,0 @@
1
- module ActiveHouse
2
- class Error < ::StandardError
3
- end
4
- end
@@ -1,29 +0,0 @@
1
- module ActiveHouse
2
- module Fromable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- private
7
-
8
- def from_subquery
9
- return model_class._table_name if @subquery.nil?
10
- query = @subquery.is_a?(ActiveHouse::Query) ? @subquery.to_query : @subquery
11
- "( #{query} )"
12
- end
13
-
14
- def build_from_query_part
15
- "FROM #{from_subquery}"
16
- end
17
- end
18
-
19
- def initialize(*)
20
- @subquery = nil
21
- super
22
- end
23
-
24
- def from(table_or_subquery)
25
- raise ArgumentError, '' if !table_or_subquery.is_a?(ActiveHouse::Query) && !table_or_subquery.is_a?(String)
26
- chain_query subquery: table_or_subquery.dup
27
- end
28
- end
29
- end
@@ -1,23 +0,0 @@
1
- module ActiveHouse
2
- module Groupable
3
- extend ActiveSupport::Concern
4
-
5
- included do
6
- private
7
-
8
- def build_group_by_query_part
9
- "GROUP BY #{@grouping.join(', ')}" unless @grouping.empty?
10
- end
11
- end
12
-
13
- def initialize(*)
14
- @grouping = []
15
- super
16
- end
17
-
18
- def group_by(*fields)
19
- raise ArgumentError, 'wrong number of arguments' if fields.empty?
20
- chain_query grouping: (@grouping + fields.map(&:to_s)).uniq
21
- end
22
- end
23
- end
@@ -1,50 +0,0 @@
1
- require_relative 'prepared_statement'
2
- require 'active_support/core_ext/array/wrap'
3
-
4
- module ActiveHouse
5
- module Havingable
6
- extend ActiveSupport::Concern
7
-
8
- included do
9
- private
10
-
11
- def format_having(*conditions)
12
- raise ArgumentError, 'wrong number of arguments' if conditions.empty?
13
- return ActiveHouse::PreparedStatement.prepare_sql(*conditions) if conditions.size > 1
14
- condition = conditions.first
15
- if condition.is_a?(Hash)
16
- condition.map do |field, value|
17
- "#{field} #{sign_for_having(value)} #{ActiveHouse::PreparedStatement.format_value(value)}"
18
- end
19
- else
20
- condition.to_s
21
- end
22
- end
23
-
24
- def sign_for_having(value)
25
- if value.is_a?(Array)
26
- 'IN'
27
- elsif value.nil?
28
- 'IS'
29
- else
30
- '='
31
- end
32
- end
33
-
34
- def build_having_query_part
35
- "HAVING\n" + @having.join(" AND\n") unless @having.empty?
36
- end
37
- end
38
-
39
- def initialize(*)
40
- @having = []
41
- super
42
- end
43
-
44
- def having(*conditions)
45
- raise ArgumentError, 'wrong number of arguments' if conditions.empty?
46
- formatted_conditions = Array.wrap(format_having(*conditions))
47
- chain_query having: (@having + formatted_conditions).uniq
48
- end
49
- end
50
- end