nitro 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/AUTHORS +4 -1
  2. data/ChangeLog +290 -7
  3. data/README +3 -3
  4. data/RELEASES +94 -0
  5. data/Rakefile +7 -7
  6. data/benchmark/og/bench.rb +11 -10
  7. data/{ChangeLog.1 → doc/ChangeLog.1} +0 -0
  8. data/doc/apache.txt +9 -0
  9. data/doc/architecture.txt +1 -27
  10. data/doc/bugs.txt +11 -4
  11. data/doc/config.txt +22 -0
  12. data/doc/og_config.txt +35 -0
  13. data/doc/og_tutorial.txt +595 -0
  14. data/doc/tutorial.txt +22 -0
  15. data/examples/blog/conf/apache.conf +30 -0
  16. data/examples/blog/conf/lhttpd.conf +2 -2
  17. data/examples/blog/lib/blog/controller.rb +11 -2
  18. data/examples/blog/log/apache.error_log +5528 -0
  19. data/examples/blog/root/fcgi.rb +1 -1
  20. data/examples/blog/run.rb +9 -3
  21. data/examples/flash/run.rb +2 -2
  22. data/examples/no_xsl_blog/conf/apache.conf +30 -0
  23. data/examples/no_xsl_blog/conf/lhttpd.conf +1 -1
  24. data/examples/no_xsl_blog/lib/blog/controller.rb +2 -2
  25. data/examples/no_xsl_blog/log/apache.error_log +68 -0
  26. data/examples/no_xsl_blog/root/fcgi.rb +2 -2
  27. data/examples/no_xsl_blog/run.rb +3 -3
  28. data/examples/og/run.rb +1 -1
  29. data/examples/tiny/conf/apache.conf +29 -4
  30. data/examples/tiny/conf/lhttpd.conf +1 -1
  31. data/examples/tiny/log/apache.error_log +30 -0
  32. data/examples/tiny/root/fcgi.rb +2 -2
  33. data/examples/tiny/root/index.xhtml +1 -1
  34. data/examples/tiny/run.rb +3 -2
  35. data/examples/wee_style/run.rb +7 -9
  36. data/examples/why_wiki/README +5 -0
  37. data/examples/why_wiki/run.rb +57 -0
  38. data/examples/why_wiki/wiki.yml +6 -0
  39. data/examples/wiki.yml +1 -0
  40. data/lib/glue/array.rb +14 -33
  41. data/lib/glue/hash.rb +32 -53
  42. data/lib/glue/pool.rb +9 -12
  43. data/lib/glue/property.rb +31 -9
  44. data/lib/nitro.rb +30 -8
  45. data/lib/nitro/adapters/cgi.rb +23 -3
  46. data/lib/nitro/adapters/webrick.rb +9 -3
  47. data/lib/nitro/builders/form.rb +21 -13
  48. data/lib/nitro/builders/rss.rb +20 -9
  49. data/lib/nitro/builders/table.rb +69 -10
  50. data/lib/nitro/builders/xhtml.rb +13 -4
  51. data/lib/nitro/component.rb +15 -0
  52. data/lib/nitro/conf.rb +4 -3
  53. data/lib/nitro/context.rb +22 -14
  54. data/lib/nitro/controller.rb +63 -5
  55. data/lib/nitro/dispatcher.rb +11 -6
  56. data/lib/nitro/output.rb +28 -0
  57. data/lib/nitro/render.rb +78 -59
  58. data/lib/nitro/request.rb +5 -1
  59. data/lib/nitro/runner.rb +20 -6
  60. data/lib/nitro/session.rb +89 -18
  61. data/lib/nitro/session/drb.rb +31 -0
  62. data/lib/nitro/session/drbserver.rb +71 -0
  63. data/lib/nitro/session/memory.rb +13 -0
  64. data/lib/nitro/simple.rb +7 -0
  65. data/lib/nitro/ui/date-select.rb +2 -5
  66. data/lib/nitro/ui/pager.rb +4 -4
  67. data/lib/nitro/ui/tabs.rb +2 -4
  68. data/lib/nitro/uri.rb +7 -4
  69. data/lib/og.rb +20 -12
  70. data/lib/og/adapter.rb +40 -13
  71. data/lib/og/adapters/filesys.rb +121 -0
  72. data/lib/og/adapters/mysql.rb +10 -5
  73. data/lib/og/adapters/oracle.rb +374 -0
  74. data/lib/og/adapters/psql.rb +10 -23
  75. data/lib/og/adapters/sqlite.rb +3 -3
  76. data/lib/og/backend.rb +2 -2
  77. data/lib/og/connection.rb +6 -6
  78. data/lib/og/database.rb +5 -5
  79. data/lib/og/enchant.rb +6 -2
  80. data/lib/og/meta.rb +56 -26
  81. data/lib/og/mock.rb +1 -1
  82. data/lib/og/typemacros.rb +23 -0
  83. data/lib/parts/content.rb +4 -10
  84. data/test/nitro/adapters/tc_cgi.rb +1 -1
  85. data/test/nitro/builders/tc_rss.rb +1 -1
  86. data/test/nitro/builders/tc_table.rb +30 -0
  87. data/test/nitro/tc_context.rb +4 -0
  88. data/test/nitro/tc_controller.rb +9 -2
  89. data/test/og/tc_filesys.rb +83 -0
  90. data/test/og/tc_meta.rb +55 -0
  91. data/test/tc_og.rb +115 -36
  92. data/vendor/README +11 -5
  93. data/vendor/breakpoint.rb +35 -38
  94. data/vendor/breakpoint_client.rb +119 -80
  95. data/vendor/composite_sexp_processor.rb +43 -0
  96. data/vendor/parse_tree.rb +745 -0
  97. data/vendor/sexp_processor.rb +453 -0
  98. metadata +34 -7
  99. data/examples/no_xsl_blog/conf/app.conf.rb +0 -47
