lore 0.4.8 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. data/Manifest.txt +16 -7
  2. data/README.rdoc +91 -0
  3. data/benchmark/benchmark.sql +11 -0
  4. data/benchmark/results.txt +28 -0
  5. data/benchmark/select.rb +352 -0
  6. data/lib/lore.rb +22 -8
  7. data/lib/lore/adapters/context.rb +64 -0
  8. data/lib/lore/adapters/postgres-pr.rb +6 -0
  9. data/lib/lore/adapters/postgres-pr/connection.rb +93 -0
  10. data/lib/lore/adapters/postgres-pr/result.rb +63 -0
  11. data/lib/lore/{types.rb → adapters/postgres-pr/types.rb} +36 -0
  12. data/lib/lore/adapters/postgres.rb +24 -0
  13. data/lib/lore/adapters/postgres/connection.rb +81 -0
  14. data/lib/lore/adapters/postgres/result.rb +82 -0
  15. data/lib/lore/adapters/postgres/types.rb +91 -0
  16. data/lib/lore/bits.rb +18 -0
  17. data/lib/lore/cache/abstract_entity_cache.rb +2 -1
  18. data/lib/lore/cache/cacheable.rb +12 -177
  19. data/lib/lore/cache/memcache_entity_cache.rb +89 -0
  20. data/lib/lore/cache/memory_entity_cache.rb +77 -0
  21. data/lib/lore/cache/mmap_entity_cache.rb +2 -2
  22. data/lib/lore/cache/mmap_entity_cache_bork.rb +86 -0
  23. data/lib/lore/clause.rb +107 -35
  24. data/lib/lore/{exception → exceptions}/ambiguous_attribute.rb +2 -2
  25. data/lib/lore/{exception → exceptions}/cache_exception.rb +1 -1
  26. data/lib/lore/exceptions/database_exception.rb +16 -0
  27. data/lib/lore/{exception/invalid_parameter.rb → exceptions/invalid_field.rb} +7 -4
  28. data/lib/lore/exceptions/unknown_type.rb +18 -0
  29. data/lib/lore/exceptions/validation_failure.rb +71 -0
  30. data/lib/lore/gui/form_generator.rb +109 -60
  31. data/lib/lore/gui/lore_model_select_field.rb +1 -0
  32. data/lib/lore/migration.rb +84 -25
  33. data/lib/lore/model.rb +3 -18
  34. data/lib/lore/{aspect.rb → model/aspect.rb} +0 -0
  35. data/lib/lore/model/associations.rb +225 -0
  36. data/lib/lore/model/attribute_settings.rb +233 -0
  37. data/lib/lore/model/filters.rb +34 -0
  38. data/lib/lore/model/mockable.rb +62 -0
  39. data/lib/lore/{model_factory.rb → model/model_factory.rb} +68 -39
  40. data/lib/lore/model/model_instance.rb +382 -0
  41. data/lib/lore/{model_shortcuts.rb → model/model_shortcuts.rb} +7 -0
  42. data/lib/lore/model/polymorphic.rb +53 -0
  43. data/lib/lore/model/prepare.rb +97 -0
  44. data/lib/lore/model/table_accessor.rb +1016 -0
  45. data/lib/lore/query.rb +71 -0
  46. data/lib/lore/query_shortcuts.rb +43 -11
  47. data/lib/lore/strategies/table_delete.rb +115 -0
  48. data/lib/lore/strategies/table_insert.rb +146 -0
  49. data/lib/lore/strategies/table_select.rb +299 -0
  50. data/lib/lore/strategies/table_update.rb +155 -0
  51. data/lib/lore/validation/parameter_validator.rb +85 -26
  52. data/lib/lore/validation/type_validator.rb +34 -78
  53. data/{custom_models.rb → lore-0.9.2.gem} +0 -0
  54. data/lore.gemspec +26 -17
  55. data/spec/clause.rb +37 -0
  56. data/spec/fixtures/blank_models.rb +37 -0
  57. data/{test/model.rb → spec/fixtures/models.rb} +64 -41
  58. data/spec/fixtures/polymorphic_models.rb +68 -0
  59. data/spec/model_associations.rb +86 -0
  60. data/spec/model_create.rb +47 -0
  61. data/spec/model_definition.rb +151 -0
  62. data/spec/model_delete.rb +31 -0
  63. data/spec/model_inheritance.rb +50 -0
  64. data/spec/model_polymorphic.rb +85 -0
  65. data/spec/model_select.rb +101 -0
  66. data/spec/model_select_eager.rb +42 -0
  67. data/spec/model_union_select.rb +33 -0
  68. data/spec/model_update.rb +45 -0
  69. data/spec/model_validation.rb +20 -0
  70. data/spec/spec_db.sql +808 -0
  71. data/spec/spec_env.rb +19 -0
  72. data/spec/spec_helpers.rb +77 -0
  73. metadata +93 -82
  74. data/lib/lore/README.txt +0 -84
  75. data/lib/lore/behaviours/lockable.rb +0 -55
  76. data/lib/lore/behaviours/movable.rb +0 -72
  77. data/lib/lore/behaviours/paginated.rb +0 -31
  78. data/lib/lore/behaviours/versioned.rb +0 -36
  79. data/lib/lore/connection.rb +0 -152
  80. data/lib/lore/exception/invalid_klass_parameters.rb +0 -63
  81. data/lib/lore/exception/unknown_typecode.rb +0 -19
  82. data/lib/lore/result.rb +0 -119
  83. data/lib/lore/symbol.rb +0 -58
  84. data/lib/lore/table_accessor.rb +0 -1790
  85. data/lib/lore/table_deleter.rb +0 -116
  86. data/lib/lore/table_inserter.rb +0 -170
  87. data/lib/lore/table_instance.rb +0 -389
  88. data/lib/lore/table_selector.rb +0 -285
  89. data/lib/lore/table_updater.rb +0 -157
  90. data/lib/lore/validation.rb +0 -65
  91. data/lib/lore/validation/message.rb +0 -60
  92. data/lib/lore/validation/reason.rb +0 -52
  93. data/lore_test.log +0 -2366
  94. data/test/README +0 -31
  95. data/test/custom_models.rb +0 -18
  96. data/test/env.rb +0 -5
  97. data/test/prepare.rb +0 -37
  98. data/test/tc_aspect.rb +0 -58
  99. data/test/tc_cache.rb +0 -83
  100. data/test/tc_clause.rb +0 -104
  101. data/test/tc_deep_inheritance.rb +0 -49
  102. data/test/tc_factory.rb +0 -57
  103. data/test/tc_filter.rb +0 -37
  104. data/test/tc_form.rb +0 -32
  105. data/test/tc_model.rb +0 -140
  106. data/test/tc_prepare.rb +0 -44
  107. data/test/tc_refined_query.rb +0 -88
  108. data/test/tc_table_accessor.rb +0 -267
  109. data/test/tc_thread.rb +0 -100
  110. data/test/test_db.sql +0 -400
  111. data/test/test_lore.rb +0 -50
