dm-hibernate-adapter 0.1pre-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/lib/dm-hibernate-adapter.rb +471 -0
  2. data/lib/dm-hibernate-adapter/dialects.rb +37 -0
  3. data/lib/dm-hibernate-adapter/hibernate.rb +403 -0
  4. data/lib/dm-hibernate-adapter/spec/setup.rb +27 -0
  5. data/lib/dm-hibernate-adapter/transaction.rb +27 -0
  6. data/lib/dm-hibernate-adapter_ext.jar +0 -0
  7. data/lib/jibernate.rb +2 -0
  8. data/spec/abstract_adapter/adapter_shared_spec.rb +514 -0
  9. data/spec/abstract_adapter/dm-hibernate-adapter_spec.rb +25 -0
  10. data/spec/abstract_adapter/rcov.opts +6 -0
  11. data/spec/abstract_adapter/spec.opts +4 -0
  12. data/spec/abstract_adapter/spec_helper.rb +8 -0
  13. data/spec/dm_core/adapter_spec.rb +12 -0
  14. data/spec/dm_core/rcov.opts +6 -0
  15. data/spec/dm_core/spec.opts +5 -0
  16. data/spec/dm_core/spec_helper.rb +42 -0
  17. data/spec/log4j.properties +11 -0
  18. data/spec/transient/dm-hibernate-adapter_spec.rb +57 -0
  19. data/spec/transient/lib/adapter_helpers.rb +107 -0
  20. data/spec/transient/lib/collection_helpers.rb +18 -0
  21. data/spec/transient/lib/counter_adapter.rb +38 -0
  22. data/spec/transient/lib/pending_helpers.rb +46 -0
  23. data/spec/transient/lib/rspec_immediate_feedback_formatter.rb +54 -0
  24. data/spec/transient/rcov.opts +6 -0
  25. data/spec/transient/shared/adapter_shared_spec.rb +408 -0
  26. data/spec/transient/shared/finder_shared_spec.rb +1513 -0
  27. data/spec/transient/shared/model_spec.rb +165 -0
  28. data/spec/transient/shared/property_spec.rb +412 -0
  29. data/spec/transient/shared/resource_shared_spec.rb +1226 -0
  30. data/spec/transient/shared/resource_spec.rb +133 -0
  31. data/spec/transient/shared/sel_shared_spec.rb +112 -0
  32. data/spec/transient/spec.opts +4 -0
  33. data/spec/transient/spec_helper.rb +14 -0
  34. metadata +210 -0
