nitro 0.8.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. data/AUTHORS +3 -4
  2. data/ChangeLog +418 -0
  3. data/LICENSE +1 -1
  4. data/README +157 -89
  5. data/RELEASES +50 -0
  6. data/Rakefile +5 -7
  7. data/benchmark/nitro/bench.rb +5 -0
  8. data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
  9. data/benchmark/nitro/static-webrick-n-200.txt +43 -0
  10. data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
  11. data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
  12. data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
  13. data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
  14. data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
  15. data/bin/proto/README +2 -2
  16. data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
  17. data/bin/proto/conf/app.conf.rb +22 -0
  18. data/bin/proto/conf/lhttpd.conf +236 -0
  19. data/bin/proto/ctl +4 -0
  20. data/bin/proto/lib/README +5 -0
  21. data/bin/proto/log/README +3 -0
  22. data/bin/proto/root/fcgi.rb +6 -0
  23. data/bin/proto/root/index.xhtml +65 -7
  24. data/bin/proto/root/m/nitro.png +0 -0
  25. data/examples/blog/README +7 -5
  26. data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
  27. data/examples/blog/conf/app.conf.rb +56 -0
  28. data/examples/blog/conf/lhttpd.conf +236 -0
  29. data/examples/blog/ctl +4 -0
  30. data/examples/blog/lib/blog.rb +11 -136
  31. data/examples/blog/lib/blog/controller.rb +99 -0
  32. data/examples/blog/lib/blog/model.rb +39 -0
  33. data/examples/blog/log/README +3 -0
  34. data/examples/blog/root/comments.xhtml +2 -2
  35. data/examples/blog/root/fcgi.rb +6 -0
  36. data/examples/blog/root/index.xhtml +4 -5
  37. data/examples/blog/root/login.xhtml +2 -2
  38. data/examples/blog/root/style.xsl +9 -9
  39. data/examples/blog/root/view_entry.xhtml +2 -2
  40. data/examples/flash/conf/app.conf.rb +23 -0
  41. data/examples/flash/ctl +4 -0
  42. data/examples/flash/log/README +3 -0
  43. data/examples/flash/root/index.xhtml +0 -9
  44. data/examples/flash/root/show_inline_text.xhtml +10 -5
  45. data/examples/no_xsl_blog/README +12 -0
  46. data/examples/no_xsl_blog/conf/apache.conf +0 -0
  47. data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
  48. data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
  49. data/examples/no_xsl_blog/ctl +4 -0
  50. data/examples/no_xsl_blog/lib/blog.rb +20 -0
  51. data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
  52. data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
  53. data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
  54. data/examples/no_xsl_blog/log/README +3 -0
  55. data/examples/no_xsl_blog/root/comments.xhtml +41 -0
  56. data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
  57. data/examples/no_xsl_blog/root/fcgi.rb +6 -0
  58. data/examples/no_xsl_blog/root/index.xhtml +39 -0
  59. data/examples/no_xsl_blog/root/login.xhtml +21 -0
  60. data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
  61. data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
  62. data/examples/no_xsl_blog/root/m/down.gif +0 -0
  63. data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
  64. data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
  65. data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
  66. data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
  67. data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
  68. data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
  69. data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
  70. data/examples/no_xsl_blog/root/m/obull.gif +0 -0
  71. data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
  72. data/examples/no_xsl_blog/root/m/rss.gif +0 -0
  73. data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
  74. data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
  75. data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
  76. data/examples/no_xsl_blog/root/style.css +301 -0
  77. data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
  78. data/examples/no_xsl_blog/root/view_entry.xml +12 -0
  79. data/examples/og/run.rb +2 -2
  80. data/examples/tiny/README +2 -2
  81. data/examples/tiny/conf/apache.conf +5 -0
  82. data/examples/tiny/conf/app.conf.rb +21 -0
  83. data/examples/tiny/conf/lhttpd.conf +236 -0
  84. data/examples/tiny/ctl +4 -0
  85. data/examples/tiny/log/README +3 -0
  86. data/examples/tiny/root/fcgi.rb +6 -0
  87. data/examples/tiny/root/index.xhtml +7 -4
  88. data/examples/tiny/root/nitro.png +0 -0
  89. data/lib/glue.rb +13 -9
  90. data/lib/glue/array.rb +1 -1
  91. data/lib/glue/cache.rb +1 -1
  92. data/lib/glue/flexob.rb +12 -0
  93. data/lib/glue/hash.rb +1 -1
  94. data/lib/glue/inflector.rb +2 -2
  95. data/lib/glue/logger.rb +4 -8
  96. data/lib/glue/misc.rb +14 -0
  97. data/lib/glue/number.rb +1 -1
  98. data/lib/glue/object.rb +26 -0
  99. data/lib/glue/pool.rb +1 -1
  100. data/lib/glue/property.rb +84 -91
  101. data/lib/glue/string.rb +1 -1
  102. data/lib/glue/time.rb +1 -1
  103. data/lib/glue/validation.rb +1 -1
  104. data/lib/nitro.rb +18 -6
  105. data/lib/nitro/adaptors/cgi.rb +291 -0
  106. data/lib/nitro/adaptors/fastcgi.rb +42 -0
  107. data/lib/nitro/adaptors/runner.rb +123 -0
  108. data/lib/nitro/adaptors/webrick.rb +110 -0
  109. data/lib/nitro/buffering.rb +43 -0
  110. data/lib/nitro/builders/form.rb +1 -1
  111. data/lib/nitro/builders/rss.rb +1 -1
  112. data/{bin → lib/nitro}/cluster.rb +26 -30
  113. data/lib/nitro/context.rb +82 -0
  114. data/lib/nitro/controller.rb +50 -0
  115. data/lib/nitro/cookie.rb +46 -0
  116. data/lib/nitro/dispatcher.rb +105 -0
  117. data/lib/nitro/filters.rb +9 -10
  118. data/lib/nitro/localization.rb +42 -0
  119. data/lib/nitro/mail.rb +11 -14
  120. data/lib/nitro/render.rb +275 -0
  121. data/lib/nitro/request.rb +128 -0
  122. data/lib/nitro/response.rb +38 -0
  123. data/lib/nitro/scaffold.rb +11 -11
  124. data/lib/nitro/session.rb +84 -0
  125. data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
  126. data/lib/nitro/ui/pager.rb +23 -26
  127. data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
  128. data/lib/nitro/uri.rb +1 -1
  129. data/lib/nitro/version.rb +10 -8
  130. data/lib/og.rb +66 -65
  131. data/lib/og/backend.rb +1 -1
  132. data/lib/og/backends/mysql.rb +48 -52
  133. data/lib/og/backends/psql.rb +34 -37
  134. data/lib/og/connection.rb +15 -15
  135. data/lib/og/enchant.rb +16 -9
  136. data/lib/og/meta.rb +127 -54
  137. data/lib/og/mock.rb +18 -18
  138. data/lib/og/version.rb +6 -4
  139. data/lib/parts/content.rb +4 -8
  140. data/test/glue/tc_logger.rb +3 -0
  141. data/test/glue/tc_property.rb +19 -3
  142. data/test/nitro/adaptors/tc_cgi.rb +63 -0
  143. data/test/nitro/adaptors/tc_webrick.rb +15 -0
  144. data/test/nitro/builders/tc_xml.rb +2 -2
  145. data/test/nitro/tc_context.rb +13 -0
  146. data/test/nitro/tc_controller.rb +47 -0
  147. data/test/nitro/tc_dispatcher.rb +64 -0
  148. data/test/nitro/tc_session.rb +20 -0
  149. data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
  150. data/test/root/blog/list.xhtml +6 -0
  151. data/test/tc_og.rb +41 -4
  152. metadata +115 -59
  153. data/bin/proto/app.rb +0 -20
  154. data/bin/proto/config.rb +0 -77
  155. data/examples/blog/app.rb +0 -21
  156. data/examples/blog/config.rb +0 -95
  157. data/examples/blog/env.rb +0 -22
  158. data/examples/flash/README +0 -34
  159. data/examples/flash/app.rb +0 -20
  160. data/examples/flash/config.rb +0 -38
  161. data/examples/flash/lib/flash.rb +0 -40
  162. data/examples/flash/tmp.swf +0 -0
  163. data/examples/tiny/app.rb +0 -19
  164. data/examples/tiny/config.rb +0 -29
  165. data/examples/tiny/root/nitro-small.png +0 -0
  166. data/lib/nitro/application.rb +0 -217
  167. data/lib/nitro/config.rb +0 -128
  168. data/lib/nitro/events.rb +0 -122
  169. data/lib/nitro/html.rb +0 -151
  170. data/lib/nitro/http.rb +0 -102
  171. data/lib/nitro/l10n.rb +0 -30
  172. data/lib/nitro/server.rb +0 -59
  173. data/lib/nitro/server/appserver.rb +0 -67
  174. data/lib/nitro/server/cookie.rb +0 -87
  175. data/lib/nitro/server/dispatcher.rb +0 -62
  176. data/lib/nitro/server/filters.rb +0 -75
  177. data/lib/nitro/server/filters/autologin.rb +0 -51
  178. data/lib/nitro/server/fragment.rb +0 -70
  179. data/lib/nitro/server/handlers.rb +0 -127
  180. data/lib/nitro/server/render.rb +0 -426
  181. data/lib/nitro/server/request.rb +0 -658
  182. data/lib/nitro/server/requestpart.rb +0 -54
  183. data/lib/nitro/server/script.rb +0 -387
  184. data/lib/nitro/server/server.rb +0 -57
  185. data/lib/nitro/server/session.rb +0 -220
  186. data/lib/nitro/server/user.rb +0 -46
  187. data/lib/nitro/server/webrick.rb +0 -180
  188. data/lib/nitro/service.rb +0 -26
  189. data/lib/xsl/ui.xsl +0 -51
  190. data/lib/xsl/xforms.xsl +0 -28
  191. data/test/nitro/server/tc_cookie.rb +0 -34
  192. data/test/nitro/server/tc_filters.rb +0 -38
  193. data/test/nitro/server/tc_request.rb +0 -70
  194. data/test/nitro/server/tc_requestpart.rb +0 -28
  195. data/test/nitro/server/tc_session.rb +0 -34
  196. data/test/nitro/tc_events.rb +0 -44
  197. data/test/nitro/tc_html.rb +0 -79
  198. data/test/nitro/tc_http.rb +0 -18
