directiverecord 0.1.12 → 0.1.13

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,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: df721b5ec99c98a868667e250aea31187c079bea
4
- data.tar.gz: f7ef75ed7fb5f252622ad38f7def0e17a44aba60
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MjEzM2Q5ODIxZTczOTIzYzkxNTI0OTUyNGM2OTU0ZWFhNjAyNWY0YQ==
5
+ data.tar.gz: !binary |-
6
+ NjU3MGM2NjE2OTE0NjU5ZjQ1ZDdmNzM2NWRmNDI3ZjcwNTczMTYwYg==
5
7
  SHA512:
6
- metadata.gz: 732c2dfe564ef73a4ede1fc6a5d710570a232eae2815fdc125fae9bd65310f8a75f7453279a00139367e54f29ef809acd029971fa2d31a8ae219d22ec476aa61
7
- data.tar.gz: b7a5ec354819ec0c0cf68e5591c621e5f2457356858d63702fc68ed723ff77a08be74e3d993ee4b66a647986edd91ce9842042583ef4de3351b0a2f9dc49d68c
8
+ metadata.gz: !binary |-
9
+ NjdhOTBjYTE2ZTVhMGViOTE3NjU3ODNiMDZlM2M0MzIyNDUzNTAxNzFmYTVm
10
+ ODNkMTBiMjI2YzQxMmYxMDI1MmJkYTEyN2Q1ZDI2MWFlN2JlOThjNTY0ZTRm
11
+ YTg1OWYxYTM2M2JjZWYyNzhjNDFiYjYxNzA0OWNjODc1YjVjZGM=
12
+ data.tar.gz: !binary |-
13
+ NzgxNTNmYWY0NTFlN2Y4ZTlhOTA2ZDhkNWJiNTcxY2ZlZDNhMDdjMGFmYTY3
14
+ ZjY5ZWYzNWQ3MWQ1NzhlMDYwMTg2ZjAxNDE2Yzk4OGUxMGMyMjg0ZDEwOWJh
15
+ YzgyMThmMWVmYjY4OGZlODhhZDJiZWM2OWM5NzVkM2RhMGE0MzM=
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,10 @@
1
1
  = DirectiveRecord CHANGELOG
2
2
 
3
+ == Version 0.1.13 (March 9, 2015)
4
+
5
+ * Separating SELECT statement in lines when containing more than three columns
6
+ * Supporting subselects
7
+
3
8
  == Version 0.1.12 (March 8, 2015)
4
9
 
5
10
  * Being able to specify calculated :group_by option
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.12
1
+ 0.1.13
@@ -10,11 +10,12 @@ module DirectiveRecord
10
10
  options = to_options(args)
11
11
  validate_options! options
12
12
 
13
+ original_options = options.deep_dup.reject!{|k, v| v.nil?}
13
14
  check_path_delimiter! options
14
15
  optimize_query! options
15
16
 
16
17
  prepare_options! options
17
- normalize_options! options
18
+ normalize_options! options, original_options
18
19
 
19
20
  parse_joins! options
20
21
 
@@ -84,7 +85,7 @@ SQL
84
85
  end
85
86
 
86
87
  def validate_options!(options)
87
- options.assert_valid_keys :connection, :select, :where, :group_by, :order_by, :limit, :offset, :aggregates, :numerize_aliases, :period, :optimize
88
+ options.assert_valid_keys :connection, :select, :subselect, :where, :ignore_where, :group_by, :order_by, :limit, :offset, :aggregates, :numerize_aliases, :period, :optimize
88
89
  end
89
90
 
90
91
  def optimize_query!(options)
@@ -113,8 +114,9 @@ SQL
113
114
 
114
115
  def prepare_options!(options); end
115
116
 
116
- def normalize_options!(options)
117
+ def normalize_options!(options, original_options)
117
118
  normalize_select!(options)
119
+ normalize_subselect!(options, original_options)
118
120
  normalize_from!(options)
119
121
  normalize_where!(options)
120
122
  normalize_group_by!(options)
@@ -156,6 +158,7 @@ SQL
156
158
  sql_alias = $2
157
159
  end
158
160
 
161
+ sql.gsub!(/sub:(\w+)\./) { "#{quote_alias($1)}." }
159
162
  options[:aliases][sql] = sql_alias if sql_alias
160
163
 
161
164
  array << [sql, sql_alias].compact.join(" AS ")
@@ -163,6 +166,28 @@ SQL
163
166
  end
164
167
  end
165
168
 
