active_house 0.1.5 → 0.2.0

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
  SHA1:
3
- metadata.gz: 85e74ee14ef20d87860ffb175ba8adeef0488777
4
- data.tar.gz: 226c0ae19eb0e1c451ac7bcbcfec035bbd602f16
3
+ metadata.gz: d444148c72cbef93a8a193e8c73079791e77ecc4
4
+ data.tar.gz: 9fbcef6e31a2627dbc822dddc64d72b1dcb1a3ec
5
5
  SHA512:
6
- metadata.gz: aa2e80513b87275dd3996c09f6c6e63c7392fa0ab930468f1ec7fc08ae389b71d9be993cff385d1dcb6b5d98f056115dedbf1c0079164fe55dd807f1d0f09842
7
- data.tar.gz: 35c22b8dc84e426b967a10169aa707979e3ed6a5ffb472c25c6092f4dccaadd384facc4c09de719e8e9fadafe29bfd3da9c3c7e8d458a06f571045497420d8ce
6
+ metadata.gz: 92e3a2d335222804ef4f09ce2ed8037ffee60b496d6a3d70e1dabfeb86fa87242900a91b72f538c227eb30c9a4241e4707ef92fa5bfd95d9455a835b409bd660
7
+ data.tar.gz: 1e744dc7fa583e5d1861bf8561b4a7165f3624369af37110f05b493825dff5b5d9778c4ab0b5468838647875960e9b70705d57548af4d93db8d68bc59bd20c14
@@ -4,6 +4,8 @@ require_relative 'whereable'
4
4
  require_relative 'orderable'
5
5
  require_relative 'groupable'
6
6
  require_relative 'limitable'
7
+ require_relative 'havingable'
8
+ require_relative 'unionable'
7
9
  require 'active_support/concern'
8
10
 
9
11
  module ActiveHouse
@@ -15,7 +17,9 @@ module ActiveHouse
15
17
  include ActiveHouse::Whereable
16
18
  include ActiveHouse::Orderable
17
19
  include ActiveHouse::Groupable
20
+ include ActiveHouse::Havingable
18
21
  include ActiveHouse::Limitable
22
+ include ActiveHouse::Unionable
19
23
 
20
24
  included do
21
25
  protected
@@ -26,7 +30,8 @@ module ActiveHouse
26
30
 
27
31
  def data=(other_data)
28
32
  chain_methods.values.each do |var|
29
- instance_variable_set(:"@#{var}", other_data.fetch(var).dup)
33
+ value = other_data.fetch(var)
34
+ instance_variable_set(:"@#{var}", value.nil? ? nil : value.dup)
30
35
  end
31
36
  end
32
37
 
@@ -36,8 +41,10 @@ module ActiveHouse
36
41
  build_from_query_part,
37
42
  build_where_query_part,
38
43
  build_group_by_query_part,
44
+ build_having_query_part,
39
45
  build_order_by_query_part,
40
- build_limit_query_part
46
+ build_limit_query_part,
47
+ build_union_query_part
41
48
  ]
42
49
  end
43
50
 
@@ -90,7 +97,23 @@ module ActiveHouse
90
97
  where: :conditions,
91
98
  group_by: :grouping,
92
99
  order_by: :ordering,
93
- limit: :limit
100
+ limit: :limit,
101
+ having: :having,
102
+ union: :unions,
103
+ from: :subquery
104
+ }
105
+ end
106
+
107
+ def chain_defaults
108
+ {
109
+ fields: [],
110
+ conditions: [],
111
+ grouping: [],
112
+ ordering: [],
113
+ limit: { offset: nil, limit: nil },
114
+ having: [],
115
+ union: {},
116
+ subquery: nil,
94
117
  }
95
118
  end
96
119
 
@@ -103,7 +126,7 @@ module ActiveHouse
103
126
 
104
127
  new_data = {}
105
128
  chain_methods.each do |meth, var|
106
- new_data[var] = [] if values.include?(meth)
129
+ new_data[var] = chain_defaults[var].dup if values.include?(meth)
107
130
  end
108
131
  chain_query(new_data)
109
132
  end
@@ -5,18 +5,25 @@ module ActiveHouse
5
5
  included do
6
6
  private
7
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
+
8
14
  def build_from_query_part
9
- "FROM #{table_name}"
15
+ "FROM #{from_subquery}"
10
16
  end
11
17
  end
12
18
 
13
19
  def initialize(*)
14
- @table_name = model_class._table_name
20
+ @subquery = nil
15
21
  super
16
22
  end
17
23
 
18
- def table_name
19
- @table_name
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
20
27
  end
21
28
  end
22
29
  end
@@ -0,0 +1,50 @@
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
@@ -6,22 +6,22 @@ module ActiveHouse
6
6
  private
7
7
 
8
8
  def build_limit_query_part
9
- return if @limit.empty?
10
- if @limit[1]
11
- "LIMIT #{@limit[0]}, #{@limit[1]}"
9
+ return if @limit[:limit].nil?
10
+ if @limit[:offset]
11
+ "LIMIT #{@limit[:limit]}, #{@limit[:offset]}"
12
12
  else
