nitro 0.10.0 → 0.11.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 (99) hide show
  1. data/AUTHORS +4 -1
  2. data/ChangeLog +290 -7
  3. data/README +3 -3
  4. data/RELEASES +94 -0
  5. data/Rakefile +7 -7
  6. data/benchmark/og/bench.rb +11 -10
  7. data/{ChangeLog.1 → doc/ChangeLog.1} +0 -0
  8. data/doc/apache.txt +9 -0
  9. data/doc/architecture.txt +1 -27
  10. data/doc/bugs.txt +11 -4
  11. data/doc/config.txt +22 -0
  12. data/doc/og_config.txt +35 -0
  13. data/doc/og_tutorial.txt +595 -0
  14. data/doc/tutorial.txt +22 -0
  15. data/examples/blog/conf/apache.conf +30 -0
  16. data/examples/blog/conf/lhttpd.conf +2 -2
  17. data/examples/blog/lib/blog/controller.rb +11 -2
  18. data/examples/blog/log/apache.error_log +5528 -0
  19. data/examples/blog/root/fcgi.rb +1 -1
  20. data/examples/blog/run.rb +9 -3
  21. data/examples/flash/run.rb +2 -2
  22. data/examples/no_xsl_blog/conf/apache.conf +30 -0
  23. data/examples/no_xsl_blog/conf/lhttpd.conf +1 -1
  24. data/examples/no_xsl_blog/lib/blog/controller.rb +2 -2
  25. data/examples/no_xsl_blog/log/apache.error_log +68 -0
  26. data/examples/no_xsl_blog/root/fcgi.rb +2 -2
  27. data/examples/no_xsl_blog/run.rb +3 -3
  28. data/examples/og/run.rb +1 -1
  29. data/examples/tiny/conf/apache.conf +29 -4
  30. data/examples/tiny/conf/lhttpd.conf +1 -1
  31. data/examples/tiny/log/apache.error_log +30 -0
  32. data/examples/tiny/root/fcgi.rb +2 -2
  33. data/examples/tiny/root/index.xhtml +1 -1
  34. data/examples/tiny/run.rb +3 -2
  35. data/examples/wee_style/run.rb +7 -9
  36. data/examples/why_wiki/README +5 -0
  37. data/examples/why_wiki/run.rb +57 -0
  38. data/examples/why_wiki/wiki.yml +6 -0
  39. data/examples/wiki.yml +1 -0
  40. data/lib/glue/array.rb +14 -33
  41. data/lib/glue/hash.rb +32 -53
  42. data/lib/glue/pool.rb +9 -12
  43. data/lib/glue/property.rb +31 -9
  44. data/lib/nitro.rb +30 -8
  45. data/lib/nitro/adapters/cgi.rb +23 -3
  46. data/lib/nitro/adapters/webrick.rb +9 -3
  47. data/lib/nitro/builders/form.rb +21 -13
  48. data/lib/nitro/builders/rss.rb +20 -9
  49. data/lib/nitro/builders/table.rb +69 -10
  50. data/lib/nitro/builders/xhtml.rb +13 -4
  51. data/lib/nitro/component.rb +15 -0
  52. data/lib/nitro/conf.rb +4 -3
  53. data/lib/nitro/context.rb +22 -14
  54. data/lib/nitro/controller.rb +63 -5
  55. data/lib/nitro/dispatcher.rb +11 -6
  56. data/lib/nitro/output.rb +28 -0
  57. data/lib/nitro/render.rb +78 -59
  58. data/lib/nitro/request.rb +5 -1
  59. data/lib/nitro/runner.rb +20 -6
  60. data/lib/nitro/session.rb +89 -18
  61. data/lib/nitro/session/drb.rb +31 -0
  62. data/lib/nitro/session/drbserver.rb +71 -0
  63. data/lib/nitro/session/memory.rb +13 -0
  64. data/lib/nitro/simple.rb +7 -0
  65. data/lib/nitro/ui/date-select.rb +2 -5
  66. data/lib/nitro/ui/pager.rb +4 -4
  67. data/lib/nitro/ui/tabs.rb +2 -4
  68. data/lib/nitro/uri.rb +7 -4
  69. data/lib/og.rb +20 -12
  70. data/lib/og/adapter.rb +40 -13
  71. data/lib/og/adapters/filesys.rb +121 -0
  72. data/lib/og/adapters/mysql.rb +10 -5
  73. data/lib/og/adapters/oracle.rb +374 -0
  74. data/lib/og/adapters/psql.rb +10 -23
  75. data/lib/og/adapters/sqlite.rb +3 -3
  76. data/lib/og/backend.rb +2 -2
  77. data/lib/og/connection.rb +6 -6
  78. data/lib/og/database.rb +5 -5
  79. data/lib/og/enchant.rb +6 -2
  80. data/lib/og/meta.rb +56 -26
  81. data/lib/og/mock.rb +1 -1
  82. data/lib/og/typemacros.rb +23 -0
  83. data/lib/parts/content.rb +4 -10
  84. data/test/nitro/adapters/tc_cgi.rb +1 -1
  85. data/test/nitro/builders/tc_rss.rb +1 -1
  86. data/test/nitro/builders/tc_table.rb +30 -0
  87. data/test/nitro/tc_context.rb +4 -0
  88. data/test/nitro/tc_controller.rb +9 -2
  89. data/test/og/tc_filesys.rb +83 -0
  90. data/test/og/tc_meta.rb +55 -0
  91. data/test/tc_og.rb +115 -36
  92. data/vendor/README +11 -5
  93. data/vendor/breakpoint.rb +35 -38
  94. data/vendor/breakpoint_client.rb +119 -80
  95. data/vendor/composite_sexp_processor.rb +43 -0
  96. data/vendor/parse_tree.rb +745 -0
  97. data/vendor/sexp_processor.rb +453 -0
  98. metadata +34 -7
  99. data/examples/no_xsl_blog/conf/app.conf.rb +0 -47