@@ -2,7 +2,7 @@
2
2
  # * George Moschovitis <gm@navel.gr>
3
3
  #
4
4
  # (c) 2004 Navel, all rights reserved.
5
- # $Id: backend.rb 197 2004-12-21 13:50:17Z gmosx $
5
+ # $Id: backend.rb 202 2005-01-17 10:44:13Z gmosx $
6
6
 
7
7
  require "yaml"
8
8
 
@@ -1,39 +1,35 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
2
  # * Elias Athanasopoulos <elathan@navel.gr>
4
- #
5
- # (c) 2004 Navel, all rights reserved.
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 "mysql"
6
+ require 'mysql'
9
7
 
10
- require "og/backend"
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 => "integer",
24
- Fixnum => "integer",
25
- Float => "float",
26
- String => "text",
27
- Time => "timestamp",
28
- Date => "date",
29
- TrueClass => "boolean",
30
- Object => "text",
31
- Array => "text",
32
- Hash => "text"
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} || 'NULL'\}"
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 "('true' == res[#{idx}])"
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
- # Returns the code that actually inserts the object into the
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 nil unless valid?(res)
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 # module
370
+ end
@@ -1,8 +1,6 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
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} || 'NULL'\}"
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 "('true' == res.getvalue(tuple, #{idx}))"
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 nil unless valid?(res)
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 # module
386
+ end