nitro 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/{ChangeLog → CHANGELOG} +137 -0
  2. data/INSTALL +1 -2
  3. data/README +1 -1
  4. data/Rakefile +10 -61
  5. data/benchmark/{nitro/bench.rb → bench.rb} +1 -1
  6. data/benchmark/{nitro/simple-webrick-n-200.txt → simple-webrick-n-200.txt} +0 -0
  7. data/benchmark/{nitro/static-webrick-n-200.txt → static-webrick-n-200.txt} +0 -0
  8. data/benchmark/{nitro/tiny-lhttpd-n-200-c-5.txt → tiny-lhttpd-n-200-c-5.txt} +0 -0
  9. data/benchmark/{nitro/tiny-webrick-n-200-c-5.txt → tiny-webrick-n-200-c-5.txt} +0 -0
  10. data/benchmark/{nitro/tiny-webrick-n-200.txt → tiny-webrick-n-200.txt} +0 -0
  11. data/benchmark/{nitro/tiny2-webrick-n-200.txt → tiny2-webrick-n-200.txt} +0 -0
  12. data/doc/{ChangeLog.1 → CHANGELOG.1} +0 -0
  13. data/{RELEASES → doc/RELEASES} +46 -0
  14. data/doc/faq.txt +7 -0
  15. data/examples/README.windows +1 -1
  16. data/examples/ajax/controller.rb +21 -0
  17. data/examples/ajax/public/index.xhtml +70 -0
  18. data/examples/ajax/public/js/ajax.js +64 -0
  19. data/examples/ajax/run.rb +16 -0
  20. data/examples/blog/README +6 -3
  21. data/examples/blog/conf/apache.conf +2 -2
  22. data/examples/blog/conf/lhttpd.conf +2 -2
  23. data/examples/blog/log/apache.error_log +777 -0
  24. data/examples/blog/{root → public}/base.xsl +0 -0
  25. data/examples/blog/{root → public}/fcgi.rb +0 -0
  26. data/examples/blog/{root → public}/m/bubbles.gif +0 -0
  27. data/examples/blog/{root → public}/m/comments_curve.gif +0 -0
  28. data/examples/blog/{root → public}/m/down.gif +0 -0
  29. data/examples/blog/{root → public}/m/footer_bg.gif +0 -0
  30. data/examples/blog/{root → public}/m/garrow.gif +0 -0
  31. data/examples/blog/{root → public}/m/gbull.gif +0 -0
  32. data/examples/blog/{root → public}/m/grbull.gif +0 -0
  33. data/examples/blog/{root → public}/m/h1_bg.gif +0 -0
  34. data/examples/blog/{root → public}/m/header_bg.gif +0 -0
  35. data/examples/blog/{root → public}/m/nitro.gif +0 -0
  36. data/examples/blog/{root → public}/m/obull.gif +0 -0
  37. data/examples/blog/{root → public}/m/page_bg.gif +0 -0
  38. data/examples/blog/{root → public}/m/rss.gif +0 -0
  39. data/examples/blog/{root → public}/m/side_title_bg.gif +0 -0
  40. data/examples/blog/{root → public}/m/sidebar_bg.gif +0 -0
  41. data/examples/{no_xsl_blog/root → blog/public}/style.css +6 -0
  42. data/examples/blog/run.rb +10 -12
  43. data/examples/blog/{lib → src}/blog.rb +3 -3
  44. data/examples/blog/{lib/blog → src}/controller.rb +13 -2
  45. data/examples/blog/src/mailer.rb +23 -0
  46. data/examples/blog/{lib/blog/model.rb → src/models/blog.rb} +4 -7
  47. data/examples/blog/src/models/content.rb +52 -0
  48. data/examples/blog/src/views/blog_entry_email.xhtml +16 -0
  49. data/examples/blog/{root → src/views}/comments.xhtml +0 -0
  50. data/examples/blog/{root → src/views}/entry_form.xhtml +0 -0
  51. data/examples/blog/{root → src/views}/error.xhtml +0 -0
  52. data/examples/blog/{root → src/views}/index.xhtml +0 -0
  53. data/examples/blog/{root → src/views}/login.xhtml +0 -0
  54. data/examples/blog/{root → src/views}/recent_posts.xhtml +0 -0
  55. data/examples/blog/{root → src/views}/view_entry.xhtml +8 -0
  56. data/examples/blog/{root → src/views}/view_entry.xml +0 -0
  57. data/examples/blog/src/xsl/base.xsl +153 -0
  58. data/examples/blog/{root → src/xsl}/style.xsl +2 -2
  59. data/examples/no_xsl_blog/README +5 -1
  60. data/examples/no_xsl_blog/conf/apache.conf +2 -2
  61. data/examples/no_xsl_blog/conf/lhttpd.conf +2 -2
  62. data/examples/no_xsl_blog/lib/blog/model.rb +1 -1
  63. data/{lib/parts → examples/no_xsl_blog/lib}/content.rb +1 -11
  64. data/examples/no_xsl_blog/log/apache.error_log +405 -0
  65. data/examples/no_xsl_blog/{root → public}/comments.xhtml +0 -0
  66. data/examples/no_xsl_blog/{root → public}/entry_form.xhtml +0 -0
  67. data/examples/no_xsl_blog/{root → public}/fcgi.rb +0 -0
  68. data/examples/no_xsl_blog/{root → public}/index.xhtml +0 -0
  69. data/examples/no_xsl_blog/{root → public}/login.xhtml +0 -0
  70. data/examples/no_xsl_blog/{root → public}/m/bubbles.gif +0 -0
  71. data/examples/no_xsl_blog/{root → public}/m/comments_curve.gif +0 -0
  72. data/examples/no_xsl_blog/{root → public}/m/down.gif +0 -0
  73. data/examples/no_xsl_blog/{root → public}/m/footer_bg.gif +0 -0
  74. data/examples/no_xsl_blog/{root → public}/m/garrow.gif +0 -0
  75. data/examples/no_xsl_blog/{root → public}/m/gbull.gif +0 -0
  76. data/examples/no_xsl_blog/{root → public}/m/grbull.gif +0 -0
  77. data/examples/no_xsl_blog/{root → public}/m/h1_bg.gif +0 -0
  78. data/examples/no_xsl_blog/{root → public}/m/header_bg.gif +0 -0
  79. data/examples/no_xsl_blog/{root → public}/m/nitro.gif +0 -0
  80. data/examples/no_xsl_blog/{root → public}/m/obull.gif +0 -0
  81. data/examples/no_xsl_blog/{root → public}/m/page_bg.gif +0 -0
  82. data/examples/no_xsl_blog/{root → public}/m/rss.gif +0 -0
  83. data/examples/no_xsl_blog/{root → public}/m/side_title_bg.gif +0 -0
  84. data/examples/no_xsl_blog/{root → public}/m/sidebar_bg.gif +0 -0
  85. data/examples/no_xsl_blog/{root → public}/recent_posts.xhtml +0 -0
  86. data/examples/{blog/root → no_xsl_blog/public}/style.css +0 -0
  87. data/examples/no_xsl_blog/{root → public}/view_entry.xhtml +0 -0
  88. data/examples/no_xsl_blog/{root → public}/view_entry.xml +0 -0
  89. data/examples/tiny/conf/apache.conf +2 -2
  90. data/examples/tiny/log/apache.error_log +100 -0
  91. data/examples/tiny/{root → public}/fcgi.rb +0 -0
  92. data/examples/tiny/{root → public}/include.xhtml +0 -0
  93. data/examples/tiny/{root → public}/index.xhtml +0 -0
  94. data/{bin/proto/root/m → examples/tiny/public}/nitro.png +0 -0
  95. data/examples/tiny/{root → public}/upload.xhtml +0 -0
  96. data/examples/tiny/run.rb +1 -2
  97. data/examples/why_wiki/wiki.yml +1 -0
  98. data/install.rb +5 -2
  99. data/lib/nitro.rb +2 -6
  100. data/lib/nitro/adapters/fastcgi.rb +2 -2
  101. data/lib/nitro/adapters/webrick.rb +4 -4
  102. data/lib/nitro/conf.rb +5 -2
  103. data/lib/nitro/controller.rb +2 -2
  104. data/lib/nitro/dispatcher.rb +19 -8
  105. data/lib/nitro/mail.rb +252 -8
  106. data/lib/nitro/render.rb +24 -21
  107. data/lib/nitro/runner.rb +1 -1
  108. data/lib/nitro/scaffold.rb +2 -5
  109. data/lib/nitro/simple.rb +2 -1
  110. data/lib/nitro/template.rb +42 -2
  111. data/test/nitro/tc_controller.rb +9 -4
  112. data/test/nitro/tc_dispatcher.rb +4 -6
  113. data/test/nitro/tc_mail.rb +95 -0
  114. data/test/{root → public}/blog/list.xhtml +0 -0
  115. data/test/public/dummy_mailer/registration.xhtml +5 -0
  116. data/vendor/README +0 -1
  117. metadata +136 -181
  118. data/benchmark/og/bench.rb +0 -75
  119. data/benchmark/og/sqlite-no-prepare.1.txt +0 -13
  120. data/benchmark/og/sqlite-no-prepare.2.txt +0 -13
  121. data/benchmark/og/sqlite-prepare.1.txt +0 -13
  122. data/benchmark/og/sqlite-prepare.2.txt +0 -13
  123. data/bin/proto/README +0 -34
  124. data/bin/proto/conf/apache.conf +0 -1
  125. data/bin/proto/conf/app.conf.rb +0 -14
  126. data/bin/proto/conf/lhttpd.conf +0 -236
  127. data/bin/proto/ctl +0 -4
  128. data/bin/proto/lib/README +0 -5
  129. data/bin/proto/log/README +0 -3
  130. data/bin/proto/root/fcgi.rb +0 -6
  131. data/bin/proto/root/index.xhtml +0 -69
  132. data/bin/proto/root/style.css +0 -152
  133. data/bin/proto/root/style.xsl +0 -99
  134. data/doc/og_config.txt +0 -35
  135. data/doc/og_tutorial.txt +0 -595
  136. data/examples/og/README +0 -11
  137. data/examples/og/mock_example.rb +0 -50
  138. data/examples/og/mysql_to_psql.rb +0 -96
  139. data/examples/og/run.rb +0 -286
  140. data/examples/tiny/root/nitro.png +0 -0
  141. data/lib/glue.rb +0 -55
  142. data/lib/glue/array.rb +0 -61
  143. data/lib/glue/attribute.rb +0 -83
  144. data/lib/glue/cache.rb +0 -138
  145. data/lib/glue/flexob.rb +0 -12
  146. data/lib/glue/hash.rb +0 -122
  147. data/lib/glue/inflector.rb +0 -91
  148. data/lib/glue/logger.rb +0 -147
  149. data/lib/glue/misc.rb +0 -14
  150. data/lib/glue/mixins.rb +0 -36
  151. data/lib/glue/number.rb +0 -24
  152. data/lib/glue/object.rb +0 -32
  153. data/lib/glue/pool.rb +0 -60
  154. data/lib/glue/property.rb +0 -408
  155. data/lib/glue/string.rb +0 -162
  156. data/lib/glue/time.rb +0 -85
  157. data/lib/glue/validation.rb +0 -394
  158. data/lib/og.rb +0 -185
  159. data/lib/og/adapter.rb +0 -513
  160. data/lib/og/adapters/filesys.rb +0 -121
  161. data/lib/og/adapters/mysql.rb +0 -347
  162. data/lib/og/adapters/oracle.rb +0 -375
  163. data/lib/og/adapters/psql.rb +0 -273
  164. data/lib/og/adapters/sqlite.rb +0 -262
  165. data/lib/og/backend.rb +0 -297
  166. data/lib/og/connection.rb +0 -304
  167. data/lib/og/database.rb +0 -282
  168. data/lib/og/enchant.rb +0 -125
  169. data/lib/og/meta.rb +0 -373
  170. data/lib/og/mock.rb +0 -165
  171. data/lib/og/observer.rb +0 -53
  172. data/lib/og/typemacros.rb +0 -23
  173. data/lib/parts/README +0 -9
  174. data/test/glue/tc_attribute.rb +0 -22
  175. data/test/glue/tc_cache.rb +0 -45
  176. data/test/glue/tc_hash.rb +0 -38
  177. data/test/glue/tc_logger.rb +0 -39
  178. data/test/glue/tc_numbers.rb +0 -20
  179. data/test/glue/tc_property.rb +0 -89
  180. data/test/glue/tc_property_mixins.rb +0 -93
  181. data/test/glue/tc_property_type_checking.rb +0 -35
  182. data/test/glue/tc_strings.rb +0 -103
  183. data/test/glue/tc_validation.rb +0 -188
  184. data/test/og/tc_filesys.rb +0 -83
  185. data/test/og/tc_lifecycle.rb +0 -104
  186. data/test/og/tc_many_to_many.rb +0 -62
  187. data/test/og/tc_meta.rb +0 -55
  188. data/test/og/tc_observer.rb +0 -85
  189. data/test/og/tc_sqlite.rb +0 -87
  190. data/test/tc_og.rb +0 -355
  191. data/vendor/composite_sexp_processor.rb +0 -43
  192. data/vendor/parse_tree.rb +0 -745
  193. data/vendor/sexp_processor.rb +0 -453
