wherelizer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/wherelizer/sexp_extensions.rb +62 -0
- data/lib/wherelizer.rb +85 -0
- metadata +80 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
module SexpExtensions
|
2
|
+
def is_type?(expected_type)
|
3
|
+
type = self[0]
|
4
|
+
expected_type = [expected_type] unless expected_type.respond_to?(:include?)
|
5
|
+
expected_type.include? type
|
6
|
+
end
|
7
|
+
|
8
|
+
def check_type(expected_type)
|
9
|
+
raise "Unexpected type: #{expected_type} in #{self}" unless is_type?(expected_type)
|
10
|
+
end
|
11
|
+
|
12
|
+
def extract_val
|
13
|
+
check_type [:lit, :str]
|
14
|
+
self[1]
|
15
|
+
end
|
16
|
+
|
17
|
+
def extract_const
|
18
|
+
check_type :const
|
19
|
+
self[1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_assignment_target
|
23
|
+
check_type [:lasgn, :iasgn]
|
24
|
+
self[1].to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
###
|
28
|
+
# Extract the receiver of a method call.
|
29
|
+
def extract_receiver
|
30
|
+
check_type :call
|
31
|
+
self[1]
|
32
|
+
end
|
33
|
+
|
34
|
+
###
|
35
|
+
# Extract the method name of a method call.
|
36
|
+
def extract_method_name
|
37
|
+
check_type :call
|
38
|
+
self[2]
|
39
|
+
end
|
40
|
+
|
41
|
+
###
|
42
|
+
# Turn a sexp "hash" node into an actual Ruby hash.
|
43
|
+
# If process_keys is true, then we assume the hash keys are strings or symbols,
|
44
|
+
# and extract the actual string or symbol to be the key in the resulting hash.
|
45
|
+
# Otherwise, we make the key the whole sexp node that is the key.
|
46
|
+
def to_hash(process_keys=true)
|
47
|
+
check_type :hash
|
48
|
+
result = {}
|
49
|
+
self[1..-1].each_slice(2) do |key, val|
|
50
|
+
result[process_keys ? key.extract_val : key] = val
|
51
|
+
end
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
55
|
+
###
|
56
|
+
# Turns a sexp "array" node into an actual Ruby array of just the elements
|
57
|
+
def to_array
|
58
|
+
check_type :array
|
59
|
+
self[1..-1]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/wherelizer.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'ruby_parser'
|
2
|
+
require 'ruby2ruby'
|
3
|
+
require 'wherelizer/sexp_extensions'
|
4
|
+
|
5
|
+
class Sexp
|
6
|
+
include SexpExtensions
|
7
|
+
end
|
8
|
+
|
9
|
+
class Wherelizer
|
10
|
+
attr_accessor :orig, :parsed, :final, :ruby2ruby
|
11
|
+
|
12
|
+
def initialize(orig)
|
13
|
+
@orig = orig
|
14
|
+
@ruby2ruby = Ruby2Ruby.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def convert
|
18
|
+
@parsed = RubyParser.new.parse(orig)
|
19
|
+
assignment = handle_assignment
|
20
|
+
|
21
|
+
receiver = ruby2ruby.process(parsed.extract_receiver)
|
22
|
+
method_name = handle_method_name
|
23
|
+
options_hash = parsed.to_hash
|
24
|
+
|
25
|
+
where = parse_conditions(options_hash.delete(:conditions)) if options_hash[:conditions]
|
26
|
+
others = options_hash.map{|key, value| parse_basic_param(key, value)}.join
|
27
|
+
|
28
|
+
"#{assignment}#{receiver}#{where}#{others}#{method_name}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle_assignment
|
32
|
+
if parsed.is_type? [:lasgn, :iasgn]
|
33
|
+
assignment = final_assignment(parsed.extract_assignment_target)
|
34
|
+
@parsed = @parsed[2]
|
35
|
+
end
|
36
|
+
assignment
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle_method_name
|
40
|
+
method_name = parsed.extract_method_name
|
41
|
+
if method_name == :find
|
42
|
+
first_param = parsed[3]
|
43
|
+
@parsed = @parsed[4]
|
44
|
+
final_method_name(first_param.extract_val)
|
45
|
+
else
|
46
|
+
@parsed = @parsed[3]
|
47
|
+
final_method_name(method_name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def final_method_name(method_name)
|
52
|
+
".#{method_name}" unless method_name == :all
|
53
|
+
end
|
54
|
+
|
55
|
+
def final_assignment(assignment_target)
|
56
|
+
"#{assignment_target} = "
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_conditions node
|
60
|
+
where = ''
|
61
|
+
|
62
|
+
if node.is_type? :hash
|
63
|
+
node.to_hash(false).each do |key, val|
|
64
|
+
if key.is_type? :lit
|
65
|
+
where += ".where(#{key.extract_val}: #{ruby2ruby.process(val)})"
|
66
|
+
else
|
67
|
+
where += ".where(#{ruby2ruby.process(key)} => #{ruby2ruby.process(val)})"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
elsif node.is_type? :array
|
71
|
+
where = ".where(" + node.to_array.map{ |el| ruby2ruby.process(el) }.join(', ') + ")"
|
72
|
+
elsif node.is_type? :str
|
73
|
+
where = ".where(#{ruby2ruby.process(node)})"
|
74
|
+
else
|
75
|
+
raise "Unexpected type for conditions parameter. Expecting hash, array, or string."
|
76
|
+
end
|
77
|
+
|
78
|
+
where
|
79
|
+
end
|
80
|
+
|
81
|
+
def parse_basic_param name, value
|
82
|
+
method_name = name.to_s == 'include' ? 'includes' : name.to_s
|
83
|
+
".#{method_name}(#{ruby2ruby.process(value)})"
|
84
|
+
end
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wherelizer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Melinda Weathers
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby_parser
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: ruby2ruby
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: A gem for converting pre-arel ActiveRecord queries to their non-deprecated
|
47
|
+
equivalents
|
48
|
+
email: melinda@agileleague.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/wherelizer.rb
|
54
|
+
- lib/wherelizer/sexp_extensions.rb
|
55
|
+
homepage: http://github.com/agileleague/wherelizer.git"
|
56
|
+
licenses: []
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.8.25
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: ActiveRecord Query Updater
|
79
|
+
test_files: []
|
80
|
+
has_rdoc:
|