nitro 0.7.0 → 0.8.0

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.
Files changed (102) hide show
  1. data/AUTHORS +14 -4
  2. data/ChangeLog +192 -1
  3. data/README +50 -6
  4. data/RELEASES +60 -0
  5. data/Rakefile +1 -1
  6. data/bin/cluster.rb +2 -2
  7. data/bin/new_form.rb +1 -1
  8. data/examples/blog/config.rb +5 -4
  9. data/examples/blog/lib/blog.rb +56 -36
  10. data/examples/blog/root/comments.xhtml +5 -2
  11. data/examples/blog/root/entry_form.xhtml +7 -2
  12. data/examples/blog/root/login.xhtml +1 -1
  13. data/examples/blog/root/style.xsl +7 -0
  14. data/examples/og/mock_example.rb +6 -9
  15. data/examples/og/mysql_to_psql.rb +100 -0
  16. data/examples/og/run.rb +8 -17
  17. data/lib/glue.rb +7 -8
  18. data/lib/glue/array.rb +1 -1
  19. data/lib/glue/attribute.rb +86 -0
  20. data/lib/glue/cache.rb +1 -1
  21. data/lib/glue/hash.rb +1 -1
  22. data/lib/glue/inflector.rb +1 -1
  23. data/lib/glue/logger.rb +118 -18
  24. data/lib/glue/mixins.rb +1 -1
  25. data/lib/glue/number.rb +1 -1
  26. data/lib/glue/pool.rb +1 -1
  27. data/lib/glue/property.rb +48 -31
  28. data/lib/glue/string.rb +1 -1
  29. data/lib/glue/time.rb +2 -2
  30. data/lib/glue/validation.rb +400 -0
  31. data/lib/nitro/application.rb +6 -6
  32. data/lib/nitro/builders/form.rb +5 -5
  33. data/lib/nitro/builders/rss.rb +1 -1
  34. data/lib/nitro/builders/xhtml.rb +119 -0
  35. data/lib/nitro/builders/xml.rb +111 -0
  36. data/lib/nitro/config.rb +6 -6
  37. data/lib/nitro/events.rb +1 -1
  38. data/lib/nitro/html.rb +1 -1
  39. data/lib/nitro/markup.rb +15 -20
  40. data/lib/nitro/scaffold.rb +2 -2
  41. data/lib/nitro/server/appserver.rb +3 -3
  42. data/lib/nitro/server/cluster.rb +2 -2
  43. data/lib/nitro/server/dispatcher.rb +2 -2
  44. data/lib/nitro/server/filters/autologin.rb +1 -1
  45. data/lib/nitro/server/fragment.rb +2 -2
  46. data/lib/nitro/server/handlers.rb +2 -2
  47. data/lib/nitro/server/render.rb +17 -15
  48. data/lib/nitro/server/request.rb +6 -6
  49. data/lib/nitro/server/script.rb +2 -2
  50. data/lib/nitro/server/server.rb +2 -2
  51. data/lib/nitro/server/session.rb +6 -6
  52. data/lib/nitro/server/shaders.rb +2 -2
  53. data/lib/nitro/server/webrick.rb +1 -1
  54. data/lib/nitro/sitemap.rb +2 -2
  55. data/lib/nitro/uri.rb +1 -1
  56. data/lib/nitro/version.rb +7 -5
  57. data/lib/og.rb +95 -129
  58. data/lib/og/backend.rb +47 -46
  59. data/lib/og/backends/mysql.rb +64 -63
  60. data/lib/og/backends/psql.rb +73 -72
  61. data/lib/og/connection.rb +7 -8
  62. data/lib/og/enchant.rb +80 -0
  63. data/lib/og/meta.rb +21 -21
  64. data/lib/og/mock.rb +31 -88
  65. data/lib/og/version.rb +6 -5
  66. data/lib/parts/README +9 -0
  67. data/lib/parts/content.rb +23 -9
  68. data/test/glue/tc_attribute.rb +22 -0
  69. data/test/glue/tc_cache.rb +4 -6
  70. data/test/glue/tc_hash.rb +2 -2
  71. data/test/glue/tc_logger.rb +36 -0
  72. data/test/glue/tc_numbers.rb +2 -2
  73. data/test/glue/tc_property_mixins.rb +35 -4
  74. data/test/glue/tc_strings.rb +32 -32
  75. data/test/glue/tc_validation.rb +186 -0
  76. data/test/nitro/builders/tc_xhtml.rb +38 -0
  77. data/test/nitro/builders/tc_xml.rb +47 -0
  78. data/test/nitro/server/tc_request.rb +2 -2
  79. data/test/nitro/server/tc_session.rb +1 -1
  80. data/test/nitro/tc_sitemap.rb +1 -1
  81. data/test/nitro/ui/tc_pager.rb +1 -10
  82. data/test/tc_og.rb +3 -3
  83. data/vendor/blankslate.rb +53 -0
  84. data/vendor/extensions/_base.rb +153 -0
  85. data/vendor/extensions/_template.rb +36 -0
  86. data/vendor/extensions/all.rb +21 -0
  87. data/vendor/extensions/array.rb +68 -0
  88. data/vendor/extensions/binding.rb +224 -0
  89. data/vendor/extensions/class.rb +50 -0
  90. data/vendor/extensions/continuation.rb +71 -0
  91. data/vendor/extensions/enumerable.rb +250 -0
  92. data/vendor/extensions/hash.rb +23 -0
  93. data/vendor/extensions/io.rb +58 -0
  94. data/vendor/extensions/kernel.rb +42 -0
  95. data/vendor/extensions/module.rb +114 -0
  96. data/vendor/extensions/numeric.rb +230 -0
  97. data/vendor/extensions/object.rb +164 -0
  98. data/vendor/extensions/ostruct.rb +41 -0
  99. data/vendor/extensions/string.rb +316 -0
  100. data/vendor/extensions/symbol.rb +28 -0
  101. metadata +35 -13
  102. data/lib/glue/property.rb.old +0 -307