13
- "LIMIT #{@limit[0]}"
13
+ "LIMIT #{@limit[:limit]}"
14
14
  end
15
15
  end
16
16
  end
17
17
 
18
18
  def initialize(*)
19
- @limit = []
19
+ @limit = { offset: nil, limit: nil }
20
20
  super
21
21
  end
22
22
 
23
23
  def limit(limit_value, offset_value = nil)
24
- chain_query limit: (@limit + [limit_value, offset_value]).uniq
24
+ chain_query limit: { offset: offset_value || @limit[:offset], limit: limit_value }
25
25
  end
26
26
  end
27
27
  end
@@ -38,7 +38,7 @@ module ActiveHouse
38
38
 
39
39
  def attributes(*names)
40
40
  options = names.extract_options!
41
- names.each { |name| attributes(name, options.dup) }
41
+ names.each { |name| attribute(name, options.dup) }
42
42
  end
43
43
 
44
44
  def load!(params)
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/object/try'
2
+
1
3
  module ActiveHouse
2
4
  module Orderable
3
5
  extend ActiveSupport::Concern
@@ -25,7 +27,7 @@ module ActiveHouse
25
27
  elsif clause.is_a?(Hash)
26
28
  if clause.keys.one?
27
29
  direction = clause.values.first
28
- raise ArgumentError, 'direction must be asc or desc' if [:asc, :desc].exclude?(direction.try!(:to_sym))
30
+ raise ArgumentError, 'direction must be asc or desc' unless [:asc, :desc].include?(direction.try!(:to_sym))
29
31
  "#{clause.keys.first} #{direction.to_s.upcase}"
30
32
  else
31
33
  clause.assert_valid_keys(:field, :direction, :collate)
@@ -11,7 +11,7 @@ module ActiveHouse
11
11
  end
12
12
 
13
13
  class_methods do
14
- delegate :to_a, :select, :where, :group_by, :limit, to: :all
14
+ delegate :to_a, :select, :where, :group_by, :limit, :order_by, :having, to: :all
15
15
 
16
16
  def all
17
17
  _query_class.new(self)
@@ -0,0 +1,43 @@
1
+ module ActiveHouse
2
+ module Unionable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ private
7
+
8
+ def build_union_query_part
9
+ "UNION ALL\n#{@unions.values.map(&:to_query).join("\n")}" unless @unions.values.empty?
10
+ end
11
+ end
12
+
13
+ def initialize(*)
14
+ @unions = {}
15
+ super
16
+ end
17
+
18
+ def union(name, query)
19
+ query = query.all if query.is_a?(ActiveHouse::Model)
20
+ raise ArgumentError, 'argument must be model or query object' unless query.is_a?(ActiveHouse::Query)
21
+ new_unions = @unions.map { |n, q| [n, q.dup] }.to_h
22
+ new_unions[name] = query.dup
23
+ chain_query unions: new_unions
24
+ end
25
+
26
+ def update_union(name, &block)
27
+ raise ArgumentError, "can't find union by name #{name}" unless @unions.key?(name)
28
+ new_union = block.call union_for(name)
29
+ union(name, new_union)
30
+ end
31
+
32
+ def union_for(name)
33
+ raise ArgumentError, "can't find union by name #{name}" unless @unions.key?(name)
34
+ @unions[name].dup
35
+ end
36
+
37
+ def except_union(name)
38
+ new_unions = @unions.map { |n, q| [n, q.dup] }.to_h
39
+ new_unions.delete(name)
40
+ chain_query unions: new_unions
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module ActiveHouse
2
- VERSION = '0.1.5'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -8,10 +8,6 @@ module ActiveHouse
8
8
  included do
9
9
  private
10
10
 
11
- def format_condition_value(value)
12
- ActiveHouse::PreparedStatement.format_value(value)
13
- end
14
-
15
11
  def format_condition(*conditions)
16
12
  raise ArgumentError, 'wrong number of arguments' if conditions.empty?
17
13
  return ActiveHouse::PreparedStatement.prepare_sql(*conditions) if conditions.size > 1
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.1.5
4
+ version: 0.2.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: 2018-07-25 00:00:00.000000000 Z
11
+ date: 2018-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -122,6 +122,7 @@ files:
122
122
  - lib/active_house/error.rb
123
123
  - lib/active_house/fromable.rb
124
124
  - lib/active_house/groupable.rb
125
+ - lib/active_house/havingable.rb
125
126
  - lib/active_house/limitable.rb
126
127
  - lib/active_house/logger.rb
127
128
  - lib/active_house/model.rb
@@ -133,6 +134,7 @@ files:
133
134
  - lib/active_house/scopeable.rb
134
135
  - lib/active_house/scoping.rb
135
136
  - lib/active_house/selectable.rb
137
+ - lib/active_house/unionable.rb
136
138
  - lib/active_house/version.rb
137
139
  - lib/active_house/whereable.rb
138
140
  homepage: https://github.com/senid231/active_house