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/connection.rb
DELETED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
-
# $Id: connection.rb 270 2005-03-07 17:52:16Z gmosx $
|
|
4
|
-
|
|
5
|
-
module Og;
|
|
6
|
-
|
|
7
|
-
require 'glue/property'
|
|
8
|
-
require 'glue/array'
|
|
9
|
-
require 'glue/time'
|
|
10
|
-
|
|
11
|
-
# A Connection to the Database. This file defines the skeleton
|
|
12
|
-
# functionality. A backend specific implementation file (driver)
|
|
13
|
-
# implements all methods.
|
|
14
|
-
#
|
|
15
|
-
# === Future
|
|
16
|
-
#
|
|
17
|
-
# - support caching.
|
|
18
|
-
# - support prepared statements.
|
|
19
|
-
|
|
20
|
-
class Connection
|
|
21
|
-
|
|
22
|
-
# The Og database object.
|
|
23
|
-
|
|
24
|
-
attr_reader :db
|
|
25
|
-
|
|
26
|
-
# The actual connection to the backend store.
|
|
27
|
-
|
|
28
|
-
attr_accessor :store
|
|
29
|
-
|
|
30
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
31
|
-
# :section: Backend connection methods.
|
|
32
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
33
|
-
|
|
34
|
-
# Initialize a connection to the database.
|
|
35
|
-
|
|
36
|
-
def initialize(db)
|
|
37
|
-
@db = db
|
|
38
|
-
Logger.debug "Created DB connection." if $DBG
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Close the connection to the database.
|
|
42
|
-
|
|
43
|
-
def close
|
|
44
|
-
Logger.debug "Closed DB connection." if $DBG
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Create the managed object table. The properties of the
|
|
48
|
-
# object are mapped to the table columns. Additional sql relations
|
|
49
|
-
# and constrains are created (indicices, sequences, etc).
|
|
50
|
-
|
|
51
|
-
def create_table(klass)
|
|
52
|
-
raise 'Not implemented!'
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Drop the managed object table.
|
|
56
|
-
|
|
57
|
-
def drop_table(klass)
|
|
58
|
-
exec "DROP TABLE #{klass::DBTABLE}"
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# Prepare an sql statement.
|
|
62
|
-
|
|
63
|
-
def prepare(sql)
|
|
64
|
-
raise 'Not implemented!'
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Execute an SQL query and return the result.
|
|
68
|
-
|
|
69
|
-
def query(sql)
|
|
70
|
-
raise 'Not implemented!'
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Execute an SQL query, no result returned.
|
|
74
|
-
|
|
75
|
-
def exec(sql)
|
|
76
|
-
raise 'Not implemented!'
|
|
77
|
-
end
|
|
78
|
-
alias_method :execute, :exec
|
|
79
|
-
|
|
80
|
-
# Start a new transaction.
|
|
81
|
-
|
|
82
|
-
def start
|
|
83
|
-
exec 'START TRANSACTION'
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Commit a transaction.
|
|
87
|
-
|
|
88
|
-
def commit
|
|
89
|
-
exec 'COMMIT'
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Rollback a transaction.
|
|
93
|
-
|
|
94
|
-
def rollback
|
|
95
|
-
exec 'ROLLBACK'
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Transaction helper. In the transaction block use
|
|
99
|
-
# the db pointer to the backend.
|
|
100
|
-
|
|
101
|
-
def transaction(&block)
|
|
102
|
-
begin
|
|
103
|
-
start
|
|
104
|
-
yield(self)
|
|
105
|
-
commit
|
|
106
|
-
rescue => ex
|
|
107
|
-
Logger.error "DB Error: ERROR IN TRANSACTION"
|
|
108
|
-
Logger.error "#{ex}"
|
|
109
|
-
Logger.error "#{ex.backtrace}"
|
|
110
|
-
rollback
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
115
|
-
# :section: Deserialization methods.
|
|
116
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
117
|
-
|
|
118
|
-
# Is the given resultset valid?
|
|
119
|
-
|
|
120
|
-
def valid_res?(res)
|
|
121
|
-
return !(res.nil?)
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# Read (deserialize) one row of the resultset.
|
|
125
|
-
|
|
126
|
-
def read_one(res, klass)
|
|
127
|
-
raise 'Not implemented!'
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Read (deserialize) all rows of the resultset.
|
|
131
|
-
|
|
132
|
-
def read_all(res, klass)
|
|
133
|
-
raise 'Not implemented!'
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# Read the first column of the resultset as an Integer.
|
|
137
|
-
|
|
138
|
-
def read_int(res, idx = 0)
|
|
139
|
-
raise 'Not implemented!'
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
143
|
-
# :section: Managed object methods.
|
|
144
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
145
|
-
|
|
146
|
-
# Save an object to the database. Insert if this is a new object or
|
|
147
|
-
# update if this is already stored in the database.
|
|
148
|
-
|
|
149
|
-
def save(obj)
|
|
150
|
-
if obj.oid
|
|
151
|
-
# object allready inserted, update!
|
|
152
|
-
obj.og_update(self)
|
|
153
|
-
else
|
|
154
|
-
# not in the database, insert!
|
|
155
|
-
obj.og_insert(self)
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
alias_method :<<, :save
|
|
159
|
-
alias_method :put, :save
|
|
160
|
-
|
|
161
|
-
# Force insertion of managed object.
|
|
162
|
-
|
|
163
|
-
def insert(obj)
|
|
164
|
-
obj.og_insert(self)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
# Force update of managed object.
|
|
168
|
-
|
|
169
|
-
def update(obj)
|
|
170
|
-
obj.og_update(self)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Update only specific fields of the managed object.
|
|
174
|
-
#
|
|
175
|
-
# Input:
|
|
176
|
-
# sql = the sql code to updated the properties.
|
|
177
|
-
#
|
|
178
|
-
# WARNING: the object in memory is not updated.
|
|
179
|
-
#--
|
|
180
|
-
# TODO: should update the object in memory.
|
|
181
|
-
#++
|
|
182
|
-
|
|
183
|
-
def update_properties(update_sql, obj_or_oid, klass = nil)
|
|
184
|
-
oid = obj_or_oid.to_i
|
|
185
|
-
klass = obj_or_oid.class unless klass
|
|
186
|
-
|
|
187
|
-
exec "UPDATE #{klass::DBTABLE} SET #{update_sql} WHERE oid=#{oid}"
|
|
188
|
-
end
|
|
189
|
-
alias_method :pupdate, :update_properties
|
|
190
|
-
|
|
191
|
-
# Load an object from the database.
|
|
192
|
-
#
|
|
193
|
-
# Input:
|
|
194
|
-
# oid = the object oid, OR the object name.
|
|
195
|
-
|
|
196
|
-
def load(oid, klass)
|
|
197
|
-
if oid.to_i > 0 # a valid Fixnum ?
|
|
198
|
-
load_by_oid(oid, klass)
|
|
199
|
-
else
|
|
200
|
-
load_by_name(oid, klass)
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
alias_method :get, :load
|
|
204
|
-
|
|
205
|
-
# Load an object by oid.
|
|
206
|
-
|
|
207
|
-
def load_by_oid(oid, klass)
|
|
208
|
-
res = query "SELECT * FROM #{klass::DBTABLE} WHERE oid=#{oid}"
|
|
209
|
-
read_one(res, klass)
|
|
210
|
-
end
|
|
211
|
-
alias_method :get_by_oid, :load_by_oid
|
|
212
|
-
|
|
213
|
-
# Load an object by name.
|
|
214
|
-
|
|
215
|
-
def load_by_name(name, klass)
|
|
216
|
-
res = query "SELECT * FROM #{klass::DBTABLE} WHERE name='#{name}'"
|
|
217
|
-
read_one(res, klass)
|
|
218
|
-
end
|
|
219
|
-
alias_method :get_by_name, :load_by_name
|
|
220
|
-
|
|
221
|
-
# Load all objects of the given klass.
|
|
222
|
-
# Used to be called 'collect' in an earlier version.
|
|
223
|
-
|
|
224
|
-
def load_all(klass, extrasql = nil)
|
|
225
|
-
res = query "SELECT * FROM #{klass::DBTABLE} #{extrasql}"
|
|
226
|
-
read_all(res, klass)
|
|
227
|
-
end
|
|
228
|
-
alias_method :get_all, :load_all
|
|
229
|
-
|
|
230
|
-
# Perform a standard SQL query to the database. Deserializes the
|
|
231
|
-
# results.
|
|
232
|
-
|
|
233
|
-
def select(sql, klass)
|
|
234
|
-
unless sql =~ /SELECT/i
|
|
235
|
-
sql = "SELECT * FROM #{klass::DBTABLE} WHERE #{sql}"
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
res = query(sql)
|
|
239
|
-
read_all(res, klass)
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
# Optimized for one result.
|
|
243
|
-
|
|
244
|
-
def select_one(sql, klass)
|
|
245
|
-
unless sql =~ /SELECT/i
|
|
246
|
-
sql = "SELECT * FROM #{klass::DBTABLE} WHERE #{sql}"
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
res = query(sql)
|
|
250
|
-
read_one(res, klass)
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
# Perform a count query.
|
|
254
|
-
|
|
255
|
-
def count(sql, klass = nil)
|
|
256
|
-
unless sql =~ /SELECT/i
|
|
257
|
-
sql = "SELECT COUNT(*) FROM #{klass::DBTABLE} WHERE #{sql}"
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
res = query(sql)
|
|
261
|
-
return read_int(res)
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
# Delete an object from the database. Allways perform a deep delete.
|
|
265
|
-
#
|
|
266
|
-
# No need to optimize here with pregenerated code. Deletes are
|
|
267
|
-
# not used as much as reads or writes.
|
|
268
|
-
#
|
|
269
|
-
# Input:
|
|
270
|
-
#
|
|
271
|
-
# obj_or_oid = Object or oid to delete.
|
|
272
|
-
# klass = Class of object (can be nil if an object is passed)
|
|
273
|
-
#
|
|
274
|
-
#--
|
|
275
|
-
# TODO: pre evaluate for symmetry to the other methods
|
|
276
|
-
#++
|
|
277
|
-
|
|
278
|
-
def delete(obj_or_oid, klass = nil, cascade = true)
|
|
279
|
-
oid = obj_or_oid.to_i
|
|
280
|
-
klass = obj_or_oid.class unless klass
|
|
281
|
-
|
|
282
|
-
# this is a class callback!
|
|
283
|
-
|
|
284
|
-
if klass.respond_to?(:og_pre_delete)
|
|
285
|
-
klass.og_pre_delete(self, oid)
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
# TODO: implement this as stored procedure? naaah.
|
|
289
|
-
# TODO: also handle many_to_many relations.
|
|
290
|
-
|
|
291
|
-
transaction do |tx|
|
|
292
|
-
tx.exec "DELETE FROM #{klass::DBTABLE} WHERE oid=#{oid}"
|
|
293
|
-
if cascade and klass.__meta.include?(:descendants)
|
|
294
|
-
klass.__meta[:descendants].each do |dclass, linkback|
|
|
295
|
-
tx.exec "DELETE FROM #{dclass::DBTABLE} WHERE #{linkback}=#{oid}"
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
alias_method :delete!, :delete
|
|
301
|
-
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
end
|
data/lib/og/database.rb
DELETED
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
|
3
|
-
# $Id: database.rb 270 2005-03-07 17:52:16Z gmosx $
|
|
4
|
-
|
|
5
|
-
require 'glue/logger'
|
|
6
|
-
require 'glue/attribute'
|
|
7
|
-
require 'glue/property'
|
|
8
|
-
require 'glue/array'
|
|
9
|
-
require 'glue/hash'
|
|
10
|
-
require 'glue/time'
|
|
11
|
-
require 'glue/pool'
|
|
12
|
-
|
|
13
|
-
require 'og/enchant'
|
|
14
|
-
require 'og/meta'
|
|
15
|
-
require 'og/observer'
|
|
16
|
-
|
|
17
|
-
module Og
|
|
18
|
-
|
|
19
|
-
# Encapsulates an Og Database.
|
|
20
|
-
|
|
21
|
-
class Database
|
|
22
|
-
include Og::Enchant
|
|
23
|
-
|
|
24
|
-
# Managed class metadata
|
|
25
|
-
|
|
26
|
-
class ManagedClassMeta
|
|
27
|
-
# The managed class.
|
|
28
|
-
attr_accessor :klass
|
|
29
|
-
|
|
30
|
-
# A mapping of the database fields to the object properties.
|
|
31
|
-
attr_accessor :field_index
|
|
32
|
-
|
|
33
|
-
def initialize(klass = nil)
|
|
34
|
-
@klass = klass
|
|
35
|
-
@field_index = {}
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# hash of configuration options.
|
|
40
|
-
|
|
41
|
-
attr_accessor :config
|
|
42
|
-
|
|
43
|
-
# The adapter that comunicates with the backend
|
|
44
|
-
# datastore.
|
|
45
|
-
|
|
46
|
-
attr_accessor :adapter
|
|
47
|
-
|
|
48
|
-
# Pool of connections.
|
|
49
|
-
|
|
50
|
-
attr_accessor :connection_pool
|
|
51
|
-
|
|
52
|
-
# Managed classes.
|
|
53
|
-
|
|
54
|
-
attr_accessor :managed_classes
|
|
55
|
-
|
|
56
|
-
# Initialize the database interface.
|
|
57
|
-
|
|
58
|
-
def initialize(config)
|
|
59
|
-
@config = config
|
|
60
|
-
|
|
61
|
-
# populate with default options if needed.
|
|
62
|
-
@config[:connection_count] ||= 1
|
|
63
|
-
|
|
64
|
-
Logger.info "Connecting to database '#{@config[:database]}' using the '#{@config[:adapter]}' adapter."
|
|
65
|
-
|
|
66
|
-
@adapter = Adapter.for_name(@config[:adapter])
|
|
67
|
-
|
|
68
|
-
@connection_pool = N::Pool.new
|
|
69
|
-
@managed_classes = N::SafeHash.new
|
|
70
|
-
|
|
71
|
-
@config[:connection_count].times do
|
|
72
|
-
@connection_pool << @adapter.new_connection(self)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# gmosx, FIXME: this automanage code is not elegant and slow
|
|
76
|
-
# should probably recode this, along with glue/property.rb
|
|
77
|
-
|
|
78
|
-
if Og.auto_manage_classes
|
|
79
|
-
# automatically manage classes with properties and metadata.
|
|
80
|
-
# gmosx: Any idea how to optimize this?
|
|
81
|
-
|
|
82
|
-
classes_to_manage = []
|
|
83
|
-
|
|
84
|
-
ObjectSpace.each_object(Class) do |c|
|
|
85
|
-
if c.respond_to?(:__props) and c.__props
|
|
86
|
-
classes_to_manage << c
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
Logger.debug "Og auto manages the following classes:"
|
|
91
|
-
Logger.debug "#{classes_to_manage.inspect}"
|
|
92
|
-
|
|
93
|
-
manage_classes(*classes_to_manage)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# use the newly created database.
|
|
97
|
-
Og.use(self)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Shutdown the database interface.
|
|
101
|
-
|
|
102
|
-
def shutdown
|
|
103
|
-
for con in @connection_pool
|
|
104
|
-
con.close()
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
alias_method :close, :shutdown
|
|
108
|
-
|
|
109
|
-
# Get a connection from the pool to access the database.
|
|
110
|
-
# Stores the connection in a thread-local variable.
|
|
111
|
-
|
|
112
|
-
def get_connection
|
|
113
|
-
thread = Thread.current
|
|
114
|
-
|
|
115
|
-
unless conn = thread[:og_conn]
|
|
116
|
-
conn = @connection_pool.pop()
|
|
117
|
-
thread[:og_conn] = conn
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
return conn
|
|
121
|
-
end
|
|
122
|
-
alias_method :connection, :get_connection
|
|
123
|
-
|
|
124
|
-
# Restore an unused connection to the pool.
|
|
125
|
-
|
|
126
|
-
def put_connection
|
|
127
|
-
thread = Thread.current
|
|
128
|
-
|
|
129
|
-
if conn = thread[:og_conn]
|
|
130
|
-
thread[:og_conn] = nil
|
|
131
|
-
return @connection_pool.push(conn)
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
# Utility method, automatically restores a connection to the pool.
|
|
136
|
-
|
|
137
|
-
def connect(&block)
|
|
138
|
-
result = nil
|
|
139
|
-
|
|
140
|
-
begin
|
|
141
|
-
conn = get_connection
|
|
142
|
-
result = yield(conn)
|
|
143
|
-
ensure
|
|
144
|
-
put_connection
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
return result
|
|
148
|
-
end
|
|
149
|
-
alias_method :open, :connect
|
|
150
|
-
|
|
151
|
-
# Register a standard Ruby class as managed.
|
|
152
|
-
|
|
153
|
-
def manage(klass)
|
|
154
|
-
return if managed?(klass) or klass.ancestors.include?(Unmanageable)
|
|
155
|
-
|
|
156
|
-
@managed_classes[klass] = ManagedClassMeta.new(klass)
|
|
157
|
-
|
|
158
|
-
# Add standard og methods to the class.
|
|
159
|
-
convert(klass)
|
|
160
|
-
|
|
161
|
-
# Add helper methods to the class.
|
|
162
|
-
enchant(klass) if Og.enchant_managed_classes
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
# Helper method to set multiple managed classes.
|
|
166
|
-
|
|
167
|
-
def manage_classes(*klasses)
|
|
168
|
-
for klass in klasses
|
|
169
|
-
manage(klass)
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Stop managing a Ruby class
|
|
174
|
-
|
|
175
|
-
def unmanage(klass)
|
|
176
|
-
@managed_classes.delete(klass)
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# Is this class managed?
|
|
180
|
-
#
|
|
181
|
-
def managed?(klass)
|
|
182
|
-
return @managed_classes.include?(klass)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Add standard og functionality to the class
|
|
186
|
-
|
|
187
|
-
def convert(klass)
|
|
188
|
-
# gmosx: this check is needed to allow the developer to customize
|
|
189
|
-
# the sql generated for oid
|
|
190
|
-
|
|
191
|
-
@adapter.eval_og_oid(klass) unless klass.instance_methods.include?(:oid)
|
|
192
|
-
|
|
193
|
-
klass.class_eval %{
|
|
194
|
-
DBTABLE = "#{Adapter.table(klass)}"
|
|
195
|
-
DBSEQ = "#{Adapter.table(klass)}_oid_seq"
|
|
196
|
-
|
|
197
|
-
cattr_accessor :og_db
|
|
198
|
-
|
|
199
|
-
def to_i
|
|
200
|
-
@oid
|
|
201
|
-
end
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
# Set the adapter.
|
|
205
|
-
|
|
206
|
-
klass.og_db = self
|
|
207
|
-
|
|
208
|
-
# Add observer support.
|
|
209
|
-
|
|
210
|
-
klass.extend(Observable)
|
|
211
|
-
|
|
212
|
-
# Create the schema for this class if not available.
|
|
213
|
-
|
|
214
|
-
@adapter.create_table(klass, self) if Og.create_schema
|
|
215
|
-
|
|
216
|
-
# @adapter.eval_og_insert(klass, self)
|
|
217
|
-
# @adapter.eval_og_update(klass, self)
|
|
218
|
-
# @adapter.eval_og_read(klass, self)
|
|
219
|
-
|
|
220
|
-
@adapter.eval_lifecycle_methods(klass, self)
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
# Automatically wrap connection methods.
|
|
224
|
-
|
|
225
|
-
def self.wrap_method(method, args)
|
|
226
|
-
args = args.split(/,/)
|
|
227
|
-
class_eval %{
|
|
228
|
-
def #{method}(#{args.join(", ")})
|
|
229
|
-
thread = Thread.current
|
|
230
|
-
|
|
231
|
-
unless conn = thread[:og_conn]
|
|
232
|
-
conn = @connection_pool.pop()
|
|
233
|
-
thread[:og_conn] = conn
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
return conn.#{method}(#{args.collect {|a| a.split(/=/)[0]}.join(", ")})
|
|
237
|
-
end
|
|
238
|
-
}
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
wrap_method :db, ''
|
|
242
|
-
wrap_method :create_table, 'klass'
|
|
243
|
-
wrap_method :drop_table, 'klass'
|
|
244
|
-
wrap_method :save, 'obj'; alias_method :<<, :save; alias_method :put, :save
|
|
245
|
-
wrap_method :insert, 'obj'
|
|
246
|
-
wrap_method :update, 'obj'
|
|
247
|
-
wrap_method :update_properties, 'update_sql, obj_or_oid, klass = nil'
|
|
248
|
-
wrap_method :pupdate, 'update_sql, obj_or_oid, klass = nil'
|
|
249
|
-
wrap_method :load, 'oid, klass'; alias_method :get, :load
|
|
250
|
-
wrap_method :load_by_oid, 'oid, klass'
|
|
251
|
-
wrap_method :load_by_name, 'name, klass'
|
|
252
|
-
wrap_method :load_all, 'klass, extrasql = nil'
|
|
253
|
-
wrap_method :select, 'sql, klass'
|
|
254
|
-
wrap_method :select_one, 'sql, klass'
|
|
255
|
-
wrap_method :count, 'sql, klass = nil'
|
|
256
|
-
wrap_method :delete, 'obj_or_oid, klass = nil'
|
|
257
|
-
wrap_method :prepare, 'sql'
|
|
258
|
-
wrap_method :query, 'sql'
|
|
259
|
-
wrap_method :exec, 'sql'
|
|
260
|
-
|
|
261
|
-
class << self
|
|
262
|
-
|
|
263
|
-
# Create a new database.
|
|
264
|
-
|
|
265
|
-
def create_db!(config)
|
|
266
|
-
adapter = Adapter.for_name(config[:adapter])
|
|
267
|
-
adapter.create_db(config[:database], config[:user], config[:password])
|
|
268
|
-
end
|
|
269
|
-
alias_method :create!, :create_db!
|
|
270
|
-
|
|
271
|
-
# Drop an existing database.
|
|
272
|
-
|
|
273
|
-
def drop_db!(config)
|
|
274
|
-
adapter = Adapter.for_name(config[:adapter])
|
|
275
|
-
adapter.drop_db(config[:database], config[:user], config[:password])
|
|
276
|
-
end
|
|
277
|
-
alias_method :drop!, :drop_db!
|
|
278
|
-
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
end
|