@@ -8,33 +8,54 @@ require "yaml"
8
8
 
9
9
  require "og/connection"
10
10
 
11
- module Og
11
+ class Og
12
12
 
13
- # = OgUtils
13
+ # = Backend
14
14
  #
15
- # A collection of useful utilities.
15
+ # Abstract backend. A backend communicates with the RDBMS.
16
+ # This is the base class for the various backend implementations.
16
17
  #
17
- module Utils
18
+ class Backend
19
+
20
+ # The actual connection to the database
21
+ attr_accessor :conn
22
+
23
+ # Intitialize the connection to the RDBMS.
24
+ #
25
+ def initialize(config)
26
+ raise "Not implemented"
27
+ end
28
+
29
+ # Close the connection to the RDBMS.
30
+ #
31
+ def close()
32
+ @conn.close()
33
+ end
34
+
35
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36
+ # Utilities
37
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18
38
 
19
39
  # Encode the name of the klass as an sql safe string.
20
- # The Module separators are replaced with _ and NOT stripped out so
21
- # that we can convert back to the original notation if needed.
22
- # The leading module if available is removed.
40
+ # The Module separators are replaced with _ and NOT stripped
41
+ # out so that we can convert back to the original notation if
42
+ # needed. The leading module if available is removed.
23
43
  #
24
44
  def self.encode(klass)
25
45
  "#{klass.name.gsub(/^.*::/, "")}".gsub(/::/, "_").downcase
26
46
  end
27
47
 
28
- # The name of the SQL table where objects of this class are stored.
48
+ # The name of the SQL table where objects of this class
49
+ # are stored.
29
50
  #
30
51
  def self.table(klass)
31
- "_#{$og_table_prefix}#{encode(klass)}"
52
+ "_#{Og.table_prefix}#{encode(klass)}"
32
53
  end
