nitro 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/ChangeLog +175 -0
  2. data/README +41 -7
  3. data/RELEASES +24 -0
  4. data/Rakefile +5 -7
  5. data/bin/new_app.rb +26 -4
  6. data/bin/new_form.rb +54 -0
  7. data/bin/proto/config.rb +3 -3
  8. data/bin/proto/root/index.xhtml +2 -34
  9. data/bin/proto/root/style.css +4 -70
  10. data/bin/proto/root/style.xsl +8 -39
  11. data/doc/tutorial.txt +5 -0
  12. data/examples/blog/app.rb +2 -1
  13. data/examples/blog/config.rb +7 -2
  14. data/examples/blog/root/style.xsl +1 -2
  15. data/examples/flash/README +34 -0
  16. data/examples/flash/app.rb +20 -0
  17. data/examples/flash/config.rb +38 -0
  18. data/examples/flash/lib/flash.rb +40 -0
  19. data/examples/flash/root/index.xhtml +25 -0
  20. data/examples/flash/root/show_inline_text.xhtml +12 -0
  21. data/examples/flash/tmp.swf +0 -0
  22. data/examples/og/README +7 -0
  23. data/examples/og/mock_example.rb +58 -0
  24. data/examples/og/run.rb +9 -5
  25. data/examples/tiny/root/include.xhtml +3 -0
  26. data/examples/tiny/root/index.xhtml +2 -1
  27. data/lib/glue/property.rb +166 -107
  28. data/lib/glue/property.rb.old +307 -0
  29. data/lib/nitro/builders/form.rb +26 -17
  30. data/lib/nitro/events.rb +1 -1
  31. data/lib/nitro/markup.rb +120 -0
  32. data/lib/nitro/server/cookie.rb +1 -1
  33. data/lib/nitro/server/dispatcher.rb +5 -6
  34. data/lib/nitro/server/filters.rb +1 -1
  35. data/lib/nitro/server/render.rb +33 -29
  36. data/lib/nitro/server/shaders.rb +32 -3
  37. data/lib/nitro/server/user.rb +1 -1
  38. data/lib/nitro/server/webrick.rb +9 -4
  39. data/lib/nitro/ui/popup.rb +1 -1
  40. data/lib/nitro/ui/select.rb +1 -1
  41. data/lib/nitro/ui/tabs.rb +1 -1
  42. data/lib/nitro/version.rb +2 -2
  43. data/lib/og.rb +17 -6
  44. data/lib/og/backend.rb +34 -4
  45. data/lib/og/backends/mysql.rb +3 -17
  46. data/lib/og/backends/psql.rb +5 -17
  47. data/lib/og/meta.rb +41 -26
  48. data/lib/og/mock.rb +223 -0
  49. data/lib/og/version.rb +2 -2
  50. data/lib/parts/content.rb +61 -0
  51. data/test/glue/{tc_properties.rb → tc_property.rb} +0 -1
  52. data/test/glue/tc_property_mixins.rb +62 -0
  53. data/test/og/tc_lifecycle.rb +107 -0
  54. data/test/tc_og.rb +31 -4
  55. data/vendor/README +6 -0
  56. data/vendor/binding_of_caller.rb +81 -0
  57. data/vendor/breakpoint.rb +526 -0
  58. data/vendor/breakpoint_client.rb +157 -0
  59. metadata +135 -95
@@ -3,7 +3,7 @@
3
3
  # * Elias Athanasopoulos <elathan@navel.gr>
4
4
  #
5
5
  # (c) 2004 Navel, all rights reserved.
6
- # $Id: mysql.rb 185 2004-12-10 13:29:09Z gmosx $
6
+ # $Id: mysql.rb 194 2004-12-20 20:23:57Z gmosx $
7
7
 
8
8
  require "mysql"
9
9
 
@@ -263,21 +263,7 @@ class MysqlBackend < Og::Backend
263
263
  # and constrains are created (indicices, sequences, etc).
264
264
  #
265
265
  def create_table(klass)
266
- fields = []
267
-
268
- klass.__props.each do |p|
269
- klass.sql_index(p.symbol) if p.meta[:sql_index]
270
-
271
- field = "#{p.symbol}"
272
-
273
- if p.meta and p.meta[:sql]
274
- field << " #{p.meta[:sql]}"
275
- else
276
- field << " #{TYPEMAP[p.klass]}"
277
- end
278
-
279
- fields << field
280
- end
266
+ fields = create_fields(klass, TYPEMAP)
281
267
 
