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(<<-SQL.compress_lines)
      SELECT name
        FROM (SELECT * FROM sqlite_master UNION SELECT * FROM sqlite_temp_master)
       WHERE type IN('table', 'view')
         AND name NOT LIKE 'sqlite_%'
    ORDER BY name
  SQL
end

#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