33
54
 
34
55
  # The name of the join table for the two given classes.
35
56
  #
36
57
  def self.join_table(klass1, klass2)
37
- "_#{$og_table_prefix}j_#{Og::Utils.encode(klass1)}_#{Og::Utils.encode(klass2)}"
58
+ "_#{Og.table_prefix}j_#{encode(klass1)}_#{encode(klass2)}"
38
59
  end
39
60
 
40
61
  # Returns the props that will be included in the insert query.
@@ -123,8 +144,8 @@ module Utils
123
144
  end
124
145
 
125
146
  # Precompile the code to read objects of the given class
126
- # from the backend. In order to allow for changing field/attribute
127
- # orders we have to use a field mapping hash.
147
+ # from the backend. In order to allow for changing
148
+ # field/attribute orders we have to use a field mapping hash.
128
149
  #
129
150
  def self.eval_og_deserialize(klass, og)
130
151
  calc_field_index(klass, og)
@@ -136,7 +157,7 @@ module Utils
136
157
  if idx = og.managed_classes[klass].field_index[p.name]
137
158
  # more fault tolerant if a new field is added and it
138
159
  # doesnt exist in the database.
139
- code << "@#{p.name} = #{Og::Utils.read_prop(p, idx)}"
160
+ code << "@#{p.name} = #{read_prop(p, idx)}"
140
161
  end
141
162
  end
142
163
 
@@ -147,40 +168,20 @@ module Utils
147
168
  }
148
169
  end
149
170
 
150
- end
151
-
152
- # = Backend
153
- #
154
- # Abstract backend. A backend communicates with the RDBMS.
155
- # This is the base class for the various backend implementations.
156
- #
157
- class Backend
158
-
159
- # The actual connection to the database
160
- attr_accessor :conn
161
-
162
- # Intitialize the connection to the RDBMS.
163
- #
164
- def initialize(config)
165
- raise "Not implemented"
166
- end
167
-
168
- # Close the connection to the RDBMS.
169
- #
170
- def close()
171
- @conn.close()
172
- end
171
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
172
+ # Connection methods.
173
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
173
174
 
174
175
  # Create the database.
175
176
  #
176
177
  def self.create_db(database, user = nil, password = nil)
177
- $log.info "Creating database '#{database}'."
178
+ Logger.info "Creating database '#{database}'."
178
179
  end
179
180
 
180
181
  # Drop the database.
181
182
  #
182
183
  def self.drop_db(database, user = nil, password = nil)
183
- $log.info "Dropping database '#{database}'."
184
+ Logger.info "Dropping database '#{database}'."
184
185
  end
185
186
 
186
187
  # Execute an SQL query and return the result.
@@ -195,15 +196,15 @@ class Backend
195
196
  raise "Not implemented"
196
197
  end
197
198
 
198
- # Execute an SQL query and return the result. Wrapped in a rescue
199
- # block.
199
+ # Execute an SQL query and return the result. Wrapped in a
200
+ # rescue block.
200
201
  #
201
202
  def safe_query(sql)
202
203
  raise "Not implemented"
203
204
  end
204
205
 
205
- # Execute an SQL query, no result returned. Wrapped in a rescue
206
- # block.
206
+ # Execute an SQL query, no result returned. Wrapped in a
207
+ # rescue block.
207
208
  #
208
209
  def safe_exec(sql)
209
210
  raise "Not implemented"
@@ -235,9 +236,9 @@ class Backend
235
236
 
236
237
  # Create the fields that correpsond to the klass properties.
237
238
  # The generated fields array is used in create_table.
238
- # If the property has an :sql metadata this overrides the default mapping.
239
- # If the property has an :extra_sql metadata the extra sql is appended
240
- # after the default mapping.
239
+ # If the property has an :sql metadata this overrides the
240
+ # default mapping. If the property has an :extra_sql metadata
241
+ # the extra sql is appended after the default mapping.
241
242
  #
