nitro 0.12.0 → 0.13.0

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 (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