lib/mir/index.rb in mir-0.1.2 vs lib/mir/index.rb in mir-0.1.3

- old
+ new

@@ -1,24 +1,32 @@ require 'active_record' require "active_support/inflector" -# Manages database operations for application +# The index class is responsible for maintaining knowledge of files uploaded +# onto the remote file system. The index does this by scanning the directory to +# be synchronized and evaluating whether a file needs to be uploaded or has changed +# since the last indexing date + module Mir class Index MIGRATIONS_PATH = File.join(File.dirname(__FILE__), "..", "..", "db", "migrate") # Returns a databse object used to connect to the indexing database + # + # @param [String] the absolute path of the directory to be synchronized # @param [Hash] database configuration settings. See ActiveRecord#Base::establish_connection def initialize(sync_path, connection_params) @sync_path = sync_path @connection_params = connection_params end attr_reader :sync_path + # # Creates necessary database and tables if this is the first time connecting + # # @option opts [Boolean] :verbose Enable on ActiveRecord reporting # @option opts [Boolean] :force_flush Rebuild index no matter what def setup(options = {}) options[:force_flush] ||= false options[:verbose] ||= false @@ -32,28 +40,54 @@ load_tables rebuild if !tables_created? or options[:force_flush] end - # Scans the filesystem and flags any resources which need updating + ## + # Scans the synchronization path and evaluates whether a resource has changed + # since the last index or is new and needs to be added to the index. def update Mir.logger.info "Updating backup index for '#{sync_path}'" + Models::AppSetting.last_indexed_at = @last_indexed_at = DateTime.now + Dir.glob(File.join(sync_path, "**", "*")) do |f| fname = relative_path(f) file = File.new(f) resource = Models::Resource.find_by_filename(fname) if resource.nil? - Mir.logger.info "Adding file to index #{fname}" + Mir.logger.debug "Adding file to index #{fname}" resource = Models::Resource.create_from_file_and_name(file, fname) - else - resource.flag_for_update unless resource.synchronized?(file) - end + elsif !resource.synchronized?(file) + resource.flag_for_update + end + resource.update_attribute(:last_indexed_at, last_indexed_at) end + Mir.logger.info "Index updated" end + ## + # Returns any files not present since the last re-indexing. This is useful + # for finding files that have been deleted post-index. + # + # @return [Mir::Models::Resource] + def orphans + Models::Resource.not_indexed_on(last_indexed_at) + end + + def last_indexed_at + @last_indexed_at ||= Models::AppSetting.last_indexed_at + end + + + ## + # Removes any files from the index that are no longer present locally + def clean! + Models::Resource.delete_all_except(last_indexed_at) + end + private # Returns the path of a file relative to the backup directory def relative_path(file) File.absolute_path(file).gsub(sync_path,'') end @@ -61,13 +95,15 @@ # Regenerates the file system index for the backup directory def rebuild tables.each { |t| ActiveRecord::Migration.drop_table(t.table_name) if t.table_exists? } ActiveRecord::Migration.drop_table(:schema_migrations) if @connection.table_exists? :schema_migrations ActiveRecord::Migrator.migrate MIGRATIONS_PATH - Models::AppSetting.create(:name => Models::AppSetting::SYNC_PATH, :value => sync_path) - Models::AppSetting.create(:name => Models::AppSetting::INSTALL_DATE, :value => DateTime.now.to_s) + Models::AppSetting.initialize_table(sync_path) end + + ## + # TODO: no reason to lazy load these activemodels def load_tables @tables = [] models = File.join(File.dirname(__FILE__), "models", "*.rb") # load the AR models for the application \ No newline at end of file