169
+ def normalize_subselect!(options, original_options)
170
+ options[:subselect] = options[:subselect].collect do |name, (klass, opts)|
171
+ qry_options = original_options.deep_dup.reject!{|k, v| [:subselect, :numerize_aliases, :limit, :offset, :group_by, :order_by].include?(k)}
172
+
173
+ opts.each do |key, value|
174
+ value = [value].flatten
175
+ if key == :select
176
+ qry_options[key] = value
177
+ elsif key.to_s.match(/ignore_(\w+)/)
178
+ qry_options[$1.to_sym].reject!{|x| value.any?{|y| x.include?(y)}}
179
+ else
180
+ qry_options[key].concat value
181
+ end
182
+ end
183
+
184
+ base_alias = quote_alias(klass.table_name.split("_").collect{|x| x[0]}.join(""))
185
+ query = klass.to_qry(qry_options).gsub("\n", " ").gsub(/#{base_alias}[\s\.]/, "")
186
+
187
+ " , (#{query}) #{quote_alias(name)}"
188
+ end if options[:subselect]
189
+ end
190
+
166
191
  def normalize_from!(options)
167
192
  options[:from] = "#{base.table_name} #{base_alias}"
168
193
  end
@@ -285,7 +310,7 @@ SQL
285
310
  [:select, :where, :group_by, :having, :order_by].inject([]) do |paths, key|
286
311
  if value = options[key]
287
312
  value = value.join " " if value.is_a?(Array)
288
- paths.concat value.gsub(/((?<![\\])['"])((?:.(?!(?<![\\])\1))*.?)\1/, " ").scan(/[a-zA-Z_]+\.[a-zA-Z_\.]+/).collect{|x| x.split(".")[0..-2].join "."}
313
+ paths.concat value.gsub(/((?<![\\])['"])((?:.(?!(?<![\\])\1))*.?)\1/, " ").gsub(/sub:[a-zA-Z_]+\.[a-zA-Z_\.]+/, " ").scan(/[a-zA-Z_]+\.[a-zA-Z_\.]+/).collect{|x| x.split(".")[0..-2].join "."}
289
314
  else
290
315
  paths
291
316
  end
@@ -320,7 +345,13 @@ SQL
320
345
  def finalize_options!(options); end
321
346
 
322
347
  def flatten_options!(options)
323
- [:select, :group_by, :order_by].each do |key|
348
+ options[:select] = if options[:select].size <= 3
349
+ " " + options[:select].join(", ")
350
+ else
351
+ "\n " + options[:select].join(",\n ")
352
+ end
353
+
354
+ [:group_by, :order_by].each do |key|
324
355
  if value = options[key]
325
356
  options[key] = value.join(", ") if value.is_a?(Array)
326
357
  end
@@ -334,7 +365,7 @@ SQL
334
365
  end
335
366
 
336
367
  def compose_sql(options)
337
- sql = ["SELECT #{options[:select]}", "FROM #{options[:from]}", options[:joins]].compact
368
+ sql = ["SELECT#{options[:select]}", "FROM #{options[:from]}", options[:joins], options[:subselect]].compact
338
369
 
339
370
  [:where, :group_by, :having, :order_by, :limit, :offset].each do |key|
340
371
  unless (value = options[key]).blank?
@@ -1,7 +1,7 @@
1
1
  module DirectiveRecord
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- TINY = 12
4
+ TINY = 13
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
data/test/test_helper.rb CHANGED
@@ -13,5 +13,7 @@ def project_file(path)
13
13
  end
14
14
 
15
15
  def strip(sql)
16
- sql.strip.gsub(/^\s+/m, "")
16
+ sql.match(/^\n?(\s+)/)
17
+ size = $1.to_s.size
18
+ sql.gsub(/\n\s{#{size}}/, "\n").strip
17
19
  end
@@ -55,7 +55,11 @@ module Unit
55
55
  assert_equal(
56
56
  strip(
57
57
  %Q{
58
- SELECT `c`.id, `c`.name, COUNT(`orders`.id) AS order_count, GROUP_CONCAT(DISTINCT `tags`.name) AS tags
58
+ SELECT
59
+ `c`.id,
60
+ `c`.name,
61
+ COUNT(`orders`.id) AS order_count,
62
+ GROUP_CONCAT(DISTINCT `tags`.name) AS tags
59
63
  FROM customers `c`
60
64
  LEFT JOIN orders `orders` ON `orders`.customer_id = `c`.id
61
65
  LEFT JOIN customers_tags `tags_bridge_table` ON `tags_bridge_table`.customer_id = `c`.id
metadata CHANGED
@@ -1,139 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: directiverecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Engel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-08 00:00:00.000000000 Z
11
+ date: 2015-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.2.13
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 3.2.13
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: arel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "<"
31
+ - - <
32
32
  - !ruby/object:Gem::Version
33
33
  version: 6.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "<"
38
+ - - <
39
39
  - !ruby/object:Gem::Version
40
40
  version: 6.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - ! '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - ! '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: mysql2
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - ! '>='
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - ! '>='
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: minitest
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - ! '>='
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - ">="
122
+ - - ! '>='
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: mocha
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - ! '>='
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - ">="
136
+ - - ! '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  description: A layer on top of ActiveRecord for using paths within queries without
@@ -143,7 +143,7 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
- - ".gitignore"
146
+ - .gitignore
147
147
  - CHANGELOG.rdoc
148
148
  - Gemfile
149
149
  - MIT-LICENSE
@@ -195,17 +195,17 @@ require_paths:
195
195
  - lib
196
196
  required_ruby_version: !ruby/object:Gem::Requirement
197
197
  requirements:
198
- - - ">="
198
+ - - ! '>='
199
199
  - !ruby/object:Gem::Version
200
200
  version: '0'
201
201
  required_rubygems_version: !ruby/object:Gem::Requirement
202
202
  requirements:
203
- - - ">="
203
+ - - ! '>='
204
204
  - !ruby/object:Gem::Version
205
205
  version: '0'
206
206
  requirements: []
207
207
  rubyforge_project:
208
- rubygems_version: 2.2.2
208
+ rubygems_version: 2.1.11
209
209
  signing_key:
210
210
  specification_version: 4
211
211
  summary: A layer on top of ActiveRecord for using paths within queries without thinking