sql-builder 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19d3718663d028bfb26456ed26d37bef8773af4bc5af7517f83ba9d12bc3e815
4
- data.tar.gz: 2fd4be4491fe37ced91535589fe90f09ed19247aa7497e32a7682bbe40253913
3
+ metadata.gz: c0a3fd641323692f816ad2e0abf5f41b46d7dd3b0055226841fd6131e09d0f2d
4
+ data.tar.gz: f41696caa9026690a154c58d3f98450a5589124bfb3369392768f305a675acec
5
5
  SHA512:
6
- metadata.gz: 44c08df9d1c813786ac7dfc1e1b72f03a88b8c47068b1c92f7558ee2535285990d18c7c379621a3bbf33c1ffb30bfc76011bcd5bdd001e16f0138174f8183ff0
7
- data.tar.gz: 3b135e795750774e7b68b604f1a1c7b7495a72da7852ecd9c97660f583b939289be9ba30af6c4f20d070b32ee77ae383bd5f34573e7552ce9758747dccecd80c
6
+ metadata.gz: 7747d4c0791354b5e41d6d1b7fb652c69fd851ee13ac513564081852edc484d3f8344239ff2296da81424549df43f09098ce9d0d096c7fa728f6a7a299b85be1
7
+ data.tar.gz: 870ad3d029b5d31b6747981fcc16fac8a256adaebaa32ab1aaa7b87835f20fa95804ee3e099fd83f0be0323dc3abd9cb4c5834383920c5ad4475ebcf69138819
data/README.md CHANGED
@@ -63,6 +63,21 @@ WHERE age >= 18 AND status = 3 AND created_at >= '2020-01-03 10:54:08 +0800' AND
63
63
  ORDER BY id desc LIMIT 100 OFFSET 0
64
64
  ```
65
65
 
66
+ ## Or
67
+
68
+ ```rb
69
+ query = SQLBuilder.new("SELECT * FROM users")
70
+ .where("age = ?", 20).where(num: 10)
71
+ query = query.or(SQLBuilder.new.where("gender = ? AND name = ?", 1, "hello world"))
72
+ query.order("id DESC").limit(100).to_sql
73
+ ```
74
+
75
+ Returns string SQL:
76
+
77
+ ```sql
78
+ SELECT * FROM users WHERE age = 20 AND num = 10 OR gender = 1 AND name = 'hello world' ORDER BY id DESC LIMIT 100
79
+ ```
80
+
66
81
  ### Group by, Having
67
82
 
68
83
  ```rb
@@ -77,12 +92,6 @@ returns
77
92
  ```sql
78
93
  select user_id, name, count(ip) as ip_count from user_visits WHERE status = 1 AND status = 1 AND created_at > '2020-01-03 10:54:08 +0800' GROUP BY user_id, name HAVING count(ip) > 2"
79
94
  ```
80
-
81
- ## TODO
82
-
83
- - [ ] `OR` conditions;
84
- - [x] `Group By`, `Having`;
85
-
86
95
  ## License
87
96
 
88
97
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -12,6 +12,7 @@ require "active_record"
12
12
  # .to_sql
13
13
  class SQLBuilder
14
14
  attr_reader :sql, :conditions, :havings, :orders, :groups, :limit_options, :page_options
15
+ attr_accessor :ors
15
16
 
16
17
  # Create a new SQLBuilder
17
18
  #
@@ -26,8 +27,9 @@ class SQLBuilder
26
27
  @orders = []
27
28
  @groups = []
28
29
  @havings = []
30
+ @ors = []
29
31
  @limit_options = {}
30
- @page_options = { per_page: 20 }
32
+ @page_options = {per_page: 20}
31
33
  end
32
34
 
33
35
  # Add `AND` condition
@@ -90,11 +92,11 @@ class SQLBuilder
90
92
  # query.group("name").group("age").to_sql # => "GROUP BY name, age"
91
93
  #
92
94
  def group(*args)
93
- case args.first
95
+ @groups += case args.first
94
96
  when Array
95
- @groups += args.first.collect(&:to_s)
97
+ args.first.collect(&:to_s)
96
98
  else
97
- @groups += args.collect(&:to_s)
99
+ args.collect(&:to_s)
98
100
  end
99
101
 
100
102
  @groups.uniq!
@@ -111,6 +113,20 @@ class SQLBuilder
111
113
  self
112
114
  end
113
115
 
116
+ # Or
117
+ #
118
+ # query.or(query.where(num: 1)).to_sql # => "OR num = 1"
119
+ #
120
+ def or(other)
121
+ if other.is_a?(SQLBuilder)
122
+ ors << other.ors if other.ors.any?
123
+ ors << other.conditions if other.conditions.any?
124
+ else
125
+ raise ArgumentError, "You have passed #{other.class.name} object to #or. Pass an SQLBuilder object instead."
126
+ end
127
+ self
128
+ end
129
+
114
130
  # Pagination
115
131
  #
116
132
  # query.page(1).per(12).to_sql # => "LIMIT 12 OFFSET 0"
@@ -128,7 +144,7 @@ class SQLBuilder
128
144
  # See #page
129
145
  def per(per_page)
130
146
  page_options[:per_page] = per_page
131
- self.page(page_options[:page])
147
+ page(page_options[:page])
132
148
  self
133
149
  end
134
150
 
@@ -138,6 +154,9 @@ class SQLBuilder
138
154
  if conditions.any?
139
155
  sql_parts << "WHERE " + conditions.flatten.join(" AND ")
140
156
  end
157
+ if ors.any?
158
+ sql_parts = extract_sql_parts(sql_parts, ors)
159
+ end
141
160
  if orders.any?
142
161
  sql_parts << "ORDER BY " + orders.flatten.join(", ")
143
162
  end
@@ -161,7 +180,7 @@ class SQLBuilder
161
180
  # https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_for_assignment
162
181
  def sanitize_sql_for_assignment(assignments)
163
182
  case assignments.first
164
- when Hash; sanitize_sql_hash_for_assignment(assignments.first)
183
+ when Hash then sanitize_sql_hash_for_assignment(assignments.first)
165
184
  else
166
185
  sanitize_sql_array(assignments)
167
186
  end
@@ -182,4 +201,23 @@ class SQLBuilder
182
201
  return ary if ActiveRecord.version < Gem::Version.new("5.0.0")
183
202
  ActiveRecord::Base.send(:sanitize_sql_for_order, ary)
184
203
  end
204
+
205
+ def extract_sql_parts(sql_parts, ors)
206
+ if ors.is_a?(Array)
207
+ ors.each do |single_or|
208
+ next unless single_or.is_a?(Array)
209
+
210
+ if begin
211
+ single_or[0][0].is_a?(Array)
212
+ rescue
213
+ false
214
+ end
215
+ extract_sql_parts(sql_parts, single_or)
216
+ else
217
+ sql_parts << "OR " + single_or.flatten.join(" AND ")
218
+ end
219
+ end
220
+ end
221
+ sql_parts
222
+ end
185
223
  end
@@ -1,3 +1,3 @@
1
1
  class SQLBuilder
2
- VERSION = "0.4.0"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-24 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: standard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: A simple SQL builder for generate SQL for non-ActiveRecord supports databases.
70
84
  email:
71
85
  - huacnlee@gmail.com
@@ -99,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
113
  - !ruby/object:Gem::Version
100
114
  version: '0'
101
115
  requirements: []
102
- rubygems_version: 3.2.2
116
+ rubygems_version: 3.1.4
103
117
  signing_key:
104
118
  specification_version: 4
105
119
  summary: A simple SQL builder for generate SQL for non-ActiveRecord supports databases