@@ -0,0 +1,37 @@
1
+ module Hibernate
2
+ module Dialects
3
+ Cache71 = "org.hibernate.dialect.Cache71Dialect"
4
+ DataDirectOracle9 = "org.hibernate.dialect.DataDirectOracle9Dialect"
5
+ DB2390 = "org.hibernate.dialect.DB2390Dialect"
6
+ DB2400 = "org.hibernate.dialect.DB2400Dialect"
7
+ DB2 = "org.hibernate.dialect.DB2Dialect"
8
+ Derby = "org.hibernate.dialect.DerbyDialect"
9
+ Firebird = "org.hibernate.dialect.FirebirdDialect"
10
+ FrontBase = "org.hibernate.dialect.FrontBaseDialect"
11
+ H2 = "org.hibernate.dialect.H2Dialect"
12
+ HSQL = "org.hibernate.dialect.HSQLDialect"
13
+ Informix = "org.hibernate.dialect.InformixDialect"
14
+ Ingres = "org.hibernate.dialect.IngresDialect"
15
+ Interbase = "org.hibernate.dialect.InterbaseDialect"
16
+ JDataStore = "org.hibernate.dialect.JDataStoreDialect"
17
+ Mckoi = "org.hibernate.dialect.MckoiDialect"
18
+ MimerSQL = "org.hibernate.dialect.MimerSQLDialect"
19
+ MySQL5 = "org.hibernate.dialect.MySQL5Dialect"
20
+ MySQL5InnoDB = "org.hibernate.dialect.MySQL5InnoDBDialect"
21
+ MySQL = "org.hibernate.dialect.MySQLDialect"
22
+ MySQLInnoDB = "org.hibernate.dialect.MySQLInnoDBDialect"
23
+ MySQLMyISAM = "org.hibernate.dialect.MySQLMyISAMDialect"
24
+ Oracle9 = "org.hibernate.dialect.Oracle9Dialect"
25
+ Oracle = "org.hibernate.dialect.OracleDialect"
26
+ Pointbase = "org.hibernate.dialect.PointbaseDialect"
27
+ PostgreSQL = "org.hibernate.dialect.PostgreSQLDialect"
28
+ Progress = "org.hibernate.dialect.ProgressDialect"
29
+ RDMSOS2200 = "org.hibernate.dialect.RDMSOS2200Dialect"
30
+ SAPDB = "org.hibernate.dialect.SAPDBDialect"
31
+ SQLServer = "org.hibernate.dialect.SQLServerDialect"
32
+ Sybase11 = "org.hibernate.dialect.Sybase11Dialect"
33
+ SybaseAnywhere = "org.hibernate.dialect.SybaseAnywhereDialect"
34
+ Sybase = "org.hibernate.dialect.SybaseDialect"
35
+ TimesTen = "org.hibernate.dialect.TimesTenDialect"
36
+ end
37
+ end
@@ -0,0 +1,403 @@
1
+ module Hibernate
2
+ # XXX java_import: http://jira.codehaus.org/browse/JRUBY-3538
3
+ java_import 'de.saumya.jibernate.JibernateClassLoader'
4
+ java_import 'de.saumya.jibernate.JibernateJRubyClassLoader'
5
+ java_import org.hibernate.cfg.AnnotationConfiguration
6
+ JClass = java.lang.Class
7
+ JVoid = java.lang.Void::TYPE
8
+
9
+ @@logger = Slf4r::LoggerFacade.new(Hibernate)
10
+
11
+ def self.dialect=(dialect)
12
+ config.set_property "hibernate.dialect", dialect
13
+ end
14
+
15
+ def self.dialect
16
+ config.get_property "hibernate.dialect"
17
+ end
18
+
19
+ def self.current_session_context_class=(ctx_cls)
20
+ config.set_property "hibernate.current_session_context_class", ctx_cls
21
+ end
22
+
23
+ def self.connection_driver_class=(driver_class)
24
+ config.set_property "hibernate.connection.driver_class", driver_class
25
+ end
26
+
27
+ def self.connection_driver_class
28
+ config.get_property "hibernate.connection.driver_class"
29
+ end
30
+
31
+ def self.connection_url=(url)
32
+ config.set_property "hibernate.connection.url", url
33
+ end
34
+
35
+ def self.connection_url()
36
+ config.get_property "hibernate.connection.url"
37
+ end
38
+
39
+ def self.connection_username=(username)
40
+ config.set_property "hibernate.connection.username", username
41
+ end
42
+
43
+ def self.connection_username
44
+ config.get_property "hibernate.connection.username"
45
+ end
46
+
47
+ def self.connection_password=(password)
48
+ config.set_property "hibernate.connection.password", password
49
+ end
50
+
51
+ def self.connection_password
52
+ config.get_property "hibernate.connection.password"
53
+ end
54
+
55
+ def self.connection_pool_size=(size)
56
+ config.set_property "hibernate.connection.pool_size", size
57
+ end
58
+
59
+ def self.connection_pool_size
60
+ config.get_property "hibernate.connection.pool_size"
61
+ end
62
+
63
+ class PropertyShim
64
+ def initialize(config)
65
+ @config = config
66
+ end
67
+
68
+ def []=(key, value)
69
+ key = ensure_hibernate_key(key)
70
+ @config.set_property key, value
71
+ end
72
+
73
+ def [](key)
74
+ key = ensure_hibernate_key(key)
75
+ config.get_property key
76
+ end
77
+
78
+ private
79
+ def ensure_hibernate_key(key)
80
+ unless key =~ /^hibernate\./
81
+ key = 'hibernate.' + key
82
+ end
83
+ key
84
+ end
85
+ end
86
+
87
+ def self.properties()
88
+ PropertyShim.new(@config)
89
+ end
90
+
91
+ def self.tx( &block )
92
+ # http://community.jboss.org/wiki/sessionsandtransactions
93
+ if block_given?()
94
+ s = nil
95
+ begin
96
+ s = session()
97
+ s.begin_transaction()
98
+ block.call(s)
99
+ s.transaction().commit()
100
+ rescue => e
101
+ s.transaction().rollback() if s
102
+ raise( e )
103
+ ensure
104
+ s.close() if s
105
+ end
106
+ else
107
+ raise( "not supported" )
108
+ end
109
+ end
110
+
111
+ def self.factory()
112
+ @factory ||= config.build_session_factory()
113
+ end
114
+
115
+ def self.session()
116
+ factory().open_session()
117
+ end
118
+
119
+ def self.reset_config
120
+ if @config
121
+ # TODO make the whole with a list of property names
122
+ # define the static accessors with the very same list
123
+ dialect = self.dialect
124
+ username = self.connection_username
125
+ password = self.connection_password
126
+ url = self.connection_url
127
+ driver_class = self.connection_driver_class
128
+ @factory = nil
129
+ @config = AnnotationConfiguration.new()
130
+ self.dialect= dialect
131
+ self.connection_username = username
132
+ self.connection_password = password
133
+ self.connection_url = url
134
+ self.connection_driver_class = driver_class
135
+ end
136
+ end
137
+
138
+ def self.config()
139
+ @config ||= AnnotationConfiguration.new()
140
+ end
141
+
142
+ def self.add_model(model_java_class)
143
+ unless mapped?(model_java_class)
144
+ config.add_annotated_class(model_java_class)
145
+ @mapped_classes << model_java_class
146
+ @@logger.debug " model/class #{model_java_class} registered successfully"
147
+ else
148
+ @@logger.debug " model/class #{model_java_class} registered already"
149
+ end
150
+ end
151
+
152
+ private
153
+
154
+ def self.mapped?(clazz)
155
+ @mapped_classes ||= []
156
+ @mapped_classes.member?(clazz)
157
+ end
158
+
159
+ module Model
160
+
161
+ # TODO enhance TYPEs list
162
+ TYPES = {
163
+ ::String => java.lang.String,
164
+ ::Integer => java.lang.Integer,
165
+ ::Float => java.lang.Double,
166
+ ::BigDecimal => java.math.BigDecimal,
167
+ ::Date => java.util.Date,
168
+ ::DateTime => java.util.Date,
169
+ ::Time => java.util.Date,
170
+ ::TrueClass => java.lang.Boolean,
171
+ }
172
+
173
+ def self.included(model)
174
+
175
+ model.extend(ClassMethods)
176
+
177
+ # XXX WARNING
178
+ # <monkey-patching>
179
+ # if class wasn't mapped before
180
+ unless model.mapped?
181
+ [:auto_migrate!, :auto_upgrade!, :create, :all, :copy, :first, :first_or_create, :first_or_new, :get, :last, :load].each do |method|
182
+ model.before_class_method(method, :hibernate!)
183
+ end
184
+
185
+ [:save, :update, :destroy, :update_attributes].each do |method|
186
+ model.before(method) { model.hibernate! }
187
+ end
188
+ end
189
+ # </monkey-patching>
190
+
191
+ end
192
+
193
+ module ClassMethods
194
+
195
+ java_import org.hibernate.tool.hbm2ddl.SchemaExport
196
+ java_import org.hibernate.tool.hbm2ddl.SchemaUpdate
197
+
198
+ @@logger = Slf4r::LoggerFacade.new(Hibernate::Model)
199
+
200
+ def auto_migrate!(repo = nil)
201
+ config = Hibernate::config
202
+
203
+ # TODO drop only one table, not all of them !
204
+ schema_export = SchemaExport.new(config)
205
+ console = true # XXX here you can turn on/off logger
206
+ schema_export.drop(console,true)
207
+ schema_export.create(console,true)
208
+ end
209
+
210
+ def auto_upgrade!(repo = nil)
211
+ # raise "NYI" #TODO
212
+ end
213
+
214
+ def to_java_type(type)
215
+ TYPES[type] || self.to_java_type(type.primitive)
216
+ end
217
+
218
+
219
+ def to_java_class_name
220
+ # http://jira.codehaus.org/browse/JRUBY-4601
221
+ # return properly full-specified class name (ie rubyobj.Z.X.Y)
222
+ "rubyobj."+self.to_s.gsub("::",".")
223
+ end
224
+
225
+ def hibernate!
226
+ # just make sure all the properties are there
227
+ # initialize join models and target keys
228
+ relationships.each do |property, relationship|
229
+ relationship.child_key
230
+ relationship.parent_key
231
+ relationship.through if relationship.respond_to?(:through)
232
+ relationship.via if relationship.respond_to?(:via)
233
+ end
234
+ unless mapped?
235
+ discriminator = nil
236
+
237
+ relationships().each do |rel|
238
+ puts "---------------relationship: #{rel.inspect()}"
239
+ end
240
+
241
+ properties().each do |prop|
242
+ puts "---------------property: #{prop.inspect()}"
243
+ discriminator = add_java_property(prop) || discriminator
244
+ end
245
+
246
+ # "stolen" from http://github.com/superchris/hibernate
247
+ annotation = {
248
+ javax.persistence.Entity => { },
249
+ javax.persistence.Table => { "name" => self.storage_name }
250
+ }
251
+
252
+ if discriminator
253
+ annotation[javax.persistence.Inheritance] = { "strategy" => javax.persistence.InheritanceType::SINGLE_TABLE.to_s }
254
+ annotation[javax.persistence.DiscriminatorColumn] = { "name" => discriminator }
255
+ end
256
+
257
+ add_class_annotation(annotation)
258
+
259
+ Hibernate.add_model(become_java!)
260
+
261
+ unless java.lang.Thread.currentThread.context_class_loader.is_a? JibernateClassLoader
262
+ cl = java.lang.Thread.currentThread.context_class_loader
263
+ if cl.is_a? org.jruby.util.JRubyClassLoader
264
+ java.lang.Thread.currentThread.context_class_loader = JibernateJRubyClassLoader.new(cl)
265
+ else
266
+ java.lang.Thread.currentThread.context_class_loader = JibernateClassLoader.new(cl)
267
+ end
268
+ end
269
+
270
+ java.lang.Thread.currentThread.context_class_loader.register(java_class)
271
+
272
+ @@logger.debug "become_java! #{java_class}"
273
+ else
274
+ @@logger.debug "become_java! fired already #{java_class}"
275
+ end
276
+
277
+ end
278
+
279
+ #helper method
280
+ def mapped?()
281
+ Hibernate.mapped?(java_class())
282
+ end
283
+
284
+
285
+ private
286
+
287
+ def hibernate_sigs()
288
+ @hibernate_sigs ||= {}
289
+ end
290
+
291
+ # "stolen" from http://github.com/superchris/hibernate
292
+ def add_java_property(prop)
293
+ @@logger.info("#{prop.model.name} gets property added #{prop.name}")
294
+ name = prop.name
295
+ type = prop.class
296
+ return name if (type == DataMapper::Property::Discriminator)
297
+
298
+ column_name = prop.field
299
+ annotation = {}
300
+ # TODO honor prop.field mapping and maybe more
301
+ if prop.serial?
302
+ annotation[javax.persistence.Id] = {}
303
+ annotation[javax.persistence.GeneratedValue] = {}
304
+ elsif prop.key?
305
+ # TODO obey multi column keys
306
+ annotation[javax.persistence.Id] = {}
307
+ end
308
+
309
+ annotation[javax.persistence.Column] = {
310
+ "unique" => prop.unique?,
311
+ "name" => prop.field
312
+ }
313
+
314
+ unless prop.index.nil?
315
+ if (prop.index == true)
316
+ annotation[org.hibernate.annotations.Index]
317
+ elsif (prop.index.class == Symbol)
318
+ annotation[org.hibernate.annotations.Index] = {"name" => prop.index.to_s}
319
+ else
320
+ # TODO arrays !!
321
+ #annotation[org.hibernate.annotations.Index] = {"name" => []}
322
+ #prop.index.each do|index|
323
+ # annotation[org.hibernate.annotations.Index]["name"] << index.to_s
324
+ #end
325
+ end
326
+ end
327
+ if prop.required?
328
+ annotation[javax.persistence.Column]["nullable"] = !prop.required?
329
+ end
330
+ if (prop.respond_to?(:length) && !prop.length.nil?)
331
+ annotation[javax.persistence.Column]["length"] = java.lang.Integer.new(prop.length)
332
+ end
333
+ if (prop.respond_to?(:scale) && !prop.scale.nil?)
334
+ annotation[javax.persistence.Column]["scale"] = java.lang.Integer.new(prop.scale)
335
+ end
336
+ if (prop.respond_to?(:precision) && !prop.precision.nil?)
337
+ annotation[javax.persistence.Column]["precision"] = java.lang.Integer.new(prop.precision)
338
+ end
339
+
340
+ get_name = "get#{name.to_s.capitalize}"
341
+ set_name = "set#{name.to_s.capitalize}"
342
+
343
+ # TODO Time, Discriminator, EmbededValue
344
+ # to consider: in mu opinion those methods should set from/get to java objects...
345
+ if (type == DataMapper::Property::Date)
346
+ class_eval <<-EOT
347
+ def #{set_name.intern} (d)
348
+ attribute_set(:#{name} , d.nil? ? nil : Date.civil(d.year + 1900, d.month + 1, d.date))
349
+ end
350
+ EOT
351
+ class_eval <<-EOT
352
+ def #{get_name.intern}
353
+ d = attribute_get(:#{name} )
354
+ org.joda.time.DateTime.new(d.year, d.month, d.day, 0, 0, 0, 0).to_date if d
355
+ end
356
+ EOT
357
+ elsif (type == DataMapper::Property::DateTime)
358
+ class_eval <<-EOT
359
+ def #{set_name.intern} (d)
360
+ attribute_set(:#{name} , d.nil? ? nil : DateTime.civil(d.year + 1900, d.month + 1, d.date, d.hours, d.minutes, d.seconds))
361
+ end
362
+ EOT
363
+ class_eval <<-EOT
364
+ def #{get_name.intern}
365
+ d = attribute_get(:#{name} )
366
+ org.joda.time.DateTime.new(d.year, d.month, d.day, d.hour, d.min, d.sec, 0).to_date if d
367
+ end
368
+ EOT
369
+ elsif (type.to_s == BigDecimal || type == DataMapper::Property::Decimal)
370
+ class_eval <<-EOT
371
+ def #{set_name.intern} (d)
372
+ attribute_set(:#{name} , d.nil? ? nil :#{type}.new(d.to_s))
373
+ end
374
+ EOT
375
+ class_eval <<-EOT
376
+ def #{get_name.intern}
377
+ d = attribute_get(:#{name} )
378
+ java.math.BigDecimal.new(d.to_i) if d
379
+ end
380
+ EOT
381
+ else
382
+ class_eval <<-EOT
383
+ def #{set_name.intern} (d)
384
+ attribute_set(:#{name} , d)
385
+ end
386
+ EOT
387
+ class_eval <<-EOT
388
+ def #{get_name.intern}
389
+ d = attribute_get(:#{name} )
390
+ d
391
+ end
392
+ EOT
393
+ end
394
+
395
+ mapped_type = to_java_type(type).java_class
396
+ add_method_signature get_name, [mapped_type]
397
+ add_method_annotation get_name, annotation
398
+ add_method_signature set_name, [JVoid, mapped_type]
399
+ nil
400
+ end
401
+ end
402
+ end
403
+ end
@@ -0,0 +1,27 @@
1
+ require 'dm-hibernate-adapter'
2
+ require 'dm-core/spec/setup'
3
+
4
+ module DataMapper
5
+ module Spec
6
+ module Adapters
7
+
8
+ class HibernateAdapter < Adapter
9
+
10
+ def setup!
11
+ #adapter = DataMapper.setup(name, connection_uri)
12
+ adapter = DataMapper.setup(:default, :adapter => "hibernate", :dialect => "H2", :username => "sa", :url => "jdbc:h2:target/jibernate")
13
+
14
+ test_connection(adapter)
15
+ adapter
16
+ rescue Exception => e
17
+ puts "Could not connect to the database using '#{connection_uri}' because of: #{e.inspect}"
18
+ end
19
+
20
+ end
21
+
22
+ use HibernateAdapter
23
+
24
+
25
+ end
26
+ end
27
+ end