ribs 0.0.1 → 0.0.2
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.
- data/README +54 -24
- data/Rakefile +1 -1
- data/lib/ribs.jar +0 -0
- data/lib/ribs.rb +32 -11
- data/lib/ribs/db.rb +10 -10
- data/lib/ribs/definition.rb +115 -151
- data/lib/ribs/{session.rb → handle.rb} +30 -24
- data/lib/ribs/repository.rb +243 -0
- data/lib/ribs/rib.rb +100 -0
- data/test/artist_spec.rb +22 -20
- data/test/define_accessors_spec.rb +27 -0
- data/test/define_model_spec.rb +41 -0
- data/test/identity_map_spec.rb +63 -0
- data/test/repository_spec.rb +79 -0
- data/test/rib_spec.rb +73 -0
- data/test/simple_select_spec.rb +22 -22
- data/test/test_helper.rb +89 -8
- data/test/track_spec.rb +90 -78
- metadata +10 -4
- data/lib/ribs/meat.rb +0 -33
data/README
CHANGED
@@ -14,6 +14,11 @@ you to use Hibernate to persist your Ruby objects. There are many
|
|
14
14
|
things planned for Ribs, but currently it only supports quite basic
|
15
15
|
operations.
|
16
16
|
|
17
|
+
Ribs is explicitly defined to solve several data access patterns for
|
18
|
+
most Ruby development. In one end it means scaling down from something
|
19
|
+
very much like ActiveRecord, but on the other end supports such things
|
20
|
+
as Repository, Data Mapper, Unit of Work and Identity Map.
|
21
|
+
|
17
22
|
== Definitions
|
18
23
|
|
19
24
|
To get started, you first need to define a database connection for
|
@@ -37,15 +42,25 @@ See the define method and the Ribs::DB class for more information on
|
|
37
42
|
what's available.
|
38
43
|
|
39
44
|
To actually make a Ruby class a database backed objects, you use the
|
40
|
-
method {Kernel#Ribs!}[link:classes/Kernel.html#M000038] In the simple
|
41
|
-
provide any configuration, but support
|
42
|
-
columns, deciding which one is the primary
|
43
|
-
columns part of the object. The
|
45
|
+
method {Kernel#Ribs!}[link:classes/Kernel.html#M000038] In the simple
|
46
|
+
case you don't need to actually provide any configuration, but support
|
47
|
+
is available for renaming columns, deciding which one is the primary
|
48
|
+
key, and also avoid making columns part of the object. The simplest
|
49
|
+
case looks like this:
|
44
50
|
|
51
|
+
class Blog
|
52
|
+
end
|
53
|
+
|
54
|
+
That is more or less the same as doing
|
55
|
+
|
45
56
|
class Blog
|
46
57
|
Ribs!
|
47
58
|
end
|
48
59
|
|
60
|
+
This method call will not do anything that won't be done implicitly at
|
61
|
+
the first usage of it as a Ribs model. This means that if you follow
|
62
|
+
conventions exactly, you don't need to configure anything at all.
|
63
|
+
|
49
64
|
It can also be written as:
|
50
65
|
|
51
66
|
class Blog; end
|
@@ -65,22 +80,31 @@ To redefine which table to use, the names of the columns, and where
|
|
65
80
|
the primary key is, you need to provide a block to the {Ribs!}[link:classes/Kernel.html#M000038] method:
|
66
81
|
|
67
82
|
class Blog
|
68
|
-
Ribs! do |r|
|
69
|
-
r.
|
70
|
-
|
71
|
-
r.primary_key :blog_id
|
83
|
+
Ribs! :table => :blogs do |r|
|
84
|
+
r.blog_id.primary_key!
|
72
85
|
|
73
|
-
r.
|
86
|
+
r.blog_title :column => :title
|
74
87
|
|
75
|
-
r.avoid
|
88
|
+
r.irrelevant_column.avoid!
|
76
89
|
end
|
77
90
|
end
|
78
91
|
|
79
92
|
This code will back the model against the "blogs" table, have the
|
80
93
|
column name blog_id represent the primary key, and map the column
|
81
|
-
title to the property blog_title.
|
82
|
-
|
83
|
-
|
94
|
+
title to the property blog_title. Finally, avoid! tells Ribs
|
95
|
+
to avoid a specific column, so it won't try to map that.
|
96
|
+
|
97
|
+
If you have a primary key that you want to have a different name, or a
|
98
|
+
column you want to avoid but it's not nullable, you can use these
|
99
|
+
variations instead:
|
100
|
+
|
101
|
+
class Blog
|
102
|
+
Ribs! :table => :blogs do |r|
|
103
|
+
r.blog_id :primary_key, :column => :id
|
104
|
+
|
105
|
+
r.irrelevant_column :avoid, :default => "value to insert:
|
106
|
+
end
|
107
|
+
end
|
84
108
|
|
85
109
|
Currently Ribs only supports simple data types. It doesn't include
|
86
110
|
associations, and have no support for setting default values, or
|
@@ -93,46 +117,52 @@ Once you have a defined model, you can work with it in several
|
|
93
117
|
different ways.
|
94
118
|
|
95
119
|
If you want to create new instances you can do it much like with
|
96
|
-
ActiveRecord
|
120
|
+
ActiveRecord, except that you always need to surround a call to
|
121
|
+
anything regarding the database with an invocation to the method
|
122
|
+
R. This method takes either a class or an instance, and returns a
|
123
|
+
repository proxy for the argument. You can also send in a specific
|
124
|
+
database name if you want to work with another database then the
|
125
|
+
default one.:
|
97
126
|
|
98
127
|
blog = Blog.new
|
99
128
|
blog.blog_id = 1
|
100
129
|
blog.blog_title = "Foobar"
|
101
|
-
blog.save
|
130
|
+
R(blog).save
|
102
131
|
|
103
|
-
The new
|
132
|
+
The new-method returned from R can take the parameters as a hash of
|
133
|
+
symbols too:
|
104
134
|
|
105
|
-
blog = Blog.new(
|
135
|
+
blog = R(Blog).new(
|
106
136
|
:blog_id => 1,
|
107
137
|
:blog_title => "Foobar")
|
108
|
-
blog.save
|
138
|
+
R(blog).save
|
109
139
|
|
110
140
|
And as a short hand a create method is available:
|
111
141
|
|
112
|
-
blog = Blog.create(
|
142
|
+
blog = R(Blog).create(
|
113
143
|
:blog_id => 1,
|
114
144
|
:blog_title => "Foobar")
|
115
145
|
|
116
146
|
To find a specific entry:
|
117
147
|
|
118
|
-
blog = Blog.
|
148
|
+
blog = R(Blog).get(1)
|
119
149
|
|
120
150
|
Or to find all entries:
|
121
151
|
|
122
|
-
blogs = Blog.
|
152
|
+
blogs = R(Blog).all
|
123
153
|
|
124
154
|
To update an entry:
|
125
155
|
|
126
156
|
blog.blog_title = "New title"
|
127
|
-
blog.save
|
157
|
+
R(blog).save
|
128
158
|
|
129
159
|
To destroy an existing entry:
|
130
160
|
|
131
|
-
blog.destroy!
|
161
|
+
R(blog).destroy!
|
132
162
|
|
133
163
|
Or to destroy it based on id:
|
134
164
|
|
135
|
-
Blog.destroy(1)
|
165
|
+
R(Blog).destroy(1)
|
136
166
|
|
137
167
|
== License
|
138
168
|
|
data/Rakefile
CHANGED
@@ -43,7 +43,7 @@ Gem::manage_gems
|
|
43
43
|
specification = Gem::Specification.new do |s|
|
44
44
|
s.name = "ribs"
|
45
45
|
s.summary = "Ribs wraps Hibernate, to provide a good ORM for JRuby"
|
46
|
-
s.version = "0.0.
|
46
|
+
s.version = "0.0.2"
|
47
47
|
s.author = 'Ola Bini'
|
48
48
|
s.description = s.summary
|
49
49
|
s.homepage = 'http://ribs.rubyforge.org'
|
data/lib/ribs.jar
CHANGED
Binary file
|
data/lib/ribs.rb
CHANGED
@@ -22,9 +22,11 @@ require 'ribs.jar'
|
|
22
22
|
require 'bigdecimal'
|
23
23
|
|
24
24
|
require 'ribs/db'
|
25
|
+
require 'ribs/rib'
|
25
26
|
require 'ribs/definition'
|
26
|
-
require 'ribs/
|
27
|
+
require 'ribs/handle'
|
27
28
|
require 'ribs/meat'
|
29
|
+
require 'ribs/repository'
|
28
30
|
require 'ribs/core_ext/time'
|
29
31
|
|
30
32
|
# The Ribs module includes most functionality needed for Ribs. The
|
@@ -34,21 +36,40 @@ require 'ribs/core_ext/time'
|
|
34
36
|
module Ribs
|
35
37
|
class << self
|
36
38
|
|
37
|
-
# The
|
38
|
-
# low level Ribs
|
39
|
-
# in question, yield that
|
40
|
-
# the
|
39
|
+
# The with_handle method provides an easy way of working with a
|
40
|
+
# low level Ribs Handle. It will get a handle for the database
|
41
|
+
# in question, yield that handle to the block and then release
|
42
|
+
# the handle when finished. This should generally not be needed,
|
41
43
|
# but wrapping a block if code with this method is a good way of
|
42
|
-
# opening a
|
44
|
+
# opening a handle and make sure it doesn't get fully closed
|
43
45
|
# until after the block.
|
44
46
|
#
|
45
|
-
# +from+ decides which database definition to get a
|
47
|
+
# +from+ decides which database definition to get a handle for.
|
46
48
|
#
|
47
|
-
def
|
48
|
-
|
49
|
-
yield
|
49
|
+
def with_handle(from = :default)
|
50
|
+
h = Ribs::Handle.get(from)
|
51
|
+
yield h
|
50
52
|
ensure
|
51
|
-
|
53
|
+
h.release
|
54
|
+
end
|
55
|
+
|
56
|
+
# Defines a model with the given name, defining attribute
|
57
|
+
# accessors and also providing the Ribs mapping from the block
|
58
|
+
def define_model(name, options = {}, &block)
|
59
|
+
base = Object
|
60
|
+
cls = Class.new
|
61
|
+
names = name.to_s.split(/::/)
|
62
|
+
names[0..-2].each do |nm|
|
63
|
+
if !base.constants.include?(nm)
|
64
|
+
base.const_set nm, Module.new
|
65
|
+
end
|
66
|
+
base = base.const_get nm
|
67
|
+
end
|
68
|
+
base.const_set names.last, cls
|
69
|
+
|
70
|
+
Ribs!({:on => cls}.merge(options), &block)
|
71
|
+
R(cls).define_accessors
|
72
|
+
cls
|
52
73
|
end
|
53
74
|
end
|
54
75
|
end
|
data/lib/ribs/db.rb
CHANGED
@@ -146,7 +146,7 @@ module Ribs
|
|
146
146
|
properties.set_property(key, value)
|
147
147
|
end
|
148
148
|
@configuration = Configuration.new.add_properties(properties)
|
149
|
-
@configuration.set_interceptor org.jruby.ribs.
|
149
|
+
@configuration.set_interceptor org.jruby.ribs.RubyInterceptor.new(self, (self.default? ? :default : self.name).to_s)
|
150
150
|
@mappings = @configuration.create_mappings
|
151
151
|
reset_session_factory!
|
152
152
|
end
|
@@ -157,26 +157,26 @@ module Ribs
|
|
157
157
|
@session_factory = @configuration.build_session_factory
|
158
158
|
end
|
159
159
|
|
160
|
-
# Fetch a new Ribs
|
161
|
-
# a Ribs::
|
162
|
-
def
|
160
|
+
# Fetch a new Ribs handle connected to the this database. Returns
|
161
|
+
# a Ribs::Handle object.
|
162
|
+
def handle
|
163
163
|
sessions = (Thread.current[:ribs_db_sessions] ||= {})
|
164
164
|
if curr = sessions[self.object_id]
|
165
165
|
curr[1] += 1 #reference count
|
166
|
-
|
166
|
+
Handle.new(self, curr[0])
|
167
167
|
else
|
168
168
|
sess = @session_factory.open_session
|
169
169
|
sessions[self.object_id] = [sess,1]
|
170
|
-
|
170
|
+
Handle.new(self, sess)
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
# Release a Ribs::
|
175
|
-
# database. That
|
174
|
+
# Release a Ribs::Handle object that is connected to this
|
175
|
+
# database. That Handle object should not be used after this
|
176
176
|
# method has been invoked.
|
177
|
-
def release(
|
177
|
+
def release(handle)
|
178
178
|
res = Thread.current[:ribs_db_sessions][self.object_id]
|
179
|
-
if res[0] ==
|
179
|
+
if res[0] == handle.hibernate_session
|
180
180
|
res[1] -= 1
|
181
181
|
if res[1] == 0
|
182
182
|
res[0].close
|
data/lib/ribs/definition.rb
CHANGED
@@ -1,80 +1,40 @@
|
|
1
1
|
module Ribs
|
2
|
-
#
|
3
|
-
|
4
|
-
module ClassMethods
|
5
|
-
# Get the metadata for the current model
|
6
|
-
attr_reader :ribs_metadata
|
2
|
+
# Keeps track of defined Ribs
|
3
|
+
@ribs = {}
|
7
4
|
|
8
|
-
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
5
|
+
class << self
|
6
|
+
# Returns the specific metadata for a combination of model class
|
7
|
+
# and database identifier. If there is no such entry, tries to
|
8
|
+
# find the default entry for the model class.
|
9
|
+
def metadata(db, model)
|
10
|
+
@ribs[[db, model]] || @ribs[model]
|
33
11
|
end
|
34
12
|
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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)
|
13
|
+
# Adds metadata for a specific model and an optional database. If
|
14
|
+
# the database is nil, it will add the model as a default metadata
|
15
|
+
def add_metadata_for(db, model, metadata)
|
16
|
+
if db
|
17
|
+
@ribs[[db, model]] = metadata
|
18
|
+
else
|
19
|
+
@ribs[model] = metadata
|
66
20
|
end
|
67
21
|
end
|
68
22
|
|
69
|
-
#
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
23
|
+
# Tries to find metadata for the model in question and defines new
|
24
|
+
# metadata with define_ribs if no existing metadata exists. This
|
25
|
+
# means that you should do your database definitions before using
|
26
|
+
# the method R for that model.
|
27
|
+
def metadata_for(db, model, from)
|
28
|
+
if (v = metadata(db, model))
|
29
|
+
return v
|
74
30
|
end
|
31
|
+
|
32
|
+
metadata = Ribs::MetaData.new
|
33
|
+
define_ribs(model, :db => db, :metadata => metadata, :from => from)
|
34
|
+
metadata
|
75
35
|
end
|
76
36
|
end
|
77
|
-
|
37
|
+
|
78
38
|
# Collects all the meta data about a specific Ribs model
|
79
39
|
class MetaData
|
80
40
|
# The table to connect to
|
@@ -84,7 +44,14 @@ module Ribs
|
|
84
44
|
attr_accessor :persistent_class
|
85
45
|
# The Rib that defines all the mapping data
|
86
46
|
attr_accessor :rib
|
47
|
+
# Should this object be saved in an identity map?
|
48
|
+
attr_accessor :identity_map
|
87
49
|
|
50
|
+
# Should this object be saved in an identity map?
|
51
|
+
def identity_map?
|
52
|
+
self.identity_map
|
53
|
+
end
|
54
|
+
|
88
55
|
# Return the property instance for the given +name+.
|
89
56
|
def [](name)
|
90
57
|
self.persistent_class.get_property(name.to_s) rescue nil
|
@@ -93,56 +60,24 @@ module Ribs
|
|
93
60
|
# Return all the properties for this model.
|
94
61
|
def properties
|
95
62
|
self.persistent_class.property_iterator.to_a.inject({}) do |h, value|
|
96
|
-
|
63
|
+
if !value.respond_to?(:getRubyValue)
|
64
|
+
h[value.name] = value
|
65
|
+
end
|
97
66
|
h
|
98
67
|
end
|
99
68
|
end
|
100
|
-
end
|
101
69
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
70
|
+
# Return all the properties for this model.
|
71
|
+
def properties_and_identity
|
72
|
+
(self.persistent_class.property_iterator.to_a + [self.persistent_class.identifier_property]).inject({}) do |h, value|
|
73
|
+
if !value.respond_to?(:getRubyValue)
|
74
|
+
h[value.name] = value
|
75
|
+
end
|
76
|
+
h
|
126
77
|
end
|
127
78
|
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
79
|
end
|
145
|
-
|
80
|
+
|
146
81
|
Table = org.hibernate.mapping.Table
|
147
82
|
Column = org.hibernate.mapping.Column
|
148
83
|
Property = org.hibernate.mapping.Property
|
@@ -156,8 +91,15 @@ module Ribs
|
|
156
91
|
# The Ruby class
|
157
92
|
attr_accessor :ruby_class
|
158
93
|
|
94
|
+
# Initialize data for this RootClass
|
159
95
|
def initialize(*args)
|
160
96
|
super
|
97
|
+
@data = {}
|
98
|
+
end
|
99
|
+
|
100
|
+
# Sets a specific data element
|
101
|
+
def []=(key, value)
|
102
|
+
@data[key] = value
|
161
103
|
end
|
162
104
|
|
163
105
|
# Get the Ruby class. Implementation of the WithRubyClass
|
@@ -165,6 +107,29 @@ module Ribs
|
|
165
107
|
def getRubyClass
|
166
108
|
@ruby_class
|
167
109
|
end
|
110
|
+
|
111
|
+
# Gets a specific data element
|
112
|
+
def getRubyData(key)
|
113
|
+
@data[key]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# A Hibernate Property that can contain a Ruby value too.
|
118
|
+
class RubyValuedProperty < org.hibernate.mapping.Property
|
119
|
+
include org.jruby.ribs.WithRubyValue
|
120
|
+
|
121
|
+
# The Ruby class
|
122
|
+
attr_accessor :ruby_value
|
123
|
+
|
124
|
+
# Creation
|
125
|
+
def initialize(*args)
|
126
|
+
super
|
127
|
+
end
|
128
|
+
|
129
|
+
# Implement the interface - return the actual Ruby value
|
130
|
+
def getRubyValue
|
131
|
+
@ruby_value
|
132
|
+
end
|
168
133
|
end
|
169
134
|
|
170
135
|
class << self
|
@@ -175,19 +140,34 @@ module Ribs
|
|
175
140
|
# +options+ have several possible values:
|
176
141
|
# * <tt>:db</tt> - the database to connect this model to
|
177
142
|
#
|
143
|
+
# This method is in urgent need of refactoring.
|
144
|
+
#
|
178
145
|
def define_ribs(on, options = {})
|
179
146
|
rib = Rib.new
|
180
147
|
yield rib if block_given?
|
181
148
|
|
182
|
-
|
183
|
-
|
184
|
-
|
149
|
+
unless options[:metadata]
|
150
|
+
options[:metadata] = Ribs::MetaData.new
|
151
|
+
end
|
185
152
|
|
153
|
+
rm = options[:metadata]
|
154
|
+
Ribs::add_metadata_for(options[:db], on, rm)
|
155
|
+
rm.identity_map = options.key?(:identity_map) ? options[:identity_map] : true
|
156
|
+
|
157
|
+
unless options[:from]
|
158
|
+
options[:from] = R(on, options[:db] || :default)
|
159
|
+
end
|
160
|
+
|
161
|
+
rm.rib = rib
|
162
|
+
rib_data = rib.__column_data__
|
163
|
+
|
164
|
+
|
186
165
|
db = nil
|
187
|
-
|
188
|
-
db =
|
189
|
-
m =
|
190
|
-
|
166
|
+
with_handle(options[:db] || :default) do |h|
|
167
|
+
db = h.db
|
168
|
+
m = h.meta_data
|
169
|
+
|
170
|
+
name = table_name_for((options[:table] || on.name), m)
|
191
171
|
|
192
172
|
tables = m.get_tables nil, nil, name.to_s, %w(TABLE VIEW ALIAS SYNONYM).to_java(:String)
|
193
173
|
if tables.next
|
@@ -222,25 +202,35 @@ module Ribs
|
|
222
202
|
pc.add_tuplizer(org.hibernate.EntityMode::MAP, "org.jruby.ribs.RubyTuplizer")
|
223
203
|
|
224
204
|
rm.persistent_class = pc
|
205
|
+
rm.persistent_class["meatspace"] = options[:from] if options[:from]
|
225
206
|
|
226
207
|
table.column_iterator.each do |c|
|
227
|
-
unless
|
208
|
+
unless rib_data.to_avoid.include?(c.name.downcase)
|
228
209
|
prop = Property.new
|
229
210
|
prop.persistent_class = pc
|
230
|
-
prop.name = ((v=
|
211
|
+
prop.name = ((v=rib_data.columns.find{ |key, val| val[0].to_s.downcase == c.name.downcase}) && v[0]) || c.name
|
231
212
|
val = SimpleValue.new(table)
|
232
213
|
val.add_column(c)
|
233
214
|
val.type_name = get_type_for_sql(c.sql_type, c.sql_type_code)
|
234
215
|
prop.value = val
|
235
|
-
|
236
|
-
if (!rib.primary_keys.empty? && rib.primary_keys[c.name.downcase]) || c.name.downcase == 'id'
|
216
|
+
if (!rib_data.primary_keys.empty? && rib_data.primary_keys.include?(prop.name)) || c.name.downcase == 'id'
|
237
217
|
pc.identifier_property = prop
|
238
218
|
pc.identifier = val
|
239
219
|
else
|
240
220
|
pc.add_property(prop)
|
241
221
|
end
|
242
|
-
|
243
|
-
|
222
|
+
else
|
223
|
+
if !c.nullable
|
224
|
+
prop = RubyValuedProperty.new
|
225
|
+
prop.ruby_value = rib_data.default_values[c.name.downcase]
|
226
|
+
prop.persistent_class = pc
|
227
|
+
prop.name = ((v=rib_data.columns[c.name.downcase]) && v[0]) || c.name
|
228
|
+
val = SimpleValue.new(table)
|
229
|
+
val.add_column(c)
|
230
|
+
val.type_name = get_type_for_sql(c.sql_type, c.sql_type_code)
|
231
|
+
prop.value = val
|
232
|
+
pc.add_property(prop)
|
233
|
+
end
|
244
234
|
end
|
245
235
|
end
|
246
236
|
pc.create_primary_key
|
@@ -257,21 +247,6 @@ module Ribs
|
|
257
247
|
JTypes = java.sql.Types
|
258
248
|
|
259
249
|
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
250
|
# Returns the Java type for a specific combination of a type name
|
276
251
|
# and an SQL type code
|
277
252
|
def get_type_for_sql(name, code)
|
@@ -305,25 +280,14 @@ CODE
|
|
305
280
|
# Tries to figure out if a table name should be in lower case or
|
306
281
|
# upper case, and returns the table name based on that.
|
307
282
|
def table_name_for(str, metadata)
|
283
|
+
str = str.to_s.gsub(/::/, '_')
|
308
284
|
if metadata.stores_lower_case_identifiers
|
309
285
|
str.downcase
|
310
286
|
elsif metadata.stores_upper_case_identifiers
|
311
|
-
str.upcase
|
287
|
+
str.upcase
|
312
288
|
else
|
313
289
|
str
|
314
290
|
end
|
315
291
|
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
292
|
end
|
329
293
|
end
|