Module: Ribs

Defined in:
lib/ribs.rb,
lib/ribs/db.rb,
lib/ribs/rib.rb,
lib/ribs/handle.rb,
lib/ribs/definition.rb,
lib/ribs/repository.rb

Overview

The Ribs module includes most functionality needed for Ribs. The module is strictly a namespace and isn’t generally supposed to be mixed in.

Defined Under Namespace

Modules: Repository Classes: DB, Handle, MetaData, Rib, RubyRootClass, RubyValuedProperty

Constant Summary collapse

Table =
org.hibernate.mapping.Table
Column =
org.hibernate.mapping.Column
Property =
org.hibernate.mapping.Property
SimpleValue =
org.hibernate.mapping.SimpleValue
JTypes =
java.sql.Types

Class Method Summary collapse

Class Method Details

.add_metadata_for(db, model, metadata) ⇒ Object

Adds metadata for a specific model and an optional database. If the database is nil, it will add the model as a default metadata



15
16
17
18
19
20
21
# File 'lib/ribs/definition.rb', line 15

def (db, model, )
  if db
    @ribs[[db, model]] = 
  else
    @ribs[model] = 
  end
end

.define_model(name, options = {}, &block) ⇒ Object

Defines a model with the given name, defining attribute accessors and also providing the Ribs mapping from the block



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ribs.rb', line 58

def define_model(name, options = {}, &block)
  base = Object
  cls = Class.new
  names = name.to_s.split(/::/)
  names[0..-2].each do |nm|
    if !base.constants.include?(nm)
      base.const_set nm, Module.new
    end
    base = base.const_get nm
  end
  base.const_set names.last, cls

  Ribs!({:on => cls}.merge(options), &block)
  R(cls).define_accessors
  cls
end

.define_ribs(on, options = {}) {|rib| ... } ⇒ Object

Define a rib for the class on. If a block is given, will first yield an instance of Rib to it and then base the mapping definition on that.

options have several possible values:

  • :db - the database to connect this model to

This method is in urgent need of refactoring.

Yields:

  • (rib)


145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/ribs/definition.rb', line 145

def define_ribs(on, options = {})
  rib = Rib.new
  yield rib if block_given?
   
  unless options[:metadata]
    options[:metadata] = Ribs::MetaData.new      
  end

  rm = options[:metadata]
  Ribs::(options[:db], on, rm)
  rm.identity_map = options.key?(:identity_map) ? options[:identity_map] : true

  unless options[:from]
    options[:from] = R(on, options[:db] || :default)
  end

  rm.rib = rib
  rib_data = rib.__column_data__
  
  
  db = nil
  with_handle(options[:db] || :default) do |h|
    db = h.db
    m = h.

    name = table_name_for((options[:table] || on.name), m)

    tables = m.get_tables nil, nil, name.to_s, %w(TABLE VIEW ALIAS SYNONYM).to_java(:String)
    if tables.next
      table = Table.new(tables.get_string(3))
      rm.table = table
      c = tables.get_string(1)
      table.catalog = c if c && c.length > 0
      c = tables.get_string(2)
      table.schema = c if c && c.length > 0
      
      columns_rs = m.get_columns table.catalog, table.schema, table.name, nil

      while columns_rs.next
        c = Column.new(columns_rs.get_string(4))
        c.default_value = columns_rs.get_string(13)
        c.length = columns_rs.get_int(7)
        c.nullable = columns_rs.get_string(18) == 'YES'
        c.precision = columns_rs.get_int(10)
        c.scale = columns_rs.get_int(9)
        c.sql_type = columns_rs.get_string(6)
        c.sql_type_code = java.lang.Integer.new(columns_rs.get_int(5))

        table.add_column(c)
      end
      columns_rs.close rescue nil
      tables.close rescue nil
      
      pc = RubyRootClass.new
      pc.ruby_class = on
      pc.entity_name = on.name
      pc.table = table
      pc.add_tuplizer(org.hibernate.EntityMode::MAP, "org.jruby.ribs.RubyTuplizer")
      
      rm.persistent_class = pc
      rm.persistent_class["meatspace"] = options[:from] if options[:from]
      
      table.column_iterator.each do |c|
        unless rib_data.to_avoid.include?(c.name.downcase)
          prop = Property.new
          prop.persistent_class = pc
          prop.name = ((v=rib_data.columns.find{ |key, val| val[0].to_s.downcase == c.name.downcase}) && v[0]) || c.name
          val = SimpleValue.new(table)
          val.add_column(c)
          val.type_name = get_type_for_sql(c.sql_type, c.sql_type_code)
          prop.value = val
          if (!rib_data.primary_keys.empty? && rib_data.primary_keys.include?(prop.name)) || c.name.downcase == 'id'
            pc.identifier_property = prop
            pc.identifier = val
          else
            pc.add_property(prop)
          end
        else
          if !c.nullable
            prop = RubyValuedProperty.new
            prop.ruby_value = rib_data.default_values[c.name.downcase]
            prop.persistent_class = pc
            prop.name = ((v=rib_data.columns[c.name.downcase]) && v[0]) || c.name
            val = SimpleValue.new(table)
            val.add_column(c)
            val.type_name = get_type_for_sql(c.sql_type, c.sql_type_code)
            prop.value = val
            pc.add_property(prop)
          end
        end
      end
      pc.create_primary_key
      db.mappings.add_class(pc)
    else
      tables.close rescue nil
      raise "No table found for: #{name}"
    end
  end
  
  db.reset_session_factory!
