nitro 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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