active_record_sql_unionizer 0.0.1 → 0.0.2
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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6edeb9257c4226bca2f11ddf5f60659ebecd58b2
|
4
|
+
data.tar.gz: a8ea988d3fc032efdae9a2c6361c1929bd0cf7a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20096ba4f489c6646f714fec2d9616442e96025e466bc83ec0e248342fa3e9b67423d894653ce58d2e218d609fd4109944be64b0f1a1bd58749ea51a2ec99f09
|
7
|
+
data.tar.gz: ab817088c9827fad57ffe147bb4d5d1fa462146489221d5222e75da105f2cb03cf7eb52771f23699772ce842ffee3eeb52d1928ce14c3cea26d0d6b5aba9bdaf
|
@@ -4,15 +4,79 @@ module ActiveRecordSqlUnionizer
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
module ClassMethods
|
7
|
+
#passed in objects can be valid SQL strings, ActiveRecord::Relation, and class methods
|
8
|
+
#as symbols that return an ActiveRecord::Relation.
|
9
|
+
# @param [Splat] queries
|
10
|
+
#
|
11
|
+
# @return [ActiveRecord::Relation]
|
7
12
|
def unionize(*queries)
|
8
|
-
|
9
|
-
|
13
|
+
unionizer_helper = UnionizerHelper.new
|
14
|
+
|
15
|
+
table_name = unionizer_helper.get_table_name(self)
|
16
|
+
|
17
|
+
sql_queries = queries.map do |query|
|
18
|
+
query_string =
|
19
|
+
case query
|
20
|
+
when String
|
21
|
+
query
|
22
|
+
when Symbol
|
23
|
+
unionizer_helper.handle_symbol_arg(self, query)
|
24
|
+
else
|
25
|
+
query.to_sql
|
26
|
+
end
|
27
|
+
|
10
28
|
"(#{query_string})"
|
11
|
-
end
|
12
|
-
|
29
|
+
end
|
30
|
+
|
31
|
+
union_string = unionizer_helper.construct_final_query_string(sql_queries, table_name)
|
13
32
|
|
14
33
|
sql = self.connection.unprepared_statement {union_string}
|
15
34
|
self.from(sql)
|
16
35
|
end
|
17
36
|
end
|
37
|
+
|
38
|
+
class UnionizerHelper
|
39
|
+
#for 'private' methods/ readability
|
40
|
+
|
41
|
+
# @param [Object] klass
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
def get_table_name(klass)
|
45
|
+
table_klass = klass
|
46
|
+
while table_klass.superclass != ActiveRecord::Base
|
47
|
+
table_klass = table_klass.superclass
|
48
|
+
end
|
49
|
+
table_klass.to_s.underscore.downcase.pluralize
|
50
|
+
end
|
51
|
+
|
52
|
+
# @param [Symbol] arg
|
53
|
+
#
|
54
|
+
# @return [String, UnionizerError]
|
55
|
+
def handle_symbol_arg(klass, arg)
|
56
|
+
if klass.respond_to?(arg)
|
57
|
+
klass.send(arg).to_sql
|
58
|
+
else
|
59
|
+
raise(UnionizerError.new(klass.to_s, arg))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param [Array<String>] queries
|
64
|
+
# @param [String] table_name
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
def construct_final_query_string(queries, table_name)
|
68
|
+
"(#{queries.join(" UNION ")}) AS #{table_name}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class UnionizerError < StandardError
|
73
|
+
# @param [String] klass_name
|
74
|
+
# @param [Symbol] method_name
|
75
|
+
#
|
76
|
+
# @return [UnionizerError]
|
77
|
+
def initialize(klass_name, method_name)
|
78
|
+
msg = "ActiveRecordSqlUnionizer expected #{klass_name} to respond to #{method_name}, but it does not"
|
79
|
+
super(msg)
|
80
|
+
end
|
81
|
+
end
|
18
82
|
end
|