nitro 0.3.0 → 0.4.1
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.
- data/ChangeLog +284 -0
- data/{LICENCE → LICENSE} +1 -1
- data/README +13 -17
- data/RELEASES +13 -1
- data/Rakefile +1 -9
- data/bin/cluster.rb +5 -5
- data/examples/blog/README +45 -0
- data/examples/blog/apache.conf +0 -0
- data/examples/blog/app.rb +21 -0
- data/examples/blog/config.rb +88 -0
- data/examples/blog/lib/blog.rb +104 -0
- data/examples/blog/log/app.log +117 -0
- data/examples/blog/root/comments.xhtml +38 -0
- data/examples/blog/root/entry_form.xhtml +18 -0
- data/examples/blog/root/index.xhtml +43 -0
- data/examples/blog/root/login.xhtml +24 -0
- data/examples/blog/root/m/bubbles.gif +0 -0
- data/examples/blog/root/m/comments_curve.gif +0 -0
- data/examples/blog/root/m/down.gif +0 -0
- data/examples/blog/root/m/footer_bg.gif +0 -0
- data/examples/blog/root/m/garrow.gif +0 -0
- data/examples/blog/root/m/gbull.gif +0 -0
- data/examples/blog/root/m/grbull.gif +0 -0
- data/examples/blog/root/m/h1_bg.gif +0 -0
- data/examples/blog/root/m/header_bg.gif +0 -0
- data/examples/blog/root/m/obull.gif +0 -0
- data/examples/blog/root/m/page_bg.gif +0 -0
- data/examples/blog/root/m/side_title_bg.gif +0 -0
- data/examples/blog/root/m/sidebar_bg.gif +0 -0
- data/examples/blog/root/recent_posts.xhtml +14 -0
- data/examples/blog/root/style.css +201 -0
- data/examples/blog/root/style.xsl +118 -0
- data/examples/blog/root/view_entry.xhtml +29 -0
- data/examples/og/run.rb +27 -29
- data/examples/tiny/README +3 -4
- data/examples/tiny/app.rb +6 -16
- data/examples/tiny/config.rb +30 -0
- data/examples/tiny/log/app.log +23 -0
- data/examples/tiny/root/{index.sx → index.xhtml} +3 -6
- data/lib/{n/std.rb → nitro.rb} +9 -4
- data/lib/{n → nitro}/application.rb +13 -7
- data/lib/{n → nitro}/config.rb +38 -8
- data/lib/{n → nitro}/events.rb +1 -1
- data/lib/{n → nitro}/l10n.rb +1 -1
- data/lib/{n → nitro}/logger.rb +8 -8
- data/lib/{n → nitro}/macros.rb +3 -3
- data/lib/{n → nitro}/mixins.rb +1 -1
- data/lib/nitro/properties.rb +301 -0
- data/lib/{n → nitro}/server.rb +2 -2
- data/lib/{n → nitro}/server/appserver.rb +14 -5
- data/lib/{n → nitro}/server/cluster.rb +5 -5
- data/lib/{n → nitro}/server/cookie.rb +1 -1
- data/lib/nitro/server/dispatcher.rb +66 -0
- data/lib/{n → nitro}/server/filters.rb +7 -7
- data/lib/{n → nitro}/server/filters/autologin.rb +3 -3
- data/lib/{n → nitro}/server/fragment.rb +3 -3
- data/lib/{n → nitro}/server/handlers.rb +3 -3
- data/lib/nitro/server/render.rb +200 -0
- data/lib/{n → nitro}/server/request.rb +6 -6
- data/lib/{n → nitro}/server/requestpart.rb +5 -5
- data/lib/{n → nitro}/server/script.rb +3 -3
- data/lib/{n → nitro}/server/server.rb +4 -4
- data/lib/{n → nitro}/server/session.rb +3 -3
- data/lib/nitro/server/shaders.rb +165 -0
- data/lib/{n → nitro}/server/user.rb +1 -1
- data/lib/nitro/server/webrick.rb +175 -0
- data/lib/nitro/service.rb +25 -0
- data/lib/{n → nitro}/sitemap.rb +2 -2
- data/lib/{n → nitro}/ui/date-select.rb +0 -0
- data/lib/{n → nitro}/ui/pager.rb +1 -1
- data/lib/{n → nitro}/ui/popup.rb +1 -1
- data/lib/{n → nitro}/ui/select.rb +1 -1
- data/lib/{n → nitro}/ui/tabs.rb +1 -1
- data/lib/{n → nitro}/utils/array.rb +1 -1
- data/lib/{n → nitro}/utils/cache.rb +1 -1
- data/lib/{n → nitro}/utils/gfx.rb +1 -1
- data/lib/{n → nitro}/utils/hash.rb +1 -1
- data/lib/{n → nitro}/utils/html.rb +1 -1
- data/lib/{n → nitro}/utils/http.rb +1 -1
- data/lib/{n → nitro}/utils/mail.rb +1 -1
- data/lib/{n → nitro}/utils/number.rb +1 -1
- data/lib/{n → nitro}/utils/pool.rb +1 -1
- data/lib/{n → nitro}/utils/string.rb +19 -95
- data/lib/{n → nitro}/utils/template.rb +0 -0
- data/lib/{n → nitro}/utils/time.rb +1 -1
- data/lib/{n → nitro}/utils/uri.rb +3 -3
- data/lib/nitro/version.rb +11 -0
- data/lib/{n/og.rb → og.rb} +61 -31
- data/lib/{n/og → og}/backend.rb +13 -7
- data/lib/{n/og → og}/backends/mysql.rb +43 -39
- data/lib/{n/og → og}/backends/psql.rb +42 -38
- data/lib/{n/og → og}/connection.rb +21 -9
- data/lib/{n/og → og}/meta.rb +18 -12
- data/lib/xsl/base.xsl +11 -88
- data/test/n/server/tc_cookie.rb +1 -1
- data/test/n/server/tc_filters.rb +1 -1
- data/test/n/server/tc_request.rb +3 -3
- data/test/n/server/tc_requestpart.rb +2 -2
- data/test/n/server/tc_session.rb +1 -1
- data/test/n/tc_events.rb +1 -1
- data/test/n/tc_og.rb +16 -18
- data/test/n/tc_properties.rb +22 -18
- data/test/n/tc_sitemap.rb +2 -2
- data/test/n/ui/tc_pager.rb +4 -4
- data/test/n/utils/tc_cache.rb +1 -1
- data/test/n/utils/tc_hash.rb +1 -1
- data/test/n/utils/tc_html.rb +1 -1
- data/test/n/utils/tc_http.rb +1 -1
- data/test/n/utils/tc_number.rb +1 -1
- data/test/n/utils/tc_strings.rb +1 -46
- data/test/n/utils/tc_uri.rb +1 -1
- metadata +101 -108
- data/examples/simple/README +0 -42
- data/examples/simple/app.rb +0 -31
- data/examples/simple/conf/apache.conf +0 -100
- data/examples/simple/conf/config.rb +0 -72
- data/examples/simple/conf/debug-config.rb +0 -26
- data/examples/simple/conf/live-config.rb +0 -26
- data/examples/simple/conf/requires.rb +0 -43
- data/examples/simple/ctl +0 -32
- data/examples/simple/env.rb +0 -32
- data/examples/simple/install.rb +0 -12
- data/examples/simple/lib/articles/entities.rb +0 -37
- data/examples/simple/lib/articles/lc-en.rb +0 -36
- data/examples/simple/lib/articles/methods.rb +0 -55
- data/examples/simple/lib/articles/part.rb +0 -57
- data/examples/simple/root/add-article.sx +0 -15
- data/examples/simple/root/article-form.ss +0 -20
- data/examples/simple/root/comments-form.ss +0 -16
- data/examples/simple/root/comments.si +0 -30
- data/examples/simple/root/index.sx +0 -44
- data/examples/simple/root/shader/shader.xsl +0 -100
- data/examples/simple/root/shader/style.css +0 -9
- data/examples/simple/root/view-article.sx +0 -29
- data/examples/tiny/conf/config.rb +0 -62
- data/examples/tiny/conf/requires.rb +0 -33
- data/examples/tiny/ctl +0 -16
- data/lib/n/parts.rb +0 -157
- data/lib/n/properties.rb +0 -199
- data/lib/n/server/dispatcher.rb +0 -55
- data/lib/n/server/handlers/code-handler.rb +0 -182
- data/lib/n/server/handlers/page-handler.rb +0 -612
- data/lib/n/server/webrick.rb +0 -283
- data/lib/n/shaders.rb +0 -166
- data/lib/n/sync/clc.rb +0 -110
- data/lib/n/sync/handler.rb +0 -229
- data/lib/n/sync/server.rb +0 -176
- data/lib/p/README +0 -1
data/examples/tiny/README
CHANGED
data/examples/tiny/app.rb
CHANGED
@@ -8,23 +8,13 @@
|
|
8
8
|
# * George Moschovitis <gm@navel.gr>
|
9
9
|
#
|
10
10
|
# (c) 2004 Navel, all rights reserved.
|
11
|
-
# $Id: app.rb
|
11
|
+
# $Id: app.rb 146 2004-11-13 19:05:06Z gmosx $
|
12
12
|
|
13
|
-
|
13
|
+
$DBG = false
|
14
14
|
|
15
|
-
|
16
|
-
$
|
15
|
+
$LOAD_PATH.unshift "lib"
|
16
|
+
$LOAD_PATH.unshift "../../lib"
|
17
17
|
|
18
|
-
require "
|
19
|
-
require "n/server/webrick"
|
20
|
-
|
21
|
-
module App
|
22
|
-
|
23
|
-
class Server < N::Webrick
|
24
|
-
include App::Config
|
25
|
-
end
|
26
|
-
|
27
|
-
end # module
|
28
|
-
|
29
|
-
$app = App::Server.new.exec()
|
18
|
+
require "config"
|
30
19
|
|
20
|
+
$app = N::WebrickServer.new.exec()
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# = Tiny Configuration
|
2
|
+
#
|
3
|
+
# You can find additional configuration variables in
|
4
|
+
# lib/n/config.rb. Just copy the variables you want to
|
5
|
+
# change in this file
|
6
|
+
#
|
7
|
+
# code:
|
8
|
+
# * George Moschovitis <gm@navel.gr>
|
9
|
+
#
|
10
|
+
# (c) 2004 Navel, all rights reserved.
|
11
|
+
# $Id: config.rb 155 2004-11-13 20:32:12Z gmosx $
|
12
|
+
|
13
|
+
require "nitro"
|
14
|
+
require "nitro/logger"
|
15
|
+
require "nitro/config"
|
16
|
+
|
17
|
+
require "nitro/utils/number"
|
18
|
+
require "nitro/utils/string"
|
19
|
+
require "nitro/utils/array"
|
20
|
+
require "nitro/utils/hash"
|
21
|
+
require "nitro/utils/html"
|
22
|
+
require "nitro/utils/gfx"
|
23
|
+
|
24
|
+
require "nitro/server/webrick"
|
25
|
+
|
26
|
+
$name = "Tiny Example"
|
27
|
+
|
28
|
+
$srv_address = $appsrv_address = "127.0.0.1"
|
29
|
+
$srv_port = 8080
|
30
|
+
$srv_url = "http://#$srv_address:#$srv_port"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Logfile created on Sat Nov 13 20:02:50 EET 2004 by logger.rb/1.5.2.4
|
2
|
+
I: Web Server listening at http://127.0.0.1:8080
|
3
|
+
I: App Server listening at http://127.0.0.1:9090
|
4
|
+
I: Web Server listening at http://127.0.0.1:8080
|
5
|
+
I: App Server listening at http://127.0.0.1:9090
|
6
|
+
I: Web Server listening at http://127.0.0.1:8080
|
7
|
+
I: App Server listening at http://127.0.0.1:9090
|
8
|
+
I: Web Server listening at http://127.0.0.1:8080
|
9
|
+
I: App Server listening at http://127.0.0.1:9090
|
10
|
+
I: Web Server listening at http://127.0.0.1:8080
|
11
|
+
I: App Server listening at http://127.0.0.1:9090
|
12
|
+
I: Web Server listening at http://127.0.0.1:8080
|
13
|
+
I: App Server listening at http://127.0.0.1:9090
|
14
|
+
I: Web Server listening at http://127.0.0.1:8080
|
15
|
+
I: App Server listening at http://127.0.0.1:9090
|
16
|
+
I: Web Server listening at http://127.0.0.1:8080
|
17
|
+
I: App Server listening at http://127.0.0.1:9090
|
18
|
+
I: Web Server listening at http://127.0.0.1:8080
|
19
|
+
I: App Server listening at http://127.0.0.1:9090
|
20
|
+
INFO: Web Server listening at http://127.0.0.1:8080
|
21
|
+
INFO: App Server listening at http://127.0.0.1:9090
|
22
|
+
INFO: Web Server listening at http://127.0.0.1:8080
|
23
|
+
INFO: App Server listening at http://127.0.0.1:9090
|
@@ -5,14 +5,11 @@
|
|
5
5
|
<?r
|
6
6
|
# the code that populates the template comes here
|
7
7
|
|
8
|
-
unless name =
|
9
|
-
name =
|
8
|
+
unless name = params['name']
|
9
|
+
name = 'World'
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
session = request.session
|
15
|
-
session[:counter] = 0 unless session[:counter]
|
12
|
+
session[:counter] ||= 0
|
16
13
|
session[:counter] += 1
|
17
14
|
?>
|
18
15
|
|
data/lib/{n/std.rb → nitro.rb}
RENAMED
@@ -1,12 +1,18 @@
|
|
1
|
-
# = Nitro
|
1
|
+
# = Nitro
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Nitro is an efficient, yet simple engine for developing professional
|
4
|
+
# Web Applications using the Ruby language. Nitro aims to provide a
|
5
|
+
# robust infrastructure for scalable web applications that can be
|
6
|
+
# distributed over a server cluster. However, Nitro can also power
|
7
|
+
# simple web applications for deployment on intranets or even personal
|
8
|
+
# computers. Nitro integrates the powerful Og Object-Relational mapping
|
9
|
+
# library.
|
4
10
|
#
|
5
11
|
# code:
|
6
12
|
# * George Moschovitis <gm@navel.gr>
|
7
13
|
#
|
8
14
|
# (c) 2004 Navel, all rights reserved.
|
9
|
-
# $Id:
|
15
|
+
# $Id: nitro.rb 155 2004-11-13 20:32:12Z gmosx $
|
10
16
|
|
11
17
|
# we want readable code
|
12
18
|
|
@@ -50,4 +56,3 @@ end
|
|
50
56
|
# predefine some comonly used objects
|
51
57
|
|
52
58
|
EMPTY_STRING = ""
|
53
|
-
|
@@ -9,13 +9,13 @@
|
|
9
9
|
# Elias Karakoulakis <ekarak@ktismata.com>
|
10
10
|
#
|
11
11
|
# (c) 2004 Navel, all rights reserved.
|
12
|
-
# $Id: application.rb
|
12
|
+
# $Id: application.rb 155 2004-11-13 20:32:12Z gmosx $
|
13
13
|
|
14
14
|
require 'optparse'
|
15
15
|
require 'ostruct'
|
16
16
|
|
17
|
-
require "
|
18
|
-
require "
|
17
|
+
require "nitro/logger"
|
18
|
+
require "nitro"
|
19
19
|
|
20
20
|
module N
|
21
21
|
|
@@ -64,22 +64,22 @@ class Application
|
|
64
64
|
opts.separator "Specific options:"
|
65
65
|
|
66
66
|
opts.on("-s", "--start",
|
67
|
-
"Start
|
67
|
+
"Start '#$name'.") {
|
68
68
|
start()
|
69
69
|
}
|
70
70
|
|
71
71
|
opts.on("-S", "--stop",
|
72
|
-
"Stop
|
72
|
+
"Stop '#$name'.") {
|
73
73
|
stop()
|
74
74
|
}
|
75
75
|
|
76
76
|
opts.on("-r", "--restart",
|
77
|
-
"Restart
|
77
|
+
"Restart '#$name'.") {
|
78
78
|
restart()
|
79
79
|
}
|
80
80
|
|
81
81
|
opts.on("-d", "--daemon",
|
82
|
-
"Run
|
82
|
+
"Run '#$name' as a daemon.") {
|
83
83
|
daemonize()
|
84
84
|
start()
|
85
85
|
}
|
@@ -88,6 +88,12 @@ class Application
|
|
88
88
|
puts opts
|
89
89
|
exit
|
90
90
|
}
|
91
|
+
|
92
|
+
opts.on_tail("-v", "--version", "Show version.") {
|
93
|
+
puts $srv_version
|
94
|
+
exit
|
95
|
+
}
|
96
|
+
|
91
97
|
}
|
92
98
|
begin
|
93
99
|
opts.parse!(args)
|
data/lib/{n → nitro}/config.rb
RENAMED
@@ -6,13 +6,13 @@
|
|
6
6
|
# * George Moschovitis <gm@navel.gr>
|
7
7
|
#
|
8
8
|
# (c) 2004 Navel, all rights reserved.
|
9
|
-
# $Id: config.rb
|
9
|
+
# $Id: config.rb 155 2004-11-13 20:32:12Z gmosx $
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
require 'nitro/logger'
|
12
|
+
require 'nitro/utils/hash'
|
13
|
+
require 'nitro/version'
|
14
|
+
require 'nitro/service'
|
15
|
+
require 'nitro/server/shaders'
|
16
16
|
|
17
17
|
# monitor scripts for changes
|
18
18
|
#--
|
@@ -20,10 +20,14 @@ $srv_version = "0.3.0"
|
|
20
20
|
#++
|
21
21
|
$srv_monitor_scripts = true
|
22
22
|
|
23
|
+
# The root (public) directory.
|
24
|
+
$root_dir = "root"
|
25
|
+
|
23
26
|
# the default file to view in a direcotry
|
24
27
|
$index_filename = "index.sx"
|
25
28
|
|
26
29
|
# seconds till the autologin cookie expires
|
30
|
+
# TODO: move to filter.
|
27
31
|
$srv_autologin_expires = 60*60*24*30
|
28
32
|
|
29
33
|
# session timeout (in seconds)
|
@@ -39,7 +43,29 @@ $drb_state = false
|
|
39
43
|
$error_page_url = nil
|
40
44
|
|
41
45
|
# default encoding for the app.
|
42
|
-
$encoding =
|
46
|
+
$encoding = 'iso-8859-1'
|
47
|
+
|
48
|
+
# default content type.
|
49
|
+
$default_content_type = 'text/html'
|
50
|
+
|
51
|
+
# The services map.
|
52
|
+
# :index represents the '/' mount point
|
53
|
+
$services = { :index => N::Service }
|
54
|
+
|
55
|
+
# The service method map.
|
56
|
+
$methods = N::SafeHash.new
|
57
|
+
|
58
|
+
# The shader. The default shader is very simple, here
|
59
|
+
# is a typical example of a production shader pipeline:
|
60
|
+
#
|
61
|
+
# <tt>
|
62
|
+
# $shader = N::XSLTShader.new("#$root_dir/style.xsl",
|
63
|
+
# N::RubyShader.new(
|
64
|
+
# N::CompressShader.new
|
65
|
+
# )
|
66
|
+
# )
|
67
|
+
# </tt>
|
68
|
+
$shader = N::RubyShader.new
|
43
69
|
|
44
70
|
if $DBG
|
45
71
|
|
@@ -63,13 +89,16 @@ if $DBG
|
|
63
89
|
|
64
90
|
$srv_address = $appsrv_address = "127.0.0.1"
|
65
91
|
$srv_port = 8080
|
66
|
-
$appsrv_port =
|
92
|
+
$appsrv_port = 8080
|
67
93
|
$srv_url = "http://#$srv_address:#$srv_port"
|
68
94
|
|
69
95
|
else
|
70
96
|
|
71
97
|
puts "\nRunning LIVE configuration.\n\n"
|
72
98
|
|
99
|
+
$log = Logger.new("log/app.log", 10);
|
100
|
+
$log.level = Logger::INFO
|
101
|
+
|
73
102
|
# If set to true disables xsl caching. Usefull when debugging xsls.
|
74
103
|
|
75
104
|
$reload_xsl = false
|
@@ -86,4 +115,5 @@ else
|
|
86
115
|
$srv_port = 8080
|
87
116
|
$appsrv_port = 9090
|
88
117
|
$srv_url = "http://#$srv_address:#$srv_port"
|
118
|
+
|
89
119
|
end
|
data/lib/{n → nitro}/events.rb
RENAMED
data/lib/{n → nitro}/l10n.rb
RENAMED
data/lib/{n → nitro}/logger.rb
RENAMED
@@ -7,7 +7,7 @@
|
|
7
7
|
# * George Moschovitis <gm@navel.gr>
|
8
8
|
#
|
9
9
|
# (c) 2004 Navel, all rights reserved.
|
10
|
-
# $Id: logger.rb
|
10
|
+
# $Id: logger.rb 152 2004-11-13 20:02:35Z gmosx $
|
11
11
|
|
12
12
|
require "logger"
|
13
13
|
|
@@ -38,14 +38,14 @@ class Logger
|
|
38
38
|
|
39
39
|
private
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
# the default Ruby logger has a hardwired silly format.
|
42
|
+
# we use some Ruby magic to fix it!
|
43
|
+
remove_const "Format"
|
44
44
|
|
45
|
-
|
45
|
+
Format = "%5s: %s\n"
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
def format_message(severity, timestamp, msg, progname)
|
48
|
+
Format % [severity, msg]
|
49
|
+
end
|
50
50
|
end
|
51
51
|
|
data/lib/{n → nitro}/macros.rb
RENAMED
@@ -9,7 +9,7 @@
|
|
9
9
|
# George Moschovitis <gm@navel.gr>
|
10
10
|
#
|
11
11
|
# (c) 2004 Navel, all rights reserved.
|
12
|
-
# $Id: macros.rb
|
12
|
+
# $Id: macros.rb 155 2004-11-13 20:32:12Z gmosx $
|
13
13
|
|
14
14
|
$__macros__ = {}
|
15
15
|
$__required__ = {}
|
@@ -39,8 +39,8 @@ end
|
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
-
require "
|
43
|
-
require "
|
42
|
+
require "nitro/test1.rb"
|
43
|
+
require "nitro/test2.rb"
|
44
44
|
|
45
45
|
__END__
|
46
46
|
|
data/lib/{n → nitro}/mixins.rb
RENAMED
@@ -0,0 +1,301 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
# design:
|
4
|
+
# * Anastastios Koutoumanos <ak@navel.gr>
|
5
|
+
# * Elias Karakoulakis <ekarak@ktismata.com>
|
6
|
+
#
|
7
|
+
# (c) 2004 Navel, all rights reserved.
|
8
|
+
# $Id: properties.rb 155 2004-11-13 20:32:12Z gmosx $
|
9
|
+
|
10
|
+
require "nitro/utils/array"
|
11
|
+
require "nitro/utils/hash"
|
12
|
+
|
13
|
+
module N
|
14
|
+
|
15
|
+
# = Property
|
16
|
+
#
|
17
|
+
# Ruby attributes are typeless and generally this is good. Some times
|
18
|
+
# we need extra metadata though, for example in relational mapping,
|
19
|
+
# or web form population.
|
20
|
+
#
|
21
|
+
# Only Fixnums, Strings, Floats, Times, Booleans are converted.
|
22
|
+
#
|
23
|
+
# The default = methods do not force the types. A special
|
24
|
+
# __force_set method should be used instead.
|
25
|
+
#
|
26
|
+
#--
|
27
|
+
# TODO:
|
28
|
+
# Inject only the really needd methods into Module.
|
29
|
+
# Perhaps a sync is needed in evals (!!!!)
|
30
|
+
#++
|
31
|
+
#
|
32
|
+
class Property
|
33
|
+
# the symbol of the property
|
34
|
+
attr_accessor :symbol
|
35
|
+
# the string representation of the symbol
|
36
|
+
attr_accessor :name
|
37
|
+
# the class of the property
|
38
|
+
attr_accessor :klass
|
39
|
+
# additional metadata (like sql declaratio, sql index, etc)
|
40
|
+
attr_accessor :meta
|
41
|
+
|
42
|
+
def initialize(symbol, klass, meta = {})
|
43
|
+
@symbol, @klass = symbol, klass
|
44
|
+
@meta = meta
|
45
|
+
@name = @symbol.to_s()
|
46
|
+
end
|
47
|
+
|
48
|
+
def ==(other)
|
49
|
+
return @symbol == other.symbol
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end # module
|
54
|
+
|
55
|
+
class Module
|
56
|
+
|
57
|
+
# Define a property (== typed attribute)
|
58
|
+
# This works like Ruby's standard attr method, ie creates
|
59
|
+
# only one property.
|
60
|
+
#
|
61
|
+
# Use the prop_reader, prop_writer, prop_accessor methods
|
62
|
+
# for multiple properties.
|
63
|
+
#
|
64
|
+
# Examples:
|
65
|
+
# prop String, :name, :sql => "char(32), :sql_index => "name(32)"
|
66
|
+
# --> creates only writer.
|
67
|
+
# prop Fixnum, :oid, writer = true, :sql => "integer PRIMARY KEY"
|
68
|
+
# --> creates reader and writer.
|
69
|
+
#
|
70
|
+
def prop(*params)
|
71
|
+
meta = {}
|
72
|
+
klass = Object
|
73
|
+
|
74
|
+
for param in params
|
75
|
+
if param.is_a?(Class)
|
76
|
+
klass = param
|
77
|
+
elsif param.is_a?(Symbol)
|
78
|
+
symbol = param
|
79
|
+
elsif param.is_a?(TrueClass) or param.is_a?(TrueClass)
|
80
|
+
writer = param
|
81
|
+
elsif param.is_a?(Hash)
|
82
|
+
# the meta hash.
|
83
|
+
meta = param
|
84
|
+
else
|
85
|
+
raise "Error when defining property!"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
unless self.methods.include?("__props")
|
90
|
+
eval %{
|
91
|
+
# Properties
|
92
|
+
# An array is used to enforce order.
|
93
|
+
def __props
|
94
|
+
@__props
|
95
|
+
end
|
96
|
+
|
97
|
+
def __props=(props)
|
98
|
+
@__props = props
|
99
|
+
end
|
100
|
+
|
101
|
+
def __meta
|
102
|
+
@__meta
|
103
|
+
end
|
104
|
+
|
105
|
+
def __meta=(meta)
|
106
|
+
@__meta = meta
|
107
|
+
end
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
@__props = N::SafeArray.new() unless @__props
|
112
|
+
|
113
|
+
property = N::Property.new(symbol, klass, meta)
|
114
|
+
|
115
|
+
reader = meta[:reader] || true
|
116
|
+
writer = writer || meta[:writer] || false
|
117
|
+
|
118
|
+
__add_prop(property, reader, writer)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Helper method. Accepts a collection of symbols and generates
|
122
|
+
# properties. Only generates reader.
|
123
|
+
#
|
124
|
+
# Example:
|
125
|
+
# prop_reader String, :name, :title, :body, :sql => "char(32)"
|
126
|
+
#
|
127
|
+
def prop_reader(*params)
|
128
|
+
meta = {}
|
129
|
+
klass = Object
|
130
|
+
symbols = []
|
131
|
+
|
132
|
+
for param in params
|
133
|
+
if param.is_a?(Class)
|
134
|
+
klass = param
|
135
|
+
elsif param.is_a?(Symbol)
|
136
|
+
symbols << param
|
137
|
+
elsif param.is_a?(Hash)
|
138
|
+
# the meta hash.
|
139
|
+
meta = param
|
140
|
+
else
|
141
|
+
raise "Error when defining property!"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
meta[:reader] = true
|
146
|
+
meta[:writer] = false
|
147
|
+
|
148
|
+
for symbol in symbols
|
149
|
+
prop(klass, symbol, meta)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Helper method. Accepts a collection of symbols and generates
|
154
|
+
# properties. Only generates writer.
|
155
|
+
#
|
156
|
+
# Example:
|
157
|
+
# prop_writer String, :name, :title, :body, :sql => "char(32)"
|
158
|
+
#
|
159
|
+
def prop_writer(*params)
|
160
|
+
meta = {}
|
161
|
+
klass = Object
|
162
|
+
symbols = []
|
163
|
+
|
164
|
+
for param in params
|
165
|
+
if param.is_a?(Class)
|
166
|
+
klass = param
|
167
|
+
elsif param.is_a?(Symbol)
|
168
|
+
symbols << param
|
169
|
+
elsif param.is_a?(Hash)
|
170
|
+
# the meta hash.
|
171
|
+
meta = param
|
172
|
+
else
|
173
|
+
raise "Error when defining property!"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
meta[:reader] = false
|
178
|
+
meta[:writer] = true
|
179
|
+
|
180
|
+
for symbol in symbols
|
181
|
+
prop(klass, symbol, meta)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# Helper method. Accepts a collection of symbols and generates
|
186
|
+
# properties. Generates reader and writer.
|
187
|
+
#
|
188
|
+
# Example:
|
189
|
+
# prop_accessor String, :name, :title, :body, :sql => "char(32)"
|
190
|
+
#
|
191
|
+
def prop_accessor(*params)
|
192
|
+
meta = {}
|
193
|
+
klass = Object
|
194
|
+
symbols = []
|
195
|
+
|
196
|
+
for param in params
|
197
|
+
if param.is_a?(Class)
|
198
|
+
klass = param
|
199
|
+
elsif param.is_a?(Symbol)
|
200
|
+
symbols << param
|
201
|
+
elsif param.is_a?(Hash)
|
202
|
+
# the meta hash.
|
203
|
+
meta = param
|
204
|
+
else
|
205
|
+
raise "Error when defining property!"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
meta[:reader] = true
|
210
|
+
meta[:writer] = true
|
211
|
+
|
212
|
+
for symbol in symbols
|
213
|
+
prop(klass, symbol, meta)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# Add the property
|
218
|
+
#
|
219
|
+
def __add_prop(prop, reader = true, writer = true)
|
220
|
+
if idx = @__props.index(prop)
|
221
|
+
# override in case of duplicates. Keep the order of the props.
|
222
|
+
@__props[idx] = prop
|
223
|
+
else
|
224
|
+
@__props << prop
|
225
|
+
end
|
226
|
+
|
227
|
+
# Precompile the property read/write methods
|
228
|
+
|
229
|
+
s, klass = prop.symbol, prop.klass
|
230
|
+
|
231
|
+
if reader
|
232
|
+
module_eval %{
|
233
|
+
def #{s}
|
234
|
+
return @#{s}
|
235
|
+
end
|
236
|
+
}
|
237
|
+
end
|
238
|
+
|
239
|
+
if writer
|
240
|
+
module_eval %{
|
241
|
+
def #{s}=(val)
|
242
|
+
@#{s} = val
|
243
|
+
end
|
244
|
+
|
245
|
+
def __force_#{s}(val)
|
246
|
+
@#{s} = } + case klass.name
|
247
|
+
when Fixnum.name
|
248
|
+
"val.to_i()"
|
249
|
+
when String.name
|
250
|
+
"val.to_s()"
|
251
|
+
when Float.name
|
252
|
+
"val.to_f()"
|
253
|
+
when Time.name
|
254
|
+
"Time.parse(val.to_s())"
|
255
|
+
when TrueClass.name, FalseClass.name
|
256
|
+
"val.to_i() > 0"
|
257
|
+
else
|
258
|
+
"val"
|
259
|
+
end + %{
|
260
|
+
end
|
261
|
+
}
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Attach metadata
|
266
|
+
#
|
267
|
+
def meta(key, val)
|
268
|
+
@__meta = N::SafeHash.new unless @__meta
|
269
|
+
|
270
|
+
@__meta[key] = [] unless @__meta[key]
|
271
|
+
|
272
|
+
# guard against duplicates, no need to keep order.
|
273
|
+
@__meta[key].delete_if { |v| val == v }
|
274
|
+
@__meta[key] << val
|
275
|
+
end
|
276
|
+
|
277
|
+
# This method is typically called before including other
|
278
|
+
# modules to preserve properties order.
|
279
|
+
#
|
280
|
+
def inherit_meta(mod = superclass)
|
281
|
+
# concat props.
|
282
|
+
if mod.__props
|
283
|
+
@__props = N::SafeArray.new unless @__props
|
284
|
+
|
285
|
+
mod.__props.each { |p|
|
286
|
+
__add_prop(p)
|
287
|
+
}
|
288
|
+
end
|
289
|
+
|
290
|
+
# concat metadata
|
291
|
+
if mod.__meta
|
292
|
+
mod.__meta.each { |k, val|
|
293
|
+
val.each { |v|
|
294
|
+
meta(k, v)
|
295
|
+
} if val
|
296
|
+
}
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|