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