sql_mapper 1.0.1 → 1.0.2

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.
Files changed (2) hide show
  1. data/lib/sql_mapper.rb +80 -38
  2. metadata +1 -1
@@ -3,11 +3,25 @@ require 'active_record'
3
3
 
4
4
  module ActiveRecord
5
5
  module SqlMapper
6
+ def self.config(&block)
7
+ Context.instance.instance_exec &block
8
+ end
9
+
10
+ def self.fetch(opts={})
11
+ strategy = get_strategy_for(*sql_and_result_class_for(opts))
12
+ strategy.do_fetch
13
+ strategy.process_results
14
+ end
15
+
16
+ def self.fetch_one(opts={})
17
+ fetch(opts)[0]
18
+ end
19
+
6
20
  class Context
7
21
  include Singleton
8
22
 
9
23
  def initialize
10
- @result_class = Struct
24
+ @default_result_class = Struct
11
25
  @queries = {}
12
26
  end
13
27
 
@@ -15,14 +29,18 @@ module ActiveRecord
15
29
  @queries.dup
16
30
  end
17
31
 
32
+ def named_query_exists?(sym)
33
+ @queries.include? sym
34
+ end
35
+
18
36
  def map(name, sql, result_class=nil)
19
37
  mapping = QueryMapping.new name, sql, result_class
20
38
  @queries[name] = mapping
21
39
  end
22
40
 
23
41
  def result_class(clazz=nil)
24
- @result_class = clazz if not clazz.nil? and clazz.is_a? Class
25
- @result_class
42
+ @default_result_class = clazz if not clazz.nil? and clazz.is_a? Class
43
+ @default_result_class
26
44
  end
27
45
  end
28
46
 
@@ -37,7 +55,7 @@ module ActiveRecord
37
55
  end
38
56
  end
39
57
 
40
- class DefaultExecStrategy
58
+ class ObjectExecStrategy
41
59
  def initialize(sql, result_class)
42
60
  @sql = sql
43
61
  @result_class = result_class
@@ -48,19 +66,32 @@ module ActiveRecord
48
66
  end
49
67
 
50
68
  def process_results
51
- @raw_results.rows.map{|row| @result_class.new *row}
69
+ @raw_results.rows.map &instantiate_result_using_row
70
+ end
71
+
72
+ private
73
+ def instantiate_result_using_row
74
+ lambda {|row| @result_class.new *row}
52
75
  end
53
76
  end
54
77
 
55
- class StructExecStrategy < DefaultExecStrategy
78
+ class StructExecStrategy < ObjectExecStrategy
56
79
  def initialize(sql, result_class)
57
80
  super(sql, result_class)
58
81
  end
59
82
 
60
83
  def do_fetch
61
84
  @raw_results = ActiveRecord::Base.connection.exec_query(@sql)
62
- col_names = @raw_results.columns.map{|c| c.to_sym}
63
- @result_class = @result_class.new(*col_names)
85
+ @result_class = create_struct_instance_from_col_names(@raw_results)
86
+ end
87
+
88
+ private
89
+ def create_struct_instance_from_col_names(raw_results)
90
+ Struct.new *extract_col_names_from(raw_results)
91
+ end
92
+
93
+ def extract_col_names_from(raw_results)
94
+ raw_results.columns.map{|c| c.to_sym}
64
95
  end
65
96
  end
66
97
 
@@ -86,54 +117,65 @@ module ActiveRecord
86
117
 
87
118
  # Json execution strategy?
88
119
  EXEC_STRATEGIES = {
89
- :default => DefaultExecStrategy,
120
+ :object => ObjectExecStrategy,
90
121
  Struct => StructExecStrategy,
91
122
  Hash => HashExecStrategy
92
123
  }
93
124
 
94
- def self.config(&block)
95
- Context.instance.instance_exec &block
125
+ private
126
+ def self.sql_and_result_class_for(opts={})
127
+ raise ":query option must be specified" if not opts.include? :query
128
+ sql, result_class = obtain_sql_and_result_class_for(opts[:query], opts[:result_class])
129
+ sql = inject_params_into(sql, opts[:params])
130
+ [sql, result_class]
96
131
  end
97
132
 
98
- def self.fetch(opts={})
99
- sql, result_class = construct_sql_for opts
100
- strategy_class = (EXEC_STRATEGIES[result_class] || EXEC_STRATEGIES[:default])
101
- strategy = strategy_class.new(sql, result_class)
102
- strategy.do_fetch
103
- strategy.process_results
133
+ def self.wrap_non_arrays_in_array(val)
134
+ if val.kind_of? Array
135
+ val
136
+ else
137
+ [val]
138
+ end
104
139
  end
105
140
 
106
- def self.fetch_one(opts={})
107
- results = fetch(opts)
108
- results[0]
141
+ def self.get_strategy_for(sql, result_class)
142
+ get_strategy_class_for(result_class).new(sql, result_class)
109
143
  end
110
144
 
111
- private
112
- def self.construct_sql_for(opts={})
113
- raise ":query option must be specified" if not opts.include? :query
114
- sql = opts[:query]
145
+ def self.get_strategy_class_for(result_class)
146
+ (EXEC_STRATEGIES[result_class] || EXEC_STRATEGIES[:object])
147
+ end
115
148
 
116
- result_class = opts[:result_class] || Context.instance.result_class
117
- if opts[:query].kind_of? Symbol
118
- mapping = Context.instance.queries[opts[:query]]
119
- raise "No query named #{opts[:query]} found" if mapping.nil?
149
+ def self.obtain_sql_and_result_class_for(query, result_class)
150
+ if is_named_query(query)
151
+ mapping = Context.instance.queries[query]
120
152
  sql = mapping.sql
121
- result_class = mapping.result_class || result_class
153
+ result_class = result_class || mapping.result_class || Context.instance.result_class
154
+ else
155
+ sql = query
156
+ result_class = result_class || Context.instance.result_class
122
157
  end
158
+ [sql, result_class]
159
+ end
123
160
 
124
- if opts.include? :params
125
- sql_array = [sql] + wrap_non_arrays_in_array(opts[:params])
126
- sql = ActiveRecord::Base.send :sanitize_sql_array, sql_array
161
+ def self.is_named_query(query)
162
+ result = false
163
+ if query.kind_of? Symbol
164
+ if Context.instance.named_query_exists?(query)
165
+ result = true
166
+ else
167
+ raise "No query named #{query} found"
168
+ end
127
169
  end
128
- [sql, result_class]
170
+ result
129
171
  end
130
172
 
131
- def self.wrap_non_arrays_in_array(val)
132
- if val.kind_of? Array
133
- val
134
- else
135
- [val]
173
+ def self.inject_params_into(sql, params)
174
+ unless params.nil?
175
+ sql_array = [sql] + wrap_non_arrays_in_array(params)
176
+ sql = ActiveRecord::Base.send :sanitize_sql_array, sql_array
136
177
  end
178
+ sql
137
179
  end
138
180
  end
139
181
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: