sql_mapper 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: