X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Factiverecord%2Flib%2Factive_record%2Fschema_dumper.rb;fp=vendor%2Frails%2Factiverecord%2Flib%2Factive_record%2Fschema_dumper.rb;h=557a55496676404bb03fb89b12a63855eda43366;hb=437aa336c44c74a30aeea16a06743c32747ed661;hp=0000000000000000000000000000000000000000;hpb=97a0772b06264134cfe38e7494f9427efe0840a0;p=feedcatcher.git diff --git a/vendor/rails/activerecord/lib/active_record/schema_dumper.rb b/vendor/rails/activerecord/lib/active_record/schema_dumper.rb new file mode 100644 index 0000000..557a554 --- /dev/null +++ b/vendor/rails/activerecord/lib/active_record/schema_dumper.rb @@ -0,0 +1,179 @@ +require 'stringio' +require 'bigdecimal' + +module ActiveRecord + # This class is used to dump the database schema for some connection to some + # output format (i.e., ActiveRecord::Schema). + class SchemaDumper #:nodoc: + private_class_method :new + + ## + # :singleton-method: + # A list of tables which should not be dumped to the schema. + # Acceptable values are strings as well as regexp. + # This setting is only used if ActiveRecord::Base.schema_format == :ruby + cattr_accessor :ignore_tables + @@ignore_tables = [] + + def self.dump(connection=ActiveRecord::Base.connection, stream=STDOUT) + new(connection).dump(stream) + stream + end + + def dump(stream) + header(stream) + tables(stream) + trailer(stream) + stream + end + + private + + def initialize(connection) + @connection = connection + @types = @connection.native_database_types + @version = Migrator::current_version rescue nil + end + + def header(stream) + define_params = @version ? ":version => #{@version}" : "" + + stream.puts <
"#{pk}") + end + else + tbl.print ", :id => false" + end + tbl.print ", :force => true" + tbl.puts " do |t|" + + column_specs = columns.map do |column| + raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil? + next if column.name == pk + spec = {} + spec[:name] = column.name.inspect + spec[:type] = column.type.to_s + spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal + spec[:precision] = column.precision.inspect if !column.precision.nil? + spec[:scale] = column.scale.inspect if !column.scale.nil? + spec[:null] = 'false' if !column.null + spec[:default] = default_string(column.default) if column.has_default? + (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")} + spec + end.compact + + # find all migration keys used in this table + keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map(&:keys).flatten + + # figure out the lengths for each column based on above keys + lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max } + + # the string we're going to sprintf our values against, with standardized column widths + format_string = lengths.map{ |len| "%-#{len}s" } + + # find the max length for the 'type' column, which is special + type_length = column_specs.map{ |column| column[:type].length }.max + + # add column type definition to our format string + format_string.unshift " t.%-#{type_length}s " + + format_string *= '' + + column_specs.each do |colspec| + values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len } + values.unshift colspec[:type] + tbl.print((format_string % values).gsub(/,\s*$/, '')) + tbl.puts + end + + tbl.puts " end" + tbl.puts + + indexes(table, tbl) + + tbl.rewind + stream.print tbl.read + rescue => e + stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}" + stream.puts "# #{e.message}" + stream.puts + end + + stream + end + + def default_string(value) + case value + when BigDecimal + value.to_s + when Date, DateTime, Time + "'" + value.to_s(:db) + "'" + else + value.inspect + end + end + + def indexes(table, stream) + if (indexes = @connection.indexes(table)).any? + add_index_statements = indexes.map do |index| + statment_parts = [ ('add_index ' + index.table.inspect) ] + statment_parts << index.columns.inspect + statment_parts << (':name => ' + index.name.inspect) + statment_parts << ':unique => true' if index.unique + + ' ' + statment_parts.join(', ') + end + + stream.puts add_index_statements.sort.join("\n") + stream.puts + end + end + end +end \ No newline at end of file