@@ -1,22 +1,17 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: hash.rb 202 2005-01-17 10:44:13Z gmosx $
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: hash.rb 263 2005-02-23 13:45:08Z gmosx $
6
4
 
7
- require "sync"
5
+ require 'sync'
8
6
 
9
- module N;
7
+ module N
10
8
 
11
- # == SafeHash
12
- #
13
9
  # A thread-safe hash. We use a sync object instead of a mutex,
14
- # because it is re-entrant.
15
- # An exclusive lock is needed when writing, a shared lock IS NEEDED
16
- # when reading
10
+ # because it is re-entrant. An exclusive lock is needed when
11
+ # writing, a shared lock IS NEEDED when reading
17
12
  # uses the delegator pattern to allow for multiple
18
13
  # implementations!
19
- #
14
+
20
15
  class SafeHash < Hash
21
16
  attr :sync
22
17
 
@@ -27,63 +22,47 @@ class SafeHash < Hash
27
22
  end
28
23
 
29
24
  def [](key)
30
- return @sync.synchronize(::Sync::SH) {
31
- super
32
- }
25
+ @sync.synchronize(::Sync::SH) { super }
33
26
  end
34
27
 
35
28
  def []=(key, value)
36
- return @sync.synchronize(::Sync::EX) {
37
- super
38
- }
29
+ @sync.synchronize(::Sync::EX) { super }
39
30
  end
40
31
 
41
32
  def delete(key)
42
- return @sync.synchronize(::Sync::EX) {
43
- super
44
- }
33
+ @sync.synchronize(::Sync::EX) { super }
45
34
  end
46
35
 
47
36
  def clear
48
- @sync.synchronize(::Sync::EX) {
49
- super
50
- }
37
+ @sync.synchronize(::Sync::EX) { super }
51
38
  end
52
39
 
53
40
  def size
54
- return @sync.synchronize(::Sync::SH) {
55
- super
56
- }
41
+ @sync.synchronize(::Sync::SH) { super }
57
42
  end
58
43
 
59
44
  def values
60
- return @sync.synchronize(::Sync::SH) {
61
- super
62
- }
45
+ @sync.synchronize(::Sync::SH) { super }
63
46
  end
64
47
 
65
48
  def keys
66
- return @sync.synchronize(::Sync::SH) {
67
- super
68
- }
49
+ @sync.synchronize(::Sync::SH) { super }
69
50
  end
70
51
 
