Module: DataMapper::Reflection::MysqlAdapter

Defined in:
lib/dm-reflection/adapters/mysql.rb

Instance Method Summary collapse

Instance Method Details

#get_properties(table) ⇒ Hash

TODO:

Consider returning actual DataMapper::Properties from this. It would probably require passing in a Model Object.

Get the column specifications for a specific table

Parameters:

  • table (String)

    the name of the table to get column specifications for

Returns:

  • (Hash)

    the column specs are returned in a hash keyed by :name, :field, :type, :required, :default, :key



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/dm-reflection/adapters/mysql.rb', line 66

def get_properties(table)
  # TODO: use SHOW INDEXES to find out unique and non-unique indexes

  select("SHOW COLUMNS FROM #{table} IN #{options[:path][1..-1]};").map do |column|
    type           = get_type(column.type)
    auto_increment = column.extra == 'auto_increment'

    if type == Integer && auto_increment
      type = DataMapper::Types::Serial
    end

    field_name = column.field.downcase

    attribute = {
      :name     => field_name,
      :type     => type,
      :required => column.null == 'NO',
      :default  => column.default,
      :key      => column.key == 'PRI',
    }
    
    if 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] = { 
        :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

#get_storage_namesString Array

Get the list of table names

Returns:

  • (String Array)

    the names of the tables in the database.



52
53
54
55
# File 'lib/dm-reflection/adapters/mysql.rb', line 52

def get_storage_names
  # 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

#get_type(db_type) ⇒ Type

TODO:

This should be verified to identify all mysql primitive types and that they map to the correct DataMapper/Ruby types.

Convert the database type into a DataMapper type

Parameters:

  • db_type (String)

    type specified by the database

Returns:

  • (Type)

    a DataMapper or Ruby type object.



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
40
41
42
43
44
45
# File 'lib/dm-reflection/adapters/mysql.rb', line 14

def get_type(db_type)
  # TODO: return a Hash with the :type, :min, :max and other
  # options rather than just the type

  db_type.match(/\A(\w+)/)
  {
    'tinyint'     =>  Integer    ,
    'smallint'    =>  Integer    ,
    'mediumint'   =>  Integer    ,
    'int'         =>  Integer    ,
    'bigint'      =>  Integer    ,
    'integer'     =>  Integer    ,
    'varchar'     =>  String     ,
    'char'        =>  String     ,
    'enum'        =>  String     ,
    'decimal'     =>  BigDecimal ,
    'double'      =>  Float      ,
    'float'       =>  Float      ,
    'datetime'    =>  DateTime   ,
    'timestamp'   =>  DateTime   ,
    'date'        =>  Date       ,
    'boolean'     =>  Types::Boolean,
    'tinyblob'    =>  Types::Text,
    'blob'        =>  Types::Text,
    'mediumblob'  =>  Types::Text,
    'longblob'    =>  Types::Text,
    'tinytext'    =>  Types::Text,
    'text'        =>  Types::Text,
    'mediumtext'  =>  Types::Text,
    'longtext'    =>  Types::Text,
  }[$1] || raise("unknown type: #{db_type}")
end