nitro 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/{ChangeLog → CHANGELOG} +137 -0
  2. data/INSTALL +1 -2
  3. data/README +1 -1
  4. data/Rakefile +10 -61
  5. data/benchmark/{nitro/bench.rb → bench.rb} +1 -1
  6. data/benchmark/{nitro/simple-webrick-n-200.txt → simple-webrick-n-200.txt} +0 -0
  7. data/benchmark/{nitro/static-webrick-n-200.txt → static-webrick-n-200.txt} +0 -0
  8. data/benchmark/{nitro/tiny-lhttpd-n-200-c-5.txt → tiny-lhttpd-n-200-c-5.txt} +0 -0
  9. data/benchmark/{nitro/tiny-webrick-n-200-c-5.txt → tiny-webrick-n-200-c-5.txt} +0 -0
  10. data/benchmark/{nitro/tiny-webrick-n-200.txt → tiny-webrick-n-200.txt} +0 -0
  11. data/benchmark/{nitro/tiny2-webrick-n-200.txt → tiny2-webrick-n-200.txt} +0 -0
  12. data/doc/{ChangeLog.1 → CHANGELOG.1} +0 -0
  13. data/{RELEASES → doc/RELEASES} +46 -0
  14. data/doc/faq.txt +7 -0
  15. data/examples/README.windows +1 -1
  16. data/examples/ajax/controller.rb +21 -0
  17. data/examples/ajax/public/index.xhtml +70 -0
  18. data/examples/ajax/public/js/ajax.js +64 -0
  19. data/examples/ajax/run.rb +16 -0
  20. data/examples/blog/README +6 -3
  21. data/examples/blog/conf/apache.conf +2 -2
  22. data/examples/blog/conf/lhttpd.conf +2 -2
  23. data/examples/blog/log/apache.error_log +777 -0
  24. data/examples/blog/{root → public}/base.xsl +0 -0
  25. data/examples/blog/{root → public}/fcgi.rb +0 -0
  26. data/examples/blog/{root → public}/m/bubbles.gif +0 -0
  27. data/examples/blog/{root → public}/m/comments_curve.gif +0 -0
  28. data/examples/blog/{root → public}/m/down.gif +0 -0
  29. data/examples/blog/{root → public}/m/footer_bg.gif +0 -0
  30. data/examples/blog/{root → public}/m/garrow.gif +0 -0
  31. data/examples/blog/{root → public}/m/gbull.gif +0 -0
  32. data/examples/blog/{root → public}/m/grbull.gif +0 -0
  33. data/examples/blog/{root → public}/m/h1_bg.gif +0 -0
  34. data/examples/blog/{root → public}/m/header_bg.gif +0 -0
  35. data/examples/blog/{root → public}/m/nitro.gif +0 -0
  36. data/examples/blog/{root → public}/m/obull.gif +0 -0
  37. data/examples/blog/{root → public}/m/page_bg.gif +0 -0
  38. data/examples/blog/{root → public}/m/rss.gif +0 -0
  39. data/examples/blog/{root → public}/m/side_title_bg.gif +0 -0
  40. data/examples/blog/{root → public}/m/sidebar_bg.gif +0 -0
  41. data/examples/{no_xsl_blog/root → blog/public}/style.css +6 -0
  42. data/examples/blog/run.rb +10 -12
  43. data/examples/blog/{lib → src}/blog.rb +3 -3
  44. data/examples/blog/{lib/blog → src}/controller.rb +13 -2
  45. data/examples/blog/src/mailer.rb +23 -0
  46. data/examples/blog/{lib/blog/model.rb → src/models/blog.rb} +4 -7
  47. data/examples/blog/src/models/content.rb +52 -0
  48. data/examples/blog/src/views/blog_entry_email.xhtml +16 -0
  49. data/examples/blog/{root → src/views}/comments.xhtml +0 -0
  50. data/examples/blog/{root → src/views}/entry_form.xhtml +0 -0
  51. data/examples/blog/{root → src/views}/error.xhtml +0 -0
  52. data/examples/blog/{root → src/views}/index.xhtml +0 -0
  53. data/examples/blog/{root → src/views}/login.xhtml +0 -0
  54. data/examples/blog/{root → src/views}/recent_posts.xhtml +0 -0
  55. data/examples/blog/{root → src/views}/view_entry.xhtml +8 -0
  56. data/examples/blog/{root → src/views}/view_entry.xml +0 -0
  57. data/examples/blog/src/xsl/base.xsl +153 -0
  58. data/examples/blog/{root → src/xsl}/style.xsl +2 -2
  59. data/examples/no_xsl_blog/README +5 -1
  60. data/examples/no_xsl_blog/conf/apache.conf +2 -2
  61. data/examples/no_xsl_blog/conf/lhttpd.conf +2 -2
  62. data/examples/no_xsl_blog/lib/blog/model.rb +1 -1
  63. data/{lib/parts → examples/no_xsl_blog/lib}/content.rb +1 -11
  64. data/examples/no_xsl_blog/log/apache.error_log +405 -0
  65. data/examples/no_xsl_blog/{root → public}/comments.xhtml +0 -0
  66. data/examples/no_xsl_blog/{root → public}/entry_form.xhtml +0 -0
  67. data/examples/no_xsl_blog/{root → public}/fcgi.rb +0 -0
  68. data/examples/no_xsl_blog/{root → public}/index.xhtml +0 -0
  69. data/examples/no_xsl_blog/{root → public}/login.xhtml +0 -0
  70. data/examples/no_xsl_blog/{root → public}/m/bubbles.gif +0 -0
  71. data/examples/no_xsl_blog/{root → public}/m/comments_curve.gif +0 -0
  72. data/examples/no_xsl_blog/{root → public}/m/down.gif +0 -0
  73. data/examples/no_xsl_blog/{root → public}/m/footer_bg.gif +0 -0
  74. data/examples/no_xsl_blog/{root → public}/m/garrow.gif +0 -0
  75. data/examples/no_xsl_blog/{root → public}/m/gbull.gif +0 -0
  76. data/examples/no_xsl_blog/{root → public}/m/grbull.gif +0 -0
  77. data/examples/no_xsl_blog/{root → public}/m/h1_bg.gif +0 -0
  78. data/examples/no_xsl_blog/{root → public}/m/header_bg.gif +0 -0
  79. data/examples/no_xsl_blog/{root → public}/m/nitro.gif +0 -0
  80. data/examples/no_xsl_blog/{root → public}/m/obull.gif +0 -0
  81. data/examples/no_xsl_blog/{root → public}/m/page_bg.gif +0 -0
  82. data/examples/no_xsl_blog/{root → public}/m/rss.gif +0 -0
  83. data/examples/no_xsl_blog/{root → public}/m/side_title_bg.gif +0 -0
  84. data/examples/no_xsl_blog/{root → public}/m/sidebar_bg.gif +0 -0
  85. data/examples/no_xsl_blog/{root → public}/recent_posts.xhtml +0 -0
  86. data/examples/{blog/root → no_xsl_blog/public}/style.css +0 -0
  87. data/examples/no_xsl_blog/{root → public}/view_entry.xhtml +0 -0
  88. data/examples/no_xsl_blog/{root → public}/view_entry.xml +0 -0
  89. data/examples/tiny/conf/apache.conf +2 -2
  90. data/examples/tiny/log/apache.error_log +100 -0
  91. data/examples/tiny/{root → public}/fcgi.rb +0 -0
  92. data/examples/tiny/{root → public}/include.xhtml +0 -0
  93. data/examples/tiny/{root → public}/index.xhtml +0 -0
  94. data/{bin/proto/root/m → examples/tiny/public}/nitro.png +0 -0
  95. data/examples/tiny/{root → public}/upload.xhtml +0 -0
  96. data/examples/tiny/run.rb +1 -2
  97. data/examples/why_wiki/wiki.yml +1 -0
  98. data/install.rb +5 -2
  99. data/lib/nitro.rb +2 -6
  100. data/lib/nitro/adapters/fastcgi.rb +2 -2
  101. data/lib/nitro/adapters/webrick.rb +4 -4
  102. data/lib/nitro/conf.rb +5 -2
  103. data/lib/nitro/controller.rb +2 -2
  104. data/lib/nitro/dispatcher.rb +19 -8
  105. data/lib/nitro/mail.rb +252 -8
  106. data/lib/nitro/render.rb +24 -21
  107. data/lib/nitro/runner.rb +1 -1
  108. data/lib/nitro/scaffold.rb +2 -5
  109. data/lib/nitro/simple.rb +2 -1
  110. data/lib/nitro/template.rb +42 -2
  111. data/test/nitro/tc_controller.rb +9 -4
  112. data/test/nitro/tc_dispatcher.rb +4 -6
  113. data/test/nitro/tc_mail.rb +95 -0
  114. data/test/{root → public}/blog/list.xhtml +0 -0
  115. data/test/public/dummy_mailer/registration.xhtml +5 -0
  116. data/vendor/README +0 -1
  117. metadata +136 -181
  118. data/benchmark/og/bench.rb +0 -75
  119. data/benchmark/og/sqlite-no-prepare.1.txt +0 -13
  120. data/benchmark/og/sqlite-no-prepare.2.txt +0 -13
  121. data/benchmark/og/sqlite-prepare.1.txt +0 -13
  122. data/benchmark/og/sqlite-prepare.2.txt +0 -13
  123. data/bin/proto/README +0 -34
  124. data/bin/proto/conf/apache.conf +0 -1
  125. data/bin/proto/conf/app.conf.rb +0 -14
  126. data/bin/proto/conf/lhttpd.conf +0 -236
  127. data/bin/proto/ctl +0 -4
  128. data/bin/proto/lib/README +0 -5
  129. data/bin/proto/log/README +0 -3
  130. data/bin/proto/root/fcgi.rb +0 -6
  131. data/bin/proto/root/index.xhtml +0 -69
  132. data/bin/proto/root/style.css +0 -152
  133. data/bin/proto/root/style.xsl +0 -99
  134. data/doc/og_config.txt +0 -35
  135. data/doc/og_tutorial.txt +0 -595
  136. data/examples/og/README +0 -11
  137. data/examples/og/mock_example.rb +0 -50
  138. data/examples/og/mysql_to_psql.rb +0 -96
  139. data/examples/og/run.rb +0 -286
  140. data/examples/tiny/root/nitro.png +0 -0
  141. data/lib/glue.rb +0 -55
  142. data/lib/glue/array.rb +0 -61
  143. data/lib/glue/attribute.rb +0 -83
  144. data/lib/glue/cache.rb +0 -138
  145. data/lib/glue/flexob.rb +0 -12
  146. data/lib/glue/hash.rb +0 -122
  147. data/lib/glue/inflector.rb +0 -91
  148. data/lib/glue/logger.rb +0 -147
  149. data/lib/glue/misc.rb +0 -14
  150. data/lib/glue/mixins.rb +0 -36
  151. data/lib/glue/number.rb +0 -24
  152. data/lib/glue/object.rb +0 -32
  153. data/lib/glue/pool.rb +0 -60
  154. data/lib/glue/property.rb +0 -408
  155. data/lib/glue/string.rb +0 -162
  156. data/lib/glue/time.rb +0 -85
  157. data/lib/glue/validation.rb +0 -394
  158. data/lib/og.rb +0 -185
  159. data/lib/og/adapter.rb +0 -513
  160. data/lib/og/adapters/filesys.rb +0 -121
  161. data/lib/og/adapters/mysql.rb +0 -347
  162. data/lib/og/adapters/oracle.rb +0 -375
  163. data/lib/og/adapters/psql.rb +0 -273
  164. data/lib/og/adapters/sqlite.rb +0 -262
  165. data/lib/og/backend.rb +0 -297
  166. data/lib/og/connection.rb +0 -304
  167. data/lib/og/database.rb +0 -282
  168. data/lib/og/enchant.rb +0 -125
  169. data/lib/og/meta.rb +0 -373
  170. data/lib/og/mock.rb +0 -165
  171. data/lib/og/observer.rb +0 -53
  172. data/lib/og/typemacros.rb +0 -23
  173. data/lib/parts/README +0 -9
  174. data/test/glue/tc_attribute.rb +0 -22
  175. data/test/glue/tc_cache.rb +0 -45
  176. data/test/glue/tc_hash.rb +0 -38
  177. data/test/glue/tc_logger.rb +0 -39
  178. data/test/glue/tc_numbers.rb +0 -20
  179. data/test/glue/tc_property.rb +0 -89
  180. data/test/glue/tc_property_mixins.rb +0 -93
  181. data/test/glue/tc_property_type_checking.rb +0 -35
  182. data/test/glue/tc_strings.rb +0 -103
  183. data/test/glue/tc_validation.rb +0 -188
  184. data/test/og/tc_filesys.rb +0 -83
  185. data/test/og/tc_lifecycle.rb +0 -104
  186. data/test/og/tc_many_to_many.rb +0 -62
  187. data/test/og/tc_meta.rb +0 -55
  188. data/test/og/tc_observer.rb +0 -85
  189. data/test/og/tc_sqlite.rb +0 -87
  190. data/test/tc_og.rb +0 -355
  191. data/vendor/composite_sexp_processor.rb +0 -43
  192. data/vendor/parse_tree.rb +0 -745
  193. data/vendor/sexp_processor.rb +0 -453
@@ -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