242
243
  def create_fields(klass, typemap)
243
244
  fields = []
@@ -297,4 +298,4 @@ class Backend
297
298
 
298
299
  end
299
300
 
300
- end # module
301
+ end # namespace
@@ -9,13 +9,48 @@ require "mysql"
9
9
 
10
10
  require "og/backend"
11
11
 
12
- module Og
12
+ class Og
13
13
 
14
- # = Utils
14
+ # = MysqlBackend
15
15
  #
16
- # A collection of useful utilities.
16
+ # Implements a MySQL powered backend.
17
17
  #
18
- module Utils
18
+ class MysqlBackend < Og::Backend
19
+
20
+ # A mapping between Ruby and SQL types.
21
+ #
22
+ 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"
33
+ }
34
+
35
+ # Intitialize the connection to the RDBMS.
36
+ #
37
+ def initialize(config)
38
+ begin
39
+ @conn = Mysql.connect(config[:address], config[:user],
40
+ config[:password], config[:database])
41
+ rescue => ex
42
+ if ex.errno == 1049 # database does not exist.
43
+ Logger.info "Database '#{config[:database]}' not found!"
44
+ MysqlBackend.create_db(config[:database], config[:user], config[:password])
45
+ retry
46
+ end
47
+ raise
48
+ end
49
+ end
50
+
51
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
52
+ # Utilities
53
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
19
54
 
20
55
  # Escape an SQL string
21
56
  #
@@ -68,15 +103,15 @@ module Utils
68
103
  elsif p.klass.ancestors.include?(Float)
69
104
  return "#\{@#{p.symbol} || 'NULL'\}"
70
105
  elsif p.klass.ancestors.include?(String)
71
- return "'#\{Og::Utils.escape(@#{p.symbol})\}'"
106
+ return "'#\{Og::MysqlBackend.escape(@#{p.symbol})\}'"
72
107
  elsif p.klass.ancestors.include?(Time)
73
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
108
+ return %|#\{@#{p.symbol} ? "'#\{Og::MysqlBackend.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
74
109
  elsif p.klass.ancestors.include?(Date)
75
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.date(@#{p.symbol})\}'" : 'NULL'\}|
110
+ return %|#\{@#{p.symbol} ? "'#\{Og::MysqlBackend.date(@#{p.symbol})\}'" : 'NULL'\}|
76
111
  elsif p.klass.ancestors.include?(TrueClass)
77
112
  return "#\{@#{p.symbol} || 'NULL'\}"
78
113
  else
79
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
114
+ return %|#\{@#{p.symbol} ? "'#\{Og::MysqlBackend.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
80
115
  end
81
116
  end
82
117
 
@@ -91,9 +126,9 @@ module Utils
91
126
  elsif p.klass.ancestors.include?(String)
92
127
  return "res[#{idx}]"
93
128
  elsif p.klass.ancestors.include?(Time)
94
- return "Og::Utils.parse_timestamp(res[#{idx}])"
129
+ return "Og::MysqlBackend.parse_timestamp(res[#{idx}])"
95
130
  elsif p.klass.ancestors.include?(Date)
96
- return "Og::Utils.parse_date(res[#{idx}])"
131
+ return "Og::MysqlBackend.parse_date(res[#{idx}])"
97
132
  elsif p.klass.ancestors.include?(TrueClass)
98
133
  return "('true' == res[#{idx}])"
99
134
  else
@@ -140,70 +175,36 @@ module Utils
140
175
  prop_accessor :oid, Fixnum, :sql => "integer AUTO_INCREMENT PRIMARY KEY"
141
176
  }
142
177
  end
143
- end
144
178
 