@@ -1,6 +1,6 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: mysql.rb 259 2005-02-15 08:54:54Z gmosx $
3
+ # $Id: mysql.rb 266 2005-02-28 14:50:48Z gmosx $
4
4
 
5
5
  require 'mysql'
6
6
 
@@ -8,7 +8,7 @@ require 'og/adapter'
8
8
  require 'og/connection'
9
9
  require 'glue/attribute'
10
10
 
11
- class Og
11
+ module Og
12
12
 
13
13
  # The MySQL adapter. This adapter communicates with
14
14
  # an MySQL rdbms. For extra documentation see
@@ -18,7 +18,7 @@ class MysqlAdapter < Adapter
18
18
 
19
19
  def initialize
20
20
  super
21
- @typemap.update({TrueClass => 'tinyint'})
21
+ @typemap.update(TrueClass => 'tinyint')
22
22
  end
23
23
 
24
24
  def self.escape(str)
@@ -42,7 +42,7 @@ class MysqlAdapter < Adapter
42
42
  elsif p.klass.ancestors.include?(Float)
43
43
  return "#\{@#{p.symbol} || 'NULL'\}"
44
44
  elsif p.klass.ancestors.include?(String)
45
- return "'#\{#{self.class}.escape(@#{p.symbol})\}'"
45
+ return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol})\}'" : 'NULL'\}|
46
46
  elsif p.klass.ancestors.include?(Time)
47
47
  return %|#\{@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
48
48
  elsif p.klass.ancestors.include?(Date)
@@ -50,6 +50,7 @@ class MysqlAdapter < Adapter
50
50
  elsif p.klass.ancestors.include?(TrueClass)
51
51
  return "#\{@#{p.symbol} ? 1 : 0 \}"
52
52
  else
53
+ # gmosx: keep the '' for nil symbols.
53
54
  return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
54
55
  end
55
56
  end
@@ -82,6 +83,10 @@ class MysqlAdapter < Adapter
82
83
  super
83
84
  end
84
85
 
86
+ def props_for_insert(klass)
87
+ klass.__props.reject { |p| :oid == p.symbol }
88
+ end
89
+
85
90
  def insert_code(klass, db, pre_cb, post_cb)
86
91
  props = props_for_insert(klass)
87
92
  values = props.collect { |p| write_prop(p) }.join(',')
