nitro 0.9.5 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +260 -0
- data/INSTALL +60 -0
- data/LICENSE +1 -0
- data/README +19 -20
- data/RELEASES +48 -0
- data/Rakefile +102 -92
- data/benchmark/og/bench.rb +74 -0
- data/benchmark/og/sqlite-no-prepare.1.txt +13 -0
- data/benchmark/og/sqlite-no-prepare.2.txt +13 -0
- data/benchmark/og/sqlite-prepare.1.txt +13 -0
- data/benchmark/og/sqlite-prepare.2.txt +13 -0
- data/bin/cluster +1 -1
- data/bin/nitro +3 -0
- data/bin/proto/conf/app.conf.rb +2 -10
- data/examples/README.windows +9 -0
- data/examples/blog/README +16 -4
- data/examples/blog/lib/blog.rb +3 -3
- data/examples/blog/lib/blog/controller.rb +7 -9
- data/examples/blog/root/fcgi.rb +2 -4
- data/examples/blog/root/style.xsl +4 -6
- data/examples/blog/run.rb +41 -0
- data/examples/flash/run.rb +9 -0
- data/examples/no_xsl_blog/README +0 -1
- data/examples/no_xsl_blog/conf/app.conf.rb +6 -13
- data/examples/no_xsl_blog/lib/blog.rb +2 -2
- data/examples/no_xsl_blog/lib/blog/controller.rb +6 -6
- data/examples/no_xsl_blog/root/fcgi.rb +2 -4
- data/examples/no_xsl_blog/run.rb +38 -0
- data/examples/og/mock_example.rb +0 -2
- data/examples/og/mysql_to_psql.rb +0 -2
- data/examples/og/run.rb +23 -22
- data/examples/tiny/root/fcgi.rb +2 -4
- data/examples/tiny/root/index.xhtml +21 -5
- data/examples/tiny/root/upload.xhtml +23 -0
- data/examples/tiny/run.rb +9 -0
- data/examples/wee_style/{wee.rb → run.rb} +13 -13
- data/install.rb +44 -0
- data/lib/glue/array.rb +6 -10
- data/lib/glue/attribute.rb +0 -3
- data/lib/glue/cache.rb +1 -1
- data/lib/glue/inflector.rb +5 -5
- data/lib/glue/mixins.rb +3 -12
- data/lib/glue/number.rb +1 -1
- data/lib/glue/object.rb +7 -1
- data/lib/glue/property.rb +32 -22
- data/lib/glue/string.rb +13 -75
- data/lib/glue/time.rb +2 -2
- data/lib/glue/validation.rb +7 -11
- data/lib/nitro.rb +16 -1
- data/lib/nitro/{adaptors → adapters}/cgi.rb +101 -20
- data/lib/nitro/{adaptors → adapters}/fastcgi.rb +3 -2
- data/lib/nitro/{adaptors → adapters}/webrick.rb +4 -4
- data/lib/nitro/builders/rss.rb +1 -1
- data/lib/nitro/builders/xml.rb +8 -10
- data/lib/nitro/cluster.rb +1 -1
- data/lib/nitro/conf.rb +34 -0
- data/lib/nitro/controller.rb +8 -9
- data/lib/nitro/dispatcher.rb +38 -11
- data/lib/nitro/filters.rb +1 -1
- data/lib/nitro/markup.rb +14 -1
- data/lib/nitro/render.rb +7 -10
- data/lib/nitro/runner.rb +232 -0
- data/lib/nitro/ui/pager.rb +2 -6
- data/lib/nitro/uri.rb +7 -11
- data/lib/og.rb +27 -261
- data/lib/og/adapter.rb +352 -0
- data/lib/og/adapters/mysql.rb +304 -0
- data/lib/og/adapters/psql.rb +286 -0
- data/lib/og/adapters/sqlite.rb +262 -0
- data/lib/og/backend.rb +1 -1
- data/lib/og/connection.rb +123 -87
- data/lib/og/database.rb +268 -0
- data/lib/og/meta.rb +23 -22
- data/lib/og/mock.rb +2 -3
- data/lib/xsl/base.xsl +1 -55
- data/test/glue/tc_property.rb +2 -0
- data/test/glue/tc_property_type_checking.rb +32 -0
- data/test/glue/tc_strings.rb +2 -2
- data/test/glue/tc_validation.rb +2 -0
- data/test/nitro/adapters/raw_post1.bin +0 -0
- data/test/nitro/{adaptors → adapters}/tc_cgi.rb +11 -2
- data/test/nitro/{adaptors → adapters}/tc_webrick.rb +3 -3
- data/test/nitro/builders/tc_xml.rb +14 -5
- data/test/nitro/tc_dispatcher.rb +3 -3
- data/test/nitro/tc_uri.rb +2 -4
- data/test/og/tc_lifecycle.rb +22 -25
- data/test/og/tc_sqlite.rb +87 -0
- data/test/tc_og.rb +61 -42
- metadata +67 -33
- data/examples/blog/conf/app.conf.rb +0 -52
- data/examples/blog/ctl +0 -4
- data/examples/flash/conf/app.conf.rb +0 -21
- data/examples/flash/ctl +0 -4
- data/examples/no_xsl_blog/conf/apache.conf +0 -0
- data/examples/no_xsl_blog/ctl +0 -4
- data/examples/tiny/conf/app.conf.rb +0 -17
- data/examples/tiny/ctl +0 -4
- data/lib/glue/macro.rb +0 -56
- data/lib/nitro/adaptors/runner.rb +0 -123
- data/lib/nitro/version.rb +0 -15
- data/lib/og/backends/mysql.rb +0 -370
- data/lib/og/backends/psql.rb +0 -386
- data/lib/og/backends/sqlite.rb +0 -383
- data/lib/og/version.rb +0 -9
data/lib/nitro/controller.rb
CHANGED
@@ -21,14 +21,7 @@ class Controller
|
|
21
21
|
|
22
22
|
def method_missing(action, *args)
|
23
23
|
if Rendering.compile_action(self.class, action, @base)
|
24
|
-
|
25
|
-
if :partial == Rendering.reload
|
26
|
-
ret = send(action, *args)
|
27
|
-
self.class.class_eval("remove_method :#{action}") # if $DBG
|
28
|
-
return ret
|
29
|
-
else
|
30
|
-
send(action, *args)
|
31
|
-
end
|
24
|
+
send(action, *args)
|
32
25
|
else
|
33
26
|
super
|
34
27
|
end
|
@@ -39,7 +32,7 @@ class Controller
|
|
39
32
|
|
40
33
|
def inherited(subclass)
|
41
34
|
subclass.class_eval %{
|
42
|
-
DEF_FILE = caller.
|
35
|
+
DEF_FILE = caller[2].split(':').first
|
43
36
|
}
|
44
37
|
__old_inherited(subclass)
|
45
38
|
end
|
@@ -47,4 +40,10 @@ class Controller
|
|
47
40
|
|
48
41
|
end
|
49
42
|
|
43
|
+
# A simple controller, only handles templates.
|
44
|
+
# Useful to implement php/asp/jsp style applications.
|
45
|
+
|
46
|
+
class SimpleController < Controller
|
47
|
+
end
|
48
|
+
|
50
49
|
end
|
data/lib/nitro/dispatcher.rb
CHANGED
@@ -28,7 +28,7 @@ class Dispatcher
|
|
28
28
|
#
|
29
29
|
# [+controllers+]
|
30
30
|
# Either a hash of controller mappings or a single
|
31
|
-
# controller that gets mapped to :
|
31
|
+
# controller that gets mapped to :root.
|
32
32
|
#
|
33
33
|
# [+apis+]
|
34
34
|
# A hash of apis supported by the Dispatcher.
|
@@ -37,9 +37,9 @@ class Dispatcher
|
|
37
37
|
@root = 'root'
|
38
38
|
|
39
39
|
if controllers and controllers.is_a?(Class) and controllers.ancestors.include?(Controller)
|
40
|
-
@controllers = { :
|
40
|
+
@controllers = { :root => controllers }
|
41
41
|
else
|
42
|
-
@controllers = controllers || { :
|
42
|
+
@controllers = controllers || { :root => SimpleController }
|
43
43
|
end
|
44
44
|
|
45
45
|
@apis = apis
|
@@ -57,7 +57,7 @@ class Dispatcher
|
|
57
57
|
# === Examples
|
58
58
|
#
|
59
59
|
# dispatcher.mount {
|
60
|
-
# :
|
60
|
+
# :root => MainController # mounts /
|
61
61
|
# 'users' => UsersController # mounts /users
|
62
62
|
# }
|
63
63
|
|
@@ -79,8 +79,14 @@ class Dispatcher
|
|
79
79
|
# Processes the path and dispatches to the corresponding
|
80
80
|
# controller/action pair.
|
81
81
|
# The base returned contains a trailing '/'.
|
82
|
+
#
|
83
|
+
# [+path+]
|
84
|
+
# The path to dispatch.
|
85
|
+
#
|
86
|
+
# [:context]
|
87
|
+
# The dispatching context.
|
82
88
|
|
83
|
-
def dispatch(path)
|
89
|
+
def dispatch(path, context)
|
84
90
|
api = :xhtml
|
85
91
|
|
86
92
|
if @apis
|
@@ -91,32 +97,53 @@ class Dispatcher
|
|
91
97
|
|
92
98
|
case parts.size
|
93
99
|
when 0
|
100
|
+
# / -> root.index
|
94
101
|
base = @root
|
95
|
-
|
102
|
+
klass = controller_class_for(:root, context)
|
96
103
|
action = 'index'
|
97
104
|
|
98
105
|
when 2
|
99
|
-
if
|
106
|
+
if klass = controller_class_for(parts[1], context)
|
107
|
+
# controller/ -> controller.index
|
100
108
|
base = "#{@root}/#{parts[1]}"
|
101
109
|
action = 'index'
|
102
110
|
else
|
111
|
+
# action/ -> root.action
|
103
112
|
base = @root
|
104
|
-
|
113
|
+
klass = controller_class_for(:root, context)
|
105
114
|
action = parts[1]
|
106
115
|
end
|
107
116
|
|
108
117
|
when 3
|
118
|
+
# controller/action/ -> controller.action
|
109
119
|
base = "#{@root}/#{parts[1]}"
|
110
|
-
|
120
|
+
klass = controller_class_for(parts[1], context)
|
111
121
|
action = parts[2]
|
112
122
|
end
|
113
123
|
|
114
124
|
content_type = @apis ? @apis[:api] : 'text/html'
|
115
125
|
|
116
|
-
return
|
126
|
+
return klass, "__#{api}__#{action}", base, content_type
|
117
127
|
end
|
118
128
|
alias_method :split_path, :dispatch
|
119
|
-
|
129
|
+
|
130
|
+
# Get the controller for the given key.
|
131
|
+
# Also handles reloading of controllers.
|
132
|
+
|
133
|
+
def controller_class_for(key, context)
|
134
|
+
klass = @controllers[key]
|
135
|
+
|
136
|
+
if context[:__RELOADED__].nil? and (:full == Rendering.reload) and klass
|
137
|
+
def_file = klass::DEF_FILE
|
138
|
+
Controller.remove_subclasses
|
139
|
+
load(def_file)
|
140
|
+
klass = @controllers[key] = Object.const_get(klass.name.intern)
|
141
|
+
context[:__RELOADED__] = true
|
142
|
+
end
|
143
|
+
|
144
|
+
return klass
|
145
|
+
end
|
146
|
+
|
120
147
|
end
|
121
148
|
|
122
149
|
end
|
data/lib/nitro/filters.rb
CHANGED
data/lib/nitro/markup.rb
CHANGED
@@ -20,8 +20,19 @@ module PropertyUtils
|
|
20
20
|
# if true, set to default Markup
|
21
21
|
markup = N::Markup if true == markup
|
22
22
|
|
23
|
-
|
23
|
+
code = %{
|
24
24
|
def #{s}=(val)
|
25
|
+
}
|
26
|
+
|
27
|
+
if N::Property.type_checking
|
28
|
+
code << %{
|
29
|
+
unless String == val.class
|
30
|
+
raise "Invalid type, expected '#{prop.klass}', is '\#\{val.class\}'."
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
code << %{
|
25
36
|
@#{s} = #{markup}.expand(val)
|
26
37
|
end
|
27
38
|
|
@@ -29,6 +40,8 @@ module PropertyUtils
|
|
29
40
|
#{markup}.compact(@#{s})
|
30
41
|
end
|
31
42
|
}
|
43
|
+
|
44
|
+
return code
|
32
45
|
else
|
33
46
|
return %{
|
34
47
|
def #{s}=(val)
|
data/lib/nitro/render.rb
CHANGED
@@ -53,7 +53,7 @@ module Rendering
|
|
53
53
|
# base/action.xhtml
|
54
54
|
|
55
55
|
path = "#{base}/#{action}.#{ext}".squeeze('/')
|
56
|
-
|
56
|
+
|
57
57
|
unless File.exist?(path)
|
58
58
|
|
59
59
|
# attempt to find a template of the form
|
@@ -178,8 +178,11 @@ module Render
|
|
178
178
|
attr_accessor :context
|
179
179
|
alias_method :ctx, :context
|
180
180
|
alias_method :ctx=, :context=
|
181
|
-
alias_method :request, :context
|
182
181
|
|
182
|
+
# Alias for context.
|
183
|
+
|
184
|
+
attr_accessor :request
|
185
|
+
|
183
186
|
# An array holding the rendering errors for this
|
184
187
|
# request.
|
185
188
|
|
@@ -191,7 +194,7 @@ module Render
|
|
191
194
|
# A parent render/controller acts as the context.
|
192
195
|
|
193
196
|
def initialize(context, base)
|
194
|
-
@context = context
|
197
|
+
@request = @context = context
|
195
198
|
@out = context.out
|
196
199
|
@base = base
|
197
200
|
end
|
@@ -203,14 +206,8 @@ module Render
|
|
203
206
|
def render(path)
|
204
207
|
Logger.debug "Rendering '#{path}'." if $DBG
|
205
208
|
|
206
|
-
klass, action, base, ctype = @context.dispatcher.dispatch(path)
|
209
|
+
klass, action, base, ctype = @context.dispatcher.dispatch(path, @context)
|
207
210
|
|
208
|
-
if :full == Rendering.reload
|
209
|
-
def_file = klass::DEF_FILE
|
210
|
-
Controller.remove_subclasses
|
211
|
-
load(def_file)
|
212
|
-
end
|
213
|
-
|
214
211
|
@context.content_type = ctype
|
215
212
|
|
216
213
|
raise 'No controller for action' unless klass
|
data/lib/nitro/runner.rb
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# * George Moschovitis <gm@navel.gr>
|
4
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
5
|
+
# $Id$
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
|
9
|
+
require 'nitro/conf'
|
10
|
+
|
11
|
+
module N
|
12
|
+
|
13
|
+
# The Runner is a helper class that encapsulates a web
|
14
|
+
# application and is responsible for launching the
|
15
|
+
# application in differnt modes.
|
16
|
+
#
|
17
|
+
# The runner provides default parsing of command line
|
18
|
+
# and environment parameters.
|
19
|
+
#
|
20
|
+
# The default execution modes are:
|
21
|
+
#
|
22
|
+
# :debug, :stage, :live
|
23
|
+
#
|
24
|
+
# You can implement your own, custom version of the Runner
|
25
|
+
# to run your custom web applications.
|
26
|
+
|
27
|
+
class Runner
|
28
|
+
|
29
|
+
# Execution mode = (:debug, :stage, :live)
|
30
|
+
#
|
31
|
+
# [:debug]
|
32
|
+
# useful when debugging, extra debug information
|
33
|
+
# is emmited, actions, templates and shaders are
|
34
|
+
# reloaded, etc. The execution speed of the application
|
35
|
+
# is impaired.
|
36
|
+
#
|
37
|
+
# [:stage]
|
38
|
+
# test the application with live parameters
|
39
|
+
# (typically on a staging server).
|
40
|
+
#
|
41
|
+
# [:live]
|
42
|
+
# use the parameters for the live (production)
|
43
|
+
# server. Optimized for speed.
|
44
|
+
#
|
45
|
+
# The default mode is :debug
|
46
|
+
|
47
|
+
attr_accessor :mode
|
48
|
+
|
49
|
+
# :start, :stop, :restart
|
50
|
+
|
51
|
+
attr_accessor :action
|
52
|
+
|
53
|
+
# The server used to run this web application.
|
54
|
+
# :webrick, :nitro, :lhttp, :apache, :mod_apache
|
55
|
+
#
|
56
|
+
# At the moment only :webrick and :lhttp are available.
|
57
|
+
|
58
|
+
attr_accessor :server
|
59
|
+
|
60
|
+
# Parse the command line arguments and the environment
|
61
|
+
# parameters to setup the application.
|
62
|
+
|
63
|
+
def setup
|
64
|
+
|
65
|
+
@mode = :debug
|
66
|
+
@action = :start
|
67
|
+
@server = :webrick
|
68
|
+
@daemon = false
|
69
|
+
|
70
|
+
parser = OptionParser.new do |opts|
|
71
|
+
|
72
|
+
opts.banner = 'Usage: run.rb [options]'
|
73
|
+
opts.separator ''
|
74
|
+
opts.separator 'Specific options:'
|
75
|
+
|
76
|
+
opts.on('-s', '--start', 'Start application.') do
|
77
|
+
@action = :start
|
78
|
+
end
|
79
|
+
|
80
|
+
opts.on('-S', '--stop', 'Stop application.') do
|
81
|
+
@action = :stop
|
82
|
+
end
|
83
|
+
|
84
|
+
opts.on('-r', '--restart', 'Restart application.') do
|
85
|
+
@action = :restart
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on('-d', '--daemon', 'Run application as a daemon.') do
|
89
|
+
@daemon = true
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on('-D', '--debug', 'Run application in debug mode.') do
|
93
|
+
@mode = :debug
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on('-T', '--stage', 'Run application in stage mode.') do
|
97
|
+
@mode = :stage
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on('-L', '--live', 'Run application in live mode.') do
|
101
|
+
@mode = :live
|
102
|
+
end
|
103
|
+
|
104
|
+
opts.on('-w', '--webrick', 'Use a webrick server [default].') do
|
105
|
+
@server = :webrick
|
106
|
+
end
|
107
|
+
|
108
|
+
opts.on('-l', '--lhttpd', 'Use a lighttpd server.') do
|
109
|
+
@server = :lhttpd
|
110
|
+
Logger.set(Logger.new('log/app.log'))
|
111
|
+
end
|
112
|
+
|
113
|
+
opts.on('-C', '--console', 'Start a console attached to an instance of the application.') do
|
114
|
+
if RUBY_PLATFORM =~ /mswin32/
|
115
|
+
irb_name = 'irb.bat'
|
116
|
+
else
|
117
|
+
irb_name = 'irb'
|
118
|
+
end
|
119
|
+
ENV['NITRO_INVOKE'] = 'irb'
|
120
|
+
conf_file = File.basename(caller.last.split(':').first)
|
121
|
+
exec "#{irb_name} -r #{conf_file} -r irb/completion --noinspect"
|
122
|
+
exit
|
123
|
+
end
|
124
|
+
|
125
|
+
opts.on('-l', '--lhttpd', 'Use a lighttpd server.') do
|
126
|
+
@server = :lhttpd
|
127
|
+
Logger.set(Logger.new('log/app.log'))
|
128
|
+
end
|
129
|
+
|
130
|
+
opts.on_tail('-v', '--version', 'Show version.') do
|
131
|
+
puts "Nitro #{Nitro::Version}"
|
132
|
+
exit
|
133
|
+
end
|
134
|
+
|
135
|
+
opts.on_tail('-h', '--help', 'Show this message.') do
|
136
|
+
puts opts
|
137
|
+
exit
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
parser.parse!(ARGV)
|
143
|
+
|
144
|
+
return self
|
145
|
+
end
|
146
|
+
|
147
|
+
# Run the application in the declared execution mode,
|
148
|
+
# using the passed configuration parameters.
|
149
|
+
|
150
|
+
def run(conf)
|
151
|
+
|
152
|
+
if conf.is_a?(Hash)
|
153
|
+
conf = Conf.new(conf)
|
154
|
+
end
|
155
|
+
|
156
|
+
case @mode
|
157
|
+
when :debug
|
158
|
+
setup_debug(conf)
|
159
|
+
|
160
|
+
when :stage
|
161
|
+
setup_stage(conf)
|
162
|
+
|
163
|
+
when :live
|
164
|
+
setup_live(conf)
|
165
|
+
end
|
166
|
+
|
167
|
+
if 'fcgi_proc' == ENV['NITRO_INVOKE']
|
168
|
+
invoke_fcgi_proc(conf)
|
169
|
+
elsif 'irb' == ENV['NITRO_INVOKE']
|
170
|
+
invoke_irb(conf)
|
171
|
+
else
|
172
|
+
invoke_server(conf)
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
def setup_debug(conf)
|
178
|
+
$DBG = true
|
179
|
+
Rendering.reload = :full
|
180
|
+
end
|
181
|
+
|
182
|
+
def setup_stage(conf)
|
183
|
+
$DBG = false
|
184
|
+
Rendering.reload = false
|
185
|
+
Logger.set(Logger.new('log/app.log'))
|
186
|
+
end
|
187
|
+
|
188
|
+
def setup_live(conf)
|
189
|
+
$DBG = false
|
190
|
+
Rendering.reload = false
|
191
|
+
Logger.set(Logger.new('log/app.log'))
|
192
|
+
end
|
193
|
+
alias_method :setup_production, :setup_live
|
194
|
+
|
195
|
+
def invoke_fcgi_proc(conf)
|
196
|
+
require 'nitro/adapters/fastcgi'
|
197
|
+
FastCGI.start(conf)
|
198
|
+
end
|
199
|
+
|
200
|
+
def invoke_irb(conf)
|
201
|
+
$conf = conf
|
202
|
+
end
|
203
|
+
|
204
|
+
def invoke_server(conf)
|
205
|
+
case @action
|
206
|
+
when :start
|
207
|
+
|
208
|
+
case @server
|
209
|
+
|
210
|
+
when :webrick
|
211
|
+
require 'nitro/adapters/webrick'
|
212
|
+
Webrick.start(conf)
|
213
|
+
|
214
|
+
when :lhttpd
|
215
|
+
require 'nitro/adapters/fastcgi'
|
216
|
+
`lighttpd -f conf/lhttpd.conf`
|
217
|
+
end
|
218
|
+
|
219
|
+
when :stop
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Helper method.
|
225
|
+
|
226
|
+
def self.run(conf)
|
227
|
+
runner = Runner.new.setup.run(conf)
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|