ambition 0.2.2 → 0.3.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/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:
|