cohort_analysis 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
unreleased
|
2
|
+
|
3
|
+
* Enhancements
|
4
|
+
|
5
|
+
* Arel::SelectManager#cohort_possible? - in case you want to know without having to re-count.
|
6
|
+
* Simplify aliasing examples in tests.
|
7
|
+
|
1
8
|
1.0.1 / 2012-06-05
|
2
9
|
|
3
10
|
* Bug fixes
|
4
11
|
|
5
|
-
* Properly test on mysql and postgres - you'll need a table alias
|
12
|
+
* Properly test on mysql and postgres - you'll need a table/subquery alias like "AS t1"
|
6
13
|
|
7
14
|
1.0.0 / 2012-06-05
|
8
15
|
|
@@ -4,5 +4,21 @@ module CohortAnalysis
|
|
4
4
|
def cohort(characteristics, options = {})
|
5
5
|
where Strategy.create(self, characteristics, options)
|
6
6
|
end
|
7
|
+
|
8
|
+
# If a cohort has been constructed using this Arel::SelectManager, then this will tell you whether it was successful (posssible) or not.
|
9
|
+
# @return [true,false,nil]
|
10
|
+
def cohort_possible?
|
11
|
+
@cohort_possible_query
|
12
|
+
end
|
13
|
+
|
14
|
+
# @private
|
15
|
+
def cohort_possible!
|
16
|
+
@cohort_possible_query = true
|
17
|
+
end
|
18
|
+
|
19
|
+
# @private
|
20
|
+
def cohort_impossible!
|
21
|
+
@cohort_possible_query = false
|
22
|
+
end
|
7
23
|
end
|
8
24
|
end
|
@@ -37,7 +37,7 @@ module CohortAnalysis
|
|
37
37
|
@original = characteristics.dup
|
38
38
|
@current = characteristics.dup
|
39
39
|
@minimum_size = options.fetch(:minimum_size, 1)
|
40
|
-
@final_mutex =
|
40
|
+
@final_mutex = Mutex.new
|
41
41
|
end
|
42
42
|
|
43
43
|
def final
|
@@ -68,11 +68,14 @@ module CohortAnalysis
|
|
68
68
|
# Recursively look for a scope that meets the characteristics and is at least <tt>minimum_size</tt>.
|
69
69
|
def resolve!
|
70
70
|
if original.empty?
|
71
|
+
select_manager.cohort_possible!
|
71
72
|
AlwaysTrue
|
72
73
|
elsif current.empty?
|
74
|
+
select_manager.cohort_impossible!
|
73
75
|
Impossible
|
74
76
|
elsif count(current) >= minimum_size
|
75
|
-
|
77
|
+
select_manager.cohort_possible!
|
78
|
+
grasp(current).inject :and
|
76
79
|
else
|
77
80
|
reduce!
|
78
81
|
resolve!
|
data/test/helper.rb
CHANGED
@@ -183,7 +183,7 @@ shared_examples_for 'an adapter the provides #cohort' do
|
|
183
183
|
it "can get where sql" do
|
184
184
|
FactoryGirl.create(:lax_ord)
|
185
185
|
FactoryGirl.create(:lax_sfo)
|
186
|
-
model.cohort(:origin => 'LAX').where_sql.delete('"`').must_equal %{WHERE
|
186
|
+
model.cohort(:origin => 'LAX').where_sql.delete('"`').must_equal %{WHERE flights.origin = 'LAX'}
|
187
187
|
end
|
188
188
|
|
189
189
|
it "will resolve independently from other cohorts" do
|
@@ -234,23 +234,23 @@ shared_examples_for 'an adapter the provides #cohort' do
|
|
234
234
|
sfo = model.where(f_t[:dest].eq('SFO'))
|
235
235
|
ord.projections = [Arel.star]
|
236
236
|
sfo.projections = [Arel.star]
|
237
|
-
Flight.find_by_sql("SELECT * FROM #{
|
237
|
+
Flight.find_by_sql("SELECT * FROM #{ord.union(sfo).to_sql} AS subquery").must_equal [@ord, @sfo]
|
238
238
|
end
|
239
239
|
|
240
240
|
it "builds successful cohorts" do
|
241
241
|
ord = model.cohort(:dest => 'ORD').project(Arel.star)
|
242
242
|
sfo = model.cohort(:dest => 'SFO').project(Arel.star)
|
243
|
-
Flight.find_by_sql("SELECT * FROM #{
|
243
|
+
Flight.find_by_sql("SELECT * FROM #{ord.union(sfo).to_sql} AS subquery").must_equal [@ord, @sfo]
|
244
244
|
|
245
245
|
msn = model.cohort(:origin => 'LAX', :dest => 'MSN').project(Arel.star)
|
246
246
|
lhr = model.cohort(:origin => 'LAX', :dest => 'LHR').project(Arel.star)
|
247
|
-
Flight.find_by_sql("SELECT * FROM #{
|
247
|
+
Flight.find_by_sql("SELECT * FROM #{msn.union(lhr).to_sql} AS subquery").must_equal [@ord, @sfo]
|
248
248
|
end
|
249
249
|
|
250
250
|
it "doesn't somehow create unions with false positives" do
|
251
251
|
msn = model.cohort(:dest => 'MSN').project(Arel.star)
|
252
252
|
lhr = model.cohort(:dest => 'LHR').project(Arel.star)
|
253
|
-
count = ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM #{
|
253
|
+
count = ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM #{msn.union(lhr).to_sql} AS subquery")
|
254
254
|
flunk "count was nil" if count.nil?
|
255
255
|
count.to_i.must_equal 0
|
256
256
|
end
|
@@ -258,7 +258,31 @@ shared_examples_for 'an adapter the provides #cohort' do
|
|
258
258
|
it "builds unions where only one side has rows" do
|
259
259
|
msn = model.cohort(:dest => 'MSN').project(Arel.star)
|
260
260
|
ord = model.cohort(:dest => 'ORD').project(Arel.star)
|
261
|
-
Flight.find_by_sql("SELECT * FROM #{
|
261
|
+
Flight.find_by_sql("SELECT * FROM #{msn.union(ord).to_sql} AS subquery").must_equal [@ord]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
describe :cohort_possible? do
|
266
|
+
it "can be used after the cohort is resolved" do
|
267
|
+
FactoryGirl.create(:lax_ord)
|
268
|
+
FactoryGirl.create(:lax_sfo)
|
269
|
+
yes = model.cohort(:origin => 'LAX')
|
270
|
+
yes.to_sql # force the cohort to resolve
|
271
|
+
no = model.cohort(:dest => 'MSN')
|
272
|
+
no.to_sql
|
273
|
+
assert yes.cohort_possible?
|
274
|
+
refute no.cohort_possible?
|
275
|
+
end
|
276
|
+
|
277
|
+
it "may be available even after further composition" do
|
278
|
+
FactoryGirl.create(:lax_ord)
|
279
|
+
FactoryGirl.create(:lax_sfo)
|
280
|
+
yes = model.cohort(:origin => 'LAX').where(moot_condition)
|
281
|
+
yes.to_sql # force the cohort to resolve
|
282
|
+
no = model.cohort(:dest => 'MSN').where(moot_condition)
|
283
|
+
no.to_sql
|
284
|
+
assert yes.cohort_possible?
|
285
|
+
refute no.cohort_possible?
|
262
286
|
end
|
263
287
|
end
|
264
288
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cohort_analysis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-06-
|
15
|
+
date: 2012-06-06 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|