rquerypad 0.1.11

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/CHANGELOG ADDED
@@ -0,0 +1,48 @@
1
+ Changes in version 0.1.11 (2008-04-29)
2
+ -------------------------------------
3
+ fix bugs about invalid cache for options
4
+ Changes in version 0.1.10 (2008-03-26)
5
+ -------------------------------------
6
+ make alias_method name with 4rqp(for rquerypad) suffix to avoid confliction with the 3rd plugins
7
+
8
+ Changes in version 0.1.9 (2008-03-26)
9
+ -------------------------------------
10
+ use deep copy to fix bug about options in cache is changed by later operation
11
+
12
+ Changes in version 0.1.8 (2008-03-26)
13
+ -------------------------------------
14
+ use deep copy to fix bug about options in cache is changed by later operation
15
+
16
+ Changes in version 0.1.7 (2008-03-26)
17
+ -------------------------------------
18
+ fix option value nil problem due to some 3rd plugins
19
+
20
+ Changes in version 0.1.6 (2008-03-25)
21
+ -------------------------------------
22
+ fix bug about cache key not bind to class
23
+
24
+ Changes in version 0.1.5 (2008-03-21)
25
+ -------------------------------------
26
+ fix bug when field is a id with single table which has belongs_to association, such as "parent.id"
27
+
28
+ Changes in version 0.1.4 (2008-03-20)
29
+ -------------------------------------
30
+ support calculations call, such as count/avg...
31
+
32
+ Changes in version 0.1.3 (2008-03-20)
33
+ -------------------------------------
34
+ fix about rails 1.2.6 support
35
+
36
+ Changes in version 0.1.2 (2008-03-19)
37
+ -------------------------------------
38
+ fix inner join bug
39
+
40
+ Changes in version 0.1.1 (2008-03-19)
41
+ -------------------------------------
42
+ put initialized code in rquerypad's init.rb, instead of project configuration
43
+ support to rails 1.2.6
44
+
45
+
46
+ Changes in version 0.1.0 (2008-03-18)
47
+ -------------------------------------
48
+ fix bug about table_name.field as parameter
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,66 @@
1
+ Rquerypad, release 0.1.11 (Apr. 2008)
2
+ =========
3
+ Simplify query options with association automation and improve inner join for activerecord of rails
4
+
5
+ Feature
6
+ =======
7
+ 1. single name string decribe associations
8
+ 2. support to mix inner join and outer join with any order
9
+ 3. auto remove duplicated joins from other association in different depth
10
+ 4. support :conditions, :order, :group
11
+ 5. auto merge to original :include, :joins
12
+
13
+ Install
14
+ =======
15
+ ruby script/plugin install http://rquerypad.rubyforge.org/svn/trunk/rquerypad
16
+ or
17
+ ruby script/plugin install http://rquerypad.googlecode.com/svn/trunk/rquerypad
18
+
19
+ Example
20
+ =======
21
+ suppose the asscociations of User <-> Thread <-> Reply is 1:N:N
22
+
23
+ @users = User.find(:all, :group => ["threads.created_at", "name"])
24
+ generate:
25
+ [:all, {:group=>"threads.created_at, users.name", :include=>[:threads]}]
26
+
27
+ @users = User.find(:all, :conditions => ["threads_.replies.title = ?", "rquerypad"])
28
+ generate:
29
+ [:all, {:inner_joins=>["threads"], :conditions=>["replies.title = ?", "rquerypad"], :include=>[{:threads=>:replies}]}]
30
+ #note: the :inner_joints is processed by rquerypad before sending sql to database
31
+
32
+ @users = User.find(:all, :conditions => ["threads.replies.title = ? and threads.id = ?", "rquerypad", 1])
33
+ generate:
34
+ [:all, {:conditions=>["replies.title = ? and threads.id = ?", "rquerypad", 1], :include=>[{:threads=>:replies}]}]
35
+ #note: single "threads" was removed from includes
36
+
37
+ Setup
38
+ =======
39
+ #to set debug model, in rails initialized script
40
+ $RQUERYPAD_DEBUG = true
41
+
42
+ Test
43
+ =======
44
+ Note: current migrate script works only in rails 2.0
45
+
46
+ 1.Prepare
47
+
48
+ the test depends on sqlite3 database, the following code should be add into your database.yml and place rquerypad.rb(copy from test.rb) in config/environment
49
+
50
+ rquerypad:
51
+ adapter: sqlite3
52
+ database: vendor/plugins/rquerypad/test/db.rquerypad
53
+ timeout: 5000
54
+
55
+ 2.database migrate
56
+
57
+ execute the following script
58
+
59
+ rake migrate
60
+
61
+ 3.start test
62
+
63
+ execute the following script
64
+ rake
65
+
66
+ Copyright (c) 2008 Leon Li, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ PKG_NAME = "rquerypad"
4
+ PKG_VERSION = "0.1.11"
5
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
6
+ PKG_FILES = FileList[
7
+ '[A-Za-z]*',
8
+ 'lib/**/*',
9
+ 'test/**/*',
10
+ 'tasks/**/*',
11
+ ]
12
+ spec = Gem::Specification.new do |s|
13
+ s.platform = Gem::Platform::RUBY
14
+ s.summary = "Simplify query options with association automation and improve inner join for activerecord of rails"
15
+ s.name = PKG_NAME
16
+ s.version = PKG_VERSION
17
+ s.requirements << 'none'
18
+ s.require_path = 'lib'
19
+ s.rubyforge_project = 'rquerypad'
20
+ #s.executables = ['gem-sample']
21
+ #s.default_executable = 'gem-sample'
22
+ s.authors = ["Leon Li"]
23
+ s.email = "scorpio_leon@hotmail.com"
24
+ s.files = PKG_FILES
25
+ s.description = <<-EOF
26
+ Simplify query options with association automation and improve inner join for activerecord of rails
27
+ EOF
28
+ end
29
+ Rake::GemPackageTask.new(spec) do |pkg|
30
+ pkg.need_zip = true
31
+ pkg.need_tar = true
32
+ end
data/lib/rquerypad.rb ADDED
@@ -0,0 +1,318 @@
1
+ =begin Rquerypad
2
+ author: Leon Li(scorpio_leon@hotmail.com)
3
+ =end
4
+ require 'md5'
5
+ class Rquerypad
6
+ #todo scope support
7
+ class << self
8
+
9
+ def prepare_with_debug
10
+ prepare(true)
11
+ end
12
+ def prepare(debug = $RQUERYPAD_DEBUG)
13
+ return nil unless @prepared.nil?
14
+ @prepared = true
15
+ ActiveRecord::Base.class_eval %{
16
+ require "rquerypad"
17
+
18
+ class << self
19
+ @@rquerypad_cache = {}
20
+ alias_method(:old_find_4rqp, :find) unless method_defined?(:old_find_4rqp)
21
+ alias_method(:old_cfswia_4rqp, :construct_finder_sql_with_included_associations) unless method_defined?(:old_cfswia_4rqp)
22
+ VALID_FIND_OPTIONS << :inner_joins
23
+ def find(*args)
24
+ options = #{if [].respond_to?(:extract_options!) then "args.extract_options!" else "extract_options_from_args!(args)" end}
25
+ if !options.empty? && (options.include?(:conditions) || options.include?(:group) || options.include?(:order))
26
+ # if (!options.empty? && (!options[:conditions].nil? || !options[:group].nil? || !options[:order].nil?))
27
+ #{"p 'original options:', options" if debug}
28
+ cache_key = Rquerypad.options_key(options)
29
+ #p "cache_key: #\{cache_key\}"
30
+ #p "rquerypad_cache[cache_key]: #\{rquerypad_cache[cache_key]\}"
31
+ if rquerypad_cache[cache_key].nil?
32
+ #{"p 'process for:', options" if debug}
33
+ Rquerypad.new(self).improve_options!(options)
34
+ rquerypad_cache[cache_key] = Marshal.dump(options)
35
+ #p "rquerypad_cache[cache_key]: #\{rquerypad_cache[cache_key]\}"
36
+ else
37
+ options = Marshal.load(rquerypad_cache[cache_key])
38
+ end
39
+ #{"p 'new options:', options" if debug}
40
+ end
41
+ args += [options] unless options.empty?
42
+ old_find_4rqp *args
43
+ end
44
+ def construct_finder_sql_with_included_associations(options, join_dependency)
45
+ sql = old_cfswia_4rqp(options, join_dependency)
46
+ #{"p('original sql', sql) unless options[:inner_joins].nil?" if debug}
47
+ sql = Rquerypad.process_inner_join(sql, options[:inner_joins]) unless options[:inner_joins].nil?
48
+ #{"p('new sql with inner join', sql) unless options[:inner_joins].nil?" if debug}
49
+ sql
50
+ end
51
+ def rquerypad_cache
52
+ @@rquerypad_cache
53
+ end
54
+ end
55
+ }
56
+
57
+ ActiveRecord::Calculations.class_eval %{
58
+ require "rquerypad"
59
+ module ClassMethods
60
+ @@rquerypad_cache = {}
61
+ alias_method(:old_construct_calculation_sql_4rqp, :construct_calculation_sql) unless method_defined?(:old_construct_calculation_sql_4rqp)
62
+ CALCULATIONS_OPTIONS << :inner_joins
63
+ def construct_calculation_sql(operation, column_name, options)
64
+ if !options.empty? && (options.include?(:conditions) || options.include?(:group) || options.include?(:order))
65
+ #{"p 'original options:', options" if debug}
66
+ cache_key = Rquerypad.options_key(options)
67
+ if rquerypad_cache[cache_key].nil?
68
+ #{"p 'process for:', options" if debug}
69
+ Rquerypad.new(self).improve_options!(options)
70
+ rquerypad_cache[cache_key] = Marshal.load(Marshal.dump(options))
71
+ else
72
+ options = rquerypad_cache[cache_key]
73
+ end
74
+ #{"p 'new options:', options" if debug}
75
+ end
76
+ sql = old_construct_calculation_sql_4rqp(operation, column_name, options)
77
+ #{"p('original sql', sql) unless options[:inner_joins].nil?" if debug}
78
+ sql = Rquerypad.process_inner_join(sql, options[:inner_joins]) unless options[:inner_joins].nil?
79
+ #{"p('new sql with inner join', sql) unless options[:inner_joins].nil?" if debug}
80
+ sql
81
+ end
82
+ def rquerypad_cache
83
+ @@rquerypad_cache
84
+ end
85
+ end
86
+ }
87
+
88
+ Hash.class_eval do
89
+ def single_lt?(other)
90
+ return false if self == other
91
+ return true if self.size == 0
92
+ return false unless other.is_a?(Hash)
93
+ return false if other.nil? || other.size < self.size
94
+ return false if self.size != other.size || self.size > 1
95
+ a = self.to_a[0]
96
+ o = other.to_a[0]
97
+ return false if a[0] != o[0]
98
+ return true unless a[1].is_a?(Hash)
99
+ a[1].single_lt?(o[1])
100
+ end
101
+ def single_gt?(other)
102
+ return false if self == other
103
+ return !(single_lt?(other))
104
+ end
105
+ end
106
+ end
107
+
108
+ def process_inner_join(sql, inner_joins)
109
+ inner_joins.each {|i| sql.gsub!(/LEFT OUTER JOIN [`]?#{i}[`]?/, "INNER JOIN #{i}")} unless inner_joins.empty?
110
+ sql
111
+ end
112
+
113
+ def options_key(options)
114
+ key = options.to_a.to_s
115
+ key = MD5.hexdigest(key) if key.length > 100
116
+ key
117
+ end
118
+ end
119
+ def initialize(obj)
120
+ @owner = obj
121
+ @class_name = obj.to_s.scan(/(\w*::)*([^\(]*)/)[0][1]
122
+ @table_name = @class_name.pluralize.underscore
123
+ @tnwithdot = @table_name + "."
124
+ @new_include = []
125
+ @old_include = nil
126
+ @inner_joins = []
127
+ end
128
+
129
+ def improve_options!(option_hash)
130
+
131
+ option_hash.each do |key, value|
132
+ next if value.blank?
133
+ if key.to_s == "conditions"
134
+ option_hash[key] = improve_conditions(value)
135
+ elsif (key.to_s == "order" || key.to_s == "group" || key.to_s == "group_field")
136
+ option_hash[key] = improve_ordergroup(value).join(", ")
137
+ elsif (key.to_s == "include")
138
+ @old_include = value
139
+ end
140
+ end
141
+ return nil if @new_include.empty?
142
+ #generate new include
143
+
144
+ remove_dup_includes
145
+ unless @new_include.nil?
146
+ option_hash[:include] = [] if @old_include.nil?
147
+ @new_include += @old_include unless @old_include.nil?
148
+ option_hash.each do |key, value|
149
+ if key.to_s == "include"
150
+ option_hash[key] = @new_include
151
+ end
152
+ end
153
+ end
154
+ option_hash[:inner_joins] = @inner_joins unless @inner_joins.empty?
155
+ end
156
+
157
+ def remove_dup_includes
158
+ final_includes = []
159
+ @new_include.each do |ni|
160
+ next if final_includes.include?(ni)
161
+ if final_includes.size > 0
162
+ final_includes.each_index do |i|
163
+ if ni.is_a?(Hash)
164
+ if final_includes[i].is_a?(Hash)
165
+ if final_includes[i].single_lt?(ni)
166
+ final_includes[i] = ni
167
+ elsif final_includes[i].single_gt?(ni)
168
+ else
169
+ final_includes << ni
170
+ end
171
+ elsif ni.entries[0][0].to_s == final_includes[i].to_s
172
+ final_includes[i] = ni
173
+ else
174
+ final_includes << ni
175
+ end
176
+ else
177
+ if final_includes[i].is_a?(Hash)
178
+ final_includes << ni if final_includes[i].entries[0][0].to_s != ni.to_s
179
+ else
180
+ final_includes << ni if final_includes[i].to_s != ni.to_s
181
+ end
182
+ end
183
+ end
184
+ else
185
+ final_includes << ni
186
+ end
187
+ end
188
+ @new_include = final_includes
189
+ end
190
+
191
+ def improve_conditions(options)
192
+ if options.is_a?(Array)
193
+ str = options[0]
194
+ temp = str.scan(/'.*?'/)
195
+ #replace string in quote to avoid unecessary processing
196
+ str.gsub!(/'.*?'/, "'[??]'") unless temp.empty?
197
+ str.gsub!(/(([\w\(\)]+\.)+\w+)[ !><=]/) do |n|
198
+ #cut last char and abstract association for include
199
+ abstract_association(n[0..-2]) + n[-1, 1]
200
+ end
201
+ #add @table_name on single field
202
+ str.gsub!(/[\.]?\w+[\.]?/) {|x| x[-1, 1] == "." || ["and", "or", "is", "null", "not"].include?(x.downcase) ? x : @tnwithdot + x}
203
+ str.gsub!(/\.#{@table_name}\./, ".")
204
+ #recover string in quote
205
+ unless temp.empty?
206
+ i = -1
207
+ str.gsub!(/\'\[\?\?\]\'/) do
208
+ i += 1
209
+ temp[i]
210
+ end
211
+ end
212
+ options[0] = str
213
+ end
214
+ if options.is_a?(Hash)
215
+ #work around frozen issue
216
+ new_options = {}
217
+ until options.empty?
218
+ key, value = options.shift
219
+ key = key.to_s.dup
220
+ new_options[process_single!(key)] = value
221
+ end
222
+ options.merge!(new_options)
223
+ end
224
+ options
225
+ end
226
+
227
+ def process_single!(key)
228
+ if key.include?(".")
229
+ if /^(.+)[ ]/ =~ key
230
+ key.sub!("#$1", abstract_association("#$1"))
231
+ else
232
+ key.sub!(/^.+$/, abstract_association(key))
233
+ end
234
+ else
235
+ key.sub!(/^.+$/, @tnwithdot + key)
236
+ end
237
+ end
238
+
239
+ def improve_ordergroup(fields)
240
+ fields = [fields] if fields.is_a?(String)
241
+ fields.each {|field| process_single!(field)}
242
+ fields
243
+ end
244
+
245
+ def abstract_association(str)
246
+ result = nil
247
+ owner = @owner
248
+ names = str.split(".")
249
+ return str if names.size == 2 && names[0] == @table_name
250
+ #seperate assocations/tables and field
251
+ tables, field = names[0..-2], names[-1]
252
+ owners = []
253
+ #get relevant owner for each table
254
+ tables.each_index do |i|
255
+ if i == 0
256
+ owners[i] = owner
257
+ else
258
+ tname = cut_end_underscore(tables[i-1])
259
+ r = owners[i-1].reflections[tname.to_sym].options
260
+ owners[i] = r[:class_name].nil? ? eval(owners[i-1].to_s.gsub(/\w*$/, "")+tname.singularize.camelize) : Util::Common.str2class(r[:class_name])
261
+ end
262
+ end
263
+ owners.reverse!
264
+ tables.reverse!
265
+ tables.each_index do |i|
266
+ if tables[i][-1, 1] == "_"
267
+ tables[i].reverse!.sub!("_", "").reverse!
268
+ @inner_joins << transfer_table_name(tables[i], owners[i])
269
+ end
270
+ end
271
+ #process special id field in a belongs_to association
272
+ if field == "id"
273
+ if owners[0].reflections[tables[0].to_sym].macro.to_s == "belongs_to"
274
+ result = transfer_table_id(tables[0], owners[0])
275
+ @inner_joins.delete(tables[0]) if @inner_joins.include?(tables[0])
276
+ unless owners[1].nil?
277
+ result = transfer_table_name(tables[1], owners[1]) + "." + result
278
+ end
279
+ tables.delete_at(0)
280
+ owners.delete_at(0)
281
+ return result if tables.empty?
282
+ end
283
+ end
284
+
285
+ #get include
286
+ if tables.length == 1 && tables[0] != @table_name
287
+ @new_include << tables[0].to_sym unless @new_include.include?(tables[0].to_sym)
288
+ else
289
+ tables_clone = tables[0..-1]
290
+ value = tables_clone.shift.to_sym
291
+ until tables_clone.empty?
292
+ hashes = {}
293
+ hashes[tables_clone.shift.to_sym] = value
294
+ value = hashes
295
+ end
296
+ @new_include << hashes unless hashes.nil? || @new_include.include?(hashes)
297
+ end
298
+ result ||= transfer_table_name(tables[0], owners[0]) + "." + field
299
+
300
+ end
301
+
302
+ def transfer_table_name(name, owner = @owner)
303
+ owner.reflections[name.to_sym].class_name.gsub(/([\w]+::)*/, "").pluralize.underscore
304
+ end
305
+
306
+ def transfer_table_id(name, owner = @owner)
307
+ owner.reflections[name.to_sym].class_name.gsub(/([\w]+::)*/, "").underscore + "_id"
308
+ end
309
+
310
+ def cut_end_underscore(str)
311
+ str = str.reverse.sub("_", "").reverse if str[-1, 1] == "_"
312
+ str
313
+ end
314
+
315
+ def cut_end_underscore!(str)
316
+ str.reverse!.sub!("_", "").reverse! if str[-1, 1] == "_"
317
+ end
318
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :rquerypad do
3
+ # # Task goes here
4
+ # end
data/test/db.rquerypad ADDED
Binary file
@@ -0,0 +1,25 @@
1
+ reply_one:
2
+ id: 1
3
+ title: "rquerypad"
4
+ thread_id: 1
5
+ user_id: 1
6
+
7
+ reply_two:
8
+ id: 2
9
+ title: "thank you"
10
+ thread_id: 2
11
+ user_id: 2
12
+
13
+ reply_three:
14
+ id: 3
15
+ title: "thank you-1"
16
+ thread_id: 2
17
+ parent_id: 2
18
+ user_id: 2
19
+
20
+ reply_four:
21
+ id: 4
22
+ title: "thank you-2"
23
+ thread_id: 2
24
+ parent_id: 2
25
+ user_id: 2
@@ -0,0 +1,17 @@
1
+ thread_one:
2
+ id: 1
3
+ title: "welcome"
4
+ user_id: 1
5
+ created_at: "2008-03-16 00:00:00"
6
+
7
+ thread_two:
8
+ id: 2
9
+ title: "join us"
10
+ user_id: 2
11
+ created_at: "2008-03-17 00:00:00"
12
+
13
+ thread_three:
14
+ id: 3
15
+ title: "hello"
16
+ user_id: 2
17
+ created_at: "2008-03-16 20:00:00"
@@ -0,0 +1,7 @@
1
+ user_one:
2
+ id: 1
3
+ name: leon
4
+
5
+ user_two:
6
+ id: 2
7
+ name: carrol
@@ -0,0 +1,13 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string "name"
5
+ t.datetime "created_at"
6
+ t.datetime "updated_at"
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :users
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ class CreateThreads < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :threads do |t|
4
+ t.string "title"
5
+ t.string "content"
6
+ t.integer "user_id"
7
+ t.datetime "created_at"
8
+ t.datetime "updated_at"
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :threads
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ class CreateReplies < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :replies do |t|
4
+ t.string "title"
5
+ t.string "content"
6
+ t.integer "user_id"
7
+ t.integer "thread_id"
8
+ t.integer "parent_id"
9
+ t.datetime "created_at"
10
+ t.datetime "updated_at"
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :replies
16
+ end
17
+ end
data/test/model.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Model
2
+ class User < ActiveRecord::Base
3
+ has_many :threads
4
+ has_many :replies
5
+ end
6
+ class Thread < ActiveRecord::Base
7
+ has_many :replies
8
+ belongs_to :user
9
+ end
10
+ class Reply < ActiveRecord::Base
11
+ belongs_to :thread
12
+ has_many :replies
13
+ belongs_to :reply, :foreign_key => "parent_id"
14
+ belongs_to :user
15
+ acts_as_tree
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+
4
+ require 'rquerypad'
5
+ require 'test/model'
6
+ class RquerypadTest < Test::Unit::TestCase
7
+ # Replace this with your real tests.
8
+ include Model
9
+ def test_this_plugin
10
+ @fixture_path = 'vendor/plugins/rquerypad/test/fixtures'
11
+
12
+ @users = User.find(:all, :group => ["threads.created_at", "name"])
13
+ assert_equal @users.size, 2
14
+
15
+ c = User.count(:conditions => ["threads_.replies.title = ?", "rquerypad"])
16
+ assert_equal c, 1
17
+
18
+ @users = User.find(:all, :conditions => ["threads.replies.title = ? and threads.id = ?", "rquerypad", 1])
19
+ assert_equal @users.size, 1
20
+
21
+ @replies = Reply.find(:all, :conditions => ["thread.id = ?", 2])
22
+ assert_equal @replies.size, 3
23
+
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+
4
+ require 'rquerypad'
5
+
6
+ ENV["RAILS_ENV"] = "rquerypad"
7
+ #require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
8
+ require 'test_help'
9
+ Test::Unit::TestCase.fixture_path = File.expand_path(File.dirname(__FILE__) + "/fixtures/")
10
+ class Test::Unit::TestCase
11
+ # Transactional fixtures accelerate your tests by wrapping each test method
12
+ # in a transaction that's rolled back on completion. This ensures that the
13
+ # test database remains unchanged so your fixtures don't have to be reloaded
14
+ # between every test method. Fewer database queries means faster tests.
15
+ #
16
+ # Read Mike Clark's excellent walkthrough at
17
+ # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
18
+ #
19
+ # Every Active Record database supports transactions except MyISAM tables
20
+ # in MySQL. Turn off transactional fixtures in this case; however, if you
21
+ # don't care one way or the other, switching from MyISAM to InnoDB tables
22
+ # is recommended.
23
+ #
24
+ # The only drawback to using transactional fixtures is when you actually
25
+ # need to test transactions. Since your test is bracketed by a transaction,
26
+ # any transactions started in your code will be automatically rolled back.
27
+ self.use_transactional_fixtures = true
28
+
29
+ # Instantiated fixtures are slow, but give you @david where otherwise you
30
+ # would need people(:david). If you don't want to migrate your existing
31
+ # test cases which use the @david style and don't mind the speed hit (each
32
+ # instantiated fixtures translates to a database query per test method),
33
+ # then set this back to true.
34
+ self.use_instantiated_fixtures = false
35
+
36
+ # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
37
+ #
38
+ # Note: You'll currently still have to declare fixtures explicitly in integration tests
39
+ # -- they do not yet inherit this setting
40
+ fixtures :all
41
+
42
+ # Add more helper methods to be used by all tests here...
43
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rquerypad
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.11
5
+ platform: ruby
6
+ authors:
7
+ - Leon Li
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-04 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simplify query options with association automation and improve inner join for activerecord of rails
17
+ email: scorpio_leon@hotmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - CHANGELOG
26
+ - lib
27
+ - MIT-LICENSE
28
+ - pkg
29
+ - Rakefile
30
+ - README
31
+ - tasks
32
+ - test
33
+ - lib/rquerypad.rb
34
+ - test/db.rquerypad
35
+ - test/fixtures
36
+ - test/fixtures/replies.yml
37
+ - test/fixtures/threads.yml
38
+ - test/fixtures/users.yml
39
+ - test/migrate
40
+ - test/migrate/001_create_users.rb
41
+ - test/migrate/002_create_threads.rb
42
+ - test/migrate/003_create_replies.rb
43
+ - test/model.rb
44
+ - test/rquerypad_test.rb
45
+ - test/test_helper.rb
46
+ - tasks/rquerypad_tasks.rake
47
+ has_rdoc: false
48
+ homepage:
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements:
67
+ - none
68
+ rubyforge_project: rquerypad
69
+ rubygems_version: 1.0.1
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: Simplify query options with association automation and improve inner join for activerecord of rails
73
+ test_files: []
74
+