nitro 0.10.0 → 0.11.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 (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?