lib/dm-reflection/adapters/mysql.rb in dm-reflection-0.10.2 vs lib/dm-reflection/adapters/mysql.rb in dm-reflection-0.11.0
- old
+ new
@@ -42,10 +42,14 @@
'mediumtext' => Types::Text,
'longtext' => Types::Text,
}[$1] || raise("unknown type: #{db_type}")
end
+ def separator
+ '--'
+ end
+
##
# Get the list of table names
#
# @return [String Array] the names of the tables in the database.
#
@@ -53,22 +57,46 @@
# This gets all the non view tables, but has to strip column 0 out of the two column response.
select("SHOW FULL TABLES FROM #{options[:path][1..-1]} WHERE Table_type = 'BASE TABLE'").map { |item| item.first }
end
##
+ # This method breaks the join table into the two other table names
+ #
+ # @param [String] Name join table name
+ # @return [String,String] The two other table names joined.
+ #
+ def join_table_name(name, name_list=nil)
+ name_list = get_storage_names.sort if name_list.nil?
+ left = name_list[name_list.index(name)-1]
+ right = name[left.length+1..-1]
+ if name_list.include?(right)
+ return left,right
+ else
+ return nil,nil
+ end
+ end
+
+ ##
# Get the column specifications for a specific table
#
# @todo Consider returning actual DataMapper::Properties from this.
# It would probably require passing in a Model Object.
#
# @param [String] table the name of the table to get column specifications for
# @return [Hash] the column specs are returned in a hash keyed by `:name`, `:field`, `:type`, `:required`, `:default`, `:key`
#
def get_properties(table)
# TODO: use SHOW INDEXES to find out unique and non-unique indexes
+ join_table = false
+ columns = select("SHOW COLUMNS FROM #{table} IN #{options[:path][1..-1]};")
- select("SHOW COLUMNS FROM #{table} IN #{options[:path][1..-1]};").map do |column|
+ if columns.length == 2 && columns[0].field.downcase[-3,3] == "_id" && columns[1].field.downcase[-3,3] == "_id"
+ left_table_name,right_table_name = join_table_name(table)
+ join_table = true
+ end
+
+ columns.map do |column|
type = get_type(column.type)
auto_increment = column.extra == 'auto_increment'
if type == Integer && auto_increment
type = DataMapper::Types::Serial
@@ -82,27 +110,38 @@
:required => column.null == 'NO',
:default => column.default,
:key => column.key == 'PRI',
}
- if type == Integer && field_name[-3,3] == "_id"
+ # TODO: use the naming convention to compare the name vs the column name
+ unless attribute[:name] == column.field
+ attribute[:field] = column.field
+ end
+
+ if join_table
+ attribute[:type] = DataMapper::Associations::Relationship
+ attribute[:relationship] = {
+ # M:M requires we wire things a bit differently and remove the join model
+ :many_to_many => true,
+ :parent => Extlib::Inflection.classify(left_table_name),
+ :child => Extlib::Inflection.classify(right_table_name),
+ # When we can detect more from the database we can optimize this
+ :cardinality => Infinity,
+ :bidirectional => true }
+ return [attribute]
+ elsif type == Integer && field_name[-3,3] == "_id"
# This is a foriegn key. So this model belongs_to the other (_id) one.
# Add a special set of values and flag this as a relationship so the reflection code
# can rebuild the relationship when it's building the model.
attribute[:type] = DataMapper::Associations::Relationship
attribute[:relationship] = {
+ :many_to_many => false,
:parent => Extlib::Inflection.classify(field_name[0..-4]),
:child => Extlib::Inflection.classify(table),
# When we can detect more from the database we can optimize this
:cardinality => Infinity,
:bidirectional => true }
end
-
- # TODO: use the naming convention to compare the name vs the column name
- unless attribute[:name] == column.field
- attribute[:field] = column.field
- end
-
attribute
end
end
end # module MysqlAdapter
end # module Reflection