mcmire-ar_oo_select 0.1
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.
- data/README.rdoc +66 -0
- data/lib/ar_oo_select/ar_ext.rb +60 -0
- data/lib/ar_oo_select/will_paginate_ext.rb +26 -0
- data/lib/ar_oo_select.rb +25 -0
- metadata +56 -0
data/README.rdoc
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
= ar_oo_select
|
|
2
|
+
|
|
3
|
+
== About
|
|
4
|
+
|
|
5
|
+
Let's face it, ActiveRecord is slow. Sometimes you need a way to bypass ActiveRecord
|
|
6
|
+
but still enjoy the typecasting and object oriented goodness it provides.
|
|
7
|
+
ar_oo_select (for lack of a better name) allows you to do just that.
|
|
8
|
+
|
|
9
|
+
ActiveRecord gives you four methods to perform a low-level SQL query through the
|
|
10
|
+
connection object itself:
|
|
11
|
+
|
|
12
|
+
* connection.select_all
|
|
13
|
+
* connection.select_rows
|
|
14
|
+
* connection.select_one
|
|
15
|
+
* connection.select_value
|
|
16
|
+
|
|
17
|
+
Likewise, ar_oo_select gives you four methods that are simply a wrapper for their
|
|
18
|
+
builtin counterparts:
|
|
19
|
+
|
|
20
|
+
* oo_select_all
|
|
21
|
+
* oo_select_rows
|
|
22
|
+
* oo_select_one
|
|
23
|
+
* oo_select_value
|
|
24
|
+
|
|
25
|
+
The difference is that 1) your query goes through AR's <tt>sanitize_sql</tt> method before
|
|
26
|
+
reaching the connection methods and 2) the values in the result set are typecasted
|
|
27
|
+
depending on what they look like (date, time, integer, float, or boolean).
|
|
28
|
+
In the case of <tt>oo_select_all</tt>, the hashes that come from the result set
|
|
29
|
+
are converted to special hashes whose values you can access using an object-oriented
|
|
30
|
+
syntax (or openhashes for short), so it still feels like ActiveRecord. This is made
|
|
31
|
+
available using whichever library you have installed:
|
|
32
|
+
|
|
33
|
+
* the {OpenHash library}[http://github.com/mcmire/openhash] I've also written
|
|
34
|
+
* {OpenObject}[http://facets.rubyforge.org/doc/api/more/classes/OpenObject.html], a comparable library within Ruby Facets
|
|
35
|
+
* {OpenStruct}[http://apidock.com/ruby/OpenStruct], included in the Ruby standard library
|
|
36
|
+
|
|
37
|
+
== Usage
|
|
38
|
+
|
|
39
|
+
All four methods receive the same arguments as <tt>find_by_sql</tt>: either a statement,
|
|
40
|
+
or statement + bind variables.
|
|
41
|
+
|
|
42
|
+
== Installation
|
|
43
|
+
|
|
44
|
+
Put this in your environment.rb:
|
|
45
|
+
|
|
46
|
+
config.gem 'mcmire-ar_oo_select', :lib => 'ar_oo_select', :source => 'http://gems.github.com'
|
|
47
|
+
|
|
48
|
+
Then run:
|
|
49
|
+
|
|
50
|
+
rake gems:install
|
|
51
|
+
|
|
52
|
+
and, optionally:
|
|
53
|
+
|
|
54
|
+
rake gems:unpack
|
|
55
|
+
|
|
56
|
+
== Support
|
|
57
|
+
|
|
58
|
+
If you find any bugs with this plugin, feel free to:
|
|
59
|
+
|
|
60
|
+
* file a bug report in the {Issues area on Github}[http://github.com/mcmire/ar_oo_select/issues]
|
|
61
|
+
* fork the {project on Github}[http://github.com/mcmire/ar_oo_select] and send me a pull request
|
|
62
|
+
* email me (_firstname_ dot _lastname_ at gmail dot com)
|
|
63
|
+
|
|
64
|
+
== Author/License
|
|
65
|
+
|
|
66
|
+
(c) 2009 Elliot Winkler. Released under the MIT license.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module ArOoSelect
|
|
2
|
+
module ArExt
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.class_eval do
|
|
5
|
+
alias_method :oo_select, :oo_select_all
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Executes the query and returns an array of openhashes.
|
|
10
|
+
def oo_select_all(query)
|
|
11
|
+
query = sanitize_sql(query)
|
|
12
|
+
rows = connection.select_all(query)
|
|
13
|
+
rows.map do |row|
|
|
14
|
+
oh = OpenHash.new(row)
|
|
15
|
+
oh.each {|k, v| oh[k] = oo_select_type_cast(v) }
|
|
16
|
+
oh
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Executes the query and returns an array of rows.
|
|
21
|
+
def oo_select_rows(query)
|
|
22
|
+
query = sanitize_sql(query)
|
|
23
|
+
rows = connection.select_rows(query)
|
|
24
|
+
rows.map do |row|
|
|
25
|
+
row.map {|v| oo_select_type_cast(v) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Executes the query and returns the first row as an openhash.
|
|
30
|
+
def oo_select_one(query)
|
|
31
|
+
oo_select_all(query).first
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Executes the query and returns the value of the first column in the first row.
|
|
35
|
+
def oo_select_value(query)
|
|
36
|
+
query = sanitize_sql(query)
|
|
37
|
+
connection.select_value(query)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
def oo_select_type_cast(v)
|
|
42
|
+
return unless v
|
|
43
|
+
if md = v.match(/^(\d{4})-(\d{2})-(\d{2})$/)
|
|
44
|
+
Date.new(*md.captures.map(&:to_i)) rescue v
|
|
45
|
+
elsif md = v.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/)
|
|
46
|
+
Time.local(*md.captures.map(&:to_i)) rescue v
|
|
47
|
+
elsif v =~ /^(?:-|\+)?\d+$/
|
|
48
|
+
v.to_i
|
|
49
|
+
elsif v =~ /^(?:-|\+)?\d+(?:\.\d+)+$/
|
|
50
|
+
v.to_f
|
|
51
|
+
elsif v == "true"
|
|
52
|
+
true
|
|
53
|
+
elsif v == "false"
|
|
54
|
+
false
|
|
55
|
+
else
|
|
56
|
+
v
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module ArOoSelect
|
|
2
|
+
module WillPaginateExt
|
|
3
|
+
# Patch to use our oo_select_all instead of connection.select_all
|
|
4
|
+
def oo_select_paginate(sql, options)
|
|
5
|
+
WillPaginate::Collection.create(*wp_parse_options(options)) do |pager|
|
|
6
|
+
query = sanitize_sql(sql)
|
|
7
|
+
original_query = query.dup
|
|
8
|
+
# add limit, offset
|
|
9
|
+
add_limit! query, :offset => pager.offset, :limit => pager.per_page
|
|
10
|
+
# perform the find
|
|
11
|
+
pager.replace oo_select_all(query)
|
|
12
|
+
|
|
13
|
+
unless pager.total_entries
|
|
14
|
+
count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s]+$/mi, ''
|
|
15
|
+
count_query = "SELECT COUNT(*) FROM (#{count_query})"
|
|
16
|
+
|
|
17
|
+
unless ['oracle', 'oci'].include?(self.connection.adapter_name.downcase)
|
|
18
|
+
count_query << ' AS count_table'
|
|
19
|
+
end
|
|
20
|
+
# perform the count query
|
|
21
|
+
pager.total_entries = count_by_sql(count_query)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/ar_oo_select.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
# Try to load our OpenHash gem,
|
|
4
|
+
# then try Facets' OpenObject gem,
|
|
5
|
+
# then just use OpenStruct which is in the standard library
|
|
6
|
+
begin
|
|
7
|
+
require 'openhash'
|
|
8
|
+
rescue LoadError
|
|
9
|
+
begin
|
|
10
|
+
require 'facets/openobject'
|
|
11
|
+
OpenHash = OpenObject
|
|
12
|
+
rescue LoadError
|
|
13
|
+
require 'ostruct'
|
|
14
|
+
OpenHash = OpenStruct
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
require 'ar_oo_select/ar_ext'
|
|
19
|
+
ActiveRecord::Base.extend(ArOoSelect::ArExt)
|
|
20
|
+
|
|
21
|
+
# I'm not sure if this should be here?
|
|
22
|
+
#if defined?(WillPaginate)
|
|
23
|
+
# require 'ar_oo_select/will_paginate_ext'
|
|
24
|
+
# ActiveRecord::Base.extend(ArOoSelect::WillPaginateExt)
|
|
25
|
+
#end
|
metadata
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mcmire-ar_oo_select
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: "0.1"
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Elliot Winkler
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-06-28 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: Let's face it, ActiveRecord is slow. Sometimes you need a way to bypass ActiveRecord, but still enjoy the typecasting and object oriented goodness it provides.
|
|
17
|
+
email: elliot.winkler@gmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- README.rdoc
|
|
26
|
+
- lib/ar_oo_select.rb
|
|
27
|
+
- lib/ar_oo_select/ar_ext.rb
|
|
28
|
+
- lib/ar_oo_select/will_paginate_ext.rb
|
|
29
|
+
has_rdoc: false
|
|
30
|
+
homepage: http://github.com/mcmire/ar_oo_select
|
|
31
|
+
post_install_message:
|
|
32
|
+
rdoc_options: []
|
|
33
|
+
|
|
34
|
+
require_paths:
|
|
35
|
+
- lib
|
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: "0"
|
|
41
|
+
version:
|
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: "0"
|
|
47
|
+
version:
|
|
48
|
+
requirements: []
|
|
49
|
+
|
|
50
|
+
rubyforge_project:
|
|
51
|
+
rubygems_version: 1.2.0
|
|
52
|
+
signing_key:
|
|
53
|
+
specification_version: 2
|
|
54
|
+
summary: Use find_by_sql without going through ActiveRecord
|
|
55
|
+
test_files: []
|
|
56
|
+
|