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.
- data/AUTHORS +4 -1
- data/ChangeLog +290 -7
- data/README +3 -3
- data/RELEASES +94 -0
- data/Rakefile +7 -7
- data/benchmark/og/bench.rb +11 -10
- data/{ChangeLog.1 → doc/ChangeLog.1} +0 -0
- data/doc/apache.txt +9 -0
- data/doc/architecture.txt +1 -27
- data/doc/bugs.txt +11 -4
- data/doc/config.txt +22 -0
- data/doc/og_config.txt +35 -0
- data/doc/og_tutorial.txt +595 -0
- data/doc/tutorial.txt +22 -0
- data/examples/blog/conf/apache.conf +30 -0
- data/examples/blog/conf/lhttpd.conf +2 -2
- data/examples/blog/lib/blog/controller.rb +11 -2
- data/examples/blog/log/apache.error_log +5528 -0
- data/examples/blog/root/fcgi.rb +1 -1
- data/examples/blog/run.rb +9 -3
- data/examples/flash/run.rb +2 -2
- data/examples/no_xsl_blog/conf/apache.conf +30 -0
- data/examples/no_xsl_blog/conf/lhttpd.conf +1 -1
- data/examples/no_xsl_blog/lib/blog/controller.rb +2 -2
- data/examples/no_xsl_blog/log/apache.error_log +68 -0
- data/examples/no_xsl_blog/root/fcgi.rb +2 -2
- data/examples/no_xsl_blog/run.rb +3 -3
- data/examples/og/run.rb +1 -1
- data/examples/tiny/conf/apache.conf +29 -4
- data/examples/tiny/conf/lhttpd.conf +1 -1
- data/examples/tiny/log/apache.error_log +30 -0
- data/examples/tiny/root/fcgi.rb +2 -2
- data/examples/tiny/root/index.xhtml +1 -1
- data/examples/tiny/run.rb +3 -2
- data/examples/wee_style/run.rb +7 -9
- data/examples/why_wiki/README +5 -0
- data/examples/why_wiki/run.rb +57 -0
- data/examples/why_wiki/wiki.yml +6 -0
- data/examples/wiki.yml +1 -0
- data/lib/glue/array.rb +14 -33
- data/lib/glue/hash.rb +32 -53
- data/lib/glue/pool.rb +9 -12
- data/lib/glue/property.rb +31 -9
- data/lib/nitro.rb +30 -8
- data/lib/nitro/adapters/cgi.rb +23 -3
- data/lib/nitro/adapters/webrick.rb +9 -3
- data/lib/nitro/builders/form.rb +21 -13
- data/lib/nitro/builders/rss.rb +20 -9
- data/lib/nitro/builders/table.rb +69 -10
- data/lib/nitro/builders/xhtml.rb +13 -4
- data/lib/nitro/component.rb +15 -0
- data/lib/nitro/conf.rb +4 -3
- data/lib/nitro/context.rb +22 -14
- data/lib/nitro/controller.rb +63 -5
- data/lib/nitro/dispatcher.rb +11 -6
- data/lib/nitro/output.rb +28 -0
- data/lib/nitro/render.rb +78 -59
- data/lib/nitro/request.rb +5 -1
- data/lib/nitro/runner.rb +20 -6
- data/lib/nitro/session.rb +89 -18
- data/lib/nitro/session/drb.rb +31 -0
- data/lib/nitro/session/drbserver.rb +71 -0
- data/lib/nitro/session/memory.rb +13 -0
- data/lib/nitro/simple.rb +7 -0
- data/lib/nitro/ui/date-select.rb +2 -5
- data/lib/nitro/ui/pager.rb +4 -4
- data/lib/nitro/ui/tabs.rb +2 -4
- data/lib/nitro/uri.rb +7 -4
- data/lib/og.rb +20 -12
- data/lib/og/adapter.rb +40 -13
- data/lib/og/adapters/filesys.rb +121 -0
- data/lib/og/adapters/mysql.rb +10 -5
- data/lib/og/adapters/oracle.rb +374 -0
- data/lib/og/adapters/psql.rb +10 -23
- data/lib/og/adapters/sqlite.rb +3 -3
- data/lib/og/backend.rb +2 -2
- data/lib/og/connection.rb +6 -6
- data/lib/og/database.rb +5 -5
- data/lib/og/enchant.rb +6 -2
- data/lib/og/meta.rb +56 -26
- data/lib/og/mock.rb +1 -1
- data/lib/og/typemacros.rb +23 -0
- data/lib/parts/content.rb +4 -10
- data/test/nitro/adapters/tc_cgi.rb +1 -1
- data/test/nitro/builders/tc_rss.rb +1 -1
- data/test/nitro/builders/tc_table.rb +30 -0
- data/test/nitro/tc_context.rb +4 -0
- data/test/nitro/tc_controller.rb +9 -2
- data/test/og/tc_filesys.rb +83 -0
- data/test/og/tc_meta.rb +55 -0
- data/test/tc_og.rb +115 -36
- data/vendor/README +11 -5
- data/vendor/breakpoint.rb +35 -38
- data/vendor/breakpoint_client.rb +119 -80
- data/vendor/composite_sexp_processor.rb +43 -0
- data/vendor/parse_tree.rb +745 -0
- data/vendor/sexp_processor.rb +453 -0
- metadata +34 -7
- data/examples/no_xsl_blog/conf/app.conf.rb +0 -47
data/lib/og/adapters/mysql.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: mysql.rb
|
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
|
-
|
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(
|
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
|
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
|
data/lib/og/adapters/psql.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# * George Moschovitis <gm@navel.gr>
|
2
2
|
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: psql.rb
|
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
|
-
|
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
|
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
|