@@ -98,7 +103,7 @@ class MysqlAdapter < Adapter
98
103
  end
99
104
 
100
105
  def new_connection(db)
101
- return Og::MysqlConnection.new(db)
106
+ return MysqlConnection.new(db)
102
107
  end
103
108
 
104
109
  def calc_field_index(klass, db)
@@ -0,0 +1,374 @@
1
+ # * Matt Bowen <matt.bowen@farweststeel.com>
2
+ # * George Moschovitis <gm@navel.gr>
3
+ # (c) 2004-2005 Navel, all rights reserved.
4
+ # $Id: oracle.rb 266 2005-02-28 14:50:48Z gmosx $
5
+
6
+ require 'oracle'
7
+
8
+ require 'og/adapter'
9
+ require 'og/connection'
10
+ require 'glue/attribute'
11
+
12
+ module Og
13
+
14
+ # The Oracle adapter. This adapter communicates with
15
+ # an Oracle rdbms. For extra documentation see
16
+ # lib/og/adapter.rb
17
+
18
+ class OracleAdapter < Adapter
19
+
20
+ def initialize
21
+ super
22
+ @typemap.update(
23
+ Integer => 'number',
24
+ Fixnum => 'number',
25
+ String => 'varchar2(512)',
26
+ TrueClass => 'number',
27
+ Object => 'varchar2(1024)',
28
+ Array => 'varchar2(1024)',
29
+ Hash => 'varchar2(1024)'
30
+ )
31
+ end
32
+
33
+ def self.timestamp(time = Time.now)
34
+ return nil unless time
35
+ return time.strftime("%Y-%m-%d %H:%M:%S")
36
+ end
37
+
38
+ def self.date(date)
39
+ return nil unless date
40
+ return "#{date.year}-#{date.month}-#{date.mday}"
41
+ end
42
+
43
+ def write_prop(p)
44
+ if p.klass.ancestors.include?(Integer)
45
+ return "#\{@#{p.symbol} || 'NULL'\}"
46
+ elsif p.klass.ancestors.include?(Float)
47
+ return "#\{@#{p.symbol} || 'NULL'\}"
48
+ elsif p.klass.ancestors.include?(String)
49
+ return "'#\{#{self.class}.escape(@#{p.symbol})\}'"
50
+ elsif p.klass.ancestors.include?(Time)
51
+ return %|#\{@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
52
+ elsif p.klass.ancestors.include?(Date)
53
+ return %|#\{@#{p.symbol} ? "'#\{#{self.class}.date(@#{p.symbol})\}'" : 'NULL'\}|
54
+ elsif p.klass.ancestors.include?(TrueClass)
55
+ return "#\{@#{p.symbol} ? \"1\" : 'NULL' \}"
56
+ else
57
+ return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
58
+ end
59
+ end
60
+
61
+ #--
62
+ # mcb:
63
+ # Unlike MySQL or Postgres, Oracle database/schema creation is a big deal.
64
+ # I don't know how to do it from the command line. I use Oracle's Database
65
+ # Configuration Assistant utility (dbca). I takes 30min - 1hr to create
66
+ # a full blown schema. So, your FIXME comments are fine. I'm thinking you
67
+ # won't be able to do this via Og, but once created, Og will be able to create
68
+ # tables, indexes, and other objects.
69
+ #++
70
+
71
+ def create_db(database, user = nil, password = nil)
72
+ # FIXME: what is appropriate for oracle?
73
+ # `createdb #{database} -U #{user}`
74
+ super
75
+ end
76
+
77
+ def drop_db(database, user = nil, password = nil)
78
+ # FIXME: what is appropriate for oracle?
79
+ # `dropdb #{database} -U #{user}`
80
+ super
81
+ end
82
+
83
+ def insert_code(klass, db, pre_cb, post_cb)
84
+ props = props_for_insert(klass)
85
+ values = props.collect { |p| write_prop(p) }.join(',')
86
+
87
+ sql = "INSERT INTO #{klass::DBTABLE} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values})"
88
+
89
+ %{
90
+ #{pre_cb}
91
+ res = conn.store.exec("SELECT #{klass::DBSEQ}.nextval FROM DUAL")
92
+ @oid = res.fetch[0].to_i
93
+ res.close
94
+ conn.exec "#{sql}"
95
+ #{post_cb}
96
+ }
97
+ end
98
+
99
+ def new_connection(db)
100
+ return OracleConnection.new(db)
101
+ end
102
+
103
+ def calc_field_index(klass, db)
104
+ # gmosx: This is incredible!!! argh!
105
+ # res = db.query "SELECT * FROM #{klass::DBTABLE} # LIMIT 1"
106
+ res = db.query "SELECT * FROM (SELECT * FROM #{klass::DBTABLE}) WHERE ROWNUM <= 1"
107
+ meta = db.managed_classes[klass]
108
+
109
+ columns = res.getColNames
110
+
111
+ for idx in (0...columns.size)
112
+ # mcb: Oracle will return column names in uppercase.
113
+ meta.field_index[columns[idx].downcase] = idx
114
+ end
115
+
116
+ ensure
117
+ res.close if res
118
+ end
119
+
120
+ def eval_og_oid(klass)
121
+ klass.class_eval %{
122
+ prop_accessor :oid, Fixnum, :sql => "number PRIMARY KEY"
123
+ }
124
+ end
125
+
126
+ def create_table(klass, db)
127
+ conn = db.get_connection
128
+
129
+ fields = create_fields(klass)
130
+
131
+ sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
132
+
133
+ # Create table constrains.
134
+
135
+ if klass.__meta and constrains = klass.__meta[:sql_constrain]
136
+ sql << ", #{constrains.join(', ')}"
137
+ end
138
+
139
+ # mcb: Oracle driver chokes on semicolon.
140
+ sql << ")"
141
+
142
+ # mcb:
143
+ # Oracle driver appears to have problems executing multiple SQL
144
+ # statements in single exec() call. Chokes with or without semicolon
145
+ # delimiter. Solution: make separate calls for each statement.
146
+
147
+ begin
148
+ conn.store.exec(sql).close
149
+ Logger.info "Created table '#{klass::DBTABLE}'."
150
+
151
+ # Create indices.
152
+
153
+ if klass.__meta and indices = klass.__meta[:sql_index]
154
+ for data in indices
155
+ idx, options = *data
156
+ idx = idx.to_s
157
+ pre_sql, post_sql = options[:pre], options[:post]
158
+ idxname = idx.gsub(/ /, "").gsub(/,/, "_").gsub(/\(.*\)/, "")
159
+ sql = " CREATE #{pre_sql} INDEX #{klass::DBTABLE}_#{idxname}_idx #{post_sql} ON #{klass::DBTABLE} (#{idx})"
160
+ conn.store.exec(sql).close
161
+ Logger.info "Created index '#{klass::DBTABLE}_#{idxname}_idx'."
162
+ end
163
+ end
164
+ rescue Exception => ex
165
+ # gmosx: any idea how to better test this?
166
+ if ex.to_s =~ /ORA-00955/i
167
+ Logger.debug 'Table or index already exists' if $DBG
168
+ return
169
+ else
170
+ raise
171
+ end
172
+ end
173
+
174
+ # Create the sequence for this table.
175
+ begin
176
+ conn.store.exec("CREATE SEQUENCE #{klass::DBSEQ}").close
177
+ Logger.info "Created sequence '#{klass::DBSEQ}'."
178
+ rescue Exception => ex
179
+ # gmosx: any idea how to better test this?
180
+ if ex.to_s =~ /ORA-00955/i
181
+ Logger.debug "Sequence already exists" if $DBG
182
+ else
183
+ raise
184
+ end
185
+ end
186
+
187
+ # Create join tables if needed. Join tables are used in
188
+ # 'many_to_many' relations.
189
+
190
+ if klass.__meta and joins = klass.__meta[:sql_join]
191
+ for data in joins
192
+ # the class to join to and some options.
193
+ join_class, options = *data
194
+
195
+ # gmosx: dont use DBTABLE here, perhaps the join class
196
+ # is not managed yet.
197
+ join_table = "#{self.class.join_table(klass, join_class)}"
198
+ join_src = "#{self.class.encode(klass)}_oid"
199
+ join_dst = "#{self.class.encode(join_class)}_oid"
200
+ begin
201
+ conn.store.exec("CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )").close
202
+ conn.store.exec("CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)").close
203
+ conn.store.exec("CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)").close
204
+ rescue Exception => ex
205
+ # gmosx: any idea how to better test this?
206
+ if ex.to_s =~ /ORA-00955/i
207
+ Logger.debug "Join table already exists" if $DBG
208
+ else
209
+ raise
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ ensure
216
+ db.put_connection
217
+ end
218
+
219
+ def drop_table(klass)
220
+ super
221
+ exec "DROP SEQUENCE #{klass::DBSEQ}"
222
+ end
223
+
224
+ # Generate the property for oid.
225
+
226
+ #--
227
+ # mcb:
228
+ # Oracle doesn't have a "serial" datatype. Replace with
229
+ # integer (which is probably just a synonym for NUMBER(38,0))
230
+ # A sequence is created automatically by Og.
231
+ #++
232
+
233
+ def eval_og_oid(klass)
234
+ klass.class_eval %{
235
+ prop_accessor :oid, Fixnum, :sql => 'integer PRIMARY KEY'
236
+ }
237
+ end
238
+ end
239
+
240
+ # The Oracle connection.
241
+
242
+ class OracleConnection < Connection
243
+
244
+ # mcb:
245
+ # The database connection details are tucked away in a
246
+ # TNS entry (Transparent Network Substrate) which specifies host,
247
+ # port, protocol, and database instance. Here is a sample TNS
248
+ # entry:
249
+ #
250
+ # File: tns_names.ora
251
+ #
252
+ # KBSID =
253
+ # (DESCRIPTION =
254
+ # (ADDRESS_LIST =
255
+ # (ADDRESS = (PROTOCOL = TCP)(HOST = keebler.farweststeel.com)(PORT = 1521))
256
+ # )
257
+ # (CONNECT_DATA =
258
+ # (SID = KBSID)
259
+ # )
260
+ # )
261
+
262
+ def initialize(db)
263
+ super
264
+ config = db.config
265
+
266
+ begin
267
+ # FIXME: how to pass address etc?
268
+ @store = Oracle.new(config[:user], config[:password], config[:database])
269
+ # gmosx: better use this???
270
+ # @store = Oracle.new(config[:tns])
271
+
272
+ # gmosx: does this work?
273
+ @store.autocommit = true
274
+ rescue Exception => ex
275
+ # mcb:
276
+ # Oracle will raise a ORA-01017 if username, password, or
277
+ # SID aren't valid. I verified this for all three.
278
+ # irb(main):002:0> conn = Oracle.new('keebler', 'dfdfd', 'kbsid')
279
+ # /usr/local/lib/ruby/site_ruby/1.8/oracle.rb:27:in `logon': ORA-01017: invalid username/password; logon denied (OCIError)
280
+ # gmosx:
281
+ # any idea how to better test this? an integer error id?
282
+ if ex.to_s =~ /ORA-01017/i
283
+ Logger.info "Database '#{config[:database]}' not found!"
284
+ @db.adapter.create_db(config[:database], config[:user])
285
+ retry
286
+ end
287
+ raise
288
+ end
289
+ end
290
+
291
+ def close
292
+ @store.logoff
293
+ super
294
+ end
295
+
296
+ def query(sql)
297
+ Logger.debug sql if $DBG
298
+ begin
299
+ return @store.exec(sql)
300
+ rescue Exception => ex
301
+ Logger.error "DB error #{ex}, [#{sql}]"
302
+ Logger.error ex.backtrace.join("\n")
303
+ raise
304
+ # return nil
305
+ end
306
+ end
307
+
308
+ def exec(sql)
309
+ Logger.debug sql if $DBG
310
+ begin
311
+ @store.exec(sql)
312
+ rescue Exception => ex
313
+ Logger.error "DB error #{ex}, [#{sql}]"
314
+ Logger.error ex.backtrace.join("\n")
315
+ raise
316
+ end
317
+ end
318
+
319
+ def start
320
+ @store.autocommit = false
321
+ end
322
+
323
+ def commit
324
+ @store.commit
325
+ ensure
326
+ @store.autocommit = true
327
+ end
328
+
329
+ def rollback
330
+ @store.rollback
331
+ ensure
332
+ @store.autocommit = true
333
+ end
334
+
335
+ def valid_res?(res)
336
+ return !(res.nil?)
337
+ end
338
+
339
+ def read_one(res, klass)
340
+ return nil unless valid_res?(res)
341
+
342
+ row = res.fetch
343
+ return nil unless row
344
+
345
+ obj = klass.new
346
+ obj.og_read(row)
347
+
348
+ res.close
349
+ return obj
350
+ end
351
+
352
+ def read_all(res, klass)
353
+ return [] unless valid_res?(res)
354
+ objects = []
355
+
356
+ while row = res.fetch
357
+ obj = klass.new
358
+ obj.og_read(row)
359
+ objects << obj
360
+ end
361
+
362
+ res.close
363
+ return objects
364
+ end
365
+
366
+ def read_int(res, idx = 0)
367
+ val = res.fetch[idx].to_i
368
+ res.close
369
+ return val
370
+ end
371
+
372
+ end
373
+
374
+ end
@@ -1,6 +1,6 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: psql.rb 259 2005-02-15 08:54:54Z gmosx $
3
+ # $Id: psql.rb 266 2005-02-28 14:50:48Z gmosx $
4
4
 