145
- # = MysqlBackend
146
- #
147
- # Implements a MySQL powered backend.
148
- #
149
- class MysqlBackend < Og::Backend
150
-
151
- # A mapping between Ruby and SQL types.
152
- #
153
- TYPEMAP = {
154
- Integer => "integer",
155
- Fixnum => "integer",
156
- Float => "float",
157
- String => "text",
158
- Time => "timestamp",
159
- Date => "date",
160
- TrueClass => "boolean",
161
- Object => "text",
162
- Array => "text",
163
- Hash => "text"
164
- }
165
-
166
- # Intitialize the connection to the RDBMS.
167
- #
168
- def initialize(config)
169
- begin
170
- @conn = Mysql.connect(config[:address], config[:user],
171
- config[:password], config[:database])
172
- rescue => ex
173
- if ex.errno == 1049 # database does not exist.
174
- $log.info "Database '#{config[:database]}' not found!"
175
- MysqlBackend.create_db(config[:database], config[:user], config[:password])
176
- retry
177
- end
178
- raise
179
- end
180
- end
179
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
180
+ # Connection methods.
181
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
181
182
 
182
183
  # Create the database.
183
184
  #
184
185
  def self.create_db(database, user = nil, password = nil)
185
- $log.info "Creating database '#{database}'."
186
+ Logger.info "Creating database '#{database}'."
186
187
  `mysqladmin -f --user=#{user} --password=#{password} create #{database}`
187
188
  end
188
189
 
189
190
  # Drop the database.
190
191
  #
191
192
  def self.drop_db(database, user = nil, password = nil)
192
- $log.info "Dropping database '#{database}'."
193
+ Logger.info "Dropping database '#{database}'."
193
194
  `mysqladmin -f --user=#{user} --password=#{password} drop #{database}`
194
195
  end
195
196
 
196
197
  # Execute an SQL query and return the result
197
198
  #
198
199
  def query(sql)
199
- $log.debug sql if $DBG
200
+ Logger.debug sql if $DBG
200
201
  return @conn.query(sql)
201
202
  end
202
203
 
203
204
  # Execute an SQL query, no result returned.
204
205
  #
205
206
  def exec(sql)
206
- $log.debug sql if $DBG
207
+ Logger.debug sql if $DBG
207
208
  @conn.query(sql)
208
209
  end
209
210
 
@@ -211,12 +212,12 @@ class MysqlBackend < Og::Backend
211
212
  # block.
212
213
  #
213
214
  def safe_query(sql)
214
- $log.debug sql if $DBG
215
+ Logger.debug sql if $DBG
215
216
  begin
216
217
  return @conn.query(sql)
217
218
  rescue => ex
218
- $log.error "DB error #{ex}, [#{sql}]"
219
- $log.error ex.backtrace
219
+ Logger.error "DB error #{ex}, [#{sql}]"
220
+ Logger.error ex.backtrace
220
221
  return nil
221
222
  end
222
223
  end
@@ -225,12 +226,12 @@ class MysqlBackend < Og::Backend
225
226
  # block.
226
227
  #
227
228
  def safe_exec(sql)
228
- $log.debug sql if $DBG
229
+ Logger.debug sql if $DBG
229
230
  begin
230
231
  @conn.query(sql)
231
232
  rescue => ex
232
- $log.error "DB error #{ex}, [#{sql}]"
233
- $log.error ex.backtrace
233
+ Logger.error "DB error #{ex}, [#{sql}]"
234
+ Logger.error ex.backtrace
234
235
  end
235
236
  end
236
237
 
@@ -277,10 +278,10 @@ class MysqlBackend < Og::Backend
277
278
 
278
279
  begin
279
280
  exec(sql)
280
- $log.info "Created table '#{klass::DBTABLE}'."
281
+ Logger.info "Created table '#{klass::DBTABLE}'."
281
282
  rescue => ex
282
283
  if ex.errno == 1050 # table already exists.
283
- $log.debug "Table already exists" if $DBG
284
+ Logger.debug "Table already exists" if $DBG
284
285
  else
285
286
  raise
286
287
  end
@@ -308,16 +309,16 @@ class MysqlBackend < Og::Backend
308
309
 
309
310
  # gmosx: dont use DBTABLE here, perhaps the join class
