nitro 0.12.0 → 0.13.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/{ChangeLog → CHANGELOG} +137 -0
- data/INSTALL +1 -2
- data/README +1 -1
- data/Rakefile +10 -61
- data/benchmark/{nitro/bench.rb → bench.rb} +1 -1
- data/benchmark/{nitro/simple-webrick-n-200.txt → simple-webrick-n-200.txt} +0 -0
- data/benchmark/{nitro/static-webrick-n-200.txt → static-webrick-n-200.txt} +0 -0
- data/benchmark/{nitro/tiny-lhttpd-n-200-c-5.txt → tiny-lhttpd-n-200-c-5.txt} +0 -0
- data/benchmark/{nitro/tiny-webrick-n-200-c-5.txt → tiny-webrick-n-200-c-5.txt} +0 -0
- data/benchmark/{nitro/tiny-webrick-n-200.txt → tiny-webrick-n-200.txt} +0 -0
- data/benchmark/{nitro/tiny2-webrick-n-200.txt → tiny2-webrick-n-200.txt} +0 -0
- data/doc/{ChangeLog.1 → CHANGELOG.1} +0 -0
- data/{RELEASES → doc/RELEASES} +46 -0
- data/doc/faq.txt +7 -0
- data/examples/README.windows +1 -1
- data/examples/ajax/controller.rb +21 -0
- data/examples/ajax/public/index.xhtml +70 -0
- data/examples/ajax/public/js/ajax.js +64 -0
- data/examples/ajax/run.rb +16 -0
- data/examples/blog/README +6 -3
- data/examples/blog/conf/apache.conf +2 -2
- data/examples/blog/conf/lhttpd.conf +2 -2
- data/examples/blog/log/apache.error_log +777 -0
- data/examples/blog/{root → public}/base.xsl +0 -0
- data/examples/blog/{root → public}/fcgi.rb +0 -0
- data/examples/blog/{root → public}/m/bubbles.gif +0 -0
- data/examples/blog/{root → public}/m/comments_curve.gif +0 -0
- data/examples/blog/{root → public}/m/down.gif +0 -0
- data/examples/blog/{root → public}/m/footer_bg.gif +0 -0
- data/examples/blog/{root → public}/m/garrow.gif +0 -0
- data/examples/blog/{root → public}/m/gbull.gif +0 -0
- data/examples/blog/{root → public}/m/grbull.gif +0 -0
- data/examples/blog/{root → public}/m/h1_bg.gif +0 -0
- data/examples/blog/{root → public}/m/header_bg.gif +0 -0
- data/examples/blog/{root → public}/m/nitro.gif +0 -0
- data/examples/blog/{root → public}/m/obull.gif +0 -0
- data/examples/blog/{root → public}/m/page_bg.gif +0 -0
- data/examples/blog/{root → public}/m/rss.gif +0 -0
- data/examples/blog/{root → public}/m/side_title_bg.gif +0 -0
- data/examples/blog/{root → public}/m/sidebar_bg.gif +0 -0
- data/examples/{no_xsl_blog/root → blog/public}/style.css +6 -0
- data/examples/blog/run.rb +10 -12
- data/examples/blog/{lib → src}/blog.rb +3 -3
- data/examples/blog/{lib/blog → src}/controller.rb +13 -2
- data/examples/blog/src/mailer.rb +23 -0
- data/examples/blog/{lib/blog/model.rb → src/models/blog.rb} +4 -7
- data/examples/blog/src/models/content.rb +52 -0
- data/examples/blog/src/views/blog_entry_email.xhtml +16 -0
- data/examples/blog/{root → src/views}/comments.xhtml +0 -0
- data/examples/blog/{root → src/views}/entry_form.xhtml +0 -0
- data/examples/blog/{root → src/views}/error.xhtml +0 -0
- data/examples/blog/{root → src/views}/index.xhtml +0 -0
- data/examples/blog/{root → src/views}/login.xhtml +0 -0
- data/examples/blog/{root → src/views}/recent_posts.xhtml +0 -0
- data/examples/blog/{root → src/views}/view_entry.xhtml +8 -0
- data/examples/blog/{root → src/views}/view_entry.xml +0 -0
- data/examples/blog/src/xsl/base.xsl +153 -0
- data/examples/blog/{root → src/xsl}/style.xsl +2 -2
- data/examples/no_xsl_blog/README +5 -1
- data/examples/no_xsl_blog/conf/apache.conf +2 -2
- data/examples/no_xsl_blog/conf/lhttpd.conf +2 -2
- data/examples/no_xsl_blog/lib/blog/model.rb +1 -1
- data/{lib/parts → examples/no_xsl_blog/lib}/content.rb +1 -11
- data/examples/no_xsl_blog/log/apache.error_log +405 -0
- data/examples/no_xsl_blog/{root → public}/comments.xhtml +0 -0
- data/examples/no_xsl_blog/{root → public}/entry_form.xhtml +0 -0
- data/examples/no_xsl_blog/{root → public}/fcgi.rb +0 -0
- data/examples/no_xsl_blog/{root → public}/index.xhtml +0 -0
- data/examples/no_xsl_blog/{root → public}/login.xhtml +0 -0
- data/examples/no_xsl_blog/{root → public}/m/bubbles.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/comments_curve.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/down.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/footer_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/garrow.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/gbull.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/grbull.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/h1_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/header_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/nitro.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/obull.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/page_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/rss.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/side_title_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/m/sidebar_bg.gif +0 -0
- data/examples/no_xsl_blog/{root → public}/recent_posts.xhtml +0 -0
- data/examples/{blog/root → no_xsl_blog/public}/style.css +0 -0
- data/examples/no_xsl_blog/{root → public}/view_entry.xhtml +0 -0
- data/examples/no_xsl_blog/{root → public}/view_entry.xml +0 -0
- data/examples/tiny/conf/apache.conf +2 -2
- data/examples/tiny/log/apache.error_log +100 -0
- data/examples/tiny/{root → public}/fcgi.rb +0 -0
- data/examples/tiny/{root → public}/include.xhtml +0 -0
- data/examples/tiny/{root → public}/index.xhtml +0 -0
- data/{bin/proto/root/m → examples/tiny/public}/nitro.png +0 -0
- data/examples/tiny/{root → public}/upload.xhtml +0 -0
- data/examples/tiny/run.rb +1 -2
- data/examples/why_wiki/wiki.yml +1 -0
- data/install.rb +5 -2
- data/lib/nitro.rb +2 -6
- data/lib/nitro/adapters/fastcgi.rb +2 -2
- data/lib/nitro/adapters/webrick.rb +4 -4
- data/lib/nitro/conf.rb +5 -2
- data/lib/nitro/controller.rb +2 -2
- data/lib/nitro/dispatcher.rb +19 -8
- data/lib/nitro/mail.rb +252 -8
- data/lib/nitro/render.rb +24 -21
- data/lib/nitro/runner.rb +1 -1
- data/lib/nitro/scaffold.rb +2 -5
- data/lib/nitro/simple.rb +2 -1
- data/lib/nitro/template.rb +42 -2
- data/test/nitro/tc_controller.rb +9 -4
- data/test/nitro/tc_dispatcher.rb +4 -6
- data/test/nitro/tc_mail.rb +95 -0
- data/test/{root → public}/blog/list.xhtml +0 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- data/vendor/README +0 -1
- metadata +136 -181
- data/benchmark/og/bench.rb +0 -75
- data/benchmark/og/sqlite-no-prepare.1.txt +0 -13
- data/benchmark/og/sqlite-no-prepare.2.txt +0 -13
- data/benchmark/og/sqlite-prepare.1.txt +0 -13
- data/benchmark/og/sqlite-prepare.2.txt +0 -13
- data/bin/proto/README +0 -34
- data/bin/proto/conf/apache.conf +0 -1
- data/bin/proto/conf/app.conf.rb +0 -14
- data/bin/proto/conf/lhttpd.conf +0 -236
- data/bin/proto/ctl +0 -4
- data/bin/proto/lib/README +0 -5
- data/bin/proto/log/README +0 -3
- data/bin/proto/root/fcgi.rb +0 -6
- data/bin/proto/root/index.xhtml +0 -69
- data/bin/proto/root/style.css +0 -152
- data/bin/proto/root/style.xsl +0 -99
- data/doc/og_config.txt +0 -35
- data/doc/og_tutorial.txt +0 -595
- data/examples/og/README +0 -11
- data/examples/og/mock_example.rb +0 -50
- data/examples/og/mysql_to_psql.rb +0 -96
- data/examples/og/run.rb +0 -286
- data/examples/tiny/root/nitro.png +0 -0
- data/lib/glue.rb +0 -55
- data/lib/glue/array.rb +0 -61
- data/lib/glue/attribute.rb +0 -83
- data/lib/glue/cache.rb +0 -138
- data/lib/glue/flexob.rb +0 -12
- data/lib/glue/hash.rb +0 -122
- data/lib/glue/inflector.rb +0 -91
- data/lib/glue/logger.rb +0 -147
- data/lib/glue/misc.rb +0 -14
- data/lib/glue/mixins.rb +0 -36
- data/lib/glue/number.rb +0 -24
- data/lib/glue/object.rb +0 -32
- data/lib/glue/pool.rb +0 -60
- data/lib/glue/property.rb +0 -408
- data/lib/glue/string.rb +0 -162
- data/lib/glue/time.rb +0 -85
- data/lib/glue/validation.rb +0 -394
- data/lib/og.rb +0 -185
- data/lib/og/adapter.rb +0 -513
- data/lib/og/adapters/filesys.rb +0 -121
- data/lib/og/adapters/mysql.rb +0 -347
- data/lib/og/adapters/oracle.rb +0 -375
- data/lib/og/adapters/psql.rb +0 -273
- data/lib/og/adapters/sqlite.rb +0 -262
- data/lib/og/backend.rb +0 -297
- data/lib/og/connection.rb +0 -304
- data/lib/og/database.rb +0 -282
- data/lib/og/enchant.rb +0 -125
- data/lib/og/meta.rb +0 -373
- data/lib/og/mock.rb +0 -165
- data/lib/og/observer.rb +0 -53
- data/lib/og/typemacros.rb +0 -23
- data/lib/parts/README +0 -9
- data/test/glue/tc_attribute.rb +0 -22
- data/test/glue/tc_cache.rb +0 -45
- data/test/glue/tc_hash.rb +0 -38
- data/test/glue/tc_logger.rb +0 -39
- data/test/glue/tc_numbers.rb +0 -20
- data/test/glue/tc_property.rb +0 -89
- data/test/glue/tc_property_mixins.rb +0 -93
- data/test/glue/tc_property_type_checking.rb +0 -35
- data/test/glue/tc_strings.rb +0 -103
- data/test/glue/tc_validation.rb +0 -188
- data/test/og/tc_filesys.rb +0 -83
- data/test/og/tc_lifecycle.rb +0 -104
- data/test/og/tc_many_to_many.rb +0 -62
- data/test/og/tc_meta.rb +0 -55
- data/test/og/tc_observer.rb +0 -85
- data/test/og/tc_sqlite.rb +0 -87
- data/test/tc_og.rb +0 -355
- data/vendor/composite_sexp_processor.rb +0 -43
- data/vendor/parse_tree.rb +0 -745
- data/vendor/sexp_processor.rb +0 -453
data/lib/og/adapters/sqlite.rb
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
-
# $Id: sqlite.rb 270 2005-03-07 17:52:16Z gmosx $
|
|
4
|
-
|
|
5
|
-
require 'sqlite3'
|
|
6
|
-
require 'fileutils'
|
|
7
|
-
|
|
8
|
-
require 'og/adapter'
|
|
9
|
-
require 'og/connection'
|
|
10
|
-
require 'glue/attribute'
|
|
11
|
-
|
|
12
|
-
module Og
|
|
13
|
-
|
|
14
|
-
# The SQLite adapter. This adapter communicates with
|
|
15
|
-
# an SQLite3 rdbms. For extra documentation see
|
|
16
|
-
# lib/og/adapter.rb
|
|
17
|
-
|
|
18
|
-
class SqliteAdapter < Adapter
|
|
19
|
-
|
|
20
|
-
def drop_db(database, user = nil, password = nil)
|
|
21
|
-
begin
|
|
22
|
-
FileUtils.rm("#{database}.db")
|
|
23
|
-
super
|
|
24
|
-
rescue
|
|
25
|
-
Logger.error "Cannot drop '#{database}'!"
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
=begin
|
|
29
|
-
def write_prop(p)
|
|
30
|
-
if p.klass.ancestors.include?(Integer)
|
|
31
|
-
return "@#{p.symbol}"
|
|
32
|
-
elsif p.klass.ancestors.include?(Float)
|
|
33
|
-
return "@#{p.symbol}"
|
|
34
|
-
elsif p.klass.ancestors.include?(String)
|
|
35
|
-
return "#{self.class}.escape(@#{p.symbol})"
|
|
36
|
-
elsif p.klass.ancestors.include?(Time)
|
|
37
|
-
return %|#\{@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
|
|
38
|
-
elsif p.klass.ancestors.include?(Date)
|
|
39
|
-
return %|#\{@#{p.symbol} ? "'#\{#{self.class}.date(@#{p.symbol})\}'" : 'NULL'\}|
|
|
40
|
-
elsif p.klass.ancestors.include?(TrueClass)
|
|
41
|
-
return "#\{@#{p.symbol} ? \"'t'\" : 'NULL' \}"
|
|
42
|
-
else
|
|
43
|
-
return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
=end
|
|
47
|
-
def insert_code(klass, db, pre_cb, post_cb)
|
|
48
|
-
props = props_for_insert(klass)
|
|
49
|
-
values = props.collect { |p| write_prop(p) }.join(',')
|
|
50
|
-
|
|
51
|
-
sql = "INSERT INTO #{klass::DBTABLE} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values})"
|
|
52
|
-
|
|
53
|
-
%{
|
|
54
|
-
#{pre_cb}
|
|
55
|
-
conn.store.query("#{sql}").close
|
|
56
|
-
@oid = conn.store.last_insert_row_id
|
|
57
|
-
#{post_cb}
|
|
58
|
-
}
|
|
59
|
-
=begin
|
|
60
|
-
props = props_for_insert(klass)
|
|
61
|
-
|
|
62
|
-
placeholders = Array.new(props.size, '?').join(',')
|
|
63
|
-
values = props.collect { |p| write_prop(p) }.join(',')
|
|
64
|
-
|
|
65
|
-
sql = "INSERT INTO #{klass::DBTABLE} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{placeholders})"
|
|
66
|
-
klass.class_eval %{
|
|
67
|
-
cattr_accessor :og_insert_statement
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
klass.og_insert_statement = db.prepare(sql)
|
|
71
|
-
|
|
72
|
-
%{
|
|
73
|
-
#{pre_cb}
|
|
74
|
-
@@og_insert_statement.execute(#{values})
|
|
75
|
-
@oid = conn.store.last_insert_row_id
|
|
76
|
-
#{post_cb}
|
|
77
|
-
}
|
|
78
|
-
=end
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def new_connection(db)
|
|
82
|
-
return SqliteConnection.new(db)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def calc_field_index(klass, db)
|
|
86
|
-
res = db.query "SELECT * FROM #{klass::DBTABLE} LIMIT 1"
|
|
87
|
-
meta = db.managed_classes[klass]
|
|
88
|
-
|
|
89
|
-
columns = res.columns
|
|
90
|
-
|
|
91
|
-
for idx in (0...columns.size)
|
|
92
|
-
meta.field_index[columns[idx]] = idx
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
ensure
|
|
96
|
-
res.close
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def create_table(klass, db)
|
|
100
|
-
conn = db.get_connection
|
|
101
|
-
|
|
102
|
-
fields = create_fields(klass)
|
|
103
|
-
|
|
104
|
-
sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
|
|
105
|
-
|
|
106
|
-
# Create table constrains
|
|
107
|
-
|
|
108
|
-
if klass.__meta and constrains = klass.__meta[:sql_constrain]
|
|
109
|
-
sql << ", #{constrains.join(', ')}"
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
sql << ");"
|
|
113
|
-
|
|
114
|
-
# Create indices
|
|
115
|
-
|
|
116
|
-
if klass.__meta and indices = klass.__meta[:sql_index]
|
|
117
|
-
for data in indices
|
|
118
|
-
idx, options = *data
|
|
119
|
-
idx = idx.to_s
|
|
120
|
-
pre_sql, post_sql = options[:pre], options[:post]
|
|
121
|
-
idxname = idx.gsub(/ /, "").gsub(/,/, "_").gsub(/\(.*\)/, "")
|
|
122
|
-
sql << " CREATE #{pre_sql} INDEX #{klass::DBTABLE}_#{idxname}_idx #{post_sql} ON #{klass::DBTABLE} (#{idx});"
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
begin
|
|
127
|
-
conn.store.query(sql).close
|
|
128
|
-
Logger.info "Created table '#{klass::DBTABLE}'."
|
|
129
|
-
rescue Exception => ex
|
|
130
|
-
# gmosx: any idea how to better test this?
|
|
131
|
-
if ex.to_s =~ /table .* already exists/i
|
|
132
|
-
Logger.debug "Table already exists" if $DBG
|
|
133
|
-
return
|
|
134
|
-
else
|
|
135
|
-
raise
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
# Create join tables if needed. Join tables are used in
|
|
140
|
-
# 'many_to_many' relations.
|
|
141
|
-
|
|
142
|
-
if klass.__meta and joins = klass.__meta[:sql_join]
|
|
143
|
-
for data in joins
|
|
144
|
-
# the class to join to and some options.
|
|
145
|
-
join_name, join_class, options = *data
|
|
146
|
-
|
|
147
|
-
# gmosx: dont use DBTABLE here, perhaps the join class
|
|
148
|
-
# is not managed yet.
|
|
149
|
-
join_table = "#{self.class.join_table(klass, join_class, join_name)}"
|
|
150
|
-
join_src = "#{self.class.encode(klass)}_oid"
|
|
151
|
-
join_dst = "#{self.class.encode(join_class)}_oid"
|
|
152
|
-
begin
|
|
153
|
-
conn.store.query("CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )").close
|
|
154
|
-
conn.store.query("CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)").close
|
|
155
|
-
conn.store.query("CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)").close
|
|
156
|
-
rescue Exception => ex
|
|
157
|
-
# gmosx: any idea how to better test this?
|
|
158
|
-
if ex.to_s =~ /table .* already exists/i
|
|
159
|
-
Logger.debug "Join table already exists" if $DBG
|
|
160
|
-
else
|
|
161
|
-
raise
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
ensure
|
|
168
|
-
db.put_connection
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# The SQLite connection.
|
|
174
|
-
|
|
175
|
-
class SqliteConnection < Connection
|
|
176
|
-
|
|
177
|
-
def initialize(db)
|
|
178
|
-
@store = SQLite3::Database.new("#{db.config[:database]}.db")
|
|
179
|
-
super
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def close
|
|
183
|
-
@store.close
|
|
184
|
-
super
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def prepare(sql)
|
|
188
|
-
@store.prepare(sql)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def query(sql)
|
|
192
|
-
Logger.debug sql if $DBG
|
|
193
|
-
begin
|
|
194
|
-
return @store.query(sql)
|
|
195
|
-
rescue => ex
|
|
196
|
-
Logger.error "DB error #{ex}, [#{sql}]"
|
|
197
|
-
Logger.error ex.backtrace.join("\n")
|
|
198
|
-
return nil
|
|
199
|
-
end
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
def exec(sql)
|
|
203
|
-
Logger.debug sql if $DBG
|
|
204
|
-
begin
|
|
205
|
-
@store.query(sql).close
|
|
206
|
-
rescue => ex
|
|
207
|
-
Logger.error "DB error #{ex}, [#{sql}]"
|
|
208
|
-
Logger.error ex.backtrace.join("\n")
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
def start
|
|
213
|
-
@store.transaction
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
def commit
|
|
217
|
-
@store.commit
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def rollback
|
|
221
|
-
@store.rollback
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def valid_res?(res)
|
|
225
|
-
return !(res.nil?)
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def read_one(res, klass)
|
|
229
|
-
return nil unless valid_res?(res)
|
|
230
|
-
row = res.next
|
|
231
|
-
return nil unless row
|
|
232
|
-
|
|
233
|
-
obj = klass.new
|
|
234
|
-
obj.og_read(row)
|
|
235
|
-
|
|
236
|
-
res.close
|
|
237
|
-
return obj
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def read_all(res, klass)
|
|
241
|
-
return [] unless valid_res?(res)
|
|
242
|
-
objects = []
|
|
243
|
-
|
|
244
|
-
res.each do |row|
|
|
245
|
-
obj = klass.new
|
|
246
|
-
obj.og_read(row)
|
|
247
|
-
objects << obj
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
res.close
|
|
251
|
-
return objects
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def read_int(res, idx = 0)
|
|
255
|
-
val = res.next[idx].to_i
|
|
256
|
-
res.close
|
|
257
|
-
return val
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
end
|
data/lib/og/backend.rb
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
-
# $Id: backend.rb 263 2005-02-23 13:45:08Z gmosx $
|
|
4
|
-
|
|
5
|
-
require 'yaml'
|
|
6
|
-
|
|
7
|
-
require 'og/connection'
|
|
8
|
-
|
|
9
|
-
module Og
|
|
10
|
-
|
|
11
|
-
# Abstract backend. A backend communicates with the RDBMS.
|
|
12
|
-
# This is the base class for the various backend implementations.
|
|
13
|
-
|
|
14
|
-
class Backend
|
|
15
|
-
|
|
16
|
-
# The actual connection to the database
|
|
17
|
-
attr_accessor :conn
|
|
18
|
-
|
|
19
|
-
# Intitialize the connection to the RDBMS.
|
|
20
|
-
|
|
21
|
-
def initialize(config)
|
|
22
|
-
raise "Not implemented"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Close the connection to the RDBMS.
|
|
26
|
-
|
|
27
|
-
def close()
|
|
28
|
-
@conn.close()
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
32
|
-
# :section: Utilities
|
|
33
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
34
|
-
|
|
35
|
-
# Encode the name of the klass as an sql safe string.
|
|
36
|
-
# The Module separators are replaced with _ and NOT stripped
|
|
37
|
-
# out so that we can convert back to the original notation if
|
|
38
|
-
# needed. The leading module if available is removed.
|
|
39
|
-
|
|
40
|
-
def self.encode(klass)
|
|
41
|
-
"#{klass.name.gsub(/^.*::/, "")}".gsub(/::/, "_").downcase
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# The name of the SQL table where objects of this class
|
|
45
|
-
# are stored.
|
|
46
|
-
|
|
47
|
-
def self.table(klass)
|
|
48
|
-
"_#{Og.table_prefix}#{encode(klass)}"
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# The name of the join table for the two given classes.
|
|
52
|
-
|
|
53
|
-
def self.join_table(klass1, klass2)
|
|
54
|
-
"_#{Og.table_prefix}j_#{encode(klass1)}_#{encode(klass2)}"
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Returns the props that will be included in the insert query.
|
|
58
|
-
# For some backends the oid should be stripped.
|
|
59
|
-
|
|
60
|
-
def self.props_for_insert(klass)
|
|
61
|
-
klass.__props
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Precompile the insert code for the given class.
|
|
65
|
-
# The generated code sets the oid when inserting!
|
|
66
|
-
|
|
67
|
-
def self.eval_og_insert(klass)
|
|
68
|
-
props = props_for_insert(klass)
|
|
69
|
-
|
|
70
|
-
values = props.collect { |p| write_prop(p) }
|
|
71
|
-
|
|
72
|
-
sql = "INSERT INTO #{table(klass)} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values.join(',')})"
|
|
73
|
-
|
|
74
|
-
if klass.instance_methods.include?("og_pre_insert")
|
|
75
|
-
pre_cb = "og_pre_insert(conn);"
|
|
76
|
-
else
|
|
77
|
-
pre_cb = ""
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
if klass.instance_methods.include?("og_post_insert")
|
|
81
|
-
post_cb = "og_post_insert(conn);"
|
|
82
|
-
else
|
|
83
|
-
post_cb = ""
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
if klass.instance_methods.include?("og_pre_insert_update")
|
|
87
|
-
pre_cb << "og_pre_insert_update(conn);"
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
if klass.instance_methods.include?("og_post_insert_update")
|
|
91
|
-
post_cb << "og_post_insert_update(conn);"
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
klass.class_eval %{
|
|
95
|
-
def og_insert(conn)
|
|
96
|
-
#{insert_code(klass, sql, pre_cb, post_cb)}
|
|
97
|
-
end
|
|
98
|
-
}
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Precompile the update code for the given class.
|
|
102
|
-
# Ignore the oid when updating!
|
|
103
|
-
|
|
104
|
-
def self.eval_og_update(klass)
|
|
105
|
-
props = klass.__props.reject { |p| :oid == p.symbol }
|
|
106
|
-
|
|
107
|
-
updates = props.collect { |p|
|
|
108
|
-
"#{p.name}=#{write_prop(p)}"
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
sql = "UPDATE #{klass::DBTABLE} SET #{updates.join(', ')} WHERE oid=#\{@oid\}"
|
|
112
|
-
|
|
113
|
-
if klass.instance_methods.include?("og_pre_update")
|
|
114
|
-
pre_cb = "og_pre_update(conn);"
|
|
115
|
-
else
|
|
116
|
-
pre_cb = ""
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
if klass.instance_methods.include?("og_post_update")
|
|
120
|
-
post_cb = "og_post_update(conn);"
|
|
121
|
-
else
|
|
122
|
-
post_cb = ""
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
if klass.instance_methods.include?("og_pre_insert_update")
|
|
126
|
-
pre_cb << "og_pre_insert_update(conn);"
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
if klass.instance_methods.include?("og_post_insert_update")
|
|
130
|
-
post_cb << "og_post_insert_update(conn);"
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
klass.class_eval %{
|
|
134
|
-
def og_update(conn)
|
|
135
|
-
#{pre_cb}
|
|
136
|
-
conn.exec "#{sql}"
|
|
137
|
-
#{post_cb}
|
|
138
|
-
end
|
|
139
|
-
}
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Precompile the code to read objects of the given class
|
|
143
|
-
# from the backend. In order to allow for changing
|
|
144
|
-
# field/attribute orders we have to use a field mapping hash.
|
|
145
|
-
|
|
146
|
-
def self.eval_og_deserialize(klass, og)
|
|
147
|
-
calc_field_index(klass, og)
|
|
148
|
-
|
|
149
|
-
props = klass.__props
|
|
150
|
-
code = []
|
|
151
|
-
|
|
152
|
-
props.each do |p|
|
|
153
|
-
if idx = og.managed_classes[klass].field_index[p.name]
|
|
154
|
-
# more fault tolerant if a new field is added and it
|
|
155
|
-
# doesnt exist in the database.
|
|
156
|
-
code << "@#{p.name} = #{read_prop(p, idx)}"
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
klass.class_eval %{
|
|
161
|
-
def og_deserialize(res, tuple = nil)
|
|
162
|
-
#{code.join('; ')}
|
|
163
|
-
end
|
|
164
|
-
}
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
168
|
-
# :section: Connection methods.
|
|
169
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
170
|
-
|
|
171
|
-
# Create the database.
|
|
172
|
-
|
|
173
|
-
def self.create_db(database, user = nil, password = nil)
|
|
174
|
-
Logger.info "Creating database '#{database}'."
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
# Drop the database.
|
|
178
|
-
|
|
179
|
-
def self.drop_db(database, user = nil, password = nil)
|
|
180
|
-
Logger.info "Dropping database '#{database}'."
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
# Execute an SQL query and return the result.
|
|
184
|
-
|
|
185
|
-
def query(sql)
|
|
186
|
-
raise "Not implemented"
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
# Execute an SQL query, no result returned.
|
|
190
|
-
|
|
191
|
-
def exec(sql)
|
|
192
|
-
raise "Not implemented"
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# Execute an SQL query and return the result. Wrapped in a
|
|
196
|
-
# rescue block.
|
|
197
|
-
|
|
198
|
-
def safe_query(sql)
|
|
199
|
-
raise "Not implemented"
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
# Execute an SQL query, no result returned. Wrapped in a
|
|
203
|
-
# rescue block.
|
|
204
|
-
|
|
205
|
-
def safe_exec(sql)
|
|
206
|
-
raise "Not implemented"
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
# Check if it is a valid resultset.
|
|
210
|
-
|
|
211
|
-
def valid?(res)
|
|
212
|
-
raise "Not implemented"
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# Start a new transaction.
|
|
216
|
-
|
|
217
|
-
def start
|
|
218
|
-
exec "START TRANSACTION"
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
# Commit a transaction.
|
|
222
|
-
|
|
223
|
-
def commit
|
|
224
|
-
exec "COMMIT"
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
# Rollback transaction.
|
|
228
|
-
|
|
229
|
-
def rollback
|
|
230
|
-
exec "ROLLBACK"
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
# Create the fields that correpsond to the klass properties.
|
|
234
|
-
# The generated fields array is used in create_table.
|
|
235
|
-
# If the property has an :sql metadata this overrides the
|
|
236
|
-
# default mapping. If the property has an :extra_sql metadata
|
|
237
|
-
# the extra sql is appended after the default mapping.
|
|
238
|
-
|
|
239
|
-
def create_fields(klass, typemap)
|
|
240
|
-
fields = []
|
|
241
|
-
|
|
242
|
-
klass.__props.each do |p|
|
|
243
|
-
klass.sql_index(p.symbol) if p.meta[:sql_index]
|
|
244
|
-
|
|
245
|
-
field = "#{p.symbol}"
|
|
246
|
-
|
|
247
|
-
if p.meta and p.meta[:sql]
|
|
248
|
-
field << " #{p.meta[:sql]}"
|
|
249
|
-
else
|
|
250
|
-
field << " #{typemap[p.klass]}"
|
|
251
|
-
# attach extra sql
|
|
252
|
-
if p.meta and extra_sql = p.meta[:extra_sql]
|
|
253
|
-
field << " #{extra_sql}"
|
|
254
|
-
end
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
fields << field
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
return fields
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
# Create the managed object table. The properties of the
|
|
264
|
-
# object are mapped to the table columns. Additional sql relations
|
|
265
|
-
# and constrains are created (indicices, sequences, etc).
|
|
266
|
-
|
|
267
|
-
def create_table(klass)
|
|
268
|
-
return if query("SELECT * FROM #{klass::DBTABLE} LIMIT 1")
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
# Drop the managed object table
|
|
272
|
-
|
|
273
|
-
def drop_table(klass)
|
|
274
|
-
exec "DROP TABLE #{klass::DBTABLE}"
|
|
275
|
-
end
|
|
276
|
-
|
|
277
|
-
# Deserialize one row of the resultset.
|
|
278
|
-
|
|
279
|
-
def deserialize_one(res, klass)
|
|
280
|
-
raise 'Not implemented'
|
|
281
|
-
end
|
|
282
|
-
|
|
283
|
-
# Deserialize all rows of the resultset.
|
|
284
|
-
|
|
285
|
-
def deserialize_all(res, klass)
|
|
286
|
-
raise 'Not implemented'
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
# Return a single integer value from the resultset.
|
|
290
|
-
|
|
291
|
-
def get_int(res, idx = 0)
|
|
292
|
-
raise 'Not implemented'
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
end
|