nitro 0.1.2
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/AUTHORS +8 -0
- data/ChangeLog +1546 -0
- data/LICENCE +32 -0
- data/README +278 -0
- data/RELEASES +7 -0
- data/Rakefile +79 -0
- data/bin/cluster.rb +219 -0
- data/doc/architecture.txt +28 -0
- data/doc/bugs.txt +7 -0
- data/doc/css.txt +20 -0
- data/doc/ideas.txt +120 -0
- data/doc/pg.txt +47 -0
- data/doc/svn.txt +82 -0
- data/doc/todo.txt +30 -0
- data/etc/new-project.rb +18 -0
- data/examples/simple/README +15 -0
- data/examples/simple/app.rb +31 -0
- data/examples/simple/conf/apache.conf +100 -0
- data/examples/simple/conf/config.rb +89 -0
- data/examples/simple/conf/debug-config.rb +53 -0
- data/examples/simple/conf/live-config.rb +48 -0
- data/examples/simple/conf/overrides.rb +9 -0
- data/examples/simple/conf/requires.rb +51 -0
- data/examples/simple/ctl +32 -0
- data/examples/simple/env.rb +33 -0
- data/examples/simple/install.rb +12 -0
- data/examples/simple/lib/articles/entities.rb +35 -0
- data/examples/simple/lib/articles/lc-en.rb +36 -0
- data/examples/simple/lib/articles/methods.rb +55 -0
- data/examples/simple/lib/articles/part.rb +58 -0
- data/examples/simple/logs/access_log +2 -0
- data/examples/simple/logs/apache.log +3 -0
- data/examples/simple/logs/app.log +1 -0
- data/examples/simple/logs/events.log +1 -0
- data/examples/simple/root/add-article.sx +15 -0
- data/examples/simple/root/article-form.ss +20 -0
- data/examples/simple/root/comments-form.ss +16 -0
- data/examples/simple/root/comments.si +30 -0
- data/examples/simple/root/index.sx +44 -0
- data/examples/simple/root/shader/shader.xsl +100 -0
- data/examples/simple/root/shader/style.css +9 -0
- data/examples/simple/root/view-article.sx +30 -0
- data/examples/tiny/app.rb +30 -0
- data/examples/tiny/conf/apache.conf +100 -0
- data/examples/tiny/conf/config.rb +67 -0
- data/examples/tiny/conf/requires.rb +40 -0
- data/examples/tiny/ctl +31 -0
- data/examples/tiny/logs/access_log +9 -0
- data/examples/tiny/logs/apache.log +9 -0
- data/examples/tiny/root/index.sx +35 -0
- data/lib/n/app/cluster.rb +219 -0
- data/lib/n/app/cookie.rb +86 -0
- data/lib/n/app/filters/autologin.rb +50 -0
- data/lib/n/app/fragment.rb +67 -0
- data/lib/n/app/handlers.rb +120 -0
- data/lib/n/app/handlers/code-handler.rb +184 -0
- data/lib/n/app/handlers/page-handler.rb +612 -0
- data/lib/n/app/request-part.rb +59 -0
- data/lib/n/app/request.rb +653 -0
- data/lib/n/app/script.rb +398 -0
- data/lib/n/app/server.rb +53 -0
- data/lib/n/app/session.rb +224 -0
- data/lib/n/app/user.rb +47 -0
- data/lib/n/app/webrick-servlet.rb +213 -0
- data/lib/n/app/webrick.rb +70 -0
- data/lib/n/application.rb +187 -0
- data/lib/n/config.rb +31 -0
- data/lib/n/db.rb +217 -0
- data/lib/n/db/README +232 -0
- data/lib/n/db/connection.rb +369 -0
- data/lib/n/db/make-release.sh +26 -0
- data/lib/n/db/managed.rb +235 -0
- data/lib/n/db/mixins.rb +282 -0
- data/lib/n/db/mysql.rb +342 -0
- data/lib/n/db/psql.rb +378 -0
- data/lib/n/db/tools.rb +110 -0
- data/lib/n/db/utils.rb +99 -0
- data/lib/n/events.rb +118 -0
- data/lib/n/l10n.rb +22 -0
- data/lib/n/logger.rb +33 -0
- data/lib/n/macros.rb +53 -0
- data/lib/n/mixins.rb +46 -0
- data/lib/n/parts.rb +154 -0
- data/lib/n/properties.rb +194 -0
- data/lib/n/server.rb +61 -0
- data/lib/n/server/PLAYBACK.txt +8 -0
- data/lib/n/server/RESEARCH.txt +13 -0
- data/lib/n/server/filter.rb +77 -0
- data/lib/n/shaders.rb +167 -0
- data/lib/n/sitemap.rb +188 -0
- data/lib/n/std.rb +69 -0
- data/lib/n/sync/clc.rb +108 -0
- data/lib/n/sync/handler.rb +221 -0
- data/lib/n/sync/server.rb +170 -0
- data/lib/n/tools/README +11 -0
- data/lib/n/ui/date-select.rb +74 -0
- data/lib/n/ui/pager.rb +187 -0
- data/lib/n/ui/popup.rb +45 -0
- data/lib/n/ui/select.rb +41 -0
- data/lib/n/ui/tabs.rb +34 -0
- data/lib/n/utils/array.rb +92 -0
- data/lib/n/utils/cache.rb +144 -0
- data/lib/n/utils/gfx.rb +108 -0
- data/lib/n/utils/hash.rb +148 -0
- data/lib/n/utils/html.rb +147 -0
- data/lib/n/utils/http.rb +98 -0
- data/lib/n/utils/mail.rb +28 -0
- data/lib/n/utils/number.rb +31 -0
- data/lib/n/utils/pool.rb +66 -0
- data/lib/n/utils/string.rb +297 -0
- data/lib/n/utils/template.rb +38 -0
- data/lib/n/utils/time.rb +91 -0
- data/lib/n/utils/uri.rb +193 -0
- data/lib/xsl/base.xsl +205 -0
- data/lib/xsl/ce.xsl +30 -0
- data/lib/xsl/localization.xsl +23 -0
- data/lib/xsl/xforms.xsl +26 -0
- data/test/run.rb +95 -0
- metadata +187 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# = Webrick AppServer
|
|
2
|
+
#
|
|
3
|
+
# Used temporarily unitl we build our own app server.
|
|
4
|
+
#
|
|
5
|
+
# code:: gmosx, elathan
|
|
6
|
+
#
|
|
7
|
+
# (c) 2004 Navel, all rights reserved.
|
|
8
|
+
# $Id: webrick.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
9
|
+
|
|
10
|
+
require "drb"
|
|
11
|
+
require "cgi"
|
|
12
|
+
require "webrick"
|
|
13
|
+
|
|
14
|
+
require "n/logger"
|
|
15
|
+
require "n/application"
|
|
16
|
+
require "n/app/server"
|
|
17
|
+
require "n/app/webrick-servlet"
|
|
18
|
+
|
|
19
|
+
module N; module App
|
|
20
|
+
|
|
21
|
+
# = Webrick AppServer
|
|
22
|
+
#
|
|
23
|
+
# The Application Server. Handles dynamic requests in a web application.
|
|
24
|
+
# Dont keepalive (or use a VERY SMALL keepalive). Typically this server
|
|
25
|
+
# is used along with a standard http server that handles other resources.
|
|
26
|
+
#
|
|
27
|
+
class Webrick < N::Server
|
|
28
|
+
include N::App::ServerMixin
|
|
29
|
+
include WEBrick
|
|
30
|
+
|
|
31
|
+
attr_accessor :webrick
|
|
32
|
+
|
|
33
|
+
def initialize(name = "WebrickServer")
|
|
34
|
+
super
|
|
35
|
+
initialize_app()
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def start
|
|
39
|
+
accesslog = WEBrick::BasicLog::new("/dev/null")
|
|
40
|
+
referer = WEBrick::BasicLog::new("/dev/null")
|
|
41
|
+
|
|
42
|
+
@webrick = HTTPServer.new(
|
|
43
|
+
:BindAddress => $appsrv_address,
|
|
44
|
+
:Port => $appsrv_port,
|
|
45
|
+
:DirectoryIndex => ["index.sx"],
|
|
46
|
+
# gmosx, FIXME: this shit still logs!!
|
|
47
|
+
:Logger => Log.new(nil, WEBrick::Log::WARN),
|
|
48
|
+
# elathan: amateur...
|
|
49
|
+
:AccessLog => [
|
|
50
|
+
[accesslog, AccessLog::COMMON_LOG_FORMAT],
|
|
51
|
+
[referer, AccessLog::REFERER_LOG_FORMAT]
|
|
52
|
+
]
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@webrick.mount("/", N::App::WebrickServlet)
|
|
56
|
+
|
|
57
|
+
trap("INT") {
|
|
58
|
+
@webrick.shutdown()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@webrick.start()
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def stop
|
|
65
|
+
@webrick.stop
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end; end # module
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# = Application
|
|
2
|
+
#
|
|
3
|
+
# code: gmosx, ekarak, drak, elathan
|
|
4
|
+
#
|
|
5
|
+
# (c) 2004 Navel, all rights reserved.
|
|
6
|
+
# $Id: application.rb 71 2004-10-18 10:50:22Z gmosx $
|
|
7
|
+
|
|
8
|
+
require 'optparse'
|
|
9
|
+
require 'ostruct'
|
|
10
|
+
|
|
11
|
+
require "n/logger"
|
|
12
|
+
require "n/std"
|
|
13
|
+
|
|
14
|
+
module N
|
|
15
|
+
|
|
16
|
+
# == Application
|
|
17
|
+
#
|
|
18
|
+
# the default Application object of the Framework.
|
|
19
|
+
#
|
|
20
|
+
class Application
|
|
21
|
+
# credentials of the application
|
|
22
|
+
attr_accessor :name, :title, :description, :version
|
|
23
|
+
|
|
24
|
+
# the status of the application
|
|
25
|
+
# use symbols to denote status.
|
|
26
|
+
# valid status symbols:
|
|
27
|
+
# * :run = The server is running
|
|
28
|
+
# * :stop = The server is stopped
|
|
29
|
+
attr_accessor :status
|
|
30
|
+
|
|
31
|
+
# startup time of the application
|
|
32
|
+
attr_accessor :create_time
|
|
33
|
+
|
|
34
|
+
attr_reader :daemonized
|
|
35
|
+
|
|
36
|
+
# the pid of the application
|
|
37
|
+
attr_reader :pid, :pidfile
|
|
38
|
+
|
|
39
|
+
#
|
|
40
|
+
#
|
|
41
|
+
def initialize(name = "Unknown")
|
|
42
|
+
@name = name
|
|
43
|
+
@pidfile = "/tmp/#{@name}.pid"
|
|
44
|
+
@create_time = Time.now()
|
|
45
|
+
@status = :stop
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# FIXME: deleting of arguments is wrong, recode
|
|
49
|
+
# this using GETOPT.
|
|
50
|
+
#
|
|
51
|
+
def parse_arguments(args = ARGV)
|
|
52
|
+
|
|
53
|
+
opts = OptionParser.new { |opts|
|
|
54
|
+
opts.banner = "Usage: application.rb [action]"
|
|
55
|
+
|
|
56
|
+
opts.separator ""
|
|
57
|
+
opts.separator "Specific options:"
|
|
58
|
+
|
|
59
|
+
opts.on("-s", "--start",
|
|
60
|
+
"Start Navel's Application Server.") {
|
|
61
|
+
start()
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
opts.on("-S", "--stop",
|
|
65
|
+
"Stop Navel's Application Server.") {
|
|
66
|
+
stop()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
opts.on("-r", "--restart",
|
|
70
|
+
"Restart Navel's Application Server.") {
|
|
71
|
+
restart()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
opts.on("-d", "--daemon",
|
|
75
|
+
"Run Navel's Application Server as a daemon.") {
|
|
76
|
+
daemonize()
|
|
77
|
+
start()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
opts.on_tail("-?", "--help", "Show this message.") {
|
|
81
|
+
puts opts
|
|
82
|
+
exit
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
begin
|
|
86
|
+
opts.parse!(args)
|
|
87
|
+
rescue => ex
|
|
88
|
+
puts ex
|
|
89
|
+
puts "Please, either specify a valid option or invoke the usage using -? or --help."
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
alias_method :exec, :parse_arguments
|
|
93
|
+
|
|
94
|
+
#
|
|
95
|
+
#
|
|
96
|
+
def start()
|
|
97
|
+
raise "Application allready started!" unless :stop == @status
|
|
98
|
+
|
|
99
|
+
begin
|
|
100
|
+
run()
|
|
101
|
+
rescue => ex
|
|
102
|
+
puts ex
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# to allow for chaining
|
|
106
|
+
return self
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Override to properly restart the application
|
|
110
|
+
#
|
|
111
|
+
def restart()
|
|
112
|
+
stop()
|
|
113
|
+
start()
|
|
114
|
+
|
|
115
|
+
# to allow for chaining
|
|
116
|
+
return self
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Stop the application. Typically kills ths application daemon.
|
|
120
|
+
#
|
|
121
|
+
def stop
|
|
122
|
+
if dpid = daemon_pid()
|
|
123
|
+
begin
|
|
124
|
+
File.delete(@pidfile)
|
|
125
|
+
Process.kill("SIGKILL", dpid)
|
|
126
|
+
$log.info "Successfully killed #{@name} instance, pid=#{dpid}"
|
|
127
|
+
rescue => ex
|
|
128
|
+
$log.error "Cannot kill #{@name} instance, pid=#{dpid}"
|
|
129
|
+
$log.error ex
|
|
130
|
+
end
|
|
131
|
+
else
|
|
132
|
+
$log.error "Cannot locate pid of running instance!"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# to allow for chaining
|
|
136
|
+
return self
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Begin the application loop.
|
|
140
|
+
# Override this method in your application.
|
|
141
|
+
#
|
|
142
|
+
def run
|
|
143
|
+
# to allow for chaining
|
|
144
|
+
return self
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Run the application as a daemon
|
|
148
|
+
# FIXME: handle logging for daemons.
|
|
149
|
+
# ???: How does this work !?!?
|
|
150
|
+
#
|
|
151
|
+
def daemonize
|
|
152
|
+
unless @daemonized
|
|
153
|
+
trap "SIGCLD", "IGNORE"
|
|
154
|
+
|
|
155
|
+
pid = fork()
|
|
156
|
+
|
|
157
|
+
if pid # parent process
|
|
158
|
+
@pid = pid
|
|
159
|
+
File.open(@pidfile, 'w') {|f| f << "#{pid}\n" }
|
|
160
|
+
exit!
|
|
161
|
+
else # child
|
|
162
|
+
$log.info "Daemon for '#{@name}', process id: #{Process.pid}"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# change process group and lose control tty
|
|
166
|
+
Process.setpgrp()
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
@daemonized = true
|
|
170
|
+
|
|
171
|
+
return self
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Returns the pid of the running daemon
|
|
175
|
+
#
|
|
176
|
+
def daemon_pid()
|
|
177
|
+
begin
|
|
178
|
+
return File.open(@pidfile).read.chomp.to_i
|
|
179
|
+
rescue
|
|
180
|
+
$log.info "Could not read pid from #{@pidfile}"
|
|
181
|
+
return nil
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end # module
|
|
187
|
+
|
data/lib/n/config.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# = Config
|
|
2
|
+
#
|
|
3
|
+
# Configuration
|
|
4
|
+
#
|
|
5
|
+
# code:
|
|
6
|
+
# George Moschovitis <gm@navel.gr>
|
|
7
|
+
#
|
|
8
|
+
# (c) 2004 Navel, all rights reserved.
|
|
9
|
+
# $Id: config.rb 89 2004-10-20 12:55:58Z gmosx $
|
|
10
|
+
|
|
11
|
+
$srv_name = "Nitro"
|
|
12
|
+
$srv_version = "0.1.2"
|
|
13
|
+
|
|
14
|
+
$srv_monitor_scripts = true
|
|
15
|
+
$srv_default_file = "index.sx"
|
|
16
|
+
$srv_autologin_expires = 60*60*24*30
|
|
17
|
+
|
|
18
|
+
# session timeout (in seconds)
|
|
19
|
+
$srv_session_timeout = 35*60
|
|
20
|
+
|
|
21
|
+
# session timeout for anonymous user (in seconds)
|
|
22
|
+
$srv_anon_session_timeout = 30*60
|
|
23
|
+
|
|
24
|
+
# enable distributed state?
|
|
25
|
+
$drb_state = false
|
|
26
|
+
|
|
27
|
+
# use the default error page.
|
|
28
|
+
$error_page_url = nil
|
|
29
|
+
|
|
30
|
+
# default encoding for the app.
|
|
31
|
+
$conf_encoding = "iso-8859-1"
|
data/lib/n/db.rb
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# = Database
|
|
2
|
+
#
|
|
3
|
+
# An efficient, yet simple Object-Relational Mapper.
|
|
4
|
+
#
|
|
5
|
+
# === Design
|
|
6
|
+
#
|
|
7
|
+
# Keep this class backend agnostic. Put backend specific code in
|
|
8
|
+
# the Connection / Managed class.
|
|
9
|
+
#
|
|
10
|
+
# Try to make the methods work with oids. We do keep
|
|
11
|
+
# a unified id space. Include the N::Sequenced Marker to
|
|
12
|
+
# denote custom id space.
|
|
13
|
+
# Do NOT implement descendants use a root id (rid).
|
|
14
|
+
#
|
|
15
|
+
# For class ids we use the name instead of a hash. Class ids are
|
|
16
|
+
# typically not used in querys, they are stored for completeness.
|
|
17
|
+
# If we store a hash we cannot reclaim the class thus invalidating
|
|
18
|
+
# the point. Instead of .name(), to_s() is used so the methods
|
|
19
|
+
# are more flexible (they accept class names too!!)
|
|
20
|
+
#
|
|
21
|
+
# === WARNING:
|
|
22
|
+
#
|
|
23
|
+
# When creating a new db exec the following:
|
|
24
|
+
# CREATE SEQUENCE oids_seq;
|
|
25
|
+
#
|
|
26
|
+
# or
|
|
27
|
+
#
|
|
28
|
+
# DbTools.create_oids_seq
|
|
29
|
+
#
|
|
30
|
+
#
|
|
31
|
+
# === Todo
|
|
32
|
+
#
|
|
33
|
+
# - support caching
|
|
34
|
+
# - support prepared statements
|
|
35
|
+
# - foreign keys (delete cascade)
|
|
36
|
+
# - keep attribudes as marshaled!!
|
|
37
|
+
#
|
|
38
|
+
# code:
|
|
39
|
+
# George Moschovitis <gm@navel.gr>
|
|
40
|
+
#
|
|
41
|
+
# (c) 2004 Navel, all rights reserved.
|
|
42
|
+
# $Id: db.rb 79 2004-10-18 16:38:19Z gmosx $
|
|
43
|
+
|
|
44
|
+
module N;
|
|
45
|
+
|
|
46
|
+
require "n/properties"
|
|
47
|
+
require "n/utils/array"
|
|
48
|
+
require "n/utils/time"
|
|
49
|
+
require "n/utils/pool"
|
|
50
|
+
|
|
51
|
+
require "n/db/utils"
|
|
52
|
+
require "n/db/managed"
|
|
53
|
+
require "n/db/connection"
|
|
54
|
+
require "n/db/mixins"
|
|
55
|
+
|
|
56
|
+
# Configuration
|
|
57
|
+
|
|
58
|
+
# if true, enables the read only mode
|
|
59
|
+
$db_read_only_mode = false
|
|
60
|
+
|
|
61
|
+
# = Database
|
|
62
|
+
#
|
|
63
|
+
# === Design:
|
|
64
|
+
#
|
|
65
|
+
# - This is NOT a singleton, an application may access multiple
|
|
66
|
+
# databases.
|
|
67
|
+
#
|
|
68
|
+
class Db
|
|
69
|
+
# hash of configuration options.
|
|
70
|
+
attr_accessor :config
|
|
71
|
+
|
|
72
|
+
# Pool of connections to the backend.
|
|
73
|
+
attr_accessor :pool
|
|
74
|
+
|
|
75
|
+
# Entities cache.
|
|
76
|
+
attr_accessor :cache
|
|
77
|
+
|
|
78
|
+
# Managed classes fields. A hash of hashes.
|
|
79
|
+
attr_accessor :fields
|
|
80
|
+
|
|
81
|
+
# Initialize the database interface.
|
|
82
|
+
#
|
|
83
|
+
def initialize(config)
|
|
84
|
+
@config = config
|
|
85
|
+
|
|
86
|
+
if backend = config[:backend]
|
|
87
|
+
require "n/db/#{backend}"
|
|
88
|
+
else
|
|
89
|
+
require "n/db/psql"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
$log.info "Connecting to database '#{config[:database]}'."
|
|
93
|
+
|
|
94
|
+
@pool = N::Pool.new
|
|
95
|
+
@fields = N::SafeHash.new
|
|
96
|
+
|
|
97
|
+
for i in (0...config[:connection_count])
|
|
98
|
+
@pool << DbConnection.new(config)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Shutdown the database interface.
|
|
103
|
+
#
|
|
104
|
+
def shutdown
|
|
105
|
+
for con in @pool
|
|
106
|
+
con.close()
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
alias_method :close, :shutdown
|
|
110
|
+
|
|
111
|
+
# Get a connection from the pool to access the database.
|
|
112
|
+
#
|
|
113
|
+
def get_connection
|
|
114
|
+
return @pool.pop()
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Restore an unused connection to the pool.
|
|
118
|
+
#
|
|
119
|
+
def put_connection(connection)
|
|
120
|
+
return @pool.push(connection)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Utility method, automatically restores a connection to the pool.
|
|
124
|
+
#
|
|
125
|
+
def connect(deserialize = nil, &block)
|
|
126
|
+
result = nil
|
|
127
|
+
|
|
128
|
+
begin
|
|
129
|
+
db = @pool.pop()
|
|
130
|
+
db.deserialize = deserialize unless deserialize.nil?
|
|
131
|
+
|
|
132
|
+
result = yield(db)
|
|
133
|
+
|
|
134
|
+
db.deserialize = true
|
|
135
|
+
ensure
|
|
136
|
+
@pool.push(db)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
return result
|
|
140
|
+
end
|
|
141
|
+
alias_method :open, :connect
|
|
142
|
+
|
|
143
|
+
# Utility method, gets connection and encloses in transaction.
|
|
144
|
+
#
|
|
145
|
+
def transaction(deserialize = nil, &block)
|
|
146
|
+
result = nil
|
|
147
|
+
|
|
148
|
+
begin
|
|
149
|
+
db = @pool.pop()
|
|
150
|
+
db.deserialize = deserialize if deserialize
|
|
151
|
+
|
|
152
|
+
db.start()
|
|
153
|
+
result = yield(db)
|
|
154
|
+
db.commit()
|
|
155
|
+
|
|
156
|
+
db.deserialize = true
|
|
157
|
+
ensure
|
|
158
|
+
@pool.push(db)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
return result
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Utility method, creates an entity from a row
|
|
165
|
+
#
|
|
166
|
+
def entity_from_row(row, klass)
|
|
167
|
+
entity = klass.new()
|
|
168
|
+
entity.__db_read_row__(row)
|
|
169
|
+
return entity
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# Automatically wrap connection methods.
|
|
175
|
+
#
|
|
176
|
+
def self.wrap_method(method, args)
|
|
177
|
+
args = args.split(/,/)
|
|
178
|
+
class_eval %{
|
|
179
|
+
def #{method}(#{args.join(", ")})
|
|
180
|
+
begin
|
|
181
|
+
db = @pool.pop()
|
|
182
|
+
res = db.#{method}(#{args.collect {|a| a.split(/=/)[0]}.join(", ")})
|
|
183
|
+
ensure
|
|
184
|
+
@pool.push(db)
|
|
185
|
+
end
|
|
186
|
+
return res
|
|
187
|
+
end
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
wrap_method :put, "entity"
|
|
192
|
+
alias_method :<<, :put
|
|
193
|
+
wrap_method :insert, "obj"
|
|
194
|
+
wrap_method :update, "obj"
|
|
195
|
+
wrap_method :update_properties, "update_sql, ent_or_oid, klass = nil"
|
|
196
|
+
wrap_method :pupdate, "update_sql, ent_or_oid, klass = nil"
|
|
197
|
+
wrap_method :get, "oid, klass"
|
|
198
|
+
wrap_method :get_by_oid, "oid, klass"
|
|
199
|
+
wrap_method :get_by_name, "name, klass"
|
|
200
|
+
wrap_method :get_all, "klass, extrasql = nil"
|
|
201
|
+
wrap_method :select, "sql, klass, join_fields = nil"
|
|
202
|
+
wrap_method :select_one, "sql, klass, join_fields = nil"
|
|
203
|
+
wrap_method :child, "entity, klass, extrasql = nil"
|
|
204
|
+
wrap_method :children, "entity, klass, extrasql = nil"
|
|
205
|
+
wrap_method :count_children, "entity, klass, extrasql = nil"
|
|
206
|
+
wrap_method :delete, "entity, klass = nil, cascade = true"
|
|
207
|
+
wrap_method :query, "sql"
|
|
208
|
+
wrap_method :query_one, "sql"
|
|
209
|
+
wrap_method :count, "sql"
|
|
210
|
+
wrap_method :match, "sql"
|
|
211
|
+
wrap_method :exec, "sql"
|
|
212
|
+
wrap_method :exec_and_clear, "sql"
|
|
213
|
+
wrap_method :exec_clear, "sql"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
end # module
|
|
217
|
+
|