end

.metadata(db, model) ⇒ Object

Returns the specific metadata for a combination of model class and database identifier. If there is no such entry, tries to find the default entry for the model class.



9
10
11
# File 'lib/ribs/definition.rb', line 9

def (db, model)
  @ribs[[db, model]] || @ribs[model]
end

.metadata_for(db, model, from) ⇒ Object

Tries to find metadata for the model in question and defines new metadata with define_ribs if no existing metadata exists. This means that you should do your database definitions before using the method R for that model.



27
28
29
30
31
32
33
34
35
# File 'lib/ribs/definition.rb', line 27

def (db, model, from)
  if (v = (db, model))
    return v
  end

   = Ribs::MetaData.new
  define_ribs(model, :db => db, :metadata => , :from => from)
  
end

.Repository(obj, db = :default) ⇒ Object

Gets a Repository object for the object in question. If the object is a class, the repository returned will be a Repository::Class, otherwise it will be a Repository::Instance. Specifically, what you will get for the class FooBar will be the class Ribs::Repository::DB_default::FooBar and you will get an instance of that class if the object is an instance of FooBar. This allows you to add specific functionality to these repositories. The class Ribs::Repository::DB_default::FooBar will also include Ribs::Repository::FooBar and extend Ribs::Repository::FooBar::ClassMethods so you can add behavior to these that map over all databases.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ribs/repository.rb', line 13

def self.Repository(obj, db = :default)
  db_name = "DB_#{db}"
  model_type = case obj
        when Class
          obj
        else
          obj.class
        end

  dbmod = Ribs::Repository::const_get(db_name)
  name = model_type.name.split(/::/).join("_")

  if !dbmod.constants.include?(name)
    Repository::create_repository(name, dbmod)
  end
  
  cls = dbmod::const_get(name.to_sym)
  Ribs::Repository.ensure_repository(name, cls, model_type, db)

  return cls if obj.kind_of?(Class)

  ret = cls.allocate
  ret.send :initialize
  ret.instance_variable_set :@database, db
  ret.instance_variable_set :@model, obj
  ret
end

.with_handle(from = :default) ⇒ Object

The with_handle method provides an easy way of working with a low level Ribs Handle. It will get a handle for the database in question, yield that handle to the block and then release the handle when finished. This should generally not be needed, but wrapping a block if code with this method is a good way of opening a handle and make sure it doesn’t get fully closed until after the block.

from decides which database definition to get a handle for.



49
50
51
52
53
54
# File 'lib/ribs.rb', line 49

def with_handle(from = :default)
  h = Ribs::Handle.get(from)
  yield h
ensure
  h.release
end