schema_statements.rb 2.8 KB
Newer Older
1 2 3 4
module ActiveRecord
  module ConnectionAdapters
    module SQLite3
      module SchemaStatements # :nodoc:
5 6 7 8 9 10 11 12 13
        # Returns an array of indexes for the given table.
        def indexes(table_name, name = nil)
          if name
            ActiveSupport::Deprecation.warn(<<-MSG.squish)
              Passing name to #indexes is deprecated without replacement.
            MSG
          end

          exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
14
            index_sql = query_value(<<-SQL, "SCHEMA")
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
              SELECT sql
              FROM sqlite_master
              WHERE name = #{quote(row['name'])} AND type = 'index'
              UNION ALL
              SELECT sql
              FROM sqlite_temp_master
              WHERE name = #{quote(row['name'])} AND type = 'index'
            SQL

            /\sWHERE\s+(?<where>.+)$/i =~ index_sql

            columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
              col["name"]
            end

            IndexDefinition.new(
              table_name,
              row["name"],
              row["unique"] != 0,
              columns,
              where: where
            )
          end
        end

40
        private
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
          def schema_creation
            SQLite3::SchemaCreation.new(self)
          end

          def create_table_definition(*args)
            SQLite3::TableDefinition.new(*args)
          end

          def new_column_from_field(table_name, field)
            default = \
              case field["dflt_value"]
              when /^null$/i
                nil
              when /^'(.*)'$/m
                $1.gsub("''", "'")
              when /^"(.*)"$/m
                $1.gsub('""', '"')
              else
                field["dflt_value"]
              end

            type_metadata = fetch_type_metadata(field["type"])
            Column.new(field["name"], default, type_metadata, field["notnull"].to_i == 0, table_name, nil, field["collation"])
          end

66 67 68 69
          def data_source_sql(name = nil, type: nil)
            scope = quoted_scope(name, type: type)
            scope[:type] ||= "'table','view'"

70
            sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'".dup
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
            sql << " AND name = #{scope[:name]}" if scope[:name]
            sql << " AND type IN (#{scope[:type]})"
            sql
          end

          def quoted_scope(name = nil, type: nil)
            type = \
              case type
              when "BASE TABLE"
                "'table'"
              when "VIEW"
                "'view'"
              end
            scope = {}
            scope[:name] = quote(name) if name
            scope[:type] = type if type
            scope
          end
      end
    end
  end
end