Module: DataMapper::Reflection::Sqlite3Adapter

Defined in:
lib/dm-reflection/adapters/sqlite3.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



56
57
58
59
60
61
62
63
64
65
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
# File 'lib/dm-reflection/adapters/sqlite3.rb', line 56

def get_properties(table)
  # TODO: consider using "SELECT sql FROM sqlite_master WHERE tbl_name = ?"
  # and parsing the create table statement since it will provide
  # more information like if a column is auto-incrementing, and what
  # indexes are used.

  select('PRAGMA table_info(%s)' % table).map do |column|
    type    = get_type(column.type)
    default = column.dflt_value

    if type == Integer && column.pk == 1
      type    = DataMapper::Types::Serial
    end

    field_name = column.name.downcase

    attribute = {
      :name     => field_name,
      :type     => type,
      :required => column.notnull == 1,
      :default  => default,
      :key      => column.pk == 1,
    }

    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 => ActiveSupport::Inflector.classify(field_name[0..-4]), 
        :child => ActiveSupport::Inflector.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.name
      attribute[:field] = column.name
    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.



37
38
39
40
41
42
43
44
45
# File 'lib/dm-reflection/adapters/sqlite3.rb', line 37

def get_storage_names
  select("      SELECT name\n        FROM (SELECT * FROM sqlite_master UNION SELECT * FROM sqlite_temp_master)\n       WHERE type IN('table', 'view')\n         AND name NOT LIKE 'sqlite_%'\n    ORDER BY name\n  SQL\nend\n".compress_lines)

#get_type(db_type) ⇒ Type

TODO:

This should be verified to identify all sqlite3 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
# File 'lib/dm-reflection/adapters/sqlite3.rb', line 14

def get_type(db_type)
  db_type.match(/\A(\w+)/)
  {
     'INTEGER'     =>  Integer      ,
     'VARCHAR'     =>  String       ,
     'DECIMAL'     =>  BigDecimal   ,
     'FLOAT'       =>  Float        ,
     'TIMESTAMP'   =>  DateTime     ,
     'DATE'        =>  Date         ,
     'BOOLEAN'     =>  Types::Boolean,
     'TEXT'        =>  Types::Text
    }[$1] || raise("unknown db type: #{db_type}")
end

#separatorObject



28
29
30
# File 'lib/dm-reflection/adapters/sqlite3.rb', line 28

def separator
  '--'
end