sql_mapper 0.0.1

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 +139 -0
  2. metadata +103 -0
data/lib/sql_mapper.rb ADDED
@@ -0,0 +1,139 @@
1
+ require 'singleton'
2
+ require 'active_record'
3
+
4
+ module ActiveRecord
5
+ module SqlMapper
6
+ class Context
7
+ include Singleton
8
+
9
+ def initialize
10
+ @result_class = Struct
11
+ @queries = {}
12
+ end
13
+
14
+ def queries
15
+ @queries.dup
16
+ end
17
+
18
+ def map(name, sql, result_class=nil)
19
+ mapping = QueryMapping.new name, sql, (result_class || @result_class)
20
+ @queries[name] = mapping
21
+ end
22
+
23
+ def result_class(clazz=nil)
24
+ @result_class = clazz if not clazz.nil? and clazz.is_a? Class
25
+ @result_class
26
+ end
27
+ end
28
+
29
+ class QueryMapping
30
+ attr_reader :key
31
+ attr_accessor :sql, :result_class
32
+
33
+ def initialize(key, sql, result_class=Context.result_class)
34
+ @key = key
35
+ @sql = sql
36
+ @result_class = result_class
37
+ end
38
+ end
39
+
40
+ class DefaultExecStrategy
41
+ def initialize(sql, result_class)
42
+ @sql = sql
43
+ @result_class = result_class
44
+ end
45
+
46
+ def do_fetch
47
+ @raw_results = ActiveRecord::Base.connection.exec_query(@sql)
48
+ end
49
+
50
+ def process_results
51
+ @raw_results.rows.map{|row| @result_class.new *row}
52
+ end
53
+ end
54
+
55
+ class StructExecStrategy < DefaultExecStrategy
56
+ def initialize(sql, result_class)
57
+ super(sql, result_class)
58
+ end
59
+
60
+ def do_fetch
61
+ @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)
64
+ end
65
+ end
66
+
67
+ class HashExecStrategy
68
+ def initialize(sql, result_class)
69
+ @sql = sql
70
+ @result_class = result_class
71
+ end
72
+
73
+ def do_fetch
74
+ @raw_results = ActiveRecord::Base.connection.select_all(@sql)
75
+ end
76
+
77
+ def process_results
78
+ @raw_results.map{|hash| symbolize_hash hash}
79
+ end
80
+
81
+ private
82
+ def symbolize_hash(hash)
83
+ hash.inject({}) {|new,(k,v)| new[k.to_sym] = v; new}
84
+ end
85
+ end
86
+
87
+ # Json execution strategy?
88
+ EXEC_STRATEGIES = {
89
+ :default => DefaultExecStrategy,
90
+ Struct => StructExecStrategy,
91
+ Hash => HashExecStrategy
92
+ }
93
+
94
+ def self.config(&block)
95
+ Context.instance.instance_exec &block
96
+ end
97
+
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
104
+ end
105
+
106
+ def self.fetch_one(opts={})
107
+ results = fetch(opts)
108
+ results[0]
109
+ end
110
+
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]
115
+
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?
120
+ sql = mapping.sql
121
+ result_class = mapping.result_class
122
+ end
123
+
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
127
+ end
128
+ [sql, result_class]
129
+ end
130
+
131
+ def self.wrap_non_arrays_in_array(val)
132
+ if val.kind_of? Array
133
+ val
134
+ else
135
+ [val]
136
+ end
137
+ end
138
+ end
139
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sql_mapper
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Lance Woodson
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-11-01 00:00:00 -05:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activerecord
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 0
31
+ version: 2.3.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: pg
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 11
44
+ - 0
45
+ version: 0.11.0
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: sqlite3
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 1
57
+ - 3
58
+ - 4
59
+ version: 1.3.4
60
+ type: :development
61
+ version_requirements: *id003
62
+ description: Object-to-sql mapping support for ActiveRecord.
63
+ email: lance@webmaneuvers.com
64
+ executables: []
65
+
66
+ extensions: []
67
+
68
+ extra_rdoc_files: []
69
+
70
+ files:
71
+ - lib/sql_mapper.rb
72
+ has_rdoc: true
73
+ homepage: http://rubygems.org/gems/sql_mapper
74
+ licenses: []
75
+
76
+ post_install_message:
77
+ rdoc_options: []
78
+
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.6
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Object-to-sql mapping support for ActiveRecord
102
+ test_files: []
103
+