ambition 0.2.2 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +2 -0
- data/README +9 -13
- data/Rakefile +6 -6
- data/lib/ambition.rb +1 -0
- data/lib/ambition/proc_to_ruby.rb +1 -0
- data/lib/ambition/processor.rb +29 -10
- data/lib/ambition/query.rb +3 -2
- data/lib/ambition/ruby_processor.rb +22 -0
- data/lib/ambition/select_processor.rb +0 -4
- data/test/benchmark.rb +6 -0
- data/test/join_test.rb +13 -0
- data/test/ruby_test.rb +9 -0
- data/test/types_test.rb +2 -3
- data/test/where_test.rb +8 -4
- metadata +14 -2
data/Manifest
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
./lib/ambition/proc_to_ruby.rb
|
5
5
|
./lib/ambition/processor.rb
|
6
6
|
./lib/ambition/query.rb
|
7
|
+
./lib/ambition/ruby_processor.rb
|
7
8
|
./lib/ambition/select_processor.rb
|
8
9
|
./lib/ambition/simple_processor.rb
|
9
10
|
./lib/ambition/sort_processor.rb
|
@@ -42,5 +43,6 @@
|
|
42
43
|
./test/order_test.rb
|
43
44
|
./test/profiler.rb
|
44
45
|
./test/source_test.rb
|
46
|
+
./test/ruby_test.rb
|
45
47
|
./test/types_test.rb
|
46
48
|
./test/where_test.rb
|
data/README
CHANGED
@@ -59,21 +59,13 @@ See, +to_hash+:
|
|
59
59
|
>> User.select { |m| m.name == 'jon' }.to_hash
|
60
60
|
=> {:conditions=>"users.name = 'jon'"}
|
61
61
|
|
62
|
-
==
|
63
|
-
|
64
|
-
You can use variables, but any more complex Ruby (right now) won't work
|
65
|
-
inside your blocks. Just do it outside the block and assign it to a variable.
|
66
|
-
|
67
|
-
Instead of:
|
68
|
-
User.select { |m| m.date == 2.days.ago }
|
69
|
-
|
70
|
-
Just do:
|
71
|
-
date = 2.days.ago
|
72
|
-
User.select { |m| m.date == date }
|
62
|
+
== Equality -- select { |u| u.field == 'bob' }
|
73
63
|
|
74
|
-
|
64
|
+
User.select { |m| m.name == 'jon' }
|
65
|
+
"SELECT * FROM users WHERE users.name = 'jon'"
|
75
66
|
|
76
|
-
|
67
|
+
User.select { |m| m.created_at > 2.days.ago }
|
68
|
+
"SELECT * FROM users WHERE users.created_at > '2007-09-26 20:37:47'"
|
77
69
|
|
78
70
|
User.select { |m| m.name == 'jon' }
|
79
71
|
"SELECT * FROM users WHERE users.name = 'jon'"
|
@@ -208,4 +200,8 @@ Found a bug? Sweet. Add it at the Lighthouse:
|
|
208
200
|
|
209
201
|
Feature requests are welcome.
|
210
202
|
|
203
|
+
And hey, join our mailing list!
|
204
|
+
|
205
|
+
http://groups.google.com/group/ambition-rb
|
206
|
+
|
211
207
|
* Chris Wanstrath [ chris@ozmm.org ]
|
data/Rakefile
CHANGED
@@ -2,19 +2,18 @@ require 'rake'
|
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rake/rdoctask'
|
4
4
|
|
5
|
-
Version = '0.
|
5
|
+
Version = '0.3.1'
|
6
6
|
|
7
7
|
module Rake::TaskManager
|
8
|
-
def
|
8
|
+
def delete_task(task_class, args, &block)
|
9
9
|
task_name, deps = resolve_args(args)
|
10
10
|
@tasks.delete(task_class.scope_name(@scope, task_name).to_s)
|
11
|
-
define_task(task_class, args, &block)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
class Rake::Task
|
15
|
-
def self.
|
14
|
+
def self.delete_task(args, &block) Rake.application.delete_task(self, args, &block) end
|
16
15
|
end
|
17
|
-
def
|
16
|
+
def delete_task(args, &block) Rake::Task.delete_task(args, &block) end
|
18
17
|
|
19
18
|
begin
|
20
19
|
require 'rubygems'
|
@@ -30,6 +29,7 @@ begin
|
|
30
29
|
p.author = 'Chris Wanstrath'
|
31
30
|
p.email = "chris@ozmm.org"
|
32
31
|
p.extra_deps << ['ParseTree', '=2.0.1']
|
32
|
+
p.extra_deps << ['ruby2ruby', '=1.1.7']
|
33
33
|
p.extra_deps << ['activerecord', '>=1.15.0']
|
34
34
|
p.test_globs = 'test/*_test.rb'
|
35
35
|
end
|
@@ -37,7 +37,7 @@ begin
|
|
37
37
|
rescue LoadError
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
delete_task :test
|
41
41
|
|
42
42
|
Rake::TestTask.new('test') do |t|
|
43
43
|
t.pattern = 'test/*_test.rb'
|
data/lib/ambition.rb
CHANGED
data/lib/ambition/processor.rb
CHANGED
@@ -14,23 +14,31 @@ module Ambition
|
|
14
14
|
|
15
15
|
##
|
16
16
|
# Processing methods
|
17
|
-
def process_error(exp)
|
18
|
-
raise "Missing process method for sexp: #{exp.inspect}"
|
19
|
-
end
|
20
|
-
|
21
17
|
def process_proc(exp)
|
22
18
|
receiver, body = process(exp.shift), exp.shift
|
23
|
-
|
19
|
+
process(body)
|
24
20
|
end
|
25
21
|
|
26
22
|
def process_dasgn_curr(exp)
|
27
|
-
@receiver = exp.
|
28
|
-
|
23
|
+
@receiver = exp.first
|
24
|
+
@receiver.to_s
|
29
25
|
end
|
26
|
+
alias_method :process_dasgn, :process_dasgn_curr
|
30
27
|
|
31
28
|
def process_array(exp)
|
32
|
-
|
33
|
-
|
29
|
+
# Branch on whether this is straight Ruby or a real array
|
30
|
+
if ruby = rubify(exp)
|
31
|
+
value ruby
|
32
|
+
else
|
33
|
+
arrayed = exp.map { |m| process(m) }
|
34
|
+
arrayed.join(', ')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def rubify(exp)
|
39
|
+
if exp.first.first == :call && exp.first[1].last != @receiver && Array(exp.first[1][1]).last != @receiver
|
40
|
+
RubyProcessor.process(exp.first)
|
41
|
+
end
|
34
42
|
end
|
35
43
|
|
36
44
|
##
|
@@ -39,6 +47,10 @@ module Ambition
|
|
39
47
|
process(@block.to_sexp).squeeze(' ')
|
40
48
|
end
|
41
49
|
|
50
|
+
def value(variable)
|
51
|
+
sanitize eval(variable, @block)
|
52
|
+
end
|
53
|
+
|
42
54
|
def sanitize(value)
|
43
55
|
if value.is_a? Array
|
44
56
|
return value.map { |v| sanitize(v) }.join(', ')
|
@@ -98,7 +110,14 @@ module Ambition
|
|
98
110
|
|
99
111
|
def process(node)
|
100
112
|
node ||= []
|
101
|
-
|
113
|
+
|
114
|
+
if respond_to?(method = "process_#{node.first}")
|
115
|
+
send(method, node[1..-1])
|
116
|
+
elsif node.blank?
|
117
|
+
''
|
118
|
+
else
|
119
|
+
raise "Missing process method for sexp: #{node.inspect}"
|
120
|
+
end
|
102
121
|
end
|
103
122
|
end
|
104
123
|
end
|
data/lib/ambition/query.rb
CHANGED
@@ -58,12 +58,13 @@ module Ambition
|
|
58
58
|
def to_s
|
59
59
|
hash = keyed_clauses
|
60
60
|
|
61
|
+
raise "Sorry, I can't construct SQL with complex joins (yet)" unless hash[:includes].blank?
|
62
|
+
|
61
63
|
sql = []
|
62
|
-
sql << "JOIN #{hash[:includes].join(', ')}" unless hash[:includes].blank?
|
63
64
|
sql << "WHERE #{hash[:conditions].join(' AND ')}" unless hash[:conditions].blank?
|
64
65
|
sql << "ORDER BY #{hash[:order].join(', ')}" unless hash[:order].blank?
|
65
66
|
sql << "LIMIT #{hash[:limit]}" unless hash[:limit].blank?
|
66
|
-
sql << "OFFSET #{hash[:
|
67
|
+
sql << "OFFSET #{hash[:offset]}" unless hash[:offset].blank?
|
67
68
|
|
68
69
|
@@select % [ @table_name, sql.join(' ') ]
|
69
70
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Ambition
|
2
|
+
class RubyProcessor < RubyToRuby
|
3
|
+
def self.process(node)
|
4
|
+
@processor ||= new
|
5
|
+
@processor.process node
|
6
|
+
end
|
7
|
+
|
8
|
+
##
|
9
|
+
# This is not DRY, and I don't care.
|
10
|
+
def process(node)
|
11
|
+
node ||= []
|
12
|
+
|
13
|
+
if respond_to?(method = "process_#{node.first}")
|
14
|
+
send(method, node[1..-1])
|
15
|
+
elsif node.blank?
|
16
|
+
''
|
17
|
+
else
|
18
|
+
raise "Missing process method for sexp: #{node.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -103,10 +103,6 @@ module Ambition
|
|
103
103
|
"(" + clauses.map { |c| process(c) }.join(" #{with} ") + ")"
|
104
104
|
end
|
105
105
|
|
106
|
-
def value(variable)
|
107
|
-
sanitize eval(variable, @block)
|
108
|
-
end
|
109
|
-
|
110
106
|
def negate(method, target = nil)
|
111
107
|
if Array(target).last == [:nil]
|
112
108
|
return 'IS NOT'
|
data/test/benchmark.rb
CHANGED
@@ -30,6 +30,12 @@ Benchmark.bm(30) do |x|
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
x.report 'simple select w/ eval' do
|
34
|
+
Times.times do
|
35
|
+
User.select { |u| u.created_at == Time.now }.to_hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
33
39
|
x.report 'dual select' do
|
34
40
|
Times.times do
|
35
41
|
User.select { |u| u.id == 20 && u.age > 20 }.to_hash
|
data/test/join_test.rb
CHANGED
@@ -25,6 +25,19 @@ context "Joins" do
|
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
28
|
+
specify "belongs_to" do
|
29
|
+
sql = User.select { |m| m.account.id > 20 }
|
30
|
+
sql.to_hash.should == {
|
31
|
+
:conditions => "accounts.id > 20",
|
32
|
+
:include => [:account]
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
specify "complex joins have no to_s" do
|
37
|
+
sql = User.select { |m| m.account.id > 20 }
|
38
|
+
should.raise { sql.to_s }
|
39
|
+
end
|
40
|
+
|
28
41
|
specify "non-existant associations" do
|
29
42
|
sql = User.select { |m| m.liquor.brand == 'Jack' }
|
30
43
|
should.raise { sql.to_hash }
|
data/test/ruby_test.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
context "Inline Ruby" do
|
4
|
+
xspecify "should know what to return" do
|
5
|
+
name = 'David'
|
6
|
+
sql = User.select { |u| name.nil? || u.name == name }.to_s
|
7
|
+
sql.should == "SELECT * FROM users WHERE (users.name = 'David')"
|
8
|
+
end
|
9
|
+
end
|
data/test/types_test.rb
CHANGED
@@ -52,9 +52,8 @@ context "Different types" do
|
|
52
52
|
sql.should == "SELECT * FROM users WHERE users.name IS NOT NULL"
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
# TODO: nothing but variables inside blocks for now
|
55
|
+
specify "Time" do
|
57
56
|
sql = User.select { |m| m.name == Time.now }.to_sql
|
58
|
-
sql.should == "SELECT * FROM users WHERE users.name =
|
57
|
+
sql.should == "SELECT * FROM users WHERE users.name = '#{Time.now.to_s(:db)}'"
|
59
58
|
end
|
60
59
|
end
|
data/test/where_test.rb
CHANGED
@@ -74,7 +74,7 @@ context "Where (using select)" do
|
|
74
74
|
sql.should == "SELECT * FROM users WHERE users.name = '#{@me}'"
|
75
75
|
end
|
76
76
|
|
77
|
-
|
77
|
+
specify "simple == with instance variable method call" do
|
78
78
|
require 'ostruct'
|
79
79
|
@person = OpenStruct.new(:name => 'chris')
|
80
80
|
|
@@ -136,11 +136,15 @@ context "Where (using select)" do
|
|
136
136
|
specify "undefined equality symbol" do
|
137
137
|
should.raise { User.select { |m| m.name =* /chris/ }.to_sql }
|
138
138
|
end
|
139
|
+
|
140
|
+
specify "block variable / assigning variable conflict" do
|
141
|
+
m = User.select { |m| m.name == 'chris' }.to_sql
|
142
|
+
m.should == "SELECT * FROM users WHERE users.name = 'chris'"
|
143
|
+
end
|
139
144
|
|
140
|
-
|
141
|
-
# TODO: implement this
|
145
|
+
specify "simple == with inline ruby" do
|
142
146
|
sql = User.select { |m| m.created_at == 2.days.ago.to_s(:db) }.to_sql
|
143
|
-
sql.should == "SELECT * FROM users WHERE users.created_at = #{2.days.ago.to_s(:db)}"
|
147
|
+
sql.should == "SELECT * FROM users WHERE users.created_at = '#{2.days.ago.to_s(:db)}'"
|
144
148
|
end
|
145
149
|
|
146
150
|
specify "inspect" do
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ambition
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.3.1
|
7
|
+
date: 2007-11-06 00:00:00 -08:00
|
8
8
|
summary: Ambition builds SQL from plain jane Ruby.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- ./lib/ambition/proc_to_ruby.rb
|
36
36
|
- ./lib/ambition/processor.rb
|
37
37
|
- ./lib/ambition/query.rb
|
38
|
+
- ./lib/ambition/ruby_processor.rb
|
38
39
|
- ./lib/ambition/select_processor.rb
|
39
40
|
- ./lib/ambition/simple_processor.rb
|
40
41
|
- ./lib/ambition/sort_processor.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- ./test/order_test.rb
|
74
75
|
- ./test/profiler.rb
|
75
76
|
- ./test/source_test.rb
|
77
|
+
- ./test/ruby_test.rb
|
76
78
|
- ./test/types_test.rb
|
77
79
|
- ./test/where_test.rb
|
78
80
|
test_files:
|
@@ -82,6 +84,7 @@ test_files:
|
|
82
84
|
- test/join_test.rb
|
83
85
|
- test/limit_test.rb
|
84
86
|
- test/order_test.rb
|
87
|
+
- test/ruby_test.rb
|
85
88
|
- test/source_test.rb
|
86
89
|
- test/types_test.rb
|
87
90
|
- test/where_test.rb
|
@@ -105,6 +108,15 @@ dependencies:
|
|
105
108
|
- !ruby/object:Gem::Version
|
106
109
|
version: 2.0.1
|
107
110
|
version:
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: ruby2ruby
|
113
|
+
version_requirement:
|
114
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
115
|
+
requirements:
|
116
|
+
- - "="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 1.1.7
|
119
|
+
version:
|
108
120
|
- !ruby/object:Gem::Dependency
|
109
121
|
name: activerecord
|
110
122
|
version_requirement:
|