ribs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +139 -0
- data/Rakefile +64 -0
- data/lib/antlr-2.7.6.jar +0 -0
- data/lib/commons-collections-3.1.jar +0 -0
- data/lib/dom4j-1.6.1.jar +0 -0
- data/lib/hibernate3.jar +0 -0
- data/lib/javassist-3.4.GA.jar +0 -0
- data/lib/jruby-complete.jar +0 -0
- data/lib/jta-1.1.jar +0 -0
- data/lib/ribs.jar +0 -0
- data/lib/ribs.rb +78 -0
- data/lib/ribs/core_ext/time.rb +21 -0
- data/lib/ribs/db.rb +188 -0
- data/lib/ribs/definition.rb +329 -0
- data/lib/ribs/meat.rb +33 -0
- data/lib/ribs/session.rb +237 -0
- data/lib/slf4j-api-1.5.2.jar +0 -0
- data/lib/slf4j-jdk14-1.5.2.jar +0 -0
- data/test/artist_spec.rb +94 -0
- data/test/find_spec.rb +2 -0
- data/test/simple_select_spec.rb +79 -0
- data/test/test_helper.rb +83 -0
- data/test/track_spec.rb +415 -0
- data/test/type_spec.rb +2 -0
- metadata +80 -0
@@ -0,0 +1,329 @@
|
|
1
|
+
module Ribs
|
2
|
+
# Ribs::ClassMethods contains all the methods that gets mixed in to
|
3
|
+
# a model class.
|
4
|
+
module ClassMethods
|
5
|
+
# Get the metadata for the current model
|
6
|
+
attr_reader :ribs_metadata
|
7
|
+
|
8
|
+
# Create a new instance of this model object, optionally setting
|
9
|
+
# properties based on +attrs+.
|
10
|
+
def new(attrs = {})
|
11
|
+
obj = super()
|
12
|
+
attrs.each do |k,v|
|
13
|
+
obj.send("#{k}=", v)
|
14
|
+
end
|
15
|
+
obj
|
16
|
+
end
|
17
|
+
|
18
|
+
# First creates a model object based on the values in +attrs+ and
|
19
|
+
# then saves this to the database directly.
|
20
|
+
def create(attrs = {})
|
21
|
+
val = new(attrs)
|
22
|
+
val.save
|
23
|
+
val
|
24
|
+
end
|
25
|
+
|
26
|
+
# Depending on the value of +id_or_sym+, tries to find the model
|
27
|
+
# with a specified id, or if +id_or_sym+ is <tt>:all</tt> returns
|
28
|
+
# all instances of this model.
|
29
|
+
def find(id_or_sym)
|
30
|
+
Ribs.with_session do |s|
|
31
|
+
s.find(self.ribs_metadata.persistent_class.entity_name, id_or_sym)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Destroys the model with the id +id+.
|
36
|
+
def destroy(id)
|
37
|
+
Ribs.with_session do |s|
|
38
|
+
s.delete(find(id))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# TODO: add inspect here
|
44
|
+
end
|
45
|
+
|
46
|
+
# Ribs::InstanceMethods provides the methods that gets mixed in to
|
47
|
+
# all instances of a model object.
|
48
|
+
module InstanceMethods
|
49
|
+
# Returns the Meat instance for this instance.
|
50
|
+
def __ribs_meat
|
51
|
+
@__ribs_meat ||= Ribs::Meat.new(self)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns an inspection based on current values of the data in the
|
55
|
+
# database.
|
56
|
+
def inspect
|
57
|
+
"#<#{self.class.name}: #{self.__ribs_meat.properties.inspect}>"
|
58
|
+
end
|
59
|
+
|
60
|
+
# Saves this instance to the database. If the instance already
|
61
|
+
# exists, it will update the database, otherwise it will create
|
62
|
+
# it.
|
63
|
+
def save
|
64
|
+
Ribs.with_session do |s|
|
65
|
+
s.save(self)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Removes this instance from the database.
|
70
|
+
def destroy!
|
71
|
+
__ribs_meat.destroyed = true
|
72
|
+
Ribs.with_session do |s|
|
73
|
+
s.delete(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Collects all the meta data about a specific Ribs model
|
79
|
+
class MetaData
|
80
|
+
# The table to connect to
|
81
|
+
attr_accessor :table
|
82
|
+
# The persistent class that Hibernate uses as a definition for
|
83
|
+
# this model.
|
84
|
+
attr_accessor :persistent_class
|
85
|
+
# The Rib that defines all the mapping data
|
86
|
+
attr_accessor :rib
|
87
|
+
|
88
|
+
# Return the property instance for the given +name+.
|
89
|
+
def [](name)
|
90
|
+
self.persistent_class.get_property(name.to_s) rescue nil
|
91
|
+
end
|
92
|
+
|
93
|
+
# Return all the properties for this model.
|
94
|
+
def properties
|
95
|
+
self.persistent_class.property_iterator.to_a.inject({}) do |h, value|
|
96
|
+
h[value.name] = value
|
97
|
+
h
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Contains the mapping data that gets created when calling the
|
103
|
+
# {Ribs!} method.
|
104
|
+
class Rib
|
105
|
+
# List of all the columns defined
|
106
|
+
attr_reader :columns
|
107
|
+
# List of all primary keys defined
|
108
|
+
attr_reader :primary_keys
|
109
|
+
# List of all columns to avoid
|
110
|
+
attr_reader :to_avoid
|
111
|
+
|
112
|
+
# Initializes object
|
113
|
+
def initialize
|
114
|
+
@columns = { }
|
115
|
+
@primary_keys = { }
|
116
|
+
@to_avoid = []
|
117
|
+
end
|
118
|
+
|
119
|
+
# Gets or sets the table name to work with. If +name+ is nil,
|
120
|
+
# returns the table name, if not sets the table name to +name+.
|
121
|
+
def table(name = nil)
|
122
|
+
if name
|
123
|
+
@table = name
|
124
|
+
else
|
125
|
+
@table
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Adds a new column mapping for a specific column.
|
130
|
+
def col(column, property = column, options = {})
|
131
|
+
@columns[column.to_s.downcase] = [property.to_s, options]
|
132
|
+
end
|
133
|
+
|
134
|
+
# Adds a new primary key mapping for a column.
|
135
|
+
def primary_key(column, property = column, options = {})
|
136
|
+
@primary_keys[column.to_s.downcase] = property.to_s
|
137
|
+
@columns[column.to_s.downcase] = [property.to_s, options]
|
138
|
+
end
|
139
|
+
|
140
|
+
# Avoids all the provided columns
|
141
|
+
def avoid(*columns)
|
142
|
+
@to_avoid += columns.map{|s| s.to_s.downcase}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
Table = org.hibernate.mapping.Table
|
147
|
+
Column = org.hibernate.mapping.Column
|
148
|
+
Property = org.hibernate.mapping.Property
|
149
|
+
SimpleValue = org.hibernate.mapping.SimpleValue
|
150
|
+
|
151
|
+
# A simple helper class that allows the Java parts of the system to
|
152
|
+
# get the Ruby class from the PersistentClass instance.
|
153
|
+
class RubyRootClass < org.hibernate.mapping.RootClass
|
154
|
+
include org.jruby.ribs.WithRubyClass
|
155
|
+
|
156
|
+
# The Ruby class
|
157
|
+
attr_accessor :ruby_class
|
158
|
+
|
159
|
+
def initialize(*args)
|
160
|
+
super
|
161
|
+
end
|
162
|
+
|
163
|
+
# Get the Ruby class. Implementation of the WithRubyClass
|
164
|
+
# interface.
|
165
|
+
def getRubyClass
|
166
|
+
@ruby_class
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
class << self
|
171
|
+
# Define a rib for the class +on+. If a block is given, will first
|
172
|
+
# yield an instance of Rib to it and then base the mapping
|
173
|
+
# definition on that.
|
174
|
+
#
|
175
|
+
# +options+ have several possible values:
|
176
|
+
# * <tt>:db</tt> - the database to connect this model to
|
177
|
+
#
|
178
|
+
def define_ribs(on, options = {})
|
179
|
+
rib = Rib.new
|
180
|
+
yield rib if block_given?
|
181
|
+
|
182
|
+
define_metadata_on_class on
|
183
|
+
rm = on.ribs_metadata
|
184
|
+
rm.rib = rib
|
185
|
+
|
186
|
+
db = nil
|
187
|
+
with_session(options[:db] || :default) do |s|
|
188
|
+
db = s.db
|
189
|
+
m = s.meta_data
|
190
|
+
name = rib.table || table_name_for(on.name, m)
|
191
|
+
|
192
|
+
tables = m.get_tables nil, nil, name.to_s, %w(TABLE VIEW ALIAS SYNONYM).to_java(:String)
|
193
|
+
if tables.next
|
194
|
+
table = Table.new(tables.get_string(3))
|
195
|
+
rm.table = table
|
196
|
+
c = tables.get_string(1)
|
197
|
+
table.catalog = c if c && c.length > 0
|
198
|
+
c = tables.get_string(2)
|
199
|
+
table.schema = c if c && c.length > 0
|
200
|
+
|
201
|
+
columns_rs = m.get_columns table.catalog, table.schema, table.name, nil
|
202
|
+
|
203
|
+
while columns_rs.next
|
204
|
+
c = Column.new(columns_rs.get_string(4))
|
205
|
+
c.default_value = columns_rs.get_string(13)
|
206
|
+
c.length = columns_rs.get_int(7)
|
207
|
+
c.nullable = columns_rs.get_string(18) == 'YES'
|
208
|
+
c.precision = columns_rs.get_int(10)
|
209
|
+
c.scale = columns_rs.get_int(9)
|
210
|
+
c.sql_type = columns_rs.get_string(6)
|
211
|
+
c.sql_type_code = java.lang.Integer.new(columns_rs.get_int(5))
|
212
|
+
|
213
|
+
table.add_column(c)
|
214
|
+
end
|
215
|
+
columns_rs.close rescue nil
|
216
|
+
tables.close rescue nil
|
217
|
+
|
218
|
+
pc = RubyRootClass.new
|
219
|
+
pc.ruby_class = on
|
220
|
+
pc.entity_name = on.name
|
221
|
+
pc.table = table
|
222
|
+
pc.add_tuplizer(org.hibernate.EntityMode::MAP, "org.jruby.ribs.RubyTuplizer")
|
223
|
+
|
224
|
+
rm.persistent_class = pc
|
225
|
+
|
226
|
+
table.column_iterator.each do |c|
|
227
|
+
unless rib.to_avoid.include?(c.name.downcase)
|
228
|
+
prop = Property.new
|
229
|
+
prop.persistent_class = pc
|
230
|
+
prop.name = ((v=rib.columns[c.name.downcase]) && v[0]) || c.name
|
231
|
+
val = SimpleValue.new(table)
|
232
|
+
val.add_column(c)
|
233
|
+
val.type_name = get_type_for_sql(c.sql_type, c.sql_type_code)
|
234
|
+
prop.value = val
|
235
|
+
|
236
|
+
if (!rib.primary_keys.empty? && rib.primary_keys[c.name.downcase]) || c.name.downcase == 'id'
|
237
|
+
pc.identifier_property = prop
|
238
|
+
pc.identifier = val
|
239
|
+
else
|
240
|
+
pc.add_property(prop)
|
241
|
+
end
|
242
|
+
|
243
|
+
define_meat_accessor(on, prop.name)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
pc.create_primary_key
|
247
|
+
db.mappings.add_class(pc)
|
248
|
+
else
|
249
|
+
tables.close rescue nil
|
250
|
+
raise "No table found for: #{name}"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
db.reset_session_factory!
|
255
|
+
end
|
256
|
+
|
257
|
+
JTypes = java.sql.Types
|
258
|
+
|
259
|
+
private
|
260
|
+
# Defines the actual accessor for a specific property on a
|
261
|
+
# class. This will define methods that use the Meat to get data.
|
262
|
+
def define_meat_accessor(clazz, name)
|
263
|
+
downcased = name.downcase
|
264
|
+
clazz.class_eval <<CODE
|
265
|
+
def #{downcased}
|
266
|
+
self.__ribs_meat[:"#{name}"]
|
267
|
+
end
|
268
|
+
|
269
|
+
def #{downcased}=(value)
|
270
|
+
self.__ribs_meat[:"#{name}"] = value
|
271
|
+
end
|
272
|
+
CODE
|
273
|
+
end
|
274
|
+
|
275
|
+
# Returns the Java type for a specific combination of a type name
|
276
|
+
# and an SQL type code
|
277
|
+
def get_type_for_sql(name, code)
|
278
|
+
case code
|
279
|
+
when JTypes::VARCHAR
|
280
|
+
"string"
|
281
|
+
when JTypes::INTEGER
|
282
|
+
"int"
|
283
|
+
when JTypes::TIME
|
284
|
+
"java.sql.Time"
|
285
|
+
when JTypes::DATE
|
286
|
+
"java.sql.Date"
|
287
|
+
when JTypes::TIMESTAMP
|
288
|
+
"java.sql.Timestamp"
|
289
|
+
when JTypes::BLOB
|
290
|
+
"java.sql.Blob"
|
291
|
+
when JTypes::CLOB
|
292
|
+
"java.sql.Clob"
|
293
|
+
when JTypes::DOUBLE
|
294
|
+
"double"
|
295
|
+
when JTypes::SMALLINT
|
296
|
+
"boolean"
|
297
|
+
when JTypes::DECIMAL
|
298
|
+
"java.math.BigDecimal"
|
299
|
+
else
|
300
|
+
$stderr.puts [name, code].inspect
|
301
|
+
nil
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Tries to figure out if a table name should be in lower case or
|
306
|
+
# upper case, and returns the table name based on that.
|
307
|
+
def table_name_for(str, metadata)
|
308
|
+
if metadata.stores_lower_case_identifiers
|
309
|
+
str.downcase
|
310
|
+
elsif metadata.stores_upper_case_identifiers
|
311
|
+
str.upcase!
|
312
|
+
else
|
313
|
+
str
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
# Defines the meta data information on a class, and mixes in
|
318
|
+
# ClassMethods and InstanceMethods to it.
|
319
|
+
def define_metadata_on_class(clazz)
|
320
|
+
clazz.instance_variable_set :@ribs_metadata, Ribs::MetaData.new
|
321
|
+
class << clazz
|
322
|
+
include ClassMethods
|
323
|
+
end
|
324
|
+
clazz.class_eval do
|
325
|
+
include InstanceMethods
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
data/lib/ribs/meat.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
module Ribs
|
2
|
+
# The Meat is what actually includes data. This is the holder object
|
3
|
+
# for all data that comes from a database. This allows Ribs to avoid
|
4
|
+
# polluting model objects with loads of instance variables. Instead
|
5
|
+
# everything is kept in one instance of Meat. The Meat also keeps
|
6
|
+
# track of whether the object is persistent or if it's been
|
7
|
+
# destroyed. Note that Meat is very implementation dependent, and
|
8
|
+
# should not be relied upon.
|
9
|
+
class Meat
|
10
|
+
# All the data for this instance
|
11
|
+
attr_reader :properties
|
12
|
+
# Is this instance persistent yet, or not?
|
13
|
+
attr_accessor :persistent
|
14
|
+
# Has this instance been destroyed?
|
15
|
+
attr_accessor :destroyed
|
16
|
+
|
17
|
+
# +inside+ is the instance this Meat belongs to.
|
18
|
+
def initialize(inside)
|
19
|
+
@inside = inside
|
20
|
+
@properties = {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets the current value of a property
|
24
|
+
def [](ix)
|
25
|
+
@properties[ix]
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sets the current value of a property
|
29
|
+
def []=(ix, value)
|
30
|
+
@properties[ix] = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/ribs/session.rb
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
module Ribs
|
2
|
+
# A Ribs session maps many-to-one with a Hibernate session. When
|
3
|
+
# there are no more Ribs sessions left, the Hibernate session will
|
4
|
+
# be released too.
|
5
|
+
#
|
6
|
+
# The methods in Session is not to be used outside the framework in
|
7
|
+
# most cases, since they are internal, brittle, not based on
|
8
|
+
# Hibernate in all cases, and very much subject to change. Currently
|
9
|
+
# they provide capabilities that aren't part of the framework yet,
|
10
|
+
# such as migrations and setting up test data.
|
11
|
+
#
|
12
|
+
class Session
|
13
|
+
# This error is thrown when an operation on a session is
|
14
|
+
# attempted but the internal Hibernate session has already
|
15
|
+
# been closed.
|
16
|
+
#
|
17
|
+
class NotConnectedError < StandardError;end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
# Returns a session object from the database +from+. The
|
21
|
+
# available values for from is either one of the existing
|
22
|
+
# defined database names, or <tt>:default</tt>, which will give
|
23
|
+
# a session to the default database.
|
24
|
+
#
|
25
|
+
def get(from = :default)
|
26
|
+
db = case from
|
27
|
+
when :default
|
28
|
+
Ribs::DB::get
|
29
|
+
when Ribs::DB
|
30
|
+
from
|
31
|
+
else
|
32
|
+
Ribs::DB::get(from)
|
33
|
+
end
|
34
|
+
db.session
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# The current database for this session
|
39
|
+
attr_reader :db
|
40
|
+
|
41
|
+
# Creates a new session that points to the provided +db+ and
|
42
|
+
# +hibernate_session+
|
43
|
+
#
|
44
|
+
def initialize(db, hibernate_session)
|
45
|
+
@db = db
|
46
|
+
@connected = true
|
47
|
+
@hibernate_session = hibernate_session
|
48
|
+
end
|
49
|
+
|
50
|
+
# Releases this session from the database. This will possibly
|
51
|
+
# result in closing the internal Hibernate session, if this is the
|
52
|
+
# last Ribs session pointing to that Hibernate session.
|
53
|
+
def release
|
54
|
+
chk_conn
|
55
|
+
@connected = false
|
56
|
+
@db.release(self)
|
57
|
+
end
|
58
|
+
|
59
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
60
|
+
def hibernate_session # :nodoc:
|
61
|
+
@hibernate_session
|
62
|
+
end
|
63
|
+
|
64
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
65
|
+
def find(entity_name, id) # :nodoc:
|
66
|
+
chk_conn
|
67
|
+
if id == :all
|
68
|
+
@hibernate_session.create_criteria(entity_name).list.to_a
|
69
|
+
else
|
70
|
+
@hibernate_session.get(entity_name, java.lang.Integer.new(id))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
75
|
+
def save(obj) # :nodoc:
|
76
|
+
chk_conn
|
77
|
+
tx = @hibernate_session.begin_transaction
|
78
|
+
if obj.__ribs_meat.persistent
|
79
|
+
@hibernate_session.update(obj)
|
80
|
+
else
|
81
|
+
@hibernate_session.save(obj)
|
82
|
+
obj.__ribs_meat.persistent = true
|
83
|
+
end
|
84
|
+
tx.commit
|
85
|
+
obj
|
86
|
+
end
|
87
|
+
|
88
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
89
|
+
def delete(obj) # :nodoc:
|
90
|
+
chk_conn
|
91
|
+
tx = @hibernate_session.begin_transaction
|
92
|
+
@hibernate_session.delete(obj)
|
93
|
+
tx.commit
|
94
|
+
obj
|
95
|
+
end
|
96
|
+
|
97
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
98
|
+
def meta_data # :nodoc:
|
99
|
+
chk_conn
|
100
|
+
@hibernate_session.connection.meta_data
|
101
|
+
end
|
102
|
+
|
103
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
104
|
+
def ddl(string) # :nodoc:
|
105
|
+
chk_conn
|
106
|
+
execute(string)
|
107
|
+
end
|
108
|
+
|
109
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
110
|
+
def insert(template, *data) # :nodoc:
|
111
|
+
chk_conn
|
112
|
+
conn = @hibernate_session.connection
|
113
|
+
stmt = conn.prepare_statement(template)
|
114
|
+
data.each do |d|
|
115
|
+
d.each_with_index do |item, index|
|
116
|
+
if item.kind_of?(Array)
|
117
|
+
set_prepared_statement(stmt, item[0], index+1, item[1])
|
118
|
+
else
|
119
|
+
set_prepared_statement(stmt, item, index+1, nil)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
stmt.execute_update
|
123
|
+
end
|
124
|
+
conn.commit
|
125
|
+
ensure
|
126
|
+
stmt.close rescue nil
|
127
|
+
end
|
128
|
+
|
129
|
+
# LOW LEVEL - shouldn't be used except by Ribs
|
130
|
+
def select(string) # :nodoc:
|
131
|
+
chk_conn
|
132
|
+
conn = @hibernate_session.connection
|
133
|
+
stmt = conn.create_statement
|
134
|
+
rs = stmt.execute_query(string)
|
135
|
+
result = []
|
136
|
+
meta = rs.meta_data
|
137
|
+
cols = meta.column_count
|
138
|
+
while rs.next
|
139
|
+
row = []
|
140
|
+
(1..cols).each do |n|
|
141
|
+
row << from_database_type(rs.get_object(n))
|
142
|
+
end
|
143
|
+
result << row
|
144
|
+
end
|
145
|
+
result
|
146
|
+
ensure
|
147
|
+
rs.close rescue nil
|
148
|
+
stmt.close rescue nil
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
# Raise a NotConnectedError if not connected
|
153
|
+
def chk_conn
|
154
|
+
raise NotConnectedError unless @connected
|
155
|
+
end
|
156
|
+
|
157
|
+
# Tries to turn a Java object from the database into an equivalent
|
158
|
+
# Ruby object. Currently supports:
|
159
|
+
#
|
160
|
+
# * Strings
|
161
|
+
# * Floats
|
162
|
+
# * Integers
|
163
|
+
# * nil
|
164
|
+
# * booleans
|
165
|
+
# * Dates
|
166
|
+
# * Times
|
167
|
+
# * Timestamps
|
168
|
+
# * Blobs
|
169
|
+
# * Clobs
|
170
|
+
# * BigDecimals
|
171
|
+
def from_database_type(obj)
|
172
|
+
case obj
|
173
|
+
when String, Float, Integer, NilClass, TrueClass, FalseClass
|
174
|
+
obj
|
175
|
+
when java.sql.Date, java.sql.Time, java.sql.Timestamp
|
176
|
+
Time.at(obj.time/1000)
|
177
|
+
when java.sql.Blob
|
178
|
+
String.from_java_bytes(obj.get_bytes(1,obj.length))
|
179
|
+
when java.sql.Clob
|
180
|
+
obj.get_sub_string(1, obj.length)
|
181
|
+
when java.math.BigDecimal
|
182
|
+
BigDecimal.new(obj.to_s)
|
183
|
+
else
|
184
|
+
raise "Can't find correct type to convert #{obj.inspect} into"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Tries to set an entry on a prepared statement, based on type
|
189
|
+
def set_prepared_statement(stmt, item, index, type)
|
190
|
+
case item
|
191
|
+
when NilClass
|
192
|
+
stmt.set_object index, nil
|
193
|
+
when String
|
194
|
+
case type
|
195
|
+
when :binary
|
196
|
+
stmt.set_bytes index, item.to_java_bytes
|
197
|
+
when :text
|
198
|
+
stmt.set_string index, item
|
199
|
+
else
|
200
|
+
stmt.set_string index, item
|
201
|
+
end
|
202
|
+
when Symbol
|
203
|
+
stmt.set_string index, item.to_s
|
204
|
+
when Integer
|
205
|
+
stmt.set_int index, item
|
206
|
+
when Float
|
207
|
+
stmt.set_float index, item
|
208
|
+
when Time
|
209
|
+
case type
|
210
|
+
when :date
|
211
|
+
stmt.set_date index, item.to_java_sql_date
|
212
|
+
when :time
|
213
|
+
stmt.set_time index, item.to_java_sql_time
|
214
|
+
when :timestamp
|
215
|
+
stmt.set_timestamp index, item.to_java_sql_time_stamp
|
216
|
+
end
|
217
|
+
when BigDecimal
|
218
|
+
stmt.set_big_decimal index, java.math.BigDecimal.new(item.to_s('F'))
|
219
|
+
when TrueClass, FalseClass
|
220
|
+
stmt.set_boolean index, item
|
221
|
+
else
|
222
|
+
raise "Can't find correct type to set prepared statement for #{item.inspect}"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Executes a SQL string against the current hibernate
|
227
|
+
# session. This should be an updating SQL string, not a query.
|
228
|
+
def execute(string)
|
229
|
+
conn = @hibernate_session.connection
|
230
|
+
stmt = conn.create_statement
|
231
|
+
stmt.execute_update(string)
|
232
|
+
conn.commit
|
233
|
+
ensure
|
234
|
+
stmt.close rescue nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|