dm-hibernate-adapter 0.1pre-java

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