@@ -1,7 +1,16 @@
1
- History.txt
2
- Manifest.txt
3
- README.txt
4
- Rakefile
5
- bin/lore
6
- lib/lore.rb
7
- test/test_lore.rb
1
+
2
+ '*',
3
+ 'benchmark/*',
4
+ 'spec/*',
5
+ 'spec/fixtures/*',
6
+ 'lib/*',
7
+ 'lib/lore/*',
8
+ 'lib/lore/adapters/*',
9
+ 'lib/lore/cache/*',
10
+ 'lib/lore/exceptions/*',
11
+ 'lib/lore/gui/*',
12
+ 'lib/lore/gui/templates/*',
13
+ 'lib/lore/model/*',
14
+ 'lib/lore/strategies/*',
15
+ 'lib/lore/validation/*',
16
+ 'bin/*'].to_a
@@ -0,0 +1,91 @@
1
+
2
+ Didn't have the time to write a "real" readme, but let me show you ...
3
+
4
+ = A short comparison
5
+
6
+ == Use Case:
7
+
8
+ class Content < Lore::Model
9
+ table :contents, :public
10
+ primary_key :id, :content_id_seq
11
+ end
12
+
13
+ class Article < Lore::Model
14
+ table :articles, :public
15
+ primary_key :id, :article_id_seq
16
+ is_a Content, :content_id
17
+ end
18
+
19
+ == Selecting Articles using ActiveRecord
20
+
21
+ Article.find(:all, :include => :content,
22
+ :conditions => "id between 1 AND 100")
23
+
24
+ == Selecting Articles using Sequel
25
+
26
+ DB[:articles].left_outer_join(:contents, :id => :content_id).filter( :articles__id => (1..100))
27
+
28
+ == Selecting Articles using Lore
29
+
30
+ Article.all_with(Article.id.in(1..100))
31
+
32
+ (joins Content automatically)
33
+
34
+ == Benchmark results (1000 queries each returning 100 rows)
35
+ Most recent benchmark results from lore/benchmark/results.txt,
36
+ generated by running
37
+
38
+ ruby lore/benchmarks/select.rb 1000
39
+
40
+ Output on my machine:
41
+
42
+ Rehearsal ------------------------------------------------------------
43
+ unprocessed query 0.030000 0.030000 0.060000 ( 1.269820)
44
+ result fetching in lore 0.400000 0.050000 0.450000 ( 1.661275)
45
+ result parsing in lore 0.540000 0.080000 0.620000 ( 3.600497)
46
+ ac_instances unfiltered 2.440000 0.430000 2.870000 ( 4.113851)
47
+ ac_instances filtered 4.650000 0.700000 5.350000 ( 6.601500)
48
+ lore select unfiltered 2.720000 0.330000 3.050000 ( 4.355712)
49
+ lore shortcut filtered 5.110000 0.790000 5.900000 ( 7.507479)
50
+ --> lore shortcut unfiltered 3.030000 0.420000 3.450000 ( 4.675418) <--
51
+ --> activerecord 15.060000 1.960000 17.020000 ( 22.098705) <--
52
+ --> sequel 8.400000 0.940000 9.340000 ( 11.373551) <--
53
+ lore using cache 2.060000 0.080000 2.140000 ( 2.131782)
54
+ lore prepared 2.400000 0.460000 2.860000 ( 4.334760)
55
+ -------------------------------------------------- total: 53.110000sec
56
+
57
+ user system total real
58
+ unprocessed query 0.040000 0.020000 0.060000 ( 1.255553)
59
+ result fetching in lore 0.380000 0.050000 0.430000 ( 1.731519)
60
+ result parsing in lore 0.600000 0.120000 0.720000 ( 3.630439)
61
+ ac_instances unfiltered 2.580000 0.330000 2.910000 ( 4.138985)
62
+ ac_instances filtered 4.660000 0.710000 5.370000 ( 6.590051)
63
+ lore select unfiltered 2.640000 0.490000 3.130000 ( 4.357413)
64
+ lore shortcut filtered 5.150000 0.760000 5.910000 ( 7.518942)
65
+ lore shortcut unfiltered 2.660000 0.450000 3.110000 ( 4.647531)
66
+ activerecord 15.330000 2.180000 17.510000 ( 22.384284)
67
+ sequel 8.470000 0.880000 9.350000 ( 11.396475)
68
+ lore using cache 2.070000 0.070000 2.140000 ( 2.137200)
69
+ lore prepared 2.610000 0.390000 3.000000 ( 4.199908)
70
+
71
+
72
+ NOTE: Perhaps results for AR and Sequel can be improved by
73
+ doing things differently - i'm using default behaviours for
74
+ benchmarking, but all SQL queries look alright, so my benchmark
75
+ code can't be that wrong.
76
+ If you know how to optimize my usage or AR and Sequel, please
77
+ let me know!
78
+
79
+ Also be aware that most applications aren't slow because of
80
+ its ORM, but because of ... sub-optimal algorithms using them.
81
+ Don't choose an ORM just because of a benchmark.
82
+
83
+ I just want to state that an ORM with both great performance
84
+ and convenient usage is feasible, and Lore is an example.
85
+
86
+ Apart from that: In case you don't like Lore, use Sequel. It's
87
+ incredibly stable, well-maintained, not that inefficient and
88
+ inconvenient as AR (see above), and its maintainer is a nice
89
+ guy - which is more important than you might think.
90
+
91
+
@@ -0,0 +1,11 @@
1
+
2
+ create table contents ( id integer not null, title varchar(100) );
3
+ create table articles ( id integer not null, content_id integer not null, content text );
4
+
5
+ create sequence content_id_seq start with 1 increment by 1;
6
+ create sequence article_id_seq start with 1 increment by 1;
7
+
8
+ grant all on contents to cuba;
9
+ grant all on articles to cuba;
10
+ grant all on content_id_seq to cuba;
11
+ grant all on article_id_seq to cuba;
@@ -0,0 +1,28 @@
1
+ Rehearsal ------------------------------------------------------------
2
+ unprocessed query 0.030000 0.030000 0.060000 ( 1.269820)
3
+ result fetching in lore 0.400000 0.050000 0.450000 ( 1.661275)
4
+ result parsing in lore 0.540000 0.080000 0.620000 ( 3.600497)
5
+ ac_instances unfiltered 2.440000 0.430000 2.870000 ( 4.113851)
6
+ ac_instances filtered 4.650000 0.700000 5.350000 ( 6.601500)
7
+ lore select unfiltered 2.720000 0.330000 3.050000 ( 4.355712)
8
+ lore shortcut filtered 5.110000 0.790000 5.900000 ( 7.507479)
9
+ lore shortcut unfiltered 3.030000 0.420000 3.450000 ( 4.675418)
10
+ activerecord 15.060000 1.960000 17.020000 ( 22.098705)
11
+ sequel 8.400000 0.940000 9.340000 ( 11.373551)
12
+ lore using cache 2.060000 0.080000 2.140000 ( 2.131782)
13
+ lore prepared 2.400000 0.460000 2.860000 ( 4.334760)
14
+ -------------------------------------------------- total: 53.110000sec
15
+
16
+ user system total real
17
+ unprocessed query 0.040000 0.020000 0.060000 ( 1.255553)
18
+ result fetching in lore 0.380000 0.050000 0.430000 ( 1.731519)
19
+ result parsing in lore 0.600000 0.120000 0.720000 ( 3.630439)
20
+ ac_instances unfiltered 2.580000 0.330000 2.910000 ( 4.138985)
21
+ ac_instances filtered 4.660000 0.710000 5.370000 ( 6.590051)
22
+ lore select unfiltered 2.640000 0.490000 3.130000 ( 4.357413)
23
+ lore shortcut filtered 5.150000 0.760000 5.910000 ( 7.518942)
24
+ lore shortcut unfiltered 2.660000 0.450000 3.110000 ( 4.647531)
25
+ activerecord 15.330000 2.180000 17.510000 ( 22.384284)
26
+ sequel 8.470000 0.880000 9.350000 ( 11.396475)
27
+ lore using cache 2.070000 0.070000 2.140000 ( 2.137200)
28
+ lore prepared 2.610000 0.390000 3.000000 ( 4.199908)
@@ -0,0 +1,352 @@
1
+
2
+ require('rubygems')
3
+ require('lore')
4
+ require('lore/model')
5
+ require('lore/cache/mmap_entity_cache')
6
+
7
+ Lore::Model.use_entity_cache Lore::Cache::Mmap_Entity_Cache
8
+ # Aurita.load_project :default
9
+ # Aurita.import_plugin_model :wiki, :article
10
+
11
+ # include Aurita::Plugins::Wiki
12
+
13
+ require('benchmark')
14
+ include Benchmark
15
+ # require('profile')
16
+ Lore.disable_logging
17
+ Lore.disable_query_log
18
+
19
+ require('rubygems')
20
+ require('activerecord')
21
+ require('sequel')
22
+
23
+ ActiveRecord::Base.establish_connection(
24
+ :adapter => 'postgresql',
25
+ :host => 'localhost',
26
+ :username => 'cuba',
27
+ :password => 'cuba23',
28
+ :database => 'artest'
29
+ )
30
+
31
+ Lore.add_login_data('artest' => ['cuba', 'cuba23'])
32
+ Lore::Context.enter :artest
33
+
34
+ DB = Sequel.connect('postgres://cuba:cuba23@localhost/artest')
35
+
36
+
37
+ range_from = 1000
38
+ range_to = 1100
39
+
40
+
41
+ module AR
42
+ class Content < ActiveRecord::Base
43
+ end
44
+
45
+ class Article < ActiveRecord::Base
46
+ belongs_to :content
47
+ end
48
+ end
49
+
50
+ module Lore
51
+ class Content < Lore::Model
52
+ table :contents, :public
53
+ primary_key :id, :content_id_seq
54
+ end
55
+
56
+ class Article < Lore::Model
57
+ table :articles, :public
58
+ primary_key :id, :article_id_seq
59
+ is_a Content, :content_id
60
+ end
61
+
62
+ Article.prepare(:id_in_range, Lore::Type.integer, Lore::Type.integer) { |a|
63
+ a.where(Article.id.between('$1', '$2'))
64
+ a.limit(100)
65
+ }
66
+
67
+ end
68
+
69
+ num_loops = ARGV[0].to_i
70
+ num_loops = 100 if num_loops == 0
71
+
72
+ class Result_Parser
73
+ # {{{
74
+ require 'inline'
75
+
76
+ def initialize(result) # expects PGresult
77
+
78
+ @result = result
79
+ @field_types = nil
80
+ @result_rows = Array.new
81
+ @num_fields = @result.num_fields
82
+ @field_name_split = Array.new
83
+ @field_name = String.new
84
+ @table_name = String.new
85
+ @field_counter = 0
86
+
87
+ end # def initialize
88
+
89
+ =begin
90
+ inline { |builder|
91
+ builder.c <<-EOC
92
+ VALUE get_row_c(VALUE result, int row_num) {
93
+ unsigned int field_counter;
94
+ VALUE row_result, field_name, table_name, field_name_split;
95
+ VALUE value_set = rb_hash_new();
96
+ field_name = rb_string_new();
97
+ table_name = rb_string_new();
98
+ row_result = rb_hash_new();
99
+ for(field_counter = 0; field_counter < num_fields; field_counter++) {
100
+ value_set = result->getvalue(row_num, UINT2NUM(field_counter));
101
+ // if(row_result[@table_name].nil?) then
102
+ if(rb_hash_aref(row_result, table_name) == QNil) {
103
+ // row_result[@table_name] = Hash.new()
104
+ rb_hash_aset(row_result, table_name, value_set)
105
+ }
106
+ rb_hash_aset(rb_hash_aref)row_result, table_name), value_set);
107
+ }
108
+ return row_result;
109
+ }
110
+ EOC
111
+ }
112
+ =end
113
+
114
+ def get_row(row_num=0)
115
+
116
+ return if @result.num_tuples == 0
117
+
118
+ row_result = Hash.new
119
+
120
+ @field_name_split = Array.new
121
+ @field_name = String.new
122
+ @table_name = String.new
123
+ @field_counter = 0
124
+ for @field_counter in 0...@num_fields do
125
+ # admin.rd__content.name -> [admin, rd__content, name]
126
+ @field_name = @result.fieldname(@field_counter)
127
+
128
+ row_result[@field_name] = @result.getvalue(row_num,@field_counter)
129
+ end
130
+
131
+ @result_rows[row_num] = row_result
132
+
133
+ end
134
+
135
+ def get_rows()
136
+ if !@result_rows.first then
137
+ for tuple_counter in 0...@result.num_tuples do
138
+ get_row(tuple_counter)
139
+ end
140
+ end
141
+ @result_rows
142
+ end
143
+
144
+ end # }}}
145
+
146
+ # SQL raw definitions
147
+ # {{{
148
+ db_name = 'artest'
149
+ connection = PGconn.connect(Lore.pg_server, Lore.pg_port, '', '', db_name.to_s, Lore.user_for(db_name), Lore.pass_for(db_name.to_s))
150
+
151
+ sql = "SELECT *
152
+ FROM public.articles
153
+ JOIN public.contents on (public.contents.id = public.articles.content_id)
154
+ WHERE public.articles.id BETWEEN #{range_from} AND #{range_to} LIMIT #{range_to-range_from} OFFSET 0"
155
+
156
+ sql_exec = "EXECUTE public_articles__id_in_range(#{range_from},#{range_to}); "
157
+
158
+ sql_prep = 'PREPARE public_articles__id_in_range(integer,integer) AS
159
+ SELECT
160
+ public.contents.id AS "public.contents.id",
161
+ public.contents.user_group_id AS "public.contents.user_group_id",
162
+ public.contents.tags AS "public.contents.tags",
163
+ public.contents.changed AS "public.contents.changed",
164
+ public.contents.created AS "public.contents.created",
165
+ public.contents.hits AS "public.contents.hits",
166
+ public.contents.locked AS "public.contents.locked",
167
+ public.contents.deleted AS "public.contents.deleted",
168
+ public.contents.version AS "public.contents.version",
169
+ public.articles.id AS "public.articles.id",
170
+ public.articles.content_id AS "public.articles.content_id",
171
+ public.articles.template_id AS "public.articles.template_id",
172
+ public.articles.title AS "public.articles.title",
173
+ public.articles.view_count AS "public.articles.view_count",
174
+ public.articles.published AS "public.articles.published"
175
+ FROM public.articles
176
+ JOIN public.contents on (public.contents.id = public.articles.content_id)
177
+ WHERE public.articles.id BETWEEN $1 AND $2 LIMIT 100 OFFSET 0'
178
+
179
+ # }}}
180
+
181
+ (0..3000).to_a.each { |i|
182
+ # Lore::Article.create(:title => "title_#{i}",
183
+ # :tags => [ :foo, :bar, :wombat ],
184
+ # :text => "text #{i}")
185
+ }
186
+
187
+
188
+ bmbm(12) { |test|
189
+ test.report("unprocessed query") {
190
+ num_loops.times {
191
+ result = connection.exec(sql)
192
+ }
193
+ }
194
+ # test.report("row parsing") {
195
+ # num_loops.times {
196
+ # result = connection.exec(sql)
197
+ # p = Result_Parser.new(result)
198
+ # p.get_rows
199
+ # }
200
+ # }
201
+ # test.report("result fetching in lore") {
202
+ # num_loops.times {
203
+ # result = connection.exec(sql)
204
+ # result = Lore::Result.new('',result)
205
+ # result.get_rows.each { |row|
206
+ # # noop
207
+ # }
208
+ # }
209
+ # }
210
+ # test.report("result parsing in lore") {
211
+ # num_loops.times {
212
+ # result = connection.exec(sql)
213
+ # result = Lore::Connection.perform(sql)
214
+ # result.get_rows.each { |row|
215
+ # # noop
216
+ # }
217
+ # }
218
+ # }
219
+ # test.report("ac_instances unfiltered") {
220
+ # Lore.disable_cache
221
+ # Lore::Article.disable_output_filters if Lore::Article.respond_to?(:disable_output_filters)
222
+ # num_loops.times {
223
+ # result = Lore::Connection.perform(sql).get_rows()
224
+ # result.map! { |row|
225
+ # row = (Lore::Article.new(row))
226
+ # }
227
+ # }
228
+ # }
229
+ # test.report("ac_instances filtered") {
230
+ # Lore.disable_cache
231
+ # Lore::Article.enable_output_filters if Lore::Article.respond_to?(:enable_output_filters)
232
+ # num_loops.times {
233
+ # result = Lore::Connection.perform(sql).get_rows()
234
+ # result.map! { |row|
235
+ # row = (Lore::Article.new(row))
236
+ # }
237
+ # }
238
+ # }
239
+ test.report("lore select unfiltered") {
240
+ Lore.disable_cache
241
+ Lore::Article.disable_output_filters if Lore::Article.respond_to?(:disable_output_filters)
242
+ id_error = false
243
+ count = 0
244
+ num_loops.times {
245
+ count = range_from
246
+ Lore::Article.select { |a|
247
+ a.where(Lore::Article.id.in(range_from..range_to))
248
+ a.limit(100)
249
+ }.each { |a|
250
+ raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id.to_s != count.to_s
251
+ count += 1
252
+ }
253
+ }
254
+ }
255
+ test.report("lore shortcut filtered") {
256
+ id_error = false
257
+ Lore.disable_cache
258
+ Lore::Article.enable_output_filters if Lore::Article.respond_to?(:enable_output_filters)
259
+ count = 0
260
+ num_loops.times {
261
+ count = range_from
262
+ r = Lore::Article.find(:all).with(Lore::Article.id.in(range_from..range_to)).each { |a|
263
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
264
+ count += 1
265
+ valid = true
266
+ valid = valid && a.tags.is_a?(Array)
267
+ valid = valid && a.id.is_a?(Fixnum)
268
+ # raise ::Exception.new("TYPE ERROR") unless valid
269
+ }
270
+ }
271
+ }
272
+ test.report("lore shortcut unfiltered") {
273
+ id_error = false
274
+ Lore.disable_cache
275
+ Lore::Article.disable_output_filters if Lore::Article.respond_to?(:disable_output_filters)
276
+ count = 0
277
+ num_loops.times {
278
+ count = range_from
279
+ r = Lore::Article.all_with(Lore::Article.id.in(range_from..range_to)).each { |a|
280
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
281
+ count += 1
282
+ valid = true
283
+ # raise ::Exception.new("TYPE ERROR") unless valid
284
+ }
285
+ }
286
+ }
287
+ test.report("sequel") {
288
+ id_error = false
289
+ count = 0
290
+ num_loops.times {
291
+ count = range_from
292
+ DB[:articles].inner_join(:contents, :id => :content_id).filter( :articles__id => (range_from..range_to)).each { |a|
293
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
294
+ count += 1
295
+ valid = true
296
+ # tags = a[:tags][1..-2].split(',')
297
+ # id = a[:id].to_i
298
+ # raise ::Exception.new("TYPE ERROR") unless valid
299
+ }
300
+ }
301
+ }
302
+ test.report("activerecord") {
303
+ id_error = false
304
+ count = 0
305
+ num_loops.times {
306
+ count = range_from
307
+ for a in AR::Article.find(:all, :include => :content, :conditions => "id between #{range_from} AND #{range_to}") do
308
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
309
+ count += 1
310
+ valid = true
311
+ valid = valid && a.tags.is_a?(Array)
312
+ valid = valid && a.id.is_a?(Fixnum)
313
+ # raise ::Exception.new("TYPE ERROR") unless valid
314
+ end
315
+ }
316
+ }
317
+ test.report('lore using cache') {
318
+ id_error = false
319
+ Lore.enable_cache
320
+ Lore::Article.disable_output_filters if Lore::Article.respond_to?(:disable_output_filters)
321
+ count = 0
322
+ num_loops.times {
323
+ count = range_from
324
+ Lore::Article.find(100).with(Lore::Article.id.in(range_from..range_to)).each { |a|
325
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
326
+ count += 1
327
+ valid = true
328
+ valid = valid && a.tags.is_a?(Array)
329
+ valid = valid && a.id.is_a?(Fixnum)
330
+ # raise ::Exception.new("TYPE ERROR") unless valid
331
+ }
332
+ }
333
+ }
334
+ test.report("lore prepared") {
335
+ id_error = false
336
+ Lore.disable_cache
337
+ count = 0
338
+ num_loops.times {
339
+ count = range_from
340
+ Lore::Article.id_in_range(range_from,range_to).each { |a|
341
+ # raise ::Exception.new("ID ERROR: #{a.id.inspect} != #{count.inspect}") if a.id != count
342
+ count += 1
343
+ valid = true
344
+ valid = valid && a.tags.is_a?(Array)
345
+ valid = valid && a.id.is_a?(Fixnum)
346
+ # raise ::Exception.new("TYPE ERROR") unless valid
347
+ }
348
+ }
349
+ }
350
+ }
351
+
352
+