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,121 +0,0 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: filesys.rb 264 2005-02-23 13:46:55Z gmosx $
4
-
5
- require 'fileutils'
6
-
7
- require 'og/adapter'
8
- require 'og/connection'
9
- require 'glue/attribute'
10
-
11
- module Og
12
-
13
- # The Filesys adapter. This adapter stores Og objectes in
14
- # the filesystem. This adapter is a proof of concept and
15
- # at the moment severely limited. For extra documentation
16
- # see lib/og/adapter.rb
17
-
18
- class FilesysAdapter < Adapter
19
-
20
- # Creates the name of the database root dir.
21
-
22
- def self.dir(database)
23
- "#{database}_db"
24
- end
25
-
26
- def create_db(database, user = nil, password = nil)
27
- begin
28
- FileUtils.mkdir_p(self.class.dir(database))
29
- rescue
30
- Logger.error "Cannot create '#{database}'!"
31
- end
32
- end
33
-
34
- def drop_db(database, user = nil, password = nil)
35
- begin
36
- FileUtils.rmdir(self.class.dir(database))
37
- super
38
- rescue
39
- Logger.error "Cannot drop '#{database}'!"
40
- end
41
- end
42
-
43
- def insert_code(klass, db, pre_cb, post_cb)
44
- props = props_for_insert(klass)
45
- values = props.collect { |p| write_prop(p) }.join(',')
46
-
47
- sql = "INSERT INTO #{klass::DBTABLE} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values})"
48
-
49
- %{
50
- #{pre_cb}
51
- conn.store.query("#{sql}").close
52
- @oid = conn.store.last_insert_row_id
53
- #{post_cb}
54
- }
55
- end
56
-
57
- def new_connection(db)
58
- return FilesysConnection.new(db)
59
- end
60
-
61
- # A 'table' is emulated by using a directory to store
62
- # one file per table row. Each file contains an object
63
- # marshaled in YAML format. A special file called
64
- # '_sequence' stores the sequence for this 'table'.
65
-
66
- def create_table(klass, db)
67
- class_dir = File.join(self.class.dir(db.config[:database]), klass::DBTABLE)
68
- FileUtils.mkdir_p(class_dir)
69
-
70
- seq_file = File.join(class_dir, 'seq')
71
- File.open(seq_file, 'w') { |f| f << '1' }
72
- rescue => ex
73
- Logger.error "Cannot create directory to store '#{klass}' classes!"
74
- end
75
-
76
- end
77
-
78
- # The Filesys adapter connection.
79
-
80
- class FilesysConnection < Connection
81
-
82
- def initialize(db)
83
- super
84
- config = db.config
85
-
86
- begin
87
- raise unless File.directory?(FilesysAdapter.dir(config[:database]))
88
- rescue => ex
89
- if true # ex.to_s =~ /database .* does not exist/i
90
- Logger.info "Database '#{config[:database]}' not found!"
91
- @db.adapter.create_db(config[:database], config[:user])
92
- retry
93
- end
94
- raise
95
- end
96
- end
97
-
98
- def save(obj)
99
- seq = nil
100
- class_dir = File.join(FilesysAdapter.dir(@db.config[:database]), obj.class::DBTABLE)
101
- File.open(File.join(class_dir, 'seq'), 'r') { |f| seq = f.read.to_i }
102
- obj.oid = seq
103
- File.open(File.join(class_dir, "#{seq}.yml"), 'w') { |f| f << obj.to_yaml }
104
- seq += 1
105
- File.open(File.join(class_dir, 'seq'), 'w') { |f| f << seq }
106
- end
107
-
108
- def load(oid, klass)
109
- obj = nil
110
- class_dir = File.join(FilesysAdapter.dir(@db.config[:database]), klass::DBTABLE)
111
- File.open(File.join(class_dir, "#{oid}.yml"), 'r') { |f| obj = YAML::load(f.read) }
112
- return obj
113
- end
114
-
115
- def close
116
- Logger.debug "Closed DB connection." if $DBG
117
- end
118
-
119
- end
120
-
121
- end
@@ -1,347 +0,0 @@
1
- # * George Moschovitis <gm@navel.gr>
2
- # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: mysql.rb 270 2005-03-07 17:52:16Z gmosx $
4
-
5
- require 'mysql'
6
-
7
- require 'og/adapter'
8
- require 'og/connection'
9
- require 'glue/attribute'
10
-
11
- module Og
12
-
13
- # The MySQL adapter. This adapter communicates with
14
- # an MySQL rdbms. For extra documentation see
15
- # lib/og/adapter.rb
16
-
17
- class MysqlAdapter < Adapter
18
-
19
- def initialize
20
- super
21
- @typemap.update(TrueClass => 'tinyint')
22
- @typecast.update(TrueClass => "#\{:s: ? \"1\" : 'NULL' \}")
23
- end
24
-
25
- def self.escape(str)
26
- return nil unless str
27
- return Mysql.quote(str)
28
- end
29
-
30
- def self.timestamp(time = Time.now)
31
- return nil unless time
32
- return time.strftime("%Y%m%d%H%M%S")
33
- end
34
-
35
- def self.date(date)
36
- return nil unless date
37
- return "#{date.year}-#{date.month}-#{date.mday}"
38
- end
39
-
40
- def write_prop(p)
41
- if p.klass.ancestors.include?(Integer)
42
- return "#\{@#{p.symbol} || 'NULL'\}"
43
- elsif p.klass.ancestors.include?(Float)
44
- return "#\{@#{p.symbol} || 'NULL'\}"
45
- elsif p.klass.ancestors.include?(String)
46
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol})\}'" : 'NULL'\}|
47
- elsif p.klass.ancestors.include?(Time)
48
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
49
- elsif p.klass.ancestors.include?(Date)
50
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.date(@#{p.symbol})\}'" : 'NULL'\}|
51
- elsif p.klass.ancestors.include?(TrueClass)
52
- return "#\{@#{p.symbol} ? 1 : 0 \}"
53
- else
54
- # gmosx: keep the '' for nil symbols.
55
- return %|#\{@#{p.symbol} ? "'#\{#{self.class}.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
56
- end
57
- end
58
-
59
- def read_prop(p, idx)
60
- if p.klass.ancestors.include?(Integer)
61
- return "res[#{idx}].to_i"
62
- elsif p.klass.ancestors.include?(Float)
63
- return "res[#{idx}].to_f"
64
- elsif p.klass.ancestors.include?(String)
65
- return "res[#{idx}]"
66
- elsif p.klass.ancestors.include?(Time)
67
- return "#{self.class}.parse_timestamp(res[#{idx}])"
68
- elsif p.klass.ancestors.include?(Date)
69
- return "#{self.class}.parse_date(res[#{idx}])"
70
- elsif p.klass.ancestors.include?(TrueClass)
71
- return "('0' != res[#{idx}])"
72
- else
73
- return "YAML::load(res[#{idx}])"
74
- end
75
- end
76
-
77
- def create_db(database, user = nil, password = nil)
78
- `mysqladmin -f --user=#{user} --password=#{password} create #{database}`
79
- super
80
- end
81
-
82
- def drop_db(database, user = nil, password = nil)
83
- `mysqladmin -f --user=#{user} --password=#{password} drop #{database}`
84
- super
85
- end
86
-
87
- def props_for_insert(klass)
88
- klass.__props.reject { |p| :oid == p.symbol }
89
- end
90
-
91
- def insert_code(klass, db, pre_cb, post_cb)
92
- props = props_for_insert(klass)
93
- values = props.collect { |p| write_prop(p) }.join(',')
94
-
95
- sql = "INSERT INTO #{klass::DBTABLE} (#{props.collect {|p| p.name}.join(',')}) VALUES (#{values})"
96
-
97
- %{
98
- #{pre_cb}
99
- conn.store.query_with_result = false
100
- conn.store.query "#{sql}"
101
- @oid = conn.store.insert_id()
102
- #{post_cb}
103
- }
104
- end
105
-
106
- def new_connection(db)
107
- return MysqlConnection.new(db)
108
- end
109
-
110
- def calc_field_index(klass, db)
111
- res = db.query "SELECT * FROM #{klass::DBTABLE} LIMIT 1"
112
- meta = db.managed_classes[klass]
113
-
114
- for idx in (0...res.num_fields)
115
- meta.field_index[res.fetch_field.name] = idx
116
- end
117
-
118
- ensure
119
- res.free if res
120
- end
121
-
122
- def create_fields(klass)
123
- fields = []
124
-
125
- klass.__props.each do |p|
126
- klass.sql_index(p.symbol) if p.meta[:sql_index]
127
-
128
- field = "#{p.symbol}"
129
-
130
- if p.meta and p.meta[:sql]
131
- field << " #{p.meta[:sql]}"
132
- else
133
- field << " #{@typemap[p.klass]}"
134
-
135
- if p.meta
136
- # set default value (gmosx: not that useful in the
137
- # current implementation).
138
- if default = p.meta[:default]
139
- field << " DEFAULT #{default.inspect} NOT NULL"
140
- end
141
-
142
- # set unique
143
- # FIXME: correctly handle UNIQUE constrain.
144
- # field << " UNIQUE" if p.meta[:unique]
145
-
146
- # attach extra sql
147
- if extra_sql = p.meta[:extra_sql]
148
- field << " #{extra_sql}"
149
- end
150
- end
151
- end
152
-
153
- fields << field
154
- end
155
-
156
- return fields
157
- end
158
-
159
- def create_table(klass, db)
160
- conn = db.get_connection
161
-
162
- fields = create_fields(klass)
163
-
164
- sql = "CREATE TABLE #{klass::DBTABLE} (#{fields.join(', ')}"
165
-
166
- conn.store.query_with_result = true
167
-
168
- # Create table constrains
169
-
170
- if klass.__meta and constrains = klass.__meta[:sql_constrain]
171
- sql << ", #{constrains.join(', ')}"
172
- end
173
-
174
- sql << ');'
175
-
176
- begin
177
- conn.store.query(sql)
178
- Logger.info "Created table '#{klass::DBTABLE}'."
179
- rescue => ex
180
- if ex.errno == 1050 # table already exists.
181
- Logger.debug "Table already exists" if $DBG
182
- return
183
- else
184
- raise
185
- end
186
- end
187
-
188
- # Create indices
189
-
190
- if klass.__meta and indices = klass.__meta[:sql_index]
191
- for data in indices
192
- idx, options = *data
193
- idx = idx.to_s
194
- pre_sql, post_sql = options[:pre], options[:post]
195
- idxname = idx.gsub(/ /, "").gsub(/,/, "_").gsub(/\(.*\)/, "")
196
- conn.store.query("CREATE #{pre_sql} INDEX #{klass::DBTABLE}_#{idxname}_idx #{post_sql} ON #{klass::DBTABLE} (#{idx})")
197
- end
198
- end
199
-
200
- # Create join tables if needed. Join tables are used in
201
- # 'many_to_many' relations.
202
-
203
- if klass.__meta and joins = klass.__meta[:sql_join]
204
- for data in joins
205
- # the class to join to and some options.
206
- join_name, join_class, options = *data
207
-
208
- # gmosx: dont use DBTABLE here, perhaps the join class
209
- # is not managed yet.
210
- join_table = "#{self.class.join_table(klass, join_class, join_name)}"
211
- join_src = "#{self.class.encode(klass)}_oid"
212
- join_dst = "#{self.class.encode(join_class)}_oid"
213
- begin
214
- conn.store.query("CREATE TABLE #{join_table} ( key1 integer NOT NULL, key2 integer NOT NULL )")
215
- conn.store.query("CREATE INDEX #{join_table}_key1_idx ON #{join_table} (key1)")
216
- conn.store.query("CREATE INDEX #{join_table}_key2_idx ON #{join_table} (key2)")
217
- rescue => ex
218
- if ex.errno == 1050 # table already exists.
219
- Logger.debug "Join table already exists" if $DBG
220
- else
221
- raise
222
- end
223
- end
224
- end
225
- end
226
-
227
- ensure
228
- db.put_connection
229
- end
230
-
231
- def eval_og_oid(klass)
232
- klass.class_eval %{
233
- prop_accessor :oid, Fixnum, :sql => 'integer AUTO_INCREMENT PRIMARY KEY'
234
- }
235
- end
236
- end
237
-
238
- # The MySQL connection.
239
-
240
- class MysqlConnection < Connection
241
-
242
- def initialize(db)
243
- super
244
-
245
- config = db.config
246
-
247
- @store = Mysql.connect(
248
- config[:address] || 'localhost',
249
- config[:user],
250
- config[:password],
251
- config[:database]
252
- )
253
- rescue => ex
254
- if ex.errno == 1049 # database does not exist.
255
- Logger.info "Database '#{config[:database]}' not found!"
256
- @db.adapter.create_db(config[:database], config[:user], config[:password])
257
- retry
258
- end
259
- raise
260
- end
261
-
262
- def close
263
- @store.close
264
- super
265
- end
266
-
267
- def prepare(sql)
268
- raise 'Not implemented!'
269
- end
270
-
271
- def query(sql)
272
- Logger.debug sql if $DBG
273
- begin
274
- @store.query_with_result = true
275
- return @store.query(sql)
276
- rescue => ex
277
- Logger.error "DB error #{ex}, [#{sql}]"
278
- Logger.error ex.backtrace.join("\n")
279
- return nil
280
- end
281
- end
282
-
283
- def exec(sql)
284
- Logger.debug sql if $DBG
285
- begin
286
- @store.query_with_result = false
287
- @store.query(sql)
288
- rescue => ex
289
- Logger.error "DB error #{ex}, [#{sql}]"
290
- Logger.error ex.backtrace.join("\n")
291
- end
292
- end
293
-
294
- def start
295
- # @store.transaction
296
- end
297
-
298
- def commit
299
- # @store.commit
300
- end
301
-
302
- def rollback
303
- # @store.rollback
304
- end
305
-
306
- def valid_res?(res)
307
- return !(res.nil? or 0 == res.num_rows)
308
- end
309
-
310
- def read_one(res, klass)
311
- return nil unless valid_res?(res)
312
-
313
- row = res.fetch_row
314
- obj = klass.new
315
- obj.og_read(row)
316
-
317
- res.free
318
- return obj
319
- end
320
-
321
- def read_all(res, klass)
322
- return [] unless valid_res?(res)
323
-
324
- objects = []
325
-
326
- for tuple in (0...res.num_rows)
327
- row = res.fetch_row
328
-
329
- obj = klass.new
330
- obj.og_read(row)
331
-
332
- objects << obj
333
- end
334
-
335
- res.free
336
- return objects
337
- end
338
-
339
- def read_int(res, idx = 0)
340
- val = res.fetch_row[idx].to_i
341
- res.free
342
- return val
343
- end
344
-
345
- end
346
-
347
- end