nitro 0.8.0 → 0.9.3
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 +3 -4
- data/ChangeLog +418 -0
- data/LICENSE +1 -1
- data/README +157 -89
- data/RELEASES +50 -0
- data/Rakefile +5 -7
- data/benchmark/nitro/bench.rb +5 -0
- data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
- data/benchmark/nitro/static-webrick-n-200.txt +43 -0
- data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
- data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
- data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
- data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
- data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
- data/bin/proto/README +2 -2
- data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
- data/bin/proto/conf/app.conf.rb +22 -0
- data/bin/proto/conf/lhttpd.conf +236 -0
- data/bin/proto/ctl +4 -0
- data/bin/proto/lib/README +5 -0
- data/bin/proto/log/README +3 -0
- data/bin/proto/root/fcgi.rb +6 -0
- data/bin/proto/root/index.xhtml +65 -7
- data/bin/proto/root/m/nitro.png +0 -0
- data/examples/blog/README +7 -5
- data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
- data/examples/blog/conf/app.conf.rb +56 -0
- data/examples/blog/conf/lhttpd.conf +236 -0
- data/examples/blog/ctl +4 -0
- data/examples/blog/lib/blog.rb +11 -136
- data/examples/blog/lib/blog/controller.rb +99 -0
- data/examples/blog/lib/blog/model.rb +39 -0
- data/examples/blog/log/README +3 -0
- data/examples/blog/root/comments.xhtml +2 -2
- data/examples/blog/root/fcgi.rb +6 -0
- data/examples/blog/root/index.xhtml +4 -5
- data/examples/blog/root/login.xhtml +2 -2
- data/examples/blog/root/style.xsl +9 -9
- data/examples/blog/root/view_entry.xhtml +2 -2
- data/examples/flash/conf/app.conf.rb +23 -0
- data/examples/flash/ctl +4 -0
- data/examples/flash/log/README +3 -0
- data/examples/flash/root/index.xhtml +0 -9
- data/examples/flash/root/show_inline_text.xhtml +10 -5
- data/examples/no_xsl_blog/README +12 -0
- data/examples/no_xsl_blog/conf/apache.conf +0 -0
- data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
- data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
- data/examples/no_xsl_blog/ctl +4 -0
- data/examples/no_xsl_blog/lib/blog.rb +20 -0
- data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
- data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
- data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
- data/examples/no_xsl_blog/log/README +3 -0
- data/examples/no_xsl_blog/root/comments.xhtml +41 -0
- data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
- data/examples/no_xsl_blog/root/fcgi.rb +6 -0
- data/examples/no_xsl_blog/root/index.xhtml +39 -0
- data/examples/no_xsl_blog/root/login.xhtml +21 -0
- data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
- data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
- data/examples/no_xsl_blog/root/m/down.gif +0 -0
- data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
- data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
- data/examples/no_xsl_blog/root/m/obull.gif +0 -0
- data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/rss.gif +0 -0
- data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
- data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
- data/examples/no_xsl_blog/root/style.css +301 -0
- data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
- data/examples/no_xsl_blog/root/view_entry.xml +12 -0
- data/examples/og/run.rb +2 -2
- data/examples/tiny/README +2 -2
- data/examples/tiny/conf/apache.conf +5 -0
- data/examples/tiny/conf/app.conf.rb +21 -0
- data/examples/tiny/conf/lhttpd.conf +236 -0
- data/examples/tiny/ctl +4 -0
- data/examples/tiny/log/README +3 -0
- data/examples/tiny/root/fcgi.rb +6 -0
- data/examples/tiny/root/index.xhtml +7 -4
- data/examples/tiny/root/nitro.png +0 -0
- data/lib/glue.rb +13 -9
- data/lib/glue/array.rb +1 -1
- data/lib/glue/cache.rb +1 -1
- data/lib/glue/flexob.rb +12 -0
- data/lib/glue/hash.rb +1 -1
- data/lib/glue/inflector.rb +2 -2
- data/lib/glue/logger.rb +4 -8
- data/lib/glue/misc.rb +14 -0
- data/lib/glue/number.rb +1 -1
- data/lib/glue/object.rb +26 -0
- data/lib/glue/pool.rb +1 -1
- data/lib/glue/property.rb +84 -91
- data/lib/glue/string.rb +1 -1
- data/lib/glue/time.rb +1 -1
- data/lib/glue/validation.rb +1 -1
- data/lib/nitro.rb +18 -6
- data/lib/nitro/adaptors/cgi.rb +291 -0
- data/lib/nitro/adaptors/fastcgi.rb +42 -0
- data/lib/nitro/adaptors/runner.rb +123 -0
- data/lib/nitro/adaptors/webrick.rb +110 -0
- data/lib/nitro/buffering.rb +43 -0
- data/lib/nitro/builders/form.rb +1 -1
- data/lib/nitro/builders/rss.rb +1 -1
- data/{bin → lib/nitro}/cluster.rb +26 -30
- data/lib/nitro/context.rb +82 -0
- data/lib/nitro/controller.rb +50 -0
- data/lib/nitro/cookie.rb +46 -0
- data/lib/nitro/dispatcher.rb +105 -0
- data/lib/nitro/filters.rb +9 -10
- data/lib/nitro/localization.rb +42 -0
- data/lib/nitro/mail.rb +11 -14
- data/lib/nitro/render.rb +275 -0
- data/lib/nitro/request.rb +128 -0
- data/lib/nitro/response.rb +38 -0
- data/lib/nitro/scaffold.rb +11 -11
- data/lib/nitro/session.rb +84 -0
- data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
- data/lib/nitro/ui/pager.rb +23 -26
- data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
- data/lib/nitro/uri.rb +1 -1
- data/lib/nitro/version.rb +10 -8
- data/lib/og.rb +66 -65
- data/lib/og/backend.rb +1 -1
- data/lib/og/backends/mysql.rb +48 -52
- data/lib/og/backends/psql.rb +34 -37
- data/lib/og/connection.rb +15 -15
- data/lib/og/enchant.rb +16 -9
- data/lib/og/meta.rb +127 -54
- data/lib/og/mock.rb +18 -18
- data/lib/og/version.rb +6 -4
- data/lib/parts/content.rb +4 -8
- data/test/glue/tc_logger.rb +3 -0
- data/test/glue/tc_property.rb +19 -3
- data/test/nitro/adaptors/tc_cgi.rb +63 -0
- data/test/nitro/adaptors/tc_webrick.rb +15 -0
- data/test/nitro/builders/tc_xml.rb +2 -2
- data/test/nitro/tc_context.rb +13 -0
- data/test/nitro/tc_controller.rb +47 -0
- data/test/nitro/tc_dispatcher.rb +64 -0
- data/test/nitro/tc_session.rb +20 -0
- data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
- data/test/root/blog/list.xhtml +6 -0
- data/test/tc_og.rb +41 -4
- metadata +115 -59
- data/bin/proto/app.rb +0 -20
- data/bin/proto/config.rb +0 -77
- data/examples/blog/app.rb +0 -21
- data/examples/blog/config.rb +0 -95
- data/examples/blog/env.rb +0 -22
- data/examples/flash/README +0 -34
- data/examples/flash/app.rb +0 -20
- data/examples/flash/config.rb +0 -38
- data/examples/flash/lib/flash.rb +0 -40
- data/examples/flash/tmp.swf +0 -0
- data/examples/tiny/app.rb +0 -19
- data/examples/tiny/config.rb +0 -29
- data/examples/tiny/root/nitro-small.png +0 -0
- data/lib/nitro/application.rb +0 -217
- data/lib/nitro/config.rb +0 -128
- data/lib/nitro/events.rb +0 -122
- data/lib/nitro/html.rb +0 -151
- data/lib/nitro/http.rb +0 -102
- data/lib/nitro/l10n.rb +0 -30
- data/lib/nitro/server.rb +0 -59
- data/lib/nitro/server/appserver.rb +0 -67
- data/lib/nitro/server/cookie.rb +0 -87
- data/lib/nitro/server/dispatcher.rb +0 -62
- data/lib/nitro/server/filters.rb +0 -75
- data/lib/nitro/server/filters/autologin.rb +0 -51
- data/lib/nitro/server/fragment.rb +0 -70
- data/lib/nitro/server/handlers.rb +0 -127
- data/lib/nitro/server/render.rb +0 -426
- data/lib/nitro/server/request.rb +0 -658
- data/lib/nitro/server/requestpart.rb +0 -54
- data/lib/nitro/server/script.rb +0 -387
- data/lib/nitro/server/server.rb +0 -57
- data/lib/nitro/server/session.rb +0 -220
- data/lib/nitro/server/user.rb +0 -46
- data/lib/nitro/server/webrick.rb +0 -180
- data/lib/nitro/service.rb +0 -26
- data/lib/xsl/ui.xsl +0 -51
- data/lib/xsl/xforms.xsl +0 -28
- data/test/nitro/server/tc_cookie.rb +0 -34
- data/test/nitro/server/tc_filters.rb +0 -38
- data/test/nitro/server/tc_request.rb +0 -70
- data/test/nitro/server/tc_requestpart.rb +0 -28
- data/test/nitro/server/tc_session.rb +0 -34
- data/test/nitro/tc_events.rb +0 -44
- data/test/nitro/tc_html.rb +0 -79
- data/test/nitro/tc_http.rb +0 -18
data/lib/og/backend.rb
CHANGED
data/lib/og/backends/mysql.rb
CHANGED
|
@@ -1,39 +1,35 @@
|
|
|
1
|
-
# code:
|
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
|
3
2
|
# * Elias Athanasopoulos <elathan@navel.gr>
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# $Id: mysql.rb 194 2004-12-20 20:23:57Z gmosx $
|
|
3
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
|
4
|
+
# $Id: mysql.rb 248 2005-01-31 13:38:34Z gmosx $
|
|
7
5
|
|
|
8
|
-
require
|
|
6
|
+
require 'mysql'
|
|
9
7
|
|
|
10
|
-
require
|
|
8
|
+
require 'og/backend'
|
|
11
9
|
|
|
12
10
|
class Og
|
|
13
11
|
|
|
14
|
-
# = MysqlBackend
|
|
15
|
-
#
|
|
16
12
|
# Implements a MySQL powered backend.
|
|
17
|
-
|
|
13
|
+
|
|
18
14
|
class MysqlBackend < Og::Backend
|
|
19
15
|
|
|
20
16
|
# A mapping between Ruby and SQL types.
|
|
21
|
-
|
|
17
|
+
|
|
22
18
|
TYPEMAP = {
|
|
23
|
-
Integer =>
|
|
24
|
-
Fixnum =>
|
|
25
|
-
Float =>
|
|
26
|
-
String =>
|
|
27
|
-
Time =>
|
|
28
|
-
Date =>
|
|
29
|
-
TrueClass =>
|
|
30
|
-
Object =>
|
|
31
|
-
Array =>
|
|
32
|
-
Hash =>
|
|
19
|
+
Integer => 'integer',
|
|
20
|
+
Fixnum => 'integer',
|
|
21
|
+
Float => 'float',
|
|
22
|
+
String => 'text',
|
|
23
|
+
Time => 'timestamp',
|
|
24
|
+
Date => 'date',
|
|
25
|
+
TrueClass => 'tinyint',
|
|
26
|
+
Object => 'text',
|
|
27
|
+
Array => 'text',
|
|
28
|
+
Hash => 'text'
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
# Intitialize the connection to the RDBMS.
|
|
36
|
-
|
|
32
|
+
|
|
37
33
|
def initialize(config)
|
|
38
34
|
begin
|
|
39
35
|
@conn = Mysql.connect(config[:address], config[:user],
|
|
@@ -53,7 +49,7 @@ class MysqlBackend < Og::Backend
|
|
|
53
49
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
54
50
|
|
|
55
51
|
# Escape an SQL string
|
|
56
|
-
|
|
52
|
+
|
|
57
53
|
def self.escape(str)
|
|
58
54
|
return nil unless str
|
|
59
55
|
return Mysql.quote(str)
|
|
@@ -61,7 +57,7 @@ class MysqlBackend < Og::Backend
|
|
|
61
57
|
|
|
62
58
|
# Convert a ruby time to an sql timestamp.
|
|
63
59
|
# TODO: Optimize this
|
|
64
|
-
|
|
60
|
+
|
|
65
61
|
def self.timestamp(time = Time.now)
|
|
66
62
|
return nil unless time
|
|
67
63
|
return time.strftime("%Y%m%d%H%M%S")
|
|
@@ -69,7 +65,7 @@ class MysqlBackend < Og::Backend
|
|
|
69
65
|
|
|
70
66
|
# Output YYY-mm-dd
|
|
71
67
|
# TODO: Optimize this
|
|
72
|
-
|
|
68
|
+
|
|
73
69
|
def self.date(date)
|
|
74
70
|
return nil unless date
|
|
75
71
|
return "#{date.year}-#{date.month}-#{date.mday}"
|
|
@@ -77,14 +73,14 @@ class MysqlBackend < Og::Backend
|
|
|
77
73
|
|
|
78
74
|
# Parse sql datetime
|
|
79
75
|
# TODO: Optimize this
|
|
80
|
-
|
|
76
|
+
|
|
81
77
|
def self.parse_timestamp(str)
|
|
82
78
|
return Time.parse(str)
|
|
83
79
|
end
|
|
84
80
|
|
|
85
81
|
# Input YYYY-mm-dd
|
|
86
82
|
# TODO: Optimize this
|
|
87
|
-
|
|
83
|
+
|
|
88
84
|
def self.parse_date(str)
|
|
89
85
|
return nil unless str
|
|
90
86
|
return Date.strptime(str)
|
|
@@ -96,7 +92,7 @@ class MysqlBackend < Og::Backend
|
|
|
96
92
|
# portable.
|
|
97
93
|
#
|
|
98
94
|
# FIXME: add extra handling for float.
|
|
99
|
-
|
|
95
|
+
|
|
100
96
|
def self.write_prop(p)
|
|
101
97
|
if p.klass.ancestors.include?(Integer)
|
|
102
98
|
return "#\{@#{p.symbol} || 'NULL'\}"
|
|
@@ -109,7 +105,7 @@ class MysqlBackend < Og::Backend
|
|
|
109
105
|
elsif p.klass.ancestors.include?(Date)
|
|
110
106
|
return %|#\{@#{p.symbol} ? "'#\{Og::MysqlBackend.date(@#{p.symbol})\}'" : 'NULL'\}|
|
|
111
107
|
elsif p.klass.ancestors.include?(TrueClass)
|
|
112
|
-
return "#\{@#{p.symbol}
|
|
108
|
+
return "#\{@#{p.symbol} ? 1 : 0 \}"
|
|
113
109
|
else
|
|
114
110
|
return %|#\{@#{p.symbol} ? "'#\{Og::MysqlBackend.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
|
|
115
111
|
end
|
|
@@ -117,7 +113,7 @@ class MysqlBackend < Og::Backend
|
|
|
117
113
|
|
|
118
114
|
# Return an evaluator for reading the property.
|
|
119
115
|
# No need to optimize this, used only to precalculate code.
|
|
120
|
-
|
|
116
|
+
|
|
121
117
|
def self.read_prop(p, idx)
|
|
122
118
|
if p.klass.ancestors.include?(Integer)
|
|
123
119
|
return "res[#{idx}].to_i()"
|
|
@@ -130,7 +126,7 @@ class MysqlBackend < Og::Backend
|
|
|
130
126
|
elsif p.klass.ancestors.include?(Date)
|
|
131
127
|
return "Og::MysqlBackend.parse_date(res[#{idx}])"
|
|
132
128
|
elsif p.klass.ancestors.include?(TrueClass)
|
|
133
|
-
return "('
|
|
129
|
+
return "('0' != res[#{idx}])"
|
|
134
130
|
else
|
|
135
131
|
return "YAML::load(res[#{idx}])"
|
|
136
132
|
end
|
|
@@ -139,14 +135,14 @@ class MysqlBackend < Og::Backend
|
|
|
139
135
|
# Returns the props that will be included in the insert query.
|
|
140
136
|
# The oid property is rejected because it is mapped to an
|
|
141
137
|
# AUTO_INCREMENT column.
|
|
142
|
-
|
|
138
|
+
|
|
143
139
|
def self.props_for_insert(klass)
|
|
144
140
|
klass.__props.reject { |p| :oid == p.symbol }
|
|
145
141
|
end
|
|
146
142
|
|
|
147
|
-
|
|
143
|
+
# Returns the code that actually inserts the object into the
|
|
148
144
|
# database. Returns the code as String.
|
|
149
|
-
|
|
145
|
+
|
|
150
146
|
def self.insert_code(klass, sql, pre_cb, post_cb)
|
|
151
147
|
%{
|
|
152
148
|
#{pre_cb}
|
|
@@ -158,7 +154,7 @@ class MysqlBackend < Og::Backend
|
|
|
158
154
|
|
|
159
155
|
# generate the mapping of the database fields to the
|
|
160
156
|
# object properties.
|
|
161
|
-
|
|
157
|
+
|
|
162
158
|
def self.calc_field_index(klass, og)
|
|
163
159
|
res = og.query "SELECT * FROM #{klass::DBTABLE} LIMIT 1"
|
|
164
160
|
meta = og.managed_classes[klass]
|
|
@@ -168,8 +164,8 @@ class MysqlBackend < Og::Backend
|
|
|
168
164
|
end
|
|
169
165
|
end
|
|
170
166
|
|
|
171
|
-
# Generate the property for oid
|
|
172
|
-
|
|
167
|
+
# Generate the property for oid.
|
|
168
|
+
|
|
173
169
|
def self.eval_og_oid(klass)
|
|
174
170
|
klass.class_eval %{
|
|
175
171
|
prop_accessor :oid, Fixnum, :sql => "integer AUTO_INCREMENT PRIMARY KEY"
|
|
@@ -181,28 +177,28 @@ class MysqlBackend < Og::Backend
|
|
|
181
177
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
182
178
|
|
|
183
179
|
# Create the database.
|
|
184
|
-
|
|
180
|
+
|
|
185
181
|
def self.create_db(database, user = nil, password = nil)
|
|
186
182
|
Logger.info "Creating database '#{database}'."
|
|
187
183
|
`mysqladmin -f --user=#{user} --password=#{password} create #{database}`
|
|
188
184
|
end
|
|
189
185
|
|
|
190
186
|
# Drop the database.
|
|
191
|
-
|
|
187
|
+
|
|
192
188
|
def self.drop_db(database, user = nil, password = nil)
|
|
193
189
|
Logger.info "Dropping database '#{database}'."
|
|
194
190
|
`mysqladmin -f --user=#{user} --password=#{password} drop #{database}`
|
|
195
191
|
end
|
|
196
192
|
|
|
197
193
|
# Execute an SQL query and return the result
|
|
198
|
-
|
|
194
|
+
|
|
199
195
|
def query(sql)
|
|
200
196
|
Logger.debug sql if $DBG
|
|
201
197
|
return @conn.query(sql)
|
|
202
198
|
end
|
|
203
199
|
|
|
204
200
|
# Execute an SQL query, no result returned.
|
|
205
|
-
|
|
201
|
+
|
|
206
202
|
def exec(sql)
|
|
207
203
|
Logger.debug sql if $DBG
|
|
208
204
|
@conn.query(sql)
|
|
@@ -210,7 +206,7 @@ class MysqlBackend < Og::Backend
|
|
|
210
206
|
|
|
211
207
|
# Execute an SQL query and return the result. Wrapped in a rescue
|
|
212
208
|
# block.
|
|
213
|
-
|
|
209
|
+
|
|
214
210
|
def safe_query(sql)
|
|
215
211
|
Logger.debug sql if $DBG
|
|
216
212
|
begin
|
|
@@ -224,7 +220,7 @@ class MysqlBackend < Og::Backend
|
|
|
224
220
|
|
|
225
221
|
# Execute an SQL query, no result returned. Wrapped in a rescue
|
|
226
222
|
# block.
|
|
227
|
-
|
|
223
|
+
|
|
228
224
|
def safe_exec(sql)
|
|
229
225
|
Logger.debug sql if $DBG
|
|
230
226
|
begin
|
|
@@ -236,25 +232,25 @@ class MysqlBackend < Og::Backend
|
|
|
236
232
|
end
|
|
237
233
|
|
|
238
234
|
# Check if it is a valid resultset.
|
|
239
|
-
|
|
235
|
+
|
|
240
236
|
def valid?(res)
|
|
241
237
|
return !(res.nil? or 0 == res.num_rows)
|
|
242
238
|
end
|
|
243
239
|
|
|
244
240
|
# Start a new transaction.
|
|
245
|
-
|
|
241
|
+
|
|
246
242
|
def start
|
|
247
243
|
# no transaction support
|
|
248
244
|
end
|
|
249
245
|
|
|
250
246
|
# Commit a transaction.
|
|
251
|
-
|
|
247
|
+
|
|
252
248
|
def commit
|
|
253
249
|
# no transaction support
|
|
254
250
|
end
|
|
255
251
|
|
|
256
252
|
# Rollback transaction.
|
|
257
|
-
|
|
253
|
+
|
|
258
254
|
def rollback
|
|
259
255
|
# no transaction support
|
|
260
256
|
end
|
|
@@ -262,7 +258,7 @@ class MysqlBackend < Og::Backend
|
|
|
262
258
|
# Create the managed object table. The properties of the
|
|
263
259
|
# object are mapped to the table columns. Additional sql relations
|
|
264
260
|
# and constrains are created (indicices, sequences, etc).
|
|
265
|
-
|
|
261
|
+
|
|
266
262
|
def create_table(klass)
|
|
267
263
|
fields = create_fields(klass, TYPEMAP)
|
|
268
264
|
|
|
@@ -328,7 +324,7 @@ class MysqlBackend < Og::Backend
|
|
|
328
324
|
end
|
|
329
325
|
|
|
330
326
|
# Deserialize one row of the resultset.
|
|
331
|
-
|
|
327
|
+
|
|
332
328
|
def deserialize_one(res, klass)
|
|
333
329
|
return nil unless valid?(res)
|
|
334
330
|
|
|
@@ -343,9 +339,9 @@ class MysqlBackend < Og::Backend
|
|
|
343
339
|
end
|
|
344
340
|
|
|
345
341
|
# Deserialize all rows of the resultset.
|
|
346
|
-
|
|
342
|
+
|
|
347
343
|
def deserialize_all(res, klass)
|
|
348
|
-
return
|
|
344
|
+
return [] unless valid?(res)
|
|
349
345
|
|
|
350
346
|
entities = []
|
|
351
347
|
|
|
@@ -364,11 +360,11 @@ class MysqlBackend < Og::Backend
|
|
|
364
360
|
end
|
|
365
361
|
|
|
366
362
|
# Return a single integer value from the resultset.
|
|
367
|
-
|
|
363
|
+
|
|
368
364
|
def get_int(res, idx = 0)
|
|
369
365
|
return res.fetch_row[idx].to_i
|
|
370
366
|
end
|
|
371
367
|
|
|
372
368
|
end
|
|
373
369
|
|
|
374
|
-
end
|
|
370
|
+
end
|
data/lib/og/backends/psql.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# code:
|
|
2
1
|
# * George Moschovitis <gm@navel.gr>
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# $Id: psql.rb 194 2004-12-20 20:23:57Z gmosx $
|
|
2
|
+
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
+
# $Id: psql.rb 248 2005-01-31 13:38:34Z gmosx $
|
|
6
4
|
|
|
7
5
|
require 'postgres'
|
|
8
6
|
|
|
@@ -10,16 +8,14 @@ require 'og/backend'
|
|
|
10
8
|
|
|
11
9
|
class Og
|
|
12
10
|
|
|
13
|
-
# = PsqlBackend
|
|
14
|
-
#
|
|
15
11
|
# Implements a PostgreSQL powered backend.
|
|
16
12
|
# This backend is compatible with Michael Neumann's postgres-pr
|
|
17
13
|
# pure ruby driver.
|
|
18
|
-
|
|
14
|
+
|
|
19
15
|
class PsqlBackend < Og::Backend
|
|
20
16
|
|
|
21
17
|
# A mapping between Ruby and SQL types.
|
|
22
|
-
|
|
18
|
+
|
|
23
19
|
TYPEMAP = {
|
|
24
20
|
Integer => 'integer',
|
|
25
21
|
Fixnum => 'integer',
|
|
@@ -34,7 +30,7 @@ class PsqlBackend < Og::Backend
|
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
# Intitialize the connection to the RDBMS.
|
|
37
|
-
|
|
33
|
+
|
|
38
34
|
def initialize(config)
|
|
39
35
|
begin
|
|
40
36
|
@conn = PGconn.connect(nil, nil, nil, nil, config[:database],
|
|
@@ -55,7 +51,7 @@ class PsqlBackend < Og::Backend
|
|
|
55
51
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
56
52
|
|
|
57
53
|
# Escape an SQL string
|
|
58
|
-
|
|
54
|
+
|
|
59
55
|
def self.escape(str)
|
|
60
56
|
return nil unless str
|
|
61
57
|
return PGconn.escape(str)
|
|
@@ -63,7 +59,7 @@ class PsqlBackend < Og::Backend
|
|
|
63
59
|
|
|
64
60
|
# Convert a ruby time to an sql timestamp.
|
|
65
61
|
# TODO: Optimize this
|
|
66
|
-
|
|
62
|
+
|
|
67
63
|
def self.timestamp(time = Time.now)
|
|
68
64
|
return nil unless time
|
|
69
65
|
return time.strftime("%Y-%m-%d %H:%M:%S")
|
|
@@ -71,7 +67,7 @@ class PsqlBackend < Og::Backend
|
|
|
71
67
|
|
|
72
68
|
# Output YYY-mm-dd
|
|
73
69
|
# TODO: Optimize this
|
|
74
|
-
|
|
70
|
+
|
|
75
71
|
def self.date(date)
|
|
76
72
|
return nil unless date
|
|
77
73
|
return "#{date.year}-#{date.month}-#{date.mday}"
|
|
@@ -79,14 +75,14 @@ class PsqlBackend < Og::Backend
|
|
|
79
75
|
|
|
80
76
|
# Parse sql datetime
|
|
81
77
|
# TODO: Optimize this
|
|
82
|
-
|
|
78
|
+
|
|
83
79
|
def self.parse_timestamp(str)
|
|
84
80
|
return Time.parse(str)
|
|
85
81
|
end
|
|
86
82
|
|
|
87
83
|
# Input YYYY-mm-dd
|
|
88
84
|
# TODO: Optimize this
|
|
89
|
-
|
|
85
|
+
|
|
90
86
|
def self.parse_date(str)
|
|
91
87
|
return nil unless str
|
|
92
88
|
return Date.strptime(str)
|
|
@@ -98,7 +94,7 @@ class PsqlBackend < Og::Backend
|
|
|
98
94
|
# portable.
|
|
99
95
|
#
|
|
100
96
|
# FIXME: add extra handling for float.
|
|
101
|
-
|
|
97
|
+
|
|
102
98
|
def self.write_prop(p)
|
|
103
99
|
if p.klass.ancestors.include?(Integer)
|
|
104
100
|
return "#\{@#{p.symbol} || 'NULL'\}"
|
|
@@ -111,7 +107,7 @@ class PsqlBackend < Og::Backend
|
|
|
111
107
|
elsif p.klass.ancestors.include?(Date)
|
|
112
108
|
return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.date(@#{p.symbol})\}'" : 'NULL'\}|
|
|
113
109
|
elsif p.klass.ancestors.include?(TrueClass)
|
|
114
|
-
return "#\{@#{p.symbol}
|
|
110
|
+
return "#\{@#{p.symbol} ? \"'t'\" : 'NULL' \}"
|
|
115
111
|
else
|
|
116
112
|
return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
|
|
117
113
|
end
|
|
@@ -119,7 +115,7 @@ class PsqlBackend < Og::Backend
|
|
|
119
115
|
|
|
120
116
|
# Return an evaluator for reading the property.
|
|
121
117
|
# No need to optimize this, used only to precalculate code.
|
|
122
|
-
|
|
118
|
+
|
|
123
119
|
def self.read_prop(p, idx)
|
|
124
120
|
if p.klass.ancestors.include?(Integer)
|
|
125
121
|
return "res.getvalue(tuple, #{idx}).to_i()"
|
|
@@ -132,7 +128,7 @@ class PsqlBackend < Og::Backend
|
|
|
132
128
|
elsif p.klass.ancestors.include?(Date)
|
|
133
129
|
return "Og::PsqlBackend.parse_date(res.getvalue(tuple, #{idx}))"
|
|
134
130
|
elsif p.klass.ancestors.include?(TrueClass)
|
|
135
|
-
return
|
|
131
|
+
return %|('t' == res.getvalue(tuple, #{idx}))|
|
|
136
132
|
else
|
|
137
133
|
return "YAML::load(res.getvalue(tuple, #{idx}))"
|
|
138
134
|
end
|
|
@@ -140,7 +136,7 @@ class PsqlBackend < Og::Backend
|
|
|
140
136
|
|
|
141
137
|
# Returns the code that actually inserts the object into the
|
|
142
138
|
# database. Returns the code as String.
|
|
143
|
-
|
|
139
|
+
|
|
144
140
|
def self.insert_code(klass, sql, pre_cb, post_cb)
|
|
145
141
|
%{
|
|
146
142
|
#{pre_cb}
|
|
@@ -153,7 +149,7 @@ class PsqlBackend < Og::Backend
|
|
|
153
149
|
|
|
154
150
|
# generate the mapping of the database fields to the
|
|
155
151
|
# object properties.
|
|
156
|
-
|
|
152
|
+
|
|
157
153
|
def self.calc_field_index(klass, og)
|
|
158
154
|
res = og.query "SELECT * FROM #{klass::DBTABLE} LIMIT 1"
|
|
159
155
|
meta = og.managed_classes[klass]
|
|
@@ -164,7 +160,7 @@ class PsqlBackend < Og::Backend
|
|
|
164
160
|
end
|
|
165
161
|
|
|
166
162
|
# Generate the property for oid
|
|
167
|
-
|
|
163
|
+
|
|
168
164
|
def self.eval_og_oid(klass)
|
|
169
165
|
klass.class_eval %{
|
|
170
166
|
prop_accessor :oid, Fixnum, :sql => "integer PRIMARY KEY"
|
|
@@ -176,28 +172,28 @@ class PsqlBackend < Og::Backend
|
|
|
176
172
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
177
173
|
|
|
178
174
|
# Create the database.
|
|
179
|
-
|
|
175
|
+
|
|
180
176
|
def self.create_db(database, user = nil, password = nil)
|
|
181
177
|
Logger.info "Creating database '#{database}'."
|
|
182
178
|
`createdb #{database} -U #{user}`
|
|
183
179
|
end
|
|
184
180
|
|
|
185
181
|
# Drop the database.
|
|
186
|
-
|
|
182
|
+
|
|
187
183
|
def self.drop_db(database, user = nil, password = nil)
|
|
188
184
|
Logger.info "Dropping database '#{database}'."
|
|
189
185
|
`dropdb #{database} -U #{user}`
|
|
190
186
|
end
|
|
191
187
|
|
|
192
|
-
# Execute an SQL query and return the result
|
|
193
|
-
|
|
188
|
+
# Execute an SQL query and return the result.
|
|
189
|
+
|
|
194
190
|
def query(sql)
|
|
195
191
|
Logger.debug sql if $DBG
|
|
196
192
|
return @conn.exec(sql)
|
|
197
193
|
end
|
|
198
194
|
|
|
199
195
|
# Execute an SQL query, no result returned.
|
|
200
|
-
|
|
196
|
+
|
|
201
197
|
def exec(sql)
|
|
202
198
|
Logger.debug sql if $DBG
|
|
203
199
|
res = @conn.exec(sql)
|
|
@@ -206,7 +202,7 @@ class PsqlBackend < Og::Backend
|
|
|
206
202
|
|
|
207
203
|
# Execute an SQL query and return the result. Wrapped in a rescue
|
|
208
204
|
# block.
|
|
209
|
-
|
|
205
|
+
|
|
210
206
|
def safe_query(sql)
|
|
211
207
|
Logger.debug sql if $DBG
|
|
212
208
|
begin
|
|
@@ -220,7 +216,7 @@ class PsqlBackend < Og::Backend
|
|
|
220
216
|
|
|
221
217
|
# Execute an SQL query, no result returned. Wrapped in a rescue
|
|
222
218
|
# block.
|
|
223
|
-
|
|
219
|
+
|
|
224
220
|
def safe_exec(sql)
|
|
225
221
|
Logger.debug sql if $DBG
|
|
226
222
|
begin
|
|
@@ -233,7 +229,7 @@ class PsqlBackend < Og::Backend
|
|
|
233
229
|
end
|
|
234
230
|
|
|
235
231
|
# Check if it is a valid resultset.
|
|
236
|
-
|
|
232
|
+
|
|
237
233
|
def valid?(res)
|
|
238
234
|
return !(res.nil? or 0 == res.num_tuples)
|
|
239
235
|
end
|
|
@@ -241,7 +237,7 @@ class PsqlBackend < Og::Backend
|
|
|
241
237
|
# Create the managed object table. The properties of the
|
|
242
238
|
# object are mapped to the table columns. Additional sql relations
|
|
243
239
|
# and constrains are created (indicices, sequences, etc).
|
|
244
|
-
|
|
240
|
+
|
|
245
241
|
def create_table(klass)
|
|
246
242
|
fields = create_fields(klass, TYPEMAP)
|
|
247
243
|
|
|
@@ -282,6 +278,7 @@ class PsqlBackend < Og::Backend
|
|
|
282
278
|
# create the sequence for this table. Even if the table
|
|
283
279
|
# uses the oids_seq, attempt to create it. This makes
|
|
284
280
|
# the system more fault tolerant.
|
|
281
|
+
|
|
285
282
|
begin
|
|
286
283
|
exec "CREATE SEQUENCE #{klass::DBSEQ}"
|
|
287
284
|
Logger.info "Created sequence '#{klass::DBSEQ}'."
|
|
@@ -336,15 +333,15 @@ class PsqlBackend < Og::Backend
|
|
|
336
333
|
|
|
337
334
|
end
|
|
338
335
|
|
|
339
|
-
# Drop the managed object table
|
|
340
|
-
|
|
336
|
+
# Drop the managed object table.
|
|
337
|
+
|
|
341
338
|
def drop_table(klass)
|
|
342
339
|
super
|
|
343
340
|
exec "DROP SEQUENCE #{klass::DBSEQ}"
|
|
344
341
|
end
|
|
345
342
|
|
|
346
343
|
# Deserialize one row of the resultset.
|
|
347
|
-
|
|
344
|
+
|
|
348
345
|
def deserialize_one(res, klass)
|
|
349
346
|
return nil unless valid?(res)
|
|
350
347
|
|
|
@@ -359,9 +356,9 @@ class PsqlBackend < Og::Backend
|
|
|
359
356
|
end
|
|
360
357
|
|
|
361
358
|
# Deserialize all rows of the resultset.
|
|
362
|
-
|
|
359
|
+
|
|
363
360
|
def deserialize_all(res, klass)
|
|
364
|
-
return
|
|
361
|
+
return [] unless valid?(res)
|
|
365
362
|
|
|
366
363
|
entities = []
|
|
367
364
|
|
|
@@ -379,11 +376,11 @@ class PsqlBackend < Og::Backend
|
|
|
379
376
|
end
|
|
380
377
|
|
|
381
378
|
# Return a single integer value from the resultset.
|
|
382
|
-
|
|
379
|
+
|
|
383
380
|
def get_int(res, idx = 0)
|
|
384
381
|
return res.getvalue(0, idx).to_i
|
|
385
382
|
end
|
|
386
383
|
|
|
387
384
|
end
|
|
388
385
|
|
|
389
|
-
end
|
|
386
|
+
end
|