71
- end # SafeHash
52
+ end
72
53
 
73
- # == SafeHashDelegator
74
- #
75
54
  # A thread-safe hash. We use a sync object instead of a mutex,
76
- # because it is re-entrant.
77
- # An exclusive lock is needed when writing, a shared lock IS NEEDED
78
- # when reading
55
+ # because it is re-entrant. An exclusive lock is needed when
56
+ # writing, a shared lock IS NEEDED when reading.
57
+ #
58
+ # === Design
79
59
  #
80
- # Design:
81
60
  # This class uses the delegator pattern. However we dont use rubys
82
61
  # delegation facilities, they are more general and powerfull than we
83
62
  # need here (and slower). Instead a custom (but simple) solution is
84
63
  # used.
85
64
  #
86
- # Example:
65
+ # === Example
87
66
  #
88
67
  # hash = SafeHashDelegator.new(Hash.new)
89
68
  # hash = SafeHashDelegator.new(Hash.new)
@@ -96,20 +75,20 @@ class SafeHashDelegator < Hash
96
75
  @sync = ::Sync.new
97
76
  end
98
77
 
99
- def [](key)
100
- return @sync.synchronize(::Sync::SH) {
78
+ def [](key)
79
+ @sync.synchronize(::Sync::SH) {
101
80
  @delegate[key]
102
81
  }
103
- end
82
+ end
104
83
 
105
- def []=(key, value)
106
- return @sync.synchronize(::Sync::EX) {
84
+ def []=(key, value)
85
+ @sync.synchronize(::Sync::EX) {
107
86
  @delegate[key] = value
108
87
  }
109
- end
88
+ end
110
89
 
111
90
  def delete(key)
112
- return @sync.synchronize(::Sync::EX) {
91
+ @sync.synchronize(::Sync::EX) {
113
92
  @delegate.delete(key)
114
93
  }
115
94
  end
@@ -121,23 +100,23 @@ class SafeHashDelegator < Hash
121
100
  end
122
101
 
123
102
  def size
124
- return @sync.synchronize(::Sync::SH) {
103
+ @sync.synchronize(::Sync::SH) {
125
104
  @delegate.size()
126
105
  }
127
106
  end
128
107
 
129
108
  def values
130
- return @sync.synchronize(::Sync::SH) {
109
+ @sync.synchronize(::Sync::SH) {
131
110
  @delegate.values()
132
111
  }
133
112
  end
134
113
 
135
114
  def keys
136
- return @sync.synchronize(::Sync::SH) {
115
+ @sync.synchronize(::Sync::SH) {
137
116
  @delegate.keys()
138
117
  }
139
118
  end
140
119
 
141
- end # SafeHashDelegator
120
+ end
142
121
 
143
- end # module
122
+ end
@@ -1,21 +1,17 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: pool.rb 202 2005-01-17 10:44:13Z gmosx $
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: pool.rb 266 2005-02-28 14:50:48Z gmosx $
6
4
 
7
- require "thread"
8
- require "monitor"
5
+ require 'thread'
6
+ require 'monitor'
9
7
 
10
8
  module N
11
9
 
12
- # = Pool
13
- #
14
10
  # Generalized object pool implementation. Implemented as a thread
15
11
  # safe stack. Exclusive locking is needed both for push and pop.
16
12
  #
17
13
  # INVESTIGATE: Could use the SizedQueue/Queue.
18
- #
14
+
19
15
  class Pool < Array
20
16
  include MonitorMixin
21
17
 
@@ -25,7 +21,7 @@ class Pool < Array
25
21
  end
26
22
 
27
23
  # Add, restore an object to the pool.
28
- #
24
+
29
25
  def push(obj)
30
26
  synchronize do
31
27
  super
@@ -34,7 +30,7 @@ class Pool < Array
34
30
  end
35
31
 
36
32
  # Obtain an object from the pool.
37
- #
33
+
38
34
  def pop
39
35
  synchronize do
40
36
  @cv.wait_while { empty? }
@@ -44,6 +40,7 @@ class Pool < Array
44
40
 
45
41
  # Obtains an object, passes it to a block for processing
46
42
  # and restores it to the pool.
43
+
47
44
  def obtain
48
45
  result = nil
49
46
 
@@ -60,4 +57,4 @@ class Pool < Array
60
57
 
61
58
  end
62
59
 
63
- end # module
60
+ end
@@ -1,7 +1,7 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # * Michael Neumann <mneumann@ntecs.de>
3
3
  # (c) 2004-2005 Navel, all rights reserved.
4
- # $Id: property.rb 254 2005-02-10 12:44:05Z gmosx $
4
+ # $Id: property.rb 266 2005-02-28 14:50:48Z gmosx $
5
5
 
6
6
  require 'glue/attribute'
7
7
  require 'glue/array'
@@ -30,22 +30,35 @@ class Property
30
30
 
31
31
  cattr_accessor :type_checking, false
32
32
 
33
- # the symbol of the property
33
+ # The symbol of the property.
34
34
 
35
35
  attr_accessor :symbol
36
36
 
37
- # the string representation of the symbol
37
+ # The string representation of the symbol.
38
38
 
39
39
  attr_accessor :name
40
40
 
41
- # the class of the property
41
+ # The class of the property.
42
42
 
43
43
  attr_accessor :klass
44
-
45
- # additional metadata (like sql declaration, sql index, etc)
44
+
45
+ # Additional metadata (like sql declaration, sql index, etc)
46
+ # Here is a list of predefined metadata:
47
+ #
48
+ # [+:reader+]
49
+ # create reader?
50
+ #
51
+ # [+:writer+]
52
+ # create writer?
53
+ #
54
+ # [+:sql_index+]
55
+ # create an sql index for the column this poperty maps to?
56
+ #
57
+ # You can use this mechanism to add your own, custom,
58
+ # metadata.
46
59
 
47
60
  attr_accessor :meta
48
-
61
+
49
62
  def initialize(symbol, klass, meta = {})
50
63
  @symbol, @klass = symbol, klass
51
64
  @meta = meta
@@ -124,6 +137,11 @@ module PropertyUtils
124
137
  else
125
138
  target.__props << prop
126
139
  end
140
+
141
+ # Store the property in the :props_and_relations
142
+ # metadata array.
143
+
144
+ target.meta :props_and_relations, prop
127
145
 
128
146
  # Precompile the property read/write methods
129
147
 
@@ -366,7 +384,7 @@ class Module
366
384
  prop(klass, symbol, meta)
367
385
  end
368
386
  end
369
-
387
+ alias_method :property, :prop_accessor
370
388
 
371
389
  # Attach metadata.
372
390
  # Guard against duplicates, no need to keep order.
@@ -375,7 +393,11 @@ class Module
375
393
  # gmosx: crappy implementation, recode.
376
394
  #++
377
395
 
378
- def meta(key, val)
396
+ def meta(key, *val)
397
+ val = val.first if val.size == 1
398
+
399
+ N::PropertyUtils.enchant(self)
400
+
379
401
  self.module_eval %{
380
402
  @@__meta[key] ||= []
381
403
  @@__meta[key].delete_if { |v| val == v }
@@ -12,17 +12,11 @@
12
12
  #
13
13
  # * George Moschovitis <gm@navel.gr>
14
14
  # (c) 2004-2005 Navel, all rights reserved.
15
- # $Id: nitro.rb 259 2005-02-15 08:54:54Z gmosx $
15
+ # $Id: nitro.rb 266 2005-02-28 14:50:48Z gmosx $
16
16
 
17
17
  require 'glue'
18
18
  require 'glue/logger'
19
19
 
20
- require 'nitro/context'
21
- require 'nitro/dispatcher'
22
- require 'nitro/render'
23
- require 'nitro/conf'
24
- require 'nitro/runner'
25
-
26
20
  # Define Nitro namespace.
27
21
 
28
22
  module Nitro
@@ -33,10 +27,38 @@ module Nitro
33
27
 
34
28
  # The version.
35
29
 
36
- Version = '0.10.0'
30
+ Version = '0.11.0'
37
31
 
38
32
  # Library path.
39
33
 
40
34
  LibPath = File.dirname(__FILE__)
41
35
 
36
+ # If set to true, action methods can have arguments which are
37
+ # automatically resolved.
38
+ #
39
+ # === Example
40
+ #
41
+ # def list(username, oid)
42
+ # ...
43
+ # end
44
+ #
45
+ # http://www.mysite.com/list?username=tml;oid=2
46
+ #
47
+ # calls list() with the correct parameters, no need to
48
+ # use request['oid'], just use oid.
49
+ #
50
+ # WARNING: this feature requires the ParseTree library which
51
+ # is not compatible with Windows.
52
+
53
+ mattr_accessor :resolve_action_arguments, false
54
+
42
55
  end
56
+
57
+ # gmosx: leave them here.
58
+
59
+ require 'nitro/context'
60
+ require 'nitro/dispatcher'
61
+ require 'nitro/render'
62
+ require 'nitro/conf'
63
+ require 'nitro/runner'
64
+ require 'nitro/component'
@@ -140,11 +140,26 @@ class CgiUtils
140
140
  end
141
141
 
142
142
  # Build the response headers for the context.
143
+ #
144
+ # [+context+]
145
+ # The context of the response.
146
+ #
147
+ # [+proto+]
148
+ # If true emmit the protocol line. Useful for MOD_RUBY.
149
+ #--
150
+ # FIXME: return the correct protocol from env.
151
+ # TODO: Perhaps I can optimize status calc.
152
+ #++
143
153
 
144
- def self.response_headers(context)
154
+ def self.response_headers(context, proto = false)
145
155
  reason = STATUS_STRINGS[context.status]
146
- buf = "HTTP/1.1 #{context.status} #{reason} #{EOL}"
147
-
156
+
157
+ if proto
158
+ buf = "HTTP/1.1 #{context.status} #{reason}#{EOL}Date: #{CGI::rfc1123_date(Time.now)}#{EOL}"
159
+ else
160
+ buf = "Status: #{context.status} #{reason}#{EOL}"
161
+ end
162
+
148
163
  context.response_headers.each do |key, value|
149
164
  tmp = key.gsub(/\bwww|^te$|\b\w/) { |s| s.upcase }
150
165
  buf << "#{tmp}: #{value}" << EOL
@@ -155,6 +170,8 @@ class CgiUtils
155
170
  end if context.response_cookies
156
171
 
157
172
  buf << EOL
173
+
174
+ return buf
158
175
  end
159
176
 
160
177
  # Initialize the request params.
@@ -184,6 +201,9 @@ class CgiUtils
184
201
  end
185
202
 
186
203
  # Parse a multipart request.
204
+ #--
205
+ # FIXME: implement me, not working
206
+ #++
187
207
 
188
208
  def self.parse_multipart(context, boundary)
189
209
  io = context.in
@@ -33,7 +33,7 @@ class Webrick
33
33
  attr_accessor :server
34
34
 
35
35
  def start(conf)
36
- conf = Flexob.new(conf) unless conf.is_a?(Flexob)
36
+ conf = Conf.new(conf) unless conf.is_a?(Conf)
37
37
 
38
38
  # patch for OSX
39
39
 
@@ -49,7 +49,7 @@ class Webrick
49
49
  accesslog = STDERR
50
50
  refererlog = STDERR
51
51
  end
52
-
52
+
53
53
  @server = WEBrick::HTTPServer.new(
54
54
  :BindAddress => conf.host,
55
55
  :Port => conf.port,
@@ -70,6 +70,10 @@ class Webrick
70
70
  end
71
71
 
72
72
  # A Webrick Adapter for Nitro.
73
+ #--
74
+ # TODO: optimize the conversion from WEBrick's
75
+ # parameters to the Nitro parameters.
76
+ #++
73
77
 
74
78
  class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
75
79
 
@@ -107,11 +111,13 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
107
111
  req.cookies.each { |c| context.cookies[c.name] = c.value }
108
112
 
109
113
  context.render(path)
110
-
114
+
111
115
  res.status = context.status
112
116
  res.header = context.response_headers || {}
113
117
  res.cookies = context.response_cookies || {}
114
118
  res.body = context.out
119
+
120
+ context.close
115
121
  end
116
122
  ensure
117
123
  # REQUEST_MUTEX.unlock if REQUEST_MUTEX.locked?