282
268
  sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
283
269
 
@@ -326,7 +312,7 @@ class MysqlBackend < Og::Backend
326
312
  join_src = "#{Og::Utils.encode(klass)}_oid"
327
313
  join_dst = "#{Og::Utils.encode(join_class)}_oid"
328
314
  begin
329
- exec "CREATE TABLE #{join_table} ( key1 integer, key2 integer )"
315
+ exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
330
316
  exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
331
317
  exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
332
318
  rescue => ex
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: psql.rb 185 2004-12-10 13:29:09Z gmosx $
5
+ # $Id: psql.rb 194 2004-12-20 20:23:57Z gmosx $
6
6
 
7
7
  require "postgres"
8
8
 
@@ -137,6 +137,8 @@ end
137
137
  # = PsqlBackend
138
138
  #
139
139
  # Implements a PostgreSQL powered backend.
140
+ # This backend is compatible with Michael Neumann's postgres-pr
141
+ # pure ruby driver.
140
142
  #
141
143
  class PsqlBackend < Og::Backend
142
144
 
@@ -240,21 +242,7 @@ class PsqlBackend < Og::Backend
240
242
  # and constrains are created (indicices, sequences, etc).
241
243
  #
242
244
  def create_table(klass)
243
- fields = []
244
-
245
- klass.__props.each do |p|
246
- klass.sql_index(p.symbol) if p.meta[:sql_index]
247
-
248
- field = "#{p.symbol}"
249
-
250
- if p.meta and p.meta[:sql]
251
- field << " #{p.meta[:sql]}"
252
- else
253
- field << " #{TYPEMAP[p.klass]}"
254
- end
255
-
256
- fields << field
257
- end
245
+ fields = create_fields(klass, TYPEMAP)
258
246
 
259
247
  sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
260
248
 
@@ -319,7 +307,7 @@ class PsqlBackend < Og::Backend
319
307
  join_src = "#{Og::Utils.encode(klass)}_oid"
320
308
  join_dst = "#{Og::Utils.encode(join_class)}_oid"
321
309
  begin
322
- exec "CREATE TABLE #{join_table} ( key1 integer, key2 integer )"
310
+ exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
323
311
  exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
324
312
  exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
325
313
  rescue => ex
data/lib/og/meta.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: meta.rb 185 2004-12-10 13:29:09Z gmosx $
5
+ # $Id: meta.rb 198 2004-12-22 11:26:59Z gmosx $
6
6
 
7
7
  require 'og/backend'
8
8
  require 'glue/inflector'
@@ -17,7 +17,9 @@ module MetaUtils # :nodoc: all
17
17
 
18
18
  # Conver the klass to a string representation
19
19
  # The leading module if available is removed.
20
- #
20
+ #--
21
+ # gmosx, FIXME: unify with the ogutils.encode method?
22
+ #++
21
23
  def self.expand(klass)
22
24
  return klass.name.gsub(/^.*::/, '').gsub(/::/, '_').downcase
23
25
  end
@@ -46,7 +48,7 @@ module MetaLanguage
46
48
  # Example:
47
49
  #
48
50
  # class MyObject
49
- # belongs_to AnotherObject, :parent
51
+ # belongs_to AnotherObject, :prop => :parent
50
52
  # end
51
53
  #
52
54
  # creates the code:
@@ -56,8 +58,12 @@ module MetaLanguage
56
58
  # def parent=(obj_or_oid); ... end
57
59
  #
58
60
  def belongs_to(name, klass, options = {})
