lore 0.4.8 → 0.9.2

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.
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
+