310
311
  # is not managed yet.
311
- join_table = "#{Og::Utils.join_table(klass, join_class)}"
312
- join_src = "#{Og::Utils.encode(klass)}_oid"
313
- join_dst = "#{Og::Utils.encode(join_class)}_oid"
312
+ join_table = "#{self.class.join_table(klass, join_class)}"
313
+ join_src = "#{self.class.encode(klass)}_oid"
314
+ join_dst = "#{self.class.encode(join_class)}_oid"
314
315
  begin
315
316
  exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
316
317
  exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
317
318
  exec "CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)"
318
319
  rescue => ex
319
320
  if ex.errno == 1050 # table already exists.
320
- $log.debug "Join table already exists" if $DBG
321
+ Logger.debug "Join table already exists" if $DBG
321
322
  else
322
323
  raise
323
324
  end
@@ -4,17 +4,55 @@
4
4
  # (c) 2004 Navel, all rights reserved.
5
5
  # $Id: psql.rb 194 2004-12-20 20:23:57Z gmosx $
6
6
 
7
- require "postgres"
7
+ require 'postgres'
8
8
 
9
- require "og/backend"
9
+ require 'og/backend'
10
10
 
11
- module Og
11
+ class Og
12
12
 
13
- # = Utils
13
+ # = PsqlBackend
14
14
  #
15
- # A collection of useful utilities.
15
+ # Implements a PostgreSQL powered backend.
16
+ # This backend is compatible with Michael Neumann's postgres-pr
17
+ # pure ruby driver.
16
18
  #
17
- module Utils
19
+ class PsqlBackend < Og::Backend
20
+
21
+ # A mapping between Ruby and SQL types.
22
+ #
23
+ TYPEMAP = {
24
+ Integer => 'integer',
25
+ Fixnum => 'integer',
26
+ Float => 'float',
27
+ String => 'text',
28
+ Time => 'timestamp',
29
+ Date => 'date',
30
+ TrueClass => 'boolean',
31
+ Object => 'text',
32
+ Array => 'text',
33
+ Hash => 'text'
34
+ }
35
+
36
+ # Intitialize the connection to the RDBMS.
37
+ #
38
+ def initialize(config)
39
+ begin
40
+ @conn = PGconn.connect(nil, nil, nil, nil, config[:database],
41
+ config[:user], config[:password])
42
+ rescue => ex
43
+ # gmosx: any idea how to better test this?
44
+ if ex.to_s =~ /database .* does not exist/i
45
+ Logger.info "Database '#{config[:database]}' not found!"
46
+ PsqlBackend.create_db(config[:database], config[:user])
47
+ retry
48
+ end
49
+ raise
50
+ end
51
+ end
52
+
53
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
54
+ # Utilities
55
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
18
56
 
19
57
  # Escape an SQL string
20
58
  #
@@ -67,15 +105,15 @@ module Utils
67
105
  elsif p.klass.ancestors.include?(Float)
68
106
  return "#\{@#{p.symbol} || 'NULL'\}"
69
107
  elsif p.klass.ancestors.include?(String)
70
- return "'#\{Og::Utils.escape(@#{p.symbol})\}'"
108
+ return "'#\{Og::PsqlBackend.escape(@#{p.symbol})\}'"
71
109
  elsif p.klass.ancestors.include?(Time)
72
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
110
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
73
111
  elsif p.klass.ancestors.include?(Date)
