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.
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