lib/chrono_model/adapter.rb in chrono_model-0.13.0 vs lib/chrono_model/adapter.rb in chrono_model-0.13.1

- old
+ new

@@ -460,12 +460,18 @@ klasses.any? { |k| e.message =~ /#{k.name}/ } end end def chrono_setup! - chrono_create_schemas + chrono_ensure_schemas + chrono_upgrade_warning + end + + def chrono_upgrade! + chrono_ensure_schemas + chrono_upgrade_structure! end # HACK: Redefine tsrange parsing support, as it is broken currently. # @@ -539,40 +545,72 @@ end private # Create the temporal and history schemas, unless they already exist # - def chrono_create_schemas + def chrono_ensure_schemas [TEMPORAL_SCHEMA, HISTORY_SCHEMA].each do |schema| execute "CREATE SCHEMA #{schema}" unless schema_exists?(schema) end end + # Locate tables needing a structure upgrade + # + def chrono_tables_needing_upgrade + tables = { } + + _on_temporal_schema { self.tables }.each do |table_name| + next unless is_chrono?(table_name) + metadata = chrono_metadata_for(table_name) + version = metadata['chronomodel'] + + if version.blank? + tables[table_name] = { version: nil, priority: 'CRITICAL' } + elsif version != VERSION + tables[table_name] = { version: version, priority: 'LOW' } + end + end + + return tables + end + + # Emit a warning about tables needing an upgrade + # + def chrono_upgrade_warning + upgrade = chrono_tables_needing_upgrade.map do |table, desc| + "#{table} - priority: #{desc[:priority]}" + end.join('; ') + + return if upgrade.empty? + + logger.warn "ChronoModel: There are tables needing a structure upgrade, and ChronoModel structures need to be recreated." + logger.warn "ChronoModel: Please run ChronoModel.upgrade! to attempt the upgrade. If you have dependant database objects" + logger.warn "ChronoModel: the upgrade will fail and you have to drop the dependent objects, run .upgrade! and create them" + logger.warn "ChronoModel: again. Sorry. Some features or the whole library may not work correctly until upgrade is complete." + logger.warn "ChronoModel: Tables pending upgrade: #{upgrade}" + end + # Upgrades existing structure for each table, if required. - # TODO: allow upgrades from pre-0.6 structure with box() and stuff. # def chrono_upgrade_structure! transaction do - current = VERSION - _on_temporal_schema { tables }.each do |table_name| - next unless is_chrono?(table_name) - metadata = chrono_metadata_for(table_name) - version = metadata['chronomodel'] + chrono_tables_needing_upgrade.each do |table_name, desc| - if version.blank? + if desc[:version].blank? + logger.info "ChronoModel: Upgrading legacy table #{table_name} to #{VERSION}" upgrade_from_legacy(table_name) + logger.info "ChronoModel: legacy #{table_name} upgrade complete" + else + logger.info "ChronoModel: upgrading #{table_name} from #{version} to #{VERSION}" + chrono_create_view_for(table_name) + logger.info "ChronoModel: #{table_name} upgrade complete" end - next if version == current - - logger.info "ChronoModel: upgrading #{table_name} from #{version} to #{current}" - chrono_create_view_for(table_name) - logger.info "ChronoModel: upgrade complete" end end rescue => e - message = "ChronoModel structure upgrade failed: #{e.message}. Please drop dependent objects and then run ActiveRecord::Base.connection.chrono_setup!" + message = "ChronoModel structure upgrade failed: #{e.message}. Please drop dependent objects first and then run ChronoModel.upgrade! again." # Quite important, output it also to stderr. # logger.error message $stderr.puts message