74
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.date(@#{p.symbol})\}'" : 'NULL'\}|
112
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.date(@#{p.symbol})\}'" : 'NULL'\}|
75
113
  elsif p.klass.ancestors.include?(TrueClass)
76
114
  return "#\{@#{p.symbol} || 'NULL'\}"
77
115
  else
78
- return %|#\{@#{p.symbol} ? "'#\{Og::Utils.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
116
+ return %|#\{@#{p.symbol} ? "'#\{Og::PsqlBackend.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
79
117
  end
80
118
  end
81
119
 
@@ -90,9 +128,9 @@ module Utils
90
128
  elsif p.klass.ancestors.include?(String)
91
129
  return "res.getvalue(tuple, #{idx})"
92
130
  elsif p.klass.ancestors.include?(Time)
93
- return "Og::Utils.parse_timestamp(res.getvalue(tuple, #{idx}))"
131
+ return "Og::PsqlBackend.parse_timestamp(res.getvalue(tuple, #{idx}))"
94
132
  elsif p.klass.ancestors.include?(Date)
95
- return "Og::Utils.parse_date(res.getvalue(tuple, #{idx}))"
133
+ return "Og::PsqlBackend.parse_date(res.getvalue(tuple, #{idx}))"
96
134
  elsif p.klass.ancestors.include?(TrueClass)
97
135
  return "('true' == res.getvalue(tuple, #{idx}))"
98
136
  else
@@ -132,73 +170,36 @@ module Utils
132
170
  prop_accessor :oid, Fixnum, :sql => "integer PRIMARY KEY"
133
171
  }
134
172
  end
135
- end
136
173
 
137
- # = PsqlBackend
138
- #
139
- # Implements a PostgreSQL powered backend.
140
- # This backend is compatible with Michael Neumann's postgres-pr
141
- # pure ruby driver.
142
- #
143
- class PsqlBackend < Og::Backend
144
-
145
- # A mapping between Ruby and SQL types.
146
- #
147
- TYPEMAP = {
148
- Integer => "integer",
149
- Fixnum => "integer",
150
- Float => "float",
151
- String => "text",
152
- Time => "timestamp",
153
- Date => "date",
154
- TrueClass => "boolean",
155
- Object => "text",
156
- Array => "text",
157
- Hash => "text"
158
- }
159
-
160
- # Intitialize the connection to the RDBMS.
161
- #
162
- def initialize(config)
163
- begin
164
- @conn = PGconn.connect(nil, nil, nil, nil, config[:database],
165
- config[:user], config[:password])
166
- rescue => ex
167
- # gmosx: any idea how to better test this?
168
- if ex.to_s =~ /database .* does not exist/i
169
- $log.info "Database '#{config[:database]}' not found!"
170
- PsqlBackend.create_db(config[:database], config[:user])
171
- retry
172
- end
173
- raise
174
- end
175
- end
174
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
175
+ # Connection methods.
176
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176
177
 
177
178
  # Create the database.
178
179
  #
179
180
  def self.create_db(database, user = nil, password = nil)
180
- $log.info "Creating database '#{database}'."
181
+ Logger.info "Creating database '#{database}'."
181
182
  `createdb #{database} -U #{user}`
182
183
  end
183
184
 
184
185
  # Drop the database.
185
186
  #
186
187
  def self.drop_db(database, user = nil, password = nil)
187
- $log.info "Dropping database '#{database}'."
188
+ Logger.info "Dropping database '#{database}'."
188
189
  `dropdb #{database} -U #{user}`
189
190
  end
190
191
 
191
192
  # Execute an SQL query and return the result
192
193
  #
193
194
  def query(sql)
194
- $log.debug sql if $DBG
195
+ Logger.debug sql if $DBG
195
196
  return @conn.exec(sql)
196
197
  end
197
198
 
198
199
  # Execute an SQL query, no result returned.
199
200
  #
200
201
  def exec(sql)
201
- $log.debug sql if $DBG
202
+ Logger.debug sql if $DBG
202
203
  res = @conn.exec(sql)
203
204
  res.clear()
204
205
  end
@@ -207,12 +208,12 @@ class PsqlBackend < Og::Backend
207
208
  # block.
208
209
  #
209
210
  def safe_query(sql)
210
- $log.debug sql if $DBG
211
+ Logger.debug sql if $DBG
211
212
  begin
212
213
  return @conn.exec(sql)
213
214
  rescue => ex
214
- $log.error "DB error #{ex}, [#{sql}]"
215
- $log.error ex.backtrace
215
+ Logger.error "DB error #{ex}, [#{sql}]"
216
+ Logger.error ex.backtrace
216
217
  return nil
217
218
  end
218
219
  end
@@ -221,13 +222,13 @@ class PsqlBackend < Og::Backend
221
222
  # block.
222
223
  #
223
224
  def safe_exec(sql)
224
- $log.debug sql if $DBG
225
+ Logger.debug sql if $DBG
225
226
  begin
226
227
  res = @conn.exec(sql)
227
228
  res.clear()
228
229
  rescue => ex
229
- $log.error "DB error #{ex}, [#{sql}]"
230
- $log.error ex.backtrace
230
+ Logger.error "DB error #{ex}, [#{sql}]"
231
+ Logger.error ex.backtrace
231
232
  end
232
233
  end
233
234
 
@@ -268,11 +269,11 @@ class PsqlBackend < Og::Backend
268
269
 
269
270
  begin
270
271
  exec(sql)
271
- $log.info "Created table '#{klass::DBTABLE}'."
272
+ Logger.info "Created table '#{klass::DBTABLE}'."
272
273
  rescue => ex
273
274
  # gmosx: any idea how to better test this?
274
275
  if ex.to_s =~ /relation .* already exists/i
275
- $log.debug "Table already exists" if $DBG
276
+ Logger.debug "Table already exists" if $DBG
276
277
  else
277
278
  raise
278
279
  end
@@ -283,11 +284,11 @@ class PsqlBackend < Og::Backend
283
284
  # the system more fault tolerant.
284
285
  begin
285
286
  exec "CREATE SEQUENCE #{klass::DBSEQ}"
286
- $log.info "Created sequence '#{klass::DBSEQ}'."
287
+ Logger.info "Created sequence '#{klass::DBSEQ}'."
287
288
  rescue => ex
288
289
  # gmosx: any idea how to better test this?
289
290
  if ex.to_s =~ /relation .* already exists/i
290
- $log.debug "Sequence already exists" if $DBG
291
+ Logger.debug "Sequence already exists" if $DBG
291
292
  else
292
293
  raise
293
294
  end
@@ -303,9 +304,9 @@ class PsqlBackend < Og::Backend
303
304
 
304
305
  # gmosx: dont use DBTABLE here, perhaps the join class
305
306
  # is not managed yet.
306
- join_table = "#{Og::Utils.join_table(klass, join_class)}"
307
- join_src = "#{Og::Utils.encode(klass)}_oid"
308
- join_dst = "#{Og::Utils.encode(join_class)}_oid"
307
+ join_table = "#{self.class.join_table(klass, join_class)}"
308
+ join_src = "#{self.class.encode(klass)}_oid"
309
+ join_dst = "#{self.class.encode(join_class)}_oid"
309
310
  begin
310
311
  exec "CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )"
311
312
  exec "CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)"
@@ -313,7 +314,7 @@ class PsqlBackend < Og::Backend
313
314
  rescue => ex
314
315
  # gmosx: any idea how to better test this?
315
316
  if ex.to_s =~ /relation .* already exists/i
316
- $log.debug "Join table already exists" if $DBG
317
+ Logger.debug "Join table already exists" if $DBG
317
318
  else
318
319
  raise
319
320
  end
@@ -323,11 +324,11 @@ class PsqlBackend < Og::Backend
323
324
 
324
325
  begin
325
326
  exec(sql)
326
- $log.info "Created join table '#{join_table}'."
327
+ Logger.info "Created join table '#{join_table}'."
327
328
  rescue => ex
328
329
  # gmosx: any idea how to better test this?
329
330
  if ex.to_s =~ /relation .* already exists/i
330
- $log.debug "Join table already exists" if $DBG
331
+ Logger.debug "Join table already exists" if $DBG
331
332
  else
332
333
  raise
333
334
  end