5
5
  require 'postgres'
6
6
 
@@ -8,7 +8,7 @@ require 'og/adapter'
8
8
  require 'og/connection'
9
9
  require 'glue/attribute'
10
10
 
11
- class Og
11
+ module Og
12
12
 
13
13
  # The PostgreSQL adapter. This adapter communicates with
14
14
  # an PostgreSQL rdbms. For extra documentation see
@@ -30,24 +30,6 @@ class PsqlAdapter < Adapter
30
30
  return nil unless date
31
31
  return "#{date.year}-#{date.month}-#{date.mday}"
32
32
  end
33
-
34
- def write_prop(p)
35
- if p.klass.ancestors.include?(Integer)
36
- return "#\{@#{p.symbol} || 'NULL'\}"
37
- elsif p.klass.ancestors.include?(Float)
38
- return "#\{@#{p.symbol} || 'NULL'\}"
39
- elsif p.klass.ancestors.include?(String)
40
- return "'#\{#{self.class}.escape(@#{p.symbol})\}'"
41
- elsif p.klass.ancestors.include?(Time)
42
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
43
- elsif p.klass.ancestors.include?(Date)
44
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.date(@#{p.symbol})\}'" : 'NULL'\}|
45
- elsif p.klass.ancestors.include?(TrueClass)
46
- return "#\{@#{p.symbol} ? \"'t'\" : 'NULL' \}"
47
- else
48
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
49
- end
50
- end
51
33
 
52
34
  def read_prop(p, idx)
53
35
  if p.klass.ancestors.include?(Integer)
@@ -94,7 +76,7 @@ class PsqlAdapter < Adapter
94
76
  end
95
77
 
96
78
  def new_connection(db)
97
- return Og::PsqlConnection.new(db)
79
+ return PsqlConnection.new(db)
98
80
  end
99
81
 
100
82
  def calc_field_index(klass, db)
@@ -116,7 +98,7 @@ class PsqlAdapter < Adapter
116
98
 
117
99
  sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
118
100
 
119
- # Create table constrains
101
+ # Create table constrains.
120
102
 
121
103
  if klass.__meta and constrains = klass.__meta[:sql_constrain]
122
104
  sql << ", #{constrains.join(', ')}"
@@ -124,7 +106,7 @@ class PsqlAdapter < Adapter
124
106
 
125
107
  sql << ") WITHOUT OIDS;"
126
108
 
127
- # Create indices
109
+ # Create indices.
128
110
 
129
111
  if klass.__meta and indices = klass.__meta[:sql_index]
130
112
  for data in indices
@@ -226,6 +208,11 @@ class PsqlConnection < Connection
226
208
  end
227
209
  end
228
210
 
211
+ def close
212
+ @store.close
213
+ super
214
+ end
215
+
229
216
  def query(sql)
230
217
  Logger.debug sql if $DBG
231
218
  begin