sql-builder 0.4.0 → 1.0.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
  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