data/lib/og/enchant.rb DELETED
@@ -1,125 +0,0 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id$
4
-
5
- module Og
6
-
7
- module Enchant
8
-
9
- # Enchant a managed class. Add useful DB related methods
10
- # to the class and its instances.
11
-
12
- def enchant(klass)
13
-
14
- # Generate standard methods.
15
-
16
- klass.module_eval %{
17
- def self.create(*params, &block)
18
- obj = #{klass}.new(*params, &block)
19
- obj.save!
20
- end
21
-
22
- def self.save(obj)
23
- @@og_db << obj
24
- end
25
-
26
- def self.load(oid_or_name)
27
- @@og_db.load(oid_or_name, #{klass})
28
- end
29
-
30
- def self.get(oid_or_name)
31
- @@og_db.load(oid_or_name, #{klass})
32
- end
33
-
34
- def self.[](oid_or_name)
35
- @@og_db.load(oid_or_name, #{klass})
36
- end
37
-
38
- def self.load_all(extra_sql = nil)
39
- @@og_db.load_all(#{klass}, extra_sql)
40
- end
41
-
42
- def self.all(extra_sql = nil)
43
- @@og_db.load_all(#{klass}, extra_sql)
44
- end
45
-
46
- def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
47
- @@og_db.count(sql, #{klass})
48
- end
49
-
50
- def self.select(sql)
51
- @@og_db.select(sql, #{klass})
52
- end
53
-
54
- def self.find(sql)
55
- @@og_db.select(sql, #{klass})
56
- end
57
-
58
- def self.select_one(sql)
59
- @@og_db.select_one(sql, #{klass})
60
- end
61
-
62
- def self.find_one(sql)
63
- @@og_db.select_one(sql, #{klass})
64
- end
65
-
66
- def self.one(sql)
67
- @@og_db.select_one(sql, #{klass})
68
- end
69
-
70
- def self.delete(obj_or_oid)
71
- @@og_db.delete(obj_or_oid, #{klass})
72
- end
73
-
74
- def self.properties_and_relations
75
- @@__meta[:props_and_relations]
76
- end
77
-
78
- def each(&block)
79
- all.each(&block)
80
- end
81
- include Enumerable
82
-
83
- def save
84
- @@og_db << self
85
- return self
86
- end
87
- alias_method :save!, :save
88
-
89
- def update_properties(updatesql)
90
- @@og_db.pupdate(updatesql, self.oid, #{klass})
91
- end
92
- alias_method :pupdate!, :update_properties
93
-
94
- def delete!
95
- @@og_db.delete(@oid, #{klass})
96
- end
97
- }
98
-
99
- # Generate finder methods.
100
-
101
- code = ''
102
-
103
- for p in klass.__props
104
- code << %{
105
- def self.find_by_#{p.name}(val, operator = '=', extra_sql = nil)
106
- }
107
-
108
- val = klass.og_db.adapter.typecast[p.klass].gsub(/\:s\:/, 'val')
109
-
110
- if p.meta[:unique]
111
- code << %{@@og_db.select_one("#{p.name}\#\{operator\}#{val} \#\{extra_sql\}", #{klass})}
112
- else
113
- code << %{@@og_db.select("#{p.name}\#\{operator\}#{val} \#\{extra_sql\}", #{klass})}
114
- end
115
- code << %{
116
- end;
117
- }
118
- end
119
-
120
- klass.module_eval(code)
121
- end
122
-
123
- end
124
-
125
- end
data/lib/og/meta.rb DELETED
@@ -1,373 +0,0 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: meta.rb 270 2005-03-07 17:52:16Z gmosx $
4
- #--
5
- # TODO:
6
- # - precreate the meta sql statements as much as possible to
7
- # avoid string interpolations.
8
- #++
9
-
10
- require 'glue/inflector'
11
- require 'og/adapter'
12
- require 'og/typemacros'
13
-
14
- module Og
15
-
16
- class Relation < N::Property
17
- alias foreign_class klass
18
- end
19
-
20
- class Has < Relation; end
21
- class HasMany < Has; end
22
- class HasOne < Has; end
23
- class ManyToMany < Has; end
24
- class BelongsTo < Relation; end
25
- class RefersTo < Relation; end
26
-
27
- # Some useful meta-language utilities.
28
-
29
- module MetaUtils # :nodoc: all
30
-
31
- # Convert the klass to a string representation
32
- # The leading module if available is removed.
33
- #--
34
- # gmosx, FIXME: unify with the ogutils.encode method?
35
- #++
36
-
37
- def self.expand(klass)
38
- return klass.name.gsub(/^.*::/, '').gsub(/::/, '_').downcase
39
- end
40
-
41
- # Infer the target klass for a relation. When defining
42
- # relations, tha target class is typically given. Some times
43
- # in order to avoid forward declarations a symbol is given instead
44
- # of a class. Other times on class is given at all, and
45
- # the inflection mechanism is used to infer the class name.
46
- #--
47
- # This is not used yet.
48
- #++
49
-
50
- def self.resolve_class(name, klass)
51
- klass ||= N::Inflector.camelize(name)
52
-
53
- return klass if klass.is_a?(Class)
54
-
55
- unless klass.is_a?(String) or klass.is_a?(Symbol)
56
- raise 'Invalid class definition'
57
- end
58
-
59
- unless Object.const_get(klass.intern)
60
- # Forward declaration.
61
- Object.class_eval("class #{klass}; end")
62
- end
63
-
64
- return Object.const_get(klass)
65
- end
66
-
67
- end
68
-
69
- # Implements a meta-language for manipulating og-managed objects
70
- # and defining their relationships. The original idea comes
71
- # from the excellent ActiveRecord library.
72
- #
73
- # Many more useful relations will be available soon.
74
-
75
- module MetaLanguage
76
-
77
- # Defines an SQL index. Useful for defining indiced
78
- # over multiple columns.
79
-
80
- def sql_index(index, options = {})
81
- meta :sql_index, [index, options]
82
- end
83
-
84
- # Implements a 'belongs_to' relation.
85
- # Automatically enchants the calling class with helper methods.
86
- #
87
- # Example:
88
- #
89
- # class MyObject
90
- # belongs_to AnotherObject, :prop => :parent
91
- # end
92
- #
93
- # creates the code:
94
- #
95
- # prop_accessor Fixnum, :parent_oid
96
- # def parent; ... end
97
- # def parent=(obj_or_oid); ... end
98
-
99
- def belongs_to(name, klass, options = {})
100
- prop_eval = "prop_accessor Fixnum, :#{name}_oid"
101
- prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
102
- prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
103
-
104
- meta :props_and_relations, BelongsTo.new(name, klass, :property => "#{name}_oid".intern)
105
-
106
- module_eval %{
107
- #{prop_eval}
108
-
109
- def #{name}
110
- Og.db.load_by_oid(@#{name}_oid, #{klass})
111
- end
112
-
113
- def #{name}=(obj_or_oid)
114
- @#{name}_oid = obj_or_oid.to_i
115
- end
116
- }
117
- end
118
-
119
- # Implements a 'has_one' relation.
120
- # Automatically enchants the calling class with helper methods.
121
- #
122
- # Example:
123
- #
124
- # class MyObject
125
- # has_one :child, TheClass
126
- # has_one :article
127
- # end
128
- #
129
- # creates the code:
130
- #
131
- # ...
132
-
133
- def has_one(name, klass = nil, options = {})
134
-
135
- # linkback is the property of the child object that 'links back'
136
- # to this object.
137
-
138
- linkback = (options[:linkback].to_s || "#{MetaUtils.expand(self)}_oid").to_s
139
-
140
- meta :descendants, klass, linkback
141
- meta :props_and_relations, HasOne.new(name, klass, :linkback => linkback)
142
-
143
- module_eval %{
144
- def #{name}(extrasql = nil)
145
- Og.db.select_one("SELECT * FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}", #{klass})
146
- end
147
-
148
- def delete_#{name}(extrasql = nil)
149
- Og.db.exec("DELETE FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
150
- end
151
- }
152
- end
153
-
154
- # Implements a 'has_many' relation.
155
- # Automatically enchants the calling class with helper methods.
156
- #
157
- # Example:
158
- #
159
- # class MyObject
160
- # has_many :articles, Article
161
- # end
162
- #
163
- # creates the code:
164
- #
165
- # obj.articles
166
- # obj.add_article(article)
167
- # obj.add_article do |a|
168
- # a.title = 'Title'
169
- # a.body = 'Body'
170
- # end
171
-
172
- def has_many(name, klass, options = {})
173
- name_s = N::Inflector.singularize(name.to_s)
174
-
175
- # linkback is the property of the child object that 'links back'
176
- # to this object.
177
-
178
- linkback = (options[:linkback] || "#{MetaUtils.expand(self)}_oid").to_s
179
-
180
- # keep belongs to metadata, useful for
181
- # reflection/scaffolding.
182
-
183
- meta :descendants, klass, linkback
184
- meta :props_and_relations, HasMany.new(name, klass, :linkback => linkback)
185
-
186
- module_eval %{
187
- def #{name}(extrasql = nil)
188
- Og.db.select("SELECT * FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}", #{klass})
189
- end
190
-
191
- def #{name}_count(extrasql = nil)
192
- Og.db.count("SELECT COUNT(*) FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
193
- end
194
-
195
- def add_#{name_s}(obj = nil)
196
- yield(obj = #{klass}.new) unless obj
197
- obj.#{linkback} = @oid
198
- obj.save!
199
- end
200
-
201
- def delete_all_#{name}(extrasql = nil)
202
- Og.db.exec("DELETE FROM #{Og::Adapter.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
203
- end
204
- }
205
- end
206
-
207
- # Implements a 'many_to_many' relation.
208
- # Two objects are associated using an intermediate join table.
209
- # Automatically enchants the calling class with helper methods.
210
- #
211
- # Options:
212
- #
213
- # Example:
214
- #
215
- # class Article
216
- # many_to_many :categories, Category, :linkback => articles
217
- # end
218
- #
219
- # article.categories
220
- # article.del_category
221
- # article.add_category
222
- # article.add_category { |c| ... }
223
- # article.clear_categories
224
- #
225
- # category.articles
226
- # ...
227
- #--
228
- # FIXME: make more compatible with other enchant methods.
229
- #++
230
-
231
- def many_to_many(name, klass, options = {})
232
- list_o = name.to_s
233
- prop_o = N::Inflector.singularize(list_o)
234
- list_m = (options[:linkback] || N::Inflector.plural_name(self)).to_s
235
- prop_m = N::Inflector.singularize(list_m)
236
-
237
- # Exit if the class is allready indirectly 'enchanted' from the
238
- # other class of the many_to_many relation.
239
-
240
- return if self.respond_to?(prop_m)
241
-
242
- # Add some metadata to the class to allow for automatic join table
243
- # calculation.
244
-
245
- meta :sql_join, name, klass, options
246
-
247
- # FIXME: should add metadata for cascading delete.
248
-
249
- meta :props_and_relations, ManyToMany.new(prop_o, klass)
250
- klass.meta :props_and_relations, ManyToMany.new(prop_m, self)
251
-
252
- # Enchant this class
253
-
254
- module_eval %{
255
- def #{list_o}(extrasql = nil)
256
- Og.db.select("SELECT d.* FROM #{Og::Adapter.table(klass)} d, #{Og::Adapter.join_table(self, klass, name)} j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
257
- end
258
-
259
- def #{list_o}_count(extrasql = nil)
260
- Og.db.select("SELECT COUNT(*) FROM #{Og::Adapter.table(klass)} d, #{Og::Adapter.join_table(self, klass, name)} j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
261
- end
262
-
263
- def add_#{prop_o}(obj = nil)
264
- yield(obj = #{klass}.new) unless obj
265
- obj.save! unless obj.oid
266
- Og.db.exec("INSERT INTO #{Og::Adapter.join_table(self, klass, name)} (key1, key2) VALUES (\#\@oid, \#\{obj.oid\})")
267
- end
268
-
269
- def delete_#{prop_o}(obj_or_oid)
270
- Og.db.exec("DELETE FROM #{Og::Adapter.join_table(self, klass, name)} WHERE key2=\#\{obj_or_oid.to_i\}")
271
- end
272
-
273
- def clear_#{list_o}
274
- Og.db.exec("DELETE FROM #{Og::Adapter.join_table(self, klass, name)} WHERE key1=\#\@oid")
275
- end
276
- }
277
-
278
- # indirectly enchant the other class of the relation.
279
-
280
- klass.module_eval %{
281
- def #{list_m}(extrasql = nil)
282
- Og.db.select("SELECT s.* FROM #{Og::Adapter.table(self)} s, #{Og::Adapter.join_table(self, klass, name)} j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
283
- end
284
-
285
- def #{list_m}_count(extrasql = nil)
286
- Og.db.select("SELECT COUNT(*) FROM #{Og::Adapter.table(self)} s, #{Og::Adapter.join_table(self, klass, name)} j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
287
- end
288
-
289
- def add_#{prop_m}(obj = nil)
290
- yield(obj = #{self}.new) unless obj
291
- obj.save! unless obj.oid
292
- Og.db.exec("INSERT INTO #{Og::Adapter.join_table(self, klass, name)} (key1, key2) VALUES (\#\{obj.oid\}, \#\@oid)")
293
- end
294
-
295
- def delete_#{prop_m}(obj_or_oid)
296
- Og.db.exec("DELETE FROM #{Og::Adapter.join_table(self, klass, name)} WHERE key1=\#\{obj_or_oid.to_i\}")
297
- end
298
-
299
- def clear_#{list_m}
300
- Og.db.exec("DELETE FROM #{Og::Adapter.join_table(self, klass, name)} WHERE key2=\#\@oid")
301
- end
302
- }
303
- end
304
- alias :has_and_belongs_to_many :many_to_many
305
-
306
- # Implements a 'refers_to' relation.
307
- # This is a one-way version of the 'has_one'/'belongs_to'
308
- # relations. The target object cannot link back to the source
309
- # object.
310
- # This is in fact EXACTLY the same as belongs_to with a
311
- # different name (!!!!)
312
- #
313
- # Automatically enchants the calling class with helper methods.
314
- #
315
- #
316
- # Example:
317
- #
318
- # class MyObject
319
- # refers_to article, Article
320
- # end
321
- #
322
- # creates the code:
323
- #
324
- # prop_accessor Fixnum, :article_oid
325
- # def article; ... end
326
- # def article=(obj_or_oid); ... end
327
-
328
- def refers_to(name, klass, options = {})
329
- prop_eval = "prop_accessor Fixnum, :#{name}_oid"
330
- prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
331
- prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
332
-
333
- meta :props_and_relations, RefersTo.new(name, klass, :property => "#{name}_oid".intern)
334
- klass.meta :descendants, self, "#{name}_oid".intern
335
-
336
- module_eval %{
337
- #{prop_eval}
338
-
339
- def #{name}
340
- Og.db.load_by_oid(@#{name}_oid, #{klass})
341
- end
342
-
343
- def #{name}=(obj_or_oid)
344
- @#{name}_oid = obj_or_oid.to_i
345
- end
346
- }
347
- end
348
-
349
- # Declares that this class can join with another class.
350
- # The join parameters are given so the join-compatible
351
- # methods are generated.
352
-
353
- def joins(klass, options = {})
354
- meta :joins, klass, options
355
- end
356
-
357
- end
358
-
359
- end
360
-
361
- # Include the meta-language extensions into Module. If the flag is
362
- # false the developer is responsible for including the MetaLanguage
363
- # module where needed.
364
- #
365
- # By default this is FALSE, to avoid polution of the Module object.
366
- # However if you include a prop_accessor or a managed Mixin in your
367
- # object MetaLanguage gets automatically extended in the class.
368
-
369
- if Og.include_meta_language
370
- class Module # :nodoc: all
371
- include Og::MetaLanguage
372
- end
373
- end