61
+ prop_eval = "prop_accessor Fixnum, :#{name}_oid"
62
+ prop_eval << ", :sql => '#{options[:sql]}'" if options[:sql]
63
+ prop_eval << ", :extra_sql => '#{options[:extra_sql]}'" if options[:extra_sql]
64
+
59
65
  module_eval %{
60
- prop_accessor Fixnum, :#{name}_oid
66
+ #{prop_eval}
61
67
 
62
68
  def #{name}
63
69
  $og.load_by_oid(@#{name}_oid, #{klass})
@@ -75,14 +81,14 @@ module MetaLanguage
75
81
  # Example:
76
82
  #
77
83
  # class MyObject
78
- # has_one :children, AnotherObject
84
+ # has_one AnotherObject
79
85
  # end
80
86
  #
81
87
  # creates the code:
82
88
  #
83
- # def children; ... end
89
+ # ...
84
90
  #
85
- def has_one(klass, name, options = {})
91
+ def has_one(name, klass, options = {})
86
92
  # linkback is the property of the child object that 'links back'
87
93
  # to this object.
88
94
  linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
@@ -117,6 +123,8 @@ module MetaLanguage
117
123
  # def children; ... end
118
124
  #
119
125
  def has_many(name, klass, options = {})
126
+ name_s = G::Inflector.singularize(name.to_s)
127
+
120
128
  # linkback is the property of the child object that 'links back'
121
129
  # to this object.
122
130
  linkback = options[:linkback] || "#{MetaUtils.expand(self)}_oid"
@@ -138,6 +146,11 @@ module MetaLanguage
138
146
  def #{name}_count(extrasql = nil)
139
147
  $og.count("SELECT COUNT(*) FROM #{Utils.table(klass)} WHERE #{linkback}=\#\@oid \#\{extrasql\}")
140
148
  end
149
+
150
+ def add_#{name_s}(obj, extra = nil)
151
+ obj.#{linkback} = @oid
152
+ obj.save!
153
+ end
141
154
  }
142
155
  end
143
156
 
@@ -145,10 +158,12 @@ module MetaLanguage
145
158
  # Two objects are associated using an intermediate join table.
146
159
  # Automatically enchants the calling class with helper methods.
147
160
  #
161
+ # Options:
162
+ #
148
163
  # Example:
149
164
  #
150
165
  # class Article
151
- # many_to_many :children, Categories
166
+ # many_to_many :categories, Category, :linkback => articles
152
167
  # end
153
168
  #
154
169
  # article.categories
@@ -162,15 +177,15 @@ module MetaLanguage
162
177
  #--
163
178
  # FIXME: make more compatible with other enchant methods.
164
179
  #++
165
- def many_to_many(klass, options = {})
166
- name1 = options[:name1] || G::Inflector.name(self)
167
- pname1 = options[:list_name1] || G::Inflector.plural_name(self)
168
- name2 = options[:name2] || G::Inflector.name(klass)
169
- pname2 = options[:list_name2] || G::Inflector.plural_name(klass)
180
+ def many_to_many(name, klass, options = {})
181
+ list_o = name.to_s
182
+ prop_o = G::Inflector.singularize(list_o)
183
+ list_m = options[:linkback] || G::Inflector.plural_name(self)
184
+ prop_m = G::Inflector.singularize(list_m)
170
185
 
171
186
  # exit if the class is allready indirectly 'enchanted' from the
172
187
  # other class of the many_to_many relation.
173
- return if self.respond_to?(name1)
188
+ return if self.respond_to?(prop_m)
174
189
 
175
190
  # Add some metadata to the class to allow for automatic join table
176
191
  # calculation.
@@ -181,24 +196,24 @@ module MetaLanguage
181
196
  # enchant this class
182
197
 
183
198
  module_eval %{
184
- def #{pname2}(extrasql = nil)
199
+ def #{list_o}(extrasql = nil)
185
200
  $og.select("SELECT d.* FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
186
201
  end
187
202
 
188
- def #{pname2}_count(extrasql = nil)
203
+ def #{list_o}_count(extrasql = nil)
189
204
  $og.select("SELECT COUNT(*) FROM #{Utils.table(klass)} AS d, #{Utils.join_table(self, klass)} AS j WHERE j.key1=\#\@oid AND j.key2=d.oid \#\{extrasql\}", #{klass})
190
205
  end
191
206
 
192
- def add_#{name2}(obj, extra = nil)
207
+ def add_#{prop_o}(obj, extra = nil)
193
208
  $og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\@oid, \#\{obj.oid\})")
194
209
  end
195
210
 
196
- def del_#{name2}(obj_or_oid, extra = nil)
211
+ def del_#{prop_o}(obj_or_oid, extra = nil)
197
212
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\{obj_or_oid.to_i\}")
198
213
  end
199
- alias_method :delete_#{name2}, :del_#{name2}
214
+ alias_method :delete_#{prop_o}, :del_#{prop_o}
200
215
 
201
- def clear_#{pname2}
216
+ def clear_#{list_o}
202
217
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\@oid")
203
218
  end
204
219
  }
@@ -206,24 +221,24 @@ module MetaLanguage
206
221
  # indirectly enchant the other class of the relation.
207
222
 
208
223
  klass.module_eval %{
209
- def #{pname1}(extrasql = nil)
224
+ def #{list_m}(extrasql = nil)
210
225
  $og.select("SELECT s.* FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
211
226
  end
212
227
 
213
- def #{pname1}_count(extrasql = nil)
228
+ def #{list_m}_count(extrasql = nil)
214
229
  $og.select("SELECT COUNT(*) FROM #{Utils.table(self)} AS s, #{Utils.join_table(self, klass)} AS j WHERE j.key2=\#\@oid AND j.key1=s.oid \#\{extrasql\}", #{self})
215
230
  end
216
231
 
217
- def add_#{name1}(obj, extra = nil)
232
+ def add_#{prop_m}(obj, extra = nil)
218
233
  $og.exec("INSERT INTO #{Utils.join_table(self, klass)} (key1, key2) VALUES (\#\{obj.oid\}, \#\@oid)")
219
234
  end
220
235
 
221
- def del_#{name1}(obj_or_oid, extra = nil)
236
+ def del_#{prop_m}(obj_or_oid, extra = nil)
222
237
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key1=\#\{obj_or_oid.to_i\}")
223
238
  end
224
- alias_method :delete_#{name1}, :del_#{name1}
239
+ alias_method :delete_#{prop_m}, :del_#{prop_m}
225
240
 
226
- def clear_#{pname1}
241
+ def clear_#{list_m}
227
242
  $og.exec("DELETE FROM #{Utils.join_table(self, klass)} WHERE key2=\#\@oid")
228
243
  end
229
244
  }
data/lib/og/mock.rb ADDED
@@ -0,0 +1,223 @@
1
+ # code:
2
+ # * George Moschovitis <gm@navel.gr>
3
+ # * Thomas Quas <tquas@yahoo.com>
4
+ #
5
+ # (c) 2004 Navel, all rights reserved.
6
+ # $Id$
7
+
8
+ require 'og'
9
+
10
+ require 'rubygems'
11
+ require_gem 'flexmock'
12
+
13
+ module Og
14
+
15
+ # = MockDatabase
16
+ #
17
+ # A utility object to Mock a Database in test units.
18
+ # Extends the standard FlexMock object.
19
+ #
20
+ #--
21
+ # TODO: Factor out common functionality with Database
22
+ # to avoid code duplication.
23
+ #++
24
+ class MockDatabase < ::FlexMock
25
+
26
+ # Managed class metadata
27
+ #
28
+ class ManagedClassMeta
29
+ # The managed class.
30
+ attr_accessor :klass
31
+
32
+ # A mapping of the database fields to the object properties.
33
+ attr_accessor :field_index
34
+
35
+ def initialize(klass = nil)
36
+ @klass = klass
37
+ @field_index = {}
38
+ end
39
+ end
40
+
41
+ # hash of configuration options.
42
+ attr_accessor :config
43
+
44
+ # Pool of connections to the backend.
45
+ attr_accessor :connection_pool
46
+
47
+ # Managed classes.
48
+ attr_accessor :managed_classes
49
+
50
+ # Initialize the database interface.
51
+ #
52
+ def initialize
53
+ # Initialize FlexMock
54
+ super
55
+
56
+ @managed_classes = G::SafeHash.new
57
+
58
+ $log.info "Using mock database."
59
+
60
+ if $og_auto_manage_classes
61
+ # automatically manage classes with properties and metadata.
62
+ # gmosx: Any idea how to optimize this?
63
+ classes_to_manage = []
64
+ ObjectSpace.each_object(Class) do |c|
65
+ if c.respond_to?(:__props) and c.__props
66
+ classes_to_manage << c
67
+ end
68
+ end
69
+ $log.info "Og auto manages the following classes:"
70
+ $log.info "#{classes_to_manage.inspect}"
71
+ manage_classes(*classes_to_manage)
72
+ end
73
+ end
74
+
75
+ # Shutdown the database interface.
76
+ #
77
+ def shutdown
78
+ end
79
+ alias_method :close, :shutdown
80
+
81
+ # Register a standard Ruby class as managed.
82
+ #
83
+ def manage(klass)
84
+ return if managed?(klass) or klass.ancestors.include?(Og::Unmanageable)
85
+
86
+ @managed_classes[klass] = ManagedClassMeta.new(klass)
87
+
88
+ # Add standard og methods to the class.
89
+ convert(klass)
90
+
91
+ # Add helper methods to the class.
92
+ enchant(klass) if $og_enchant_managed_classes
93
+ end
94
+
95
+ # Helper method to set multiple managed classes.
96
+ #
97
+ def manage_classes(*klasses)
98
+ for klass in klasses
99
+ manage(klass)
100
+ end
101
+ end
102
+
103
+ # Stop managing a Ruby class
104
+ #
105
+ def unmanage(klass)
106
+ @managed_classes.delete(klass)
107
+ end
108
+
109
+ # Is this class managed?
110
+ #
111
+ def managed?(klass)
112
+ return @managed_classes.include?(klass)
113
+ end
114
+
115
+ # Add standard og functionality to the class
116
+ #
117
+ def convert(klass)
118
+ klass.class_eval %{
119
+ DBTABLE = "#{Og::Utils.table(klass)}"
120
+ DBSEQ = "#{Og::Utils.table(klass)}_oids_seq"
121
+
122
+ def to_i()
123
+ @oid
124
+ end
125
+ }
126
+ end
127
+
128
+ # Enchant a managed class. Add useful DB related methods to the
129
+ # class and its instances.
130
+ #
131
+ def enchant(klass)
132
+ klass.class_eval %{
133
+ def self.save(obj)
134
+ $og << obj
135
+ end
136
+
137
+ def self.load(oid_or_name)
138
+ $og.load(oid_or_name, #{klass})
139
+ end
140
+
141
+ def self.[](oid_or_name)
142
+ $og.load(oid_or_name, #{klass})
143
+ end
144
+
145
+ def self.load_all(extra_sql = nil)
146
+ $og.load_all(#{klass}, extra_sql)
147
+ end
148
+
149
+ def self.all(extra_sql = nil)
150
+ $og.load_all(#{klass}, extra_sql)
151
+ end
152
+
153
+ def self.count(sql = "SELECT COUNT(*) FROM #{klass::DBTABLE}")
154
+ $og.count(sql, #{klass})
155
+ end
156
+
157
+ def self.select(sql)
158
+ $og.select(sql, #{klass})
159
+ end
160
+
161
+ def self.select_one(sql)
162
+ $og.select_one(sql, #{klass})
163
+ end
164
+
165
+ def self.delete(obj_or_oid)
166
+ $og.delete(obj_or_oid, #{klass})
167
+ end
168
+
169
+ def save
170
+ $og << self
171
+ return self
172
+ end
173
+ alias_method :save!, :save
174
+
175
+ def update_properties(updatesql)
176
+ $og.pupdate(updatesql, self.oid, #{klass})
177
+ end
178
+ alias_method :pupdate!, :update_properties
179
+
180
+ def delete!
181
+ $og.delete(@oid, #{klass})
182
+ end
183
+ }
184
+ end
185
+
186
+ # Automatically wrap connection methods.
187
+ #
188
+ def self.wrap_method(method, args)
189
+ args = args.split(/,/)
190
+ class_eval %{
191
+ def #{method}(#{args.join(", ")})
192
+ # nop
193
+ end
194
+ }
195
+ end
196
+ =begin
197
+ wrap_method :create_table, "klass"
198
+ wrap_method :drop_table, "klass"
199
+ wrap_method :save, "obj"; alias_method :<<, :save; alias_method :put, :save
200
+ wrap_method :insert, "obj"
201
+ wrap_method :update, "obj"
202
+ wrap_method :update_properties, "update_sql, obj_or_oid, klass = nil"
203
+ wrap_method :pupdate, "update_sql, obj_or_oid, klass = nil"
204
+ wrap_method :load, "oid, klass"; alias_method :get, :load
205
+ wrap_method :load_by_oid, "oid, klass"
206
+ wrap_method :load_by_name, "name, klass"
207
+ wrap_method :load_all, "klass, extrasql = nil"
208
+ wrap_method :select, "sql, klass"
209
+ wrap_method :select_one, "sql, klass"
210
+ wrap_method :count, "sql, klass = nil"
211
+ wrap_method :delete, "obj_or_oid, klass = nil"
212
+ wrap_method :query, "sql"
213
+ wrap_method :exec, "sql"
214
+ =end
215
+ def self.create_db!(config)
216
+ end
217
+
218
+ def self.drop_db!(config)
219
+ end
220
+ end